@rushstack/webpack5-localization-plugin 0.16.26 → 0.16.28
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/CHANGELOG.json +41 -0
- package/CHANGELOG.md +11 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/webpack5-localization-plugin.d.ts +2 -23
- package/lib-commonjs/LocalizationPlugin.js +55 -55
- package/lib-commonjs/LocalizationPlugin.js.map +1 -1
- package/lib-commonjs/TrueHashPlugin.js +3 -3
- package/lib-commonjs/TrueHashPlugin.js.map +1 -1
- package/lib-dts/LocalizationPlugin.d.ts +1 -22
- package/lib-dts/LocalizationPlugin.d.ts.map +1 -1
- package/lib-dts/TrueHashPlugin.d.ts +1 -1
- package/lib-dts/TrueHashPlugin.d.ts.map +1 -1
- package/lib-esm/LocalizationPlugin.js +55 -55
- package/lib-esm/LocalizationPlugin.js.map +1 -1
- package/lib-esm/TrueHashPlugin.js +3 -3
- package/lib-esm/TrueHashPlugin.js.map +1 -1
- package/package.json +7 -6
|
@@ -27,30 +27,30 @@ export function getPluginInstance(compiler) {
|
|
|
27
27
|
* @public
|
|
28
28
|
*/
|
|
29
29
|
export class LocalizationPlugin {
|
|
30
|
-
|
|
30
|
+
#locFiles = new Map();
|
|
31
31
|
/**
|
|
32
32
|
* @internal
|
|
33
33
|
*/
|
|
34
34
|
_options;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
#resolvedTranslatedStringsFromOptions = new Map();
|
|
36
|
+
#stringPlaceholderBySuffix = new Map();
|
|
37
|
+
#customDataPlaceholderBySuffix = new Map();
|
|
38
|
+
#customDataPlaceholderByUniqueId = new Map();
|
|
39
|
+
#passthroughLocaleName;
|
|
40
|
+
#defaultLocale;
|
|
41
|
+
#noStringsLocaleName;
|
|
42
|
+
#fillMissingTranslationStrings;
|
|
43
43
|
/**
|
|
44
44
|
* @remarks
|
|
45
45
|
* Include the `chunk` parameter so that the functions arity is the same as the
|
|
46
46
|
* `ValueForLocaleFn` type.
|
|
47
47
|
*/
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
#formatLocaleForFilename;
|
|
49
|
+
#pseudolocalizers = new Map();
|
|
50
50
|
/**
|
|
51
51
|
* The set of locales that have translations provided.
|
|
52
52
|
*/
|
|
53
|
-
|
|
53
|
+
#translatedLocales = new Set();
|
|
54
54
|
constructor(options) {
|
|
55
55
|
this._options = options;
|
|
56
56
|
}
|
|
@@ -61,7 +61,7 @@ export class LocalizationPlugin {
|
|
|
61
61
|
pluginForCompiler.set(compiler, this);
|
|
62
62
|
// https://github.com/webpack/webpack-dev-server/pull/1929/files#diff-15fb51940da53816af13330d8ce69b4eR66
|
|
63
63
|
const isWebpackDevServer = process.env.WEBPACK_DEV_SERVER === 'true';
|
|
64
|
-
const { errors, warnings } = this
|
|
64
|
+
const { errors, warnings } = this.#initializeAndValidateOptions(compiler, isWebpackDevServer);
|
|
65
65
|
if (errors.length > 0 || warnings.length > 0) {
|
|
66
66
|
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
67
67
|
compilation.errors.push(...errors);
|
|
@@ -143,7 +143,7 @@ export class LocalizationPlugin {
|
|
|
143
143
|
chunksWithUrlGenerators.add(activeChunkWithAsyncUrlGenerator);
|
|
144
144
|
}
|
|
145
145
|
if (chunkIdsWithStrings.size === 0) {
|
|
146
|
-
return this
|
|
146
|
+
return this.#formatLocaleForFilename(this.#noStringsLocaleName, undefined);
|
|
147
147
|
}
|
|
148
148
|
else if (chunkIdsWithoutStrings.size === 0) {
|
|
149
149
|
return `" + ${localeExpression} + "`;
|
|
@@ -166,7 +166,7 @@ export class LocalizationPlugin {
|
|
|
166
166
|
for (const id of smallerSet) {
|
|
167
167
|
chunkMapping[id] = 1;
|
|
168
168
|
}
|
|
169
|
-
const noLocaleExpression = JSON.stringify(this
|
|
169
|
+
const noLocaleExpression = JSON.stringify(this.#formatLocaleForFilename(this.#noStringsLocaleName, undefined));
|
|
170
170
|
return `" + (${JSON.stringify(chunkMapping)}[chunkId]?${isLocalizedSmaller ? localeExpression : noLocaleExpression}:${isLocalizedSmaller ? noLocaleExpression : localeExpression}) + "`;
|
|
171
171
|
}
|
|
172
172
|
});
|
|
@@ -176,9 +176,9 @@ export class LocalizationPlugin {
|
|
|
176
176
|
if (!locale) {
|
|
177
177
|
const isLocalized = _chunkHasLocalizedModules(chunkGraph, options.chunk, runtimeLocaleExpression);
|
|
178
178
|
// Ensure that the initial name maps to a file that should exist in the final output
|
|
179
|
-
locale = isLocalized ? this
|
|
179
|
+
locale = isLocalized ? this.#defaultLocale : this.#noStringsLocaleName;
|
|
180
180
|
}
|
|
181
|
-
return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, this
|
|
181
|
+
return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, this.#formatLocaleForFilename(locale, undefined));
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
else {
|
|
@@ -192,7 +192,7 @@ export class LocalizationPlugin {
|
|
|
192
192
|
// Generating derived assets, but explicitly want to create them *after* asset optimization
|
|
193
193
|
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1
|
|
194
194
|
}, async () => {
|
|
195
|
-
const locales = this
|
|
195
|
+
const locales = this.#translatedLocales;
|
|
196
196
|
const { chunkGraph, chunks } = compilation;
|
|
197
197
|
const { localizationStats: statsOptions } = this._options;
|
|
198
198
|
const filesByChunkName = statsOptions
|
|
@@ -225,10 +225,10 @@ export class LocalizationPlugin {
|
|
|
225
225
|
compilation,
|
|
226
226
|
cache,
|
|
227
227
|
locales,
|
|
228
|
-
defaultLocale: this
|
|
229
|
-
passthroughLocaleName: this
|
|
230
|
-
fillMissingTranslationStrings: this
|
|
231
|
-
formatLocaleForFilenameFn: this
|
|
228
|
+
defaultLocale: this.#defaultLocale,
|
|
229
|
+
passthroughLocaleName: this.#passthroughLocaleName,
|
|
230
|
+
fillMissingTranslationStrings: this.#fillMissingTranslationStrings,
|
|
231
|
+
formatLocaleForFilenameFn: this.#formatLocaleForFilename,
|
|
232
232
|
// Chunk-specific values
|
|
233
233
|
chunk,
|
|
234
234
|
asset,
|
|
@@ -246,8 +246,8 @@ export class LocalizationPlugin {
|
|
|
246
246
|
compilation,
|
|
247
247
|
cache,
|
|
248
248
|
hasUrlGenerator: chunksWithUrlGenerators.has(chunk),
|
|
249
|
-
noStringsLocaleName: this
|
|
250
|
-
formatLocaleForFilenameFn: this
|
|
249
|
+
noStringsLocaleName: this.#noStringsLocaleName,
|
|
250
|
+
formatLocaleForFilenameFn: this.#formatLocaleForFilename,
|
|
251
251
|
// Chunk-specific values
|
|
252
252
|
chunk,
|
|
253
253
|
asset,
|
|
@@ -309,9 +309,9 @@ export class LocalizationPlugin {
|
|
|
309
309
|
*/
|
|
310
310
|
async addDefaultLocFileAsync(context, localizedFileKey, localizedResourceData) {
|
|
311
311
|
const locFileData = convertLocalizationFileToLocData(localizedResourceData);
|
|
312
|
-
const fileInfo = this
|
|
312
|
+
const fileInfo = this.#addLocFileAndGetPlaceholders(this.#defaultLocale, localizedFileKey, locFileData);
|
|
313
313
|
const missingLocales = [];
|
|
314
|
-
for (const [translatedLocaleName, translatedStrings] of this
|
|
314
|
+
for (const [translatedLocaleName, translatedStrings] of this.#resolvedTranslatedStringsFromOptions) {
|
|
315
315
|
const translatedLocFileFromOptions = translatedStrings.get(localizedFileKey);
|
|
316
316
|
if (!translatedLocFileFromOptions) {
|
|
317
317
|
missingLocales.push(translatedLocaleName);
|
|
@@ -342,7 +342,7 @@ export class LocalizationPlugin {
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
|
-
for (const [pseudolocaleName, pseudolocalizer] of this
|
|
345
|
+
for (const [pseudolocaleName, pseudolocalizer] of this.#pseudolocalizers) {
|
|
346
346
|
const pseudolocFileData = new Map();
|
|
347
347
|
for (const [stringName, stringValue] of locFileData) {
|
|
348
348
|
pseudolocFileData.set(stringName, pseudolocalizer(stringValue));
|
|
@@ -356,7 +356,7 @@ export class LocalizationPlugin {
|
|
|
356
356
|
* @public
|
|
357
357
|
*/
|
|
358
358
|
getPlaceholder(localizedFileKey, stringName) {
|
|
359
|
-
const file = this.
|
|
359
|
+
const file = this.#locFiles.get(localizedFileKey);
|
|
360
360
|
if (!file) {
|
|
361
361
|
return undefined;
|
|
362
362
|
}
|
|
@@ -366,7 +366,7 @@ export class LocalizationPlugin {
|
|
|
366
366
|
* @beta
|
|
367
367
|
*/
|
|
368
368
|
getCustomDataPlaceholderForValueFunction(valueForLocaleFn, placeholderUniqueId) {
|
|
369
|
-
let placeholder = this.
|
|
369
|
+
let placeholder = this.#customDataPlaceholderByUniqueId.get(placeholderUniqueId);
|
|
370
370
|
if (!placeholder) {
|
|
371
371
|
// Get a hash of the unique ID to make sure its value doesn't interfere with our placeholder tokens
|
|
372
372
|
const suffix = Buffer.from(placeholderUniqueId, 'utf-8').toString('hex');
|
|
@@ -375,8 +375,8 @@ export class LocalizationPlugin {
|
|
|
375
375
|
suffix,
|
|
376
376
|
valueForLocaleFn
|
|
377
377
|
};
|
|
378
|
-
this.
|
|
379
|
-
this.
|
|
378
|
+
this.#customDataPlaceholderBySuffix.set(suffix, placeholder);
|
|
379
|
+
this.#customDataPlaceholderByUniqueId.set(placeholderUniqueId, placeholder);
|
|
380
380
|
}
|
|
381
381
|
else if (placeholder.valueForLocaleFn !== valueForLocaleFn) {
|
|
382
382
|
throw new Error(`${this.getCustomDataPlaceholderForValueFunction.name} has already been called with "${placeholderUniqueId}" ` +
|
|
@@ -388,23 +388,23 @@ export class LocalizationPlugin {
|
|
|
388
388
|
* @internal
|
|
389
389
|
*/
|
|
390
390
|
_getStringDataForSerialNumber(suffix) {
|
|
391
|
-
return this.
|
|
391
|
+
return this.#stringPlaceholderBySuffix.get(suffix);
|
|
392
392
|
}
|
|
393
393
|
/**
|
|
394
394
|
* @internal
|
|
395
395
|
*/
|
|
396
396
|
_getCustomDataForSerialNumber(suffix) {
|
|
397
|
-
return this.
|
|
397
|
+
return this.#customDataPlaceholderBySuffix.get(suffix);
|
|
398
398
|
}
|
|
399
|
-
|
|
400
|
-
let fileInfo = this.
|
|
399
|
+
#addLocFileAndGetPlaceholders(localeName, localizedFileKey, localizedFileData) {
|
|
400
|
+
let fileInfo = this.#locFiles.get(localizedFileKey);
|
|
401
401
|
if (!fileInfo) {
|
|
402
402
|
fileInfo = {
|
|
403
403
|
placeholders: new Map(),
|
|
404
404
|
translations: new Map(),
|
|
405
405
|
renderedPlaceholders: {}
|
|
406
406
|
};
|
|
407
|
-
this.
|
|
407
|
+
this.#locFiles.set(localizedFileKey, fileInfo);
|
|
408
408
|
}
|
|
409
409
|
const { placeholders, translations } = fileInfo;
|
|
410
410
|
const locFilePrefix = Buffer.from(localizedFileKey, 'utf-8').toString('hex') + '$';
|
|
@@ -421,7 +421,7 @@ export class LocalizationPlugin {
|
|
|
421
421
|
stringName
|
|
422
422
|
};
|
|
423
423
|
placeholders.set(stringName, placeholder);
|
|
424
|
-
this.
|
|
424
|
+
this.#stringPlaceholderBySuffix.set(suffix, placeholder);
|
|
425
425
|
}
|
|
426
426
|
resultObject[stringName] = placeholder.value;
|
|
427
427
|
}
|
|
@@ -429,7 +429,7 @@ export class LocalizationPlugin {
|
|
|
429
429
|
fileInfo.renderedPlaceholders = resultObject;
|
|
430
430
|
return fileInfo;
|
|
431
431
|
}
|
|
432
|
-
|
|
432
|
+
#initializeAndValidateOptions(compiler, isWebpackDevServer) {
|
|
433
433
|
const errors = [];
|
|
434
434
|
const warnings = [];
|
|
435
435
|
const { WebpackError } = compiler.webpack;
|
|
@@ -462,18 +462,18 @@ export class LocalizationPlugin {
|
|
|
462
462
|
if (passthroughLocale) {
|
|
463
463
|
const { usePassthroughLocale, passthroughLocaleName = 'passthrough' } = passthroughLocale;
|
|
464
464
|
if (usePassthroughLocale) {
|
|
465
|
-
this
|
|
466
|
-
this.
|
|
465
|
+
this.#passthroughLocaleName = passthroughLocaleName;
|
|
466
|
+
this.#translatedLocales.add(passthroughLocaleName);
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
469
|
// END options.localizedData.passthroughLocale
|
|
470
470
|
// START options.localizedData.translatedStrings
|
|
471
471
|
const resolveRelativeToContext = (configuration.context?.startsWith('/') ? path.posix.resolve : path.resolve).bind(0, configuration.context);
|
|
472
472
|
const { translatedStrings } = localizedData;
|
|
473
|
-
this.
|
|
473
|
+
this.#resolvedTranslatedStringsFromOptions.clear();
|
|
474
474
|
if (translatedStrings) {
|
|
475
475
|
for (const [localeName, locale] of Object.entries(translatedStrings)) {
|
|
476
|
-
if (this.
|
|
476
|
+
if (this.#translatedLocales.has(localeName)) {
|
|
477
477
|
errors.push(new WebpackError(`The locale "${localeName}" appears multiple times. ` +
|
|
478
478
|
'There may be multiple instances with different casing.'));
|
|
479
479
|
return { errors, warnings };
|
|
@@ -481,9 +481,9 @@ export class LocalizationPlugin {
|
|
|
481
481
|
if (!ensureValidLocaleName(localeName)) {
|
|
482
482
|
return { errors, warnings };
|
|
483
483
|
}
|
|
484
|
-
this.
|
|
484
|
+
this.#translatedLocales.add(localeName);
|
|
485
485
|
const resolvedFromOptionsForLocale = new Map();
|
|
486
|
-
this.
|
|
486
|
+
this.#resolvedTranslatedStringsFromOptions.set(localeName, resolvedFromOptionsForLocale);
|
|
487
487
|
for (const [locFilePath, locFileDataFromOptions] of Object.entries(locale)) {
|
|
488
488
|
const normalizedLocFilePath = resolveRelativeToContext(locFilePath);
|
|
489
489
|
if (resolvedFromOptionsForLocale.has(normalizedLocFilePath)) {
|
|
@@ -504,16 +504,16 @@ export class LocalizationPlugin {
|
|
|
504
504
|
if (defaultLocale) {
|
|
505
505
|
const { localeName, fillMissingTranslationStrings } = defaultLocale;
|
|
506
506
|
if (localeName) {
|
|
507
|
-
if (this.
|
|
507
|
+
if (this.#translatedLocales.has(localeName)) {
|
|
508
508
|
errors.push(new WebpackError('The default locale is also specified in the translated strings.'));
|
|
509
509
|
return { errors, warnings };
|
|
510
510
|
}
|
|
511
511
|
else if (!ensureValidLocaleName(localeName)) {
|
|
512
512
|
return { errors, warnings };
|
|
513
513
|
}
|
|
514
|
-
this.
|
|
515
|
-
this
|
|
516
|
-
this
|
|
514
|
+
this.#translatedLocales.add(localeName);
|
|
515
|
+
this.#defaultLocale = localeName;
|
|
516
|
+
this.#fillMissingTranslationStrings = !!fillMissingTranslationStrings;
|
|
517
517
|
}
|
|
518
518
|
else {
|
|
519
519
|
errors.push(new WebpackError('Missing default locale name'));
|
|
@@ -529,16 +529,16 @@ export class LocalizationPlugin {
|
|
|
529
529
|
const { pseudolocales } = localizedData;
|
|
530
530
|
if (pseudolocales) {
|
|
531
531
|
for (const [pseudolocaleName, pseudoLocaleOpts] of Object.entries(pseudolocales)) {
|
|
532
|
-
if (this
|
|
532
|
+
if (this.#defaultLocale === pseudolocaleName) {
|
|
533
533
|
errors.push(new WebpackError(`A pseudolocale (${pseudolocaleName}) name is also the default locale name.`));
|
|
534
534
|
return { errors, warnings };
|
|
535
535
|
}
|
|
536
|
-
if (this.
|
|
536
|
+
if (this.#translatedLocales.has(pseudolocaleName)) {
|
|
537
537
|
errors.push(new WebpackError(`A pseudolocale (${pseudolocaleName}) name is also specified in the translated strings.`));
|
|
538
538
|
return { errors, warnings };
|
|
539
539
|
}
|
|
540
|
-
this.
|
|
541
|
-
this.
|
|
540
|
+
this.#pseudolocalizers.set(pseudolocaleName, getPseudolocalizer(pseudoLocaleOpts));
|
|
541
|
+
this.#translatedLocales.add(pseudolocaleName);
|
|
542
542
|
}
|
|
543
543
|
}
|
|
544
544
|
// END options.localizedData.pseudoLocales
|
|
@@ -552,15 +552,15 @@ export class LocalizationPlugin {
|
|
|
552
552
|
if (noStringsLocaleName === undefined ||
|
|
553
553
|
noStringsLocaleName === null ||
|
|
554
554
|
!ensureValidLocaleName(noStringsLocaleName)) {
|
|
555
|
-
this
|
|
555
|
+
this.#noStringsLocaleName = 'none';
|
|
556
556
|
}
|
|
557
557
|
else {
|
|
558
|
-
this
|
|
558
|
+
this.#noStringsLocaleName = noStringsLocaleName;
|
|
559
559
|
}
|
|
560
560
|
// END options.noStringsLocaleName
|
|
561
561
|
// START options.formatLocaleForFilename
|
|
562
562
|
const { formatLocaleForFilename = (localeName) => localeName } = this._options;
|
|
563
|
-
this
|
|
563
|
+
this.#formatLocaleForFilename = formatLocaleForFilename;
|
|
564
564
|
// END options.formatLocaleForFilename
|
|
565
565
|
return { errors, warnings };
|
|
566
566
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalizationPlugin.js","sourceRoot":"","sources":["../src/LocalizationPlugin.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAelC,OAAO,EAAE,kBAAkB,EAA0B,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAC7G,OAAO,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAE/D,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AASnD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,mCAAmC,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAe,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AA2DvD,MAAM,WAAW,GAAmB,cAAc,CAAC;AAEnD,MAAM,iBAAiB,GAA0C,IAAI,OAAO,EAAE,CAAC;AAE/E;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAA8B;IAC9D,MAAM,QAAQ,GAAmC,QAAQ,IAAI,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,kBAAkB;IACZ,SAAS,GAAsC,IAAI,GAAG,EAAE,CAAC;IAE1E;;OAEG;IACa,QAAQ,CAA6B;IACpC,qCAAqC,GAGlD,IAAI,GAAG,EAAE,CAAC;IACG,0BAA0B,GAAoC,IAAI,GAAG,EAAE,CAAC;IACxE,8BAA8B,GAAwC,IAAI,GAAG,EAAE,CAAC;IAChF,gCAAgC,GAAwC,IAAI,GAAG,EAAE,CAAC;IAC3F,sBAAsB,CAAU;IAChC,cAAc,CAAU;IACxB,oBAAoB,CAAU;IAC9B,8BAA8B,CAAW;IACjD;;;;OAIG;IACK,wBAAwB,CAA2C;IAC1D,iBAAiB,GAAyC,IAAI,GAAG,EAAE,CAAC;IAErF;;OAEG;IACK,kBAAkB,GAAgB,IAAI,GAAG,EAAE,CAAC;IAEpD,YAAmB,OAAmC;QACpD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,QAAkB;QAC7B,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEtC,yGAAyG;QACzG,MAAM,kBAAkB,GAAY,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAC;QAE9E,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,6BAA6B,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QAE9F,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,WAAwB,EAAE,EAAE;gBACvE,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;gBACnC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,sFAAsF;gBACtF,2BAA2B;gBAC3B,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC;QAC1C,MAAM,EACJ,YAAY,EACZ,OAAO,EAAE,EAAE,6BAA6B,EAAE,EAC3C,GAAG,WAAW,CAAC;QAEhB,sGAAsG;QACtG,8EAA8E;QAC9E,IAAI,0BAA6C,CAAC;QAElD,MAAM,gBAAgB,GACpB,6BAA6B,CAAC,SAAS,CAAC,QAAQ,CAAC;QACnD,6BAA6B,CAAC,SAAS,CAAC,QAAQ,GAAG;YAGjD,mFAAmF;YACnF,mGAAmG;YACnG,0BAA0B,GAAG,IAAI,CAAC,KAAK,CAAC;YACxC,MAAM,MAAM,GAAkB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,yFAAyF;YACzF,0BAA0B,GAAG,SAAS,CAAC;YACvC,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,kBAAkB,GAAW,QAAQ,CAAC;QAE5C,MAAM,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAElD,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,WAAwB,EAAE,EAAE;YAC3E,IAAI,MAA0B,CAAC;YAC/B,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;gBAClC,IAAI,uBAAuB,EAAE,CAAC;oBAC5B,WAAW,CAAC,MAAM,CAAC,IAAI,CACrB,IAAI,YAAY,CACd,4FAA4F,CAC7F,CACF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,eAAe,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;iBAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,eAAe,EAAE,CAAC;gBAC1D,WAAW,CAAC,MAAM,CAAC,IAAI,CACrB,IAAI,WAAW,CAAC,YAAY,CAC1B,8DAA8D,kBAAkB,CAAC,IAAI,KAAK;oBACxF,sGAAsG;oBACtG,qCAAqC,kBAAkB,CAAC,IAAI,UAAU,CACzE,CACF,CAAC;YACJ,CAAC;YAED,MAAM,uBAAuB,GAAmB,IAAI,OAAO,EAAE,CAAC;YAE9D,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAC7B,WAAW,EACX,CAAC,SAAiB,EAAE,OAA0B,EAAU,EAAE;gBACxD,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;gBAEnC,IACE,OAAO,CAAC,eAAe,KAAK,YAAY;oBACxC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,2BAA2B,CAAC,EACtD,CAAC;oBACD,oDAAoD;oBACpD,IAAI,OAAO,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;wBACxF,MAAM,mBAAmB,GAAyB,IAAI,GAAG,EAAmB,CAAC;wBAC7E,MAAM,sBAAsB,GAAyB,IAAI,GAAG,EAAmB,CAAC;wBAEhF,MAAM,gCAAgC,GAAsB,0BAA0B,CAAC;wBAEvF,IAAI,CAAC,gCAAgC,EAAE,CAAC;4BACtC,WAAW,CAAC,MAAM,CAAC,IAAI,CACrB,IAAI,YAAY,CAAC,+DAA+D,CAAC,CAClF,CAAC;4BACF,OAAO,SAAS,CAAC;wBACnB,CAAC;wBAED,MAAM,WAAW,GAAe,gCAAgC,CAAC,iBAAiB,EAAE,CAAC;wBACrF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;4BACrC,MAAM,OAAO,GAA2B,UAAU,CAAC,EAAE,CAAC;4BAEtD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gCAC9C,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,CAAC,IAAI,8BAA8B,CAAC,CAAC;4BAC3E,CAAC;4BAED,IAAI,yBAAyB,CAAC,UAAU,EAAE,UAAU,EAAE,uBAAuB,CAAC,EAAE,CAAC;gCAC/E,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;4BACnC,CAAC;iCAAM,CAAC;gCACN,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;4BACtC,CAAC;wBACH,CAAC;wBAED,OAAO,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,2BAA2B,EAAE,GAAG,EAAE;4BACnE,uFAAuF;4BAEvF,2FAA2F;4BAC3F,uDAAuD;4BACvD,MAAM,gBAAgB,GACpB,CAAC,CAAC,yBAAyB,CACzB,UAAU,EACV,gCAAgC,EAChC,uBAAuB,CACxB;gCACC,uBAAuB,CAAC;gCAC1B,SAAS,CAAC,iBAAiB,CAAC;4BAC9B,IAAI,gBAAgB,KAAK,SAAS,CAAC,iBAAiB,EAAE,CAAC;gCACrD,uBAAuB,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;4BAChE,CAAC;4BAED,IAAI,mBAAmB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gCACnC,OAAO,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;4BAC7E,CAAC;iCAAM,IAAI,sBAAsB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gCAC7C,OAAO,OAAO,gBAAgB,MAAM,CAAC;4BACvC,CAAC;iCAAM,CAAC;gCACN,sGAAsG;gCACtG,gGAAgG;gCAChG,kGAAkG;gCAClG,wBAAwB;gCACxB,EAAE;gCACF,2GAA2G;gCAC3G,oDAAoD;gCACpD,MAAM,YAAY,GAA6B,EAAE,CAAC;gCAClD,+DAA+D;gCAC/D,MAAM,kBAAkB,GAAY,mBAAmB,CAAC,IAAI,IAAI,sBAAsB,CAAC,IAAI,CAAC;gCAC5F,+EAA+E;gCAC/E,MAAM,UAAU,GAAyB,kBAAkB;oCACzD,CAAC,CAAC,mBAAmB;oCACrB,CAAC,CAAC,sBAAsB,CAAC;gCAC3B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;oCAC5B,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gCACvB,CAAC;gCAED,MAAM,kBAAkB,GAAW,IAAI,CAAC,SAAS,CAC/C,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CACpE,CAAC;gCAEF,OAAO,QAAQ,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,aACzC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAC1C,IAAI,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,OAAO,CAAC;4BACxE,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,IAAI,MAAM,GAAuB,OAAO,CAAC,MAAM,CAAC;wBAChD,IAAI,CAAC,MAAM,EAAE,CAAC;4BACZ,MAAM,WAAW,GAAY,yBAAyB,CACpD,UAAU,EACV,OAAO,CAAC,KAAc,EACtB,uBAAuB,CACxB,CAAC;4BACF,oFAAoF;4BACpF,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC;wBACzE,CAAC;wBACD,OAAO,SAAS,CAAC,OAAO,CACtB,SAAS,CAAC,2BAA2B,EACrC,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,SAAS,CAAC,CACjD,CAAC;oBACJ,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC,CACF,CAAC;YAEF,MAAM,EAAE,aAAa,EAAE,GAAG,WAAW,CAAC;YAEtC,2GAA2G;YAC3G,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CACxC;gBACE,IAAI,EAAE,WAAW;gBACjB,2FAA2F;gBAC3F,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,gCAAgC,GAAG,CAAC;aACzE,EACD,KAAK,IAAmB,EAAE;gBACxB,MAAM,OAAO,GAAgB,IAAI,CAAC,kBAAkB,CAAC;gBAErD,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC;gBAC3C,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAE1D,MAAM,gBAAgB,GAAoD,YAAY;oBACpF,CAAC,CAAC,IAAI,GAAG,EAAE;oBACX,CAAC,CAAC,SAAS,CAAC;gBACd,MAAM,wBAAwB,GAAa,EAAE,CAAC;gBAC9C,MAAM,mBAAmB,GAAa,EAAE,CAAC;gBAGzC,MAAM,KAAK,GAAgB,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAE7D,MAAM,KAAK,CAAC,YAAY,CACtB,MAAM,EACN,KAAK,EAAE,KAAY,EAAE,EAAE;oBACrB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;wBAClC,OAAO;oBACT,CAAC;oBAED,MAAM,WAAW,GAAY,yBAAyB,CACpD,UAAU,EACV,KAAK,EACL,uBAAuB,CACxB,CAAC;oBAEF,MAAM,QAAQ,GACZ,KAAK,CAAC,gBAAgB;wBACtB,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAE,CAAC;oBAE/E,MAAM,gBAAgB,GAAW,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE;wBAC7D,KAAK;wBACL,eAAe,EAAE,YAAY;wBAC7B,kEAAkE;qBACnE,CAAC,CAAC;oBAEH,MAAM,KAAK,GAAsB,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;oBACxE,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,gCAAgC,gBAAgB,EAAE,CAAC,CAAC,CAAC;wBAC9F,OAAO;oBACT,CAAC;oBAED,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,eAAe,GAA2B,MAAM,gCAAgC,CAAC;4BACrF,gBAAgB;4BAChB,MAAM,EAAE,IAAI;4BACZ,WAAW;4BACX,KAAK;4BACL,OAAO;4BACP,aAAa,EAAE,IAAI,CAAC,cAAc;4BAClC,qBAAqB,EAAE,IAAI,CAAC,sBAAsB;4BAClD,6BAA6B,EAAE,IAAI,CAAC,8BAA8B;4BAClE,yBAAyB,EAAE,IAAI,CAAC,wBAAwB;4BACxD,wBAAwB;4BACxB,KAAK;4BACL,KAAK;4BACL,gBAAgB,EAAE,QAAQ;yBAC3B,CAAC,CAAC;wBAEH,IAAI,gBAAgB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;4BACnC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;4BAClD,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACzF,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,MAAM,mCAAmC,CAAC;4BACxC,gBAAgB;4BAChB,MAAM,EAAE,IAAI;4BACZ,WAAW;4BACX,KAAK;4BACL,eAAe,EAAE,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC;4BACnD,mBAAmB,EAAE,IAAI,CAAC,oBAAoB;4BAC9C,yBAAyB,EAAE,IAAI,CAAC,wBAAwB;4BACxD,wBAAwB;4BACxB,KAAK;4BACL,KAAK;4BACL,QAAQ,EAAE,gBAAgB;yBAC3B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,EACD;oBACE,0CAA0C;oBAC1C,WAAW,EAAE,EAAE;iBAChB,CACF,CAAC;gBAEF,IAAI,MAAM,EAAE,CAAC;oBACX,iBAAiB,CAAC;wBAChB,WAAW;wBACX,WAAW;wBACX,MAAM;wBACN,gBAAgB;qBACjB,CAAC,CAAC;gBACL,CAAC;gBAED,0EAA0E;gBAC1E,IAAI,YAAY,IAAI,gBAAgB,EAAE,CAAC;oBACrC,MAAM,iBAAiB,GAAuB;wBAC5C,WAAW,EAAE,EAAE;wBACf,gBAAgB,EAAE,EAAE;qBACrB,CAAC;oBAEF,sDAAsD;oBACtD,mBAAmB,CAAC,IAAI,EAAE,CAAC;oBAC3B,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE,CAAC;wBAC5C,iBAAiB,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG;4BAC9C,eAAe,EAAE,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE;yBAClD,CAAC;oBACJ,CAAC;oBAED,sDAAsD;oBACtD,wBAAwB,CAAC,IAAI,EAAE,CAAC;oBAChC,KAAK,MAAM,SAAS,IAAI,wBAAwB,EAAE,CAAC;wBACjD,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG;4BACzC,eAAe,EAAE,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE;yBAClD,CAAC;oBACJ,CAAC;oBAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC;oBAE5C,IAAI,QAAQ,EAAE,CAAC;wBACb,WAAW,CAAC,SAAS,CACnB,QAAQ,EACR,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAC1E,CAAC;oBACJ,CAAC;oBAED,IAAI,QAAQ,EAAE,CAAC;wBACb,IAAI,CAAC;4BACH,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;wBAC3C,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACX,sCAAsC;wBACxC,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,sBAAsB,CACjC,OAA0B,EAC1B,gBAAwB,EACxB,qBAAwC;QAExC,MAAM,WAAW,GAAgC,gCAAgC,CAAC,qBAAqB,CAAC,CAAC;QACzG,MAAM,QAAQ,GAAyB,IAAI,CAAC,6BAA6B,CACvE,IAAI,CAAC,cAAc,EACnB,gBAAgB,EAChB,WAAW,CACZ,CAAC;QAEF,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,IAAI,IAAI,CAAC,qCAAqC,EAAE,CAAC;YACnG,MAAM,4BAA4B,GAChC,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAE1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBAClC,cAAc,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,qBAAqB,GAAgC,MAAM,2BAA2B,CAC1F,OAAO,EACP,4BAA4B,CAC7B,CAAC;gBACF,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAED,MAAM,EAAE,+BAA+B,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;QAExE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,+BAA+B,EAAE,CAAC;YACjE,IAAI,sBAAsB,GAA6C,SAAS,CAAC;YACjF,IAAI,CAAC;gBACH,sBAAsB,GAAG,MAAM,+BAA+B,CAC5D,cAAc,EACd,gBAAgB,EAChB,OAAO,CACR,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YAED,IAAI,sBAAsB,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GACZ,sBAAsB,YAAY,GAAG;oBACnC,CAAC,CAAC,sBAAsB,CAAC,OAAO,EAAE;oBAClC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;gBAC7C,KAAK,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,IAAI,QAAQ,EAAE,CAAC;oBAChE,IAAI,kBAAkB,EAAE,CAAC;wBACvB,MAAM,qBAAqB,GAAgC,MAAM,2BAA2B,CAC1F,OAAO,EACP,kBAAkB,CACnB,CAAC;wBACF,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;oBACvE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,MAAM,CAAC,gBAAgB,EAAE,eAAe,CAAC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzE,MAAM,iBAAiB,GAAwB,IAAI,GAAG,EAAE,CAAC;YAEzD,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,WAAW,EAAE,CAAC;gBACpD,iBAAiB,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;YAClE,CAAC;YAED,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;QACjE,CAAC;QAED,UAAU,CAAC,OAAO,CAAC,OAAQ,EAAE,IAAI,CAAC,CAAC;QAEnC,OAAO,QAAQ,CAAC,oBAAoB,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,gBAAwB,EAAE,UAAkB;QAChE,MAAM,IAAI,GAAqC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACpF,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,wCAAwC,CAC7C,gBAAkC,EAClC,mBAA2B;QAE3B,IAAI,WAAW,GACb,IAAI,CAAC,gCAAgC,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,mGAAmG;YACnG,MAAM,MAAM,GAAW,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACjF,WAAW,GAAG;gBACZ,KAAK,EAAE,GAAG,SAAS,CAAC,yBAAyB,IAAI,SAAS,CAAC,wBAAwB,IAAI,MAAM,GAAG;gBAChG,MAAM;gBACN,gBAAgB;aACjB,CAAC;YACF,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAC7D,IAAI,CAAC,gCAAgC,CAAC,GAAG,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;QAC9E,CAAC;aAAM,IAAI,WAAW,CAAC,gBAAgB,KAAK,gBAAgB,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,wCAAwC,CAAC,IAAI,kCAAkC,mBAAmB,IAAI;gBAC5G,mCAAmC,CACtC,CAAC;QACJ,CAAC;QAED,OAAO,WAAW,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACI,6BAA6B,CAAC,MAAc;QACjD,OAAO,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACI,6BAA6B,CAAC,MAAc;QACjD,OAAO,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IAEO,6BAA6B,CACnC,UAAkB,EAClB,gBAAwB,EACxB,iBAA8C;QAE9C,IAAI,QAAQ,GAAqC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACtF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG;gBACT,YAAY,EAAE,IAAI,GAAG,EAAE;gBACvB,YAAY,EAAE,IAAI,GAAG,EAAE;gBACvB,oBAAoB,EAAE,EAAE;aACzB,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC;QAChD,MAAM,aAAa,GAAW,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;QAE3F,MAAM,YAAY,GAA2B,EAAE,CAAC;QAChD,KAAK,MAAM,UAAU,IAAI,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,WAAW,GAAmC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC/E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAW,GAAG,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAE7F,WAAW,GAAG;oBACZ,KAAK,EAAE,GAAG,SAAS,CAAC,yBAAyB,IAAI,SAAS,CAAC,wBAAwB,OAAO,MAAM,GAAG;oBACnG,MAAM;oBACN,YAAY,EAAE,YAAY;oBAC1B,WAAW,EAAE,gBAAgB;oBAC7B,UAAU;iBACX,CAAC;gBAEF,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;gBAC1C,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAC3D,CAAC;YAED,YAAY,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;QAC/C,CAAC;QAED,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;QAChD,QAAQ,CAAC,oBAAoB,GAAG,YAAY,CAAC;QAE7C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,6BAA6B,CACnC,QAAkB,EAClB,kBAA2B;QAE3B,MAAM,MAAM,GAAmB,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAmB,EAAE,CAAC;QAEpC,MAAM,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC1C,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,QAAQ,CAAC;QAE5C,MAAM,iBAAiB,GAAW,SAAS,CAAC;QAC5C,SAAS,qBAAqB,CAAC,UAAkB;YAC/C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACzC,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,wBAAwB,UAAU,sDAAsD,CACzF,CACF,CAAC;gBACF,OAAO,KAAK,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,IACE,CAAC,aAAa,CAAC,MAAM;YACrB,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ;YAC9B,OAAO,aAAa,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ;YACjD,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,EAC7E,CAAC;YACD,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,kGAAkG;gBAChG,OAAO,SAAS,CAAC,qBAAqB,cAAc,CACvD,CACF,CAAC;QACJ,CAAC;QACD,oBAAoB;QAEpB,qBAAqB;QACrB,8BAA8B;QAC9B,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxC,IAAI,aAAa,EAAE,CAAC;YAClB,gDAAgD;YAChD,MAAM,EAAE,iBAAiB,EAAE,GAAG,aAAa,CAAC;YAC5C,IAAI,iBAAiB,EAAE,CAAC;gBACtB,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,aAAa,EAAE,GAAG,iBAAiB,CAAC;gBAC1F,IAAI,oBAAoB,EAAE,CAAC;oBACzB,IAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;oBACpD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;YACD,8CAA8C;YAE9C,gDAAgD;YAChD,MAAM,wBAAwB,GAAiC,CAC7D,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAC3E,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC,OAAQ,CAAC,CAAC;YAClC,MAAM,EAAE,iBAAiB,EAAE,GAAG,aAAa,CAAC;YAC5C,IAAI,CAAC,qCAAqC,CAAC,KAAK,EAAE,CAAC;YACnD,IAAI,iBAAiB,EAAE,CAAC;gBACtB,KAAK,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACrE,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC5C,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,eAAe,UAAU,4BAA4B;4BACnD,wDAAwD,CAC3D,CACF,CAAC;wBACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC;wBACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBACxC,MAAM,4BAA4B,GAAiC,IAAI,GAAG,EAAE,CAAC;oBAC7E,IAAI,CAAC,qCAAqC,CAAC,GAAG,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;oBAEzF,KAAK,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC3E,MAAM,qBAAqB,GAAW,wBAAwB,CAAC,WAAW,CAAC,CAAC;wBAE5E,IAAI,4BAA4B,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,CAAC;4BAC5D,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,+BAA+B,WAAW,sCAAsC,UAAU,IAAI;gCAC5F,wDAAwD,CAC3D,CACF,CAAC;4BACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;wBAC9B,CAAC;wBAED,MAAM,gCAAgC,GACpC,OAAO,sBAAsB,KAAK,QAAQ;4BACxC,CAAC,CAAC,wBAAwB,CAAC,sBAAsB,CAAC;4BAClD,CAAC,CAAC,sBAAsB,CAAC;wBAE7B,4BAA4B,CAAC,GAAG,CAAC,qBAAqB,EAAE,gCAAgC,CAAC,CAAC;oBAC5F,CAAC;gBACH,CAAC;YACH,CAAC;YACD,8CAA8C;YAE9C,4CAA4C;YAC5C,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;YACxC,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,EAAE,UAAU,EAAE,6BAA6B,EAAE,GAAG,aAAa,CAAC;gBACpE,IAAI,UAAU,EAAE,CAAC;oBACf,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC5C,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,iEAAiE,CAAC,CAAC,CAAC;wBACjG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;yBAAM,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC9C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBACxC,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC;oBACjC,IAAI,CAAC,8BAA8B,GAAG,CAAC,CAAC,6BAA6B,CAAC;gBACxE,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,6BAA6B,CAAC,CAAC,CAAC;oBAC7D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,iCAAiC,CAAC,CAAC,CAAC;gBACjE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;YAC9B,CAAC;YACD,0CAA0C;YAE1C,4CAA4C;YAC5C,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;YACxC,IAAI,aAAa,EAAE,CAAC;gBAClB,KAAK,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;oBACjF,IAAI,IAAI,CAAC,cAAc,KAAK,gBAAgB,EAAE,CAAC;wBAC7C,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CAAC,mBAAmB,gBAAgB,yCAAyC,CAAC,CAC/F,CAAC;wBACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBAClD,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,mBAAmB,gBAAgB,qDAAqD,CACzF,CACF,CAAC;wBACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBACnF,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YACD,0CAA0C;QAC5C,CAAC;aAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC3F,CAAC;QACD,4BAA4B;QAE5B,oCAAoC;QACpC,MAAM,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9C,IACE,mBAAmB,KAAK,SAAS;YACjC,mBAAmB,KAAK,IAAI;YAC5B,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,EAC3C,CAAC;YACD,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,oBAAoB,GAAG,mBAAmB,CAAC;QAClD,CAAC;QACD,kCAAkC;QAElC,wCAAwC;QACxC,MAAM,EAAE,uBAAuB,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACvF,IAAI,CAAC,wBAAwB,GAAG,uBAAuB,CAAC;QACxD,sCAAsC;QACtC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;CACF;AAED,SAAS,yBAAyB,CAChC,UAAsB,EACtB,KAAY,EACZ,uBAA2C;IAE3C,IAAI,qBAAqB,GAAwB,OAAO,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,qBAAqB,KAAK,SAAS,EAAE,CAAC;QACxC,qBAAqB,GAAG,KAAK,CAAC;QAC9B,MAAM,gBAAgB,GAAiC,UAAU,CAAC,mCAAmC,CACnG,KAAK,EACL,YAAY,CACb,CAAC;QACF,IAAI,gBAAgB,EAAE,CAAC;YACrB,KAAK,EAAE,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;gBAC7C,MAAM,UAAU,GAAwB,OAAO,CAAC,MAAM,CAAC,CAAC;gBACxD,IAAI,UAAU,EAAE,CAAC;oBACf,qBAAqB,GAAG,IAAI,CAAC;oBAC7B,MAAM;gBACR,CAAC;qBAAM,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;oBAChC,SAAS;gBACX,CAAC;gBAED,iCAAiC;gBACjC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAyC,CAAC;gBACxE,IAAI,OAAO,EAAE,CAAC;oBACZ,KAAK,MAAM,YAAY,IAAI,OAAO,EAAE,CAAC;wBACnC,IAAI,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;4BAC1B,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;4BACzB,qBAAqB,GAAG,IAAI,CAAC;4BAC7B,MAAM,KAAK,CAAC;wBACd,CAAC;oBACH,CAAC;oBACD,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,8EAA8E;QAC9E,uCAAuC;QACvC,yEAAyE;QACzE,mBAAmB;QACnB,IAAI,CAAC,qBAAqB,IAAI,CAAC,uBAAuB,IAAI,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;YAC7E,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC;gBACnD,IAAI,yBAAyB,CAAC,UAAU,EAAE,UAAU,EAAE,uBAAuB,CAAC,EAAE,CAAC;oBAC/E,qBAAqB,GAAG,IAAI,CAAC;oBAC7B,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,UAAU,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,SAAS,gCAAgC,CAAC,OAA0B;IAClE,MAAM,WAAW,GAAwB,IAAI,GAAG,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjE,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,OAA0B,EAC1B,aAA8B;IAE9B,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACtC,+DAA+D;QAC/D,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;QACrC,MAAM,OAAO,GAAW,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5D,2FAA2F;YAC3F,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;gBAC/C,IAAI,GAAG,EAAE,CAAC;oBACR,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;qBAAM,IAAI,CAAC,IAAI,EAAE,CAAC;oBACjB,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,aAAa,EAAE,CAAC,CAAC,CAAC;gBAC1D,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAsB,YAAY,CAAC;YACvD,QAAQ,EAAE,aAAa;YACvB,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,gCAAgC,CAAC,gBAAgB,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,aAAa,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as path from 'node:path';\n\nimport type {\n Asset,\n Chunk,\n ChunkGraph,\n Compilation,\n Compiler,\n LoaderContext,\n Module,\n runtime,\n WebpackError,\n WebpackPluginInstance\n} from 'webpack';\n\nimport { getPseudolocalizer, type ILocalizationFile, parseResJson } from '@rushstack/localization-utilities';\nimport { Async } from '@rushstack/node-core-library/lib/Async';\n\nimport * as Constants from './utilities/Constants';\nimport type {\n ILocalizationPluginOptions,\n ILocalizationStats,\n ILocaleFileData,\n ILocaleFileObject,\n IResolvedMissingTranslations\n} from './interfaces';\nimport type { IAssetPathOptions } from './webpackInterfaces';\nimport { markEntity, getMark } from './utilities/EntityMarker';\nimport { processLocalizedAssetCachedAsync, processNonLocalizedAssetCachedAsync } from './AssetProcessor';\nimport { getHashFunction, type HashFn, updateAssetHashes } from './trueHashes';\nimport { chunkIsJs } from './utilities/chunkUtilities';\n\n/**\n * @public\n */\nexport type ValueForLocaleFn = (locale: string, chunk: Chunk) => string;\n\n/**\n * @public\n */\nexport interface IValuePlaceholderBase {\n /**\n * The literal string that will be injected for later replacement.\n */\n value: string;\n\n /**\n * The identifier for this particular placeholder, for lookup.\n */\n suffix: string;\n}\n\n/**\n * @public\n */\nexport interface IStringPlaceholder extends IValuePlaceholderBase {\n /**\n * The values of this string in each output locale.\n */\n translations: ReadonlyMap<string, ReadonlyMap<string, string>>;\n\n /**\n * The key used to identify the source file containing the string.\n */\n locFilePath: string;\n\n /**\n * The identifier of the string within its original source file.\n */\n stringName: string;\n}\n\n/**\n * @internal\n */\nexport interface ICustomDataPlaceholder extends IValuePlaceholderBase {\n /**\n * The function that will be invoked to get the value for this placeholder.\n * The function will be invoked with the locale name as the first argument.\n */\n valueForLocaleFn: ValueForLocaleFn;\n}\n\nexport interface IFileTranslationInfo {\n placeholders: Map<string, IStringPlaceholder>;\n translations: Map<string, ReadonlyMap<string, string>>;\n renderedPlaceholders: Record<string, string>;\n}\n\nconst PLUGIN_NAME: 'localization' = 'localization';\n\nconst pluginForCompiler: WeakMap<Compiler, LocalizationPlugin> = new WeakMap();\n\n/**\n * Gets the instance of the LocalizationPlugin bound to the specified webpack compiler.\n * Used by loaders.\n */\nexport function getPluginInstance(compiler: Compiler | undefined): LocalizationPlugin {\n const instance: LocalizationPlugin | undefined = compiler && pluginForCompiler.get(compiler);\n if (!instance) {\n throw new Error(`Could not find a LocalizationPlugin instance for the current webpack compiler!`);\n }\n return instance;\n}\n\n/**\n * This plugin facilitates localization in webpack.\n *\n * @public\n */\nexport class LocalizationPlugin implements WebpackPluginInstance {\n private readonly _locFiles: Map<string, IFileTranslationInfo> = new Map();\n\n /**\n * @internal\n */\n public readonly _options: ILocalizationPluginOptions;\n private readonly _resolvedTranslatedStringsFromOptions: Map<\n string,\n Map<string, ILocaleFileObject | string | ReadonlyMap<string, string>>\n > = new Map();\n private readonly _stringPlaceholderBySuffix: Map<string, IStringPlaceholder> = new Map();\n private readonly _customDataPlaceholderBySuffix: Map<string, ICustomDataPlaceholder> = new Map();\n private readonly _customDataPlaceholderByUniqueId: Map<string, ICustomDataPlaceholder> = new Map();\n private _passthroughLocaleName!: string;\n private _defaultLocale!: string;\n private _noStringsLocaleName!: string;\n private _fillMissingTranslationStrings!: boolean;\n /**\n * @remarks\n * Include the `chunk` parameter so that the functions arity is the same as the\n * `ValueForLocaleFn` type.\n */\n private _formatLocaleForFilename!: (loc: string, chunk: unknown) => string;\n private readonly _pseudolocalizers: Map<string, (str: string) => string> = new Map();\n\n /**\n * The set of locales that have translations provided.\n */\n private _translatedLocales: Set<string> = new Set();\n\n public constructor(options: ILocalizationPluginOptions) {\n this._options = options;\n }\n\n /**\n * Apply this plugin to the specified webpack compiler.\n */\n public apply(compiler: Compiler): void {\n pluginForCompiler.set(compiler, this);\n\n // https://github.com/webpack/webpack-dev-server/pull/1929/files#diff-15fb51940da53816af13330d8ce69b4eR66\n const isWebpackDevServer: boolean = process.env.WEBPACK_DEV_SERVER === 'true';\n\n const { errors, warnings } = this._initializeAndValidateOptions(compiler, isWebpackDevServer);\n\n if (errors.length > 0 || warnings.length > 0) {\n compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n compilation.errors.push(...errors);\n compilation.warnings.push(...warnings);\n });\n\n if (errors.length > 0) {\n // If there are any errors, just pass through the resources in source and don't do any\n // additional configuration\n return;\n }\n }\n\n const { webpack: thisWebpack } = compiler;\n const {\n WebpackError,\n runtime: { GetChunkFilenameRuntimeModule }\n } = thisWebpack;\n\n // Side-channel for async chunk URL generator chunk, since the actual chunk is completely inaccessible\n // from the assetPath hook below when invoked to build the async URL generator\n let chunkWithAsyncURLGenerator: Chunk | undefined;\n\n const originalGenerate: typeof GetChunkFilenameRuntimeModule.prototype.generate =\n GetChunkFilenameRuntimeModule.prototype.generate;\n GetChunkFilenameRuntimeModule.prototype.generate = function (\n this: runtime.GetChunkFilenameRuntimeModule\n ): string | null {\n // `originalGenerate` will invoke `getAssetPath` to produce the async URL generator\n // Need to know the identity of the containing chunk to correctly produce the asset path expression\n chunkWithAsyncURLGenerator = this.chunk;\n const result: string | null = originalGenerate.call(this);\n // Unset after the call finishes because we are no longer generating async URL generators\n chunkWithAsyncURLGenerator = undefined;\n return result;\n };\n\n const asyncGeneratorTest: RegExp = /^\\\" \\+/;\n\n const { runtimeLocaleExpression } = this._options;\n\n compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n let hashFn: HashFn | undefined;\n if (this._options.realContentHash) {\n if (runtimeLocaleExpression) {\n compilation.errors.push(\n new WebpackError(\n `The \"realContentHash\" option cannot be used in conjunction with \"runtimeLocaleExpression\".`\n )\n );\n } else {\n hashFn = getHashFunction({ thisWebpack, compilation });\n }\n } else if (compiler.options.optimization?.realContentHash) {\n compilation.errors.push(\n new thisWebpack.WebpackError(\n `The \\`optimization.realContentHash\\` option is set and the ${LocalizationPlugin.name}'s ` +\n '`realContentHash` option is not set. This will likely produce invalid results. Consider setting the ' +\n `\\`realContentHash\\` option in the ${LocalizationPlugin.name} plugin.`\n )\n );\n }\n\n const chunksWithUrlGenerators: WeakSet<Chunk> = new WeakSet();\n\n compilation.hooks.assetPath.tap(\n PLUGIN_NAME,\n (assetPath: string, options: IAssetPathOptions): string => {\n const { chunkGraph } = compilation;\n\n if (\n options.contentHashType === 'javascript' &&\n assetPath.match(Constants.LOCALE_FILENAME_TOKEN_REGEX)\n ) {\n // Does this look like an async chunk URL generator?\n if (typeof options.chunk?.id === 'string' && options.chunk.id.match(asyncGeneratorTest)) {\n const chunkIdsWithStrings: Set<number | string> = new Set<number | string>();\n const chunkIdsWithoutStrings: Set<number | string> = new Set<number | string>();\n\n const activeChunkWithAsyncUrlGenerator: Chunk | undefined = chunkWithAsyncURLGenerator;\n\n if (!activeChunkWithAsyncUrlGenerator) {\n compilation.errors.push(\n new WebpackError(`No active chunk while constructing async chunk URL generator!`)\n );\n return assetPath;\n }\n\n const asyncChunks: Set<Chunk> = activeChunkWithAsyncUrlGenerator.getAllAsyncChunks();\n for (const asyncChunk of asyncChunks) {\n const chunkId: number | string | null = asyncChunk.id;\n\n if (chunkId === null || chunkId === undefined) {\n throw new Error(`Chunk \"${asyncChunk.name}\"'s ID is null or undefined.`);\n }\n\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkIdsWithStrings.add(chunkId);\n } else {\n chunkIdsWithoutStrings.add(chunkId);\n }\n }\n\n return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, () => {\n // Use a replacer function so that we don't need to escape anything in the return value\n\n // If the runtime chunk is itself localized, forcibly match the locale of the runtime chunk\n // Otherwise prefer the runtime expression if specified\n const localeExpression: string =\n (!_chunkHasLocalizedModules(\n chunkGraph,\n activeChunkWithAsyncUrlGenerator,\n runtimeLocaleExpression\n ) &&\n runtimeLocaleExpression) ||\n Constants.JSONP_PLACEHOLDER;\n if (localeExpression === Constants.JSONP_PLACEHOLDER) {\n chunksWithUrlGenerators.add(activeChunkWithAsyncUrlGenerator);\n }\n\n if (chunkIdsWithStrings.size === 0) {\n return this._formatLocaleForFilename(this._noStringsLocaleName, undefined);\n } else if (chunkIdsWithoutStrings.size === 0) {\n return `\" + ${localeExpression} + \"`;\n } else {\n // Generate an object that is used to select between <locale> and <nostrings locale> for each chunk ID\n // Method: pick the smaller set of (localized, non-localized) and map that to 1 (a truthy value)\n // All other IDs map to `undefined` (a falsy value), so we then use the ternary operator to select\n // the appropriate token\n //\n // This can be improved in the future. We can maybe sort the chunks such that the chunks below a certain ID\n // number are localized and the those above are not.\n const chunkMapping: { [chunkId: string]: 1 } = {};\n // Use the map with the fewest values to shorten the expression\n const isLocalizedSmaller: boolean = chunkIdsWithStrings.size <= chunkIdsWithoutStrings.size;\n // These are the ids for which the expression should evaluate to a truthy value\n const smallerSet: Set<number | string> = isLocalizedSmaller\n ? chunkIdsWithStrings\n : chunkIdsWithoutStrings;\n for (const id of smallerSet) {\n chunkMapping[id] = 1;\n }\n\n const noLocaleExpression: string = JSON.stringify(\n this._formatLocaleForFilename(this._noStringsLocaleName, undefined)\n );\n\n return `\" + (${JSON.stringify(chunkMapping)}[chunkId]?${\n isLocalizedSmaller ? localeExpression : noLocaleExpression\n }:${isLocalizedSmaller ? noLocaleExpression : localeExpression}) + \"`;\n }\n });\n } else {\n let locale: string | undefined = options.locale;\n if (!locale) {\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n options.chunk as Chunk,\n runtimeLocaleExpression\n );\n // Ensure that the initial name maps to a file that should exist in the final output\n locale = isLocalized ? this._defaultLocale : this._noStringsLocaleName;\n }\n return assetPath.replace(\n Constants.LOCALE_FILENAME_TOKEN_REGEX,\n this._formatLocaleForFilename(locale, undefined)\n );\n }\n } else {\n return assetPath;\n }\n }\n );\n\n const { outputOptions } = compilation;\n\n // For compatibility with minifiers, need to generate the additional assets after the optimize process runs\n compilation.hooks.processAssets.tapPromise(\n {\n name: PLUGIN_NAME,\n // Generating derived assets, but explicitly want to create them *after* asset optimization\n stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1\n },\n async (): Promise<void> => {\n const locales: Set<string> = this._translatedLocales;\n\n const { chunkGraph, chunks } = compilation;\n const { localizationStats: statsOptions } = this._options;\n\n const filesByChunkName: Map<string, Record<string, string>> | undefined = statsOptions\n ? new Map()\n : undefined;\n const localizedEntryPointNames: string[] = [];\n const localizedChunkNames: string[] = [];\n\n type CacheFacade = ReturnType<Compilation['getCache']>;\n const cache: CacheFacade = compilation.getCache(PLUGIN_NAME);\n\n await Async.forEachAsync(\n chunks,\n async (chunk: Chunk) => {\n if (!chunkIsJs(chunk, chunkGraph)) {\n return;\n }\n\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n chunk,\n runtimeLocaleExpression\n );\n\n const template: Parameters<typeof Compilation.prototype.getAssetPath>[0] =\n chunk.filenameTemplate ||\n (chunk.hasRuntime() ? outputOptions.filename : outputOptions.chunkFilename)!;\n\n const defaultAssetName: string = compilation.getPath(template, {\n chunk,\n contentHashType: 'javascript'\n // Without locale this should return the name of the default asset\n });\n\n const asset: Asset | undefined = compilation.getAsset(defaultAssetName);\n if (!asset) {\n compilation.errors.push(new WebpackError(`Missing expected chunk asset ${defaultAssetName}`));\n return;\n }\n\n if (isLocalized) {\n const localizedAssets: Record<string, string> = await processLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n locales,\n defaultLocale: this._defaultLocale,\n passthroughLocaleName: this._passthroughLocaleName,\n fillMissingTranslationStrings: this._fillMissingTranslationStrings,\n formatLocaleForFilenameFn: this._formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n filenameTemplate: template\n });\n\n if (filesByChunkName && chunk.name) {\n filesByChunkName.set(chunk.name, localizedAssets);\n (chunk.hasRuntime() ? localizedEntryPointNames : localizedChunkNames).push(chunk.name);\n }\n } else {\n await processNonLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n hasUrlGenerator: chunksWithUrlGenerators.has(chunk),\n noStringsLocaleName: this._noStringsLocaleName,\n formatLocaleForFilenameFn: this._formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n fileName: defaultAssetName\n });\n }\n },\n {\n // Only async component is the cache layer\n concurrency: 20\n }\n );\n\n if (hashFn) {\n updateAssetHashes({\n thisWebpack,\n compilation,\n hashFn,\n filesByChunkName\n });\n }\n\n // Since the stats generation doesn't depend on content, do it immediately\n if (statsOptions && filesByChunkName) {\n const localizationStats: ILocalizationStats = {\n entrypoints: {},\n namedChunkGroups: {}\n };\n\n // Sort in lexicographic order to ensure stable output\n localizedChunkNames.sort();\n for (const chunkName of localizedChunkNames) {\n localizationStats.namedChunkGroups[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n // Sort in lexicographic order to ensure stable output\n localizedEntryPointNames.sort();\n for (const chunkName of localizedEntryPointNames) {\n localizationStats.entrypoints[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n const { dropPath, callback } = statsOptions;\n\n if (dropPath) {\n compilation.emitAsset(\n dropPath,\n new compiler.webpack.sources.RawSource(JSON.stringify(localizationStats))\n );\n }\n\n if (callback) {\n try {\n callback(localizationStats, compilation);\n } catch (e) {\n /* swallow errors from the callback */\n }\n }\n }\n }\n );\n });\n }\n\n /**\n * @public\n *\n * @returns An object mapping the string keys to placeholders\n */\n public async addDefaultLocFileAsync(\n context: LoaderContext<{}>,\n localizedFileKey: string,\n localizedResourceData: ILocalizationFile\n ): Promise<Record<string, string>> {\n const locFileData: ReadonlyMap<string, string> = convertLocalizationFileToLocData(localizedResourceData);\n const fileInfo: IFileTranslationInfo = this._addLocFileAndGetPlaceholders(\n this._defaultLocale,\n localizedFileKey,\n locFileData\n );\n\n const missingLocales: string[] = [];\n for (const [translatedLocaleName, translatedStrings] of this._resolvedTranslatedStringsFromOptions) {\n const translatedLocFileFromOptions: ILocaleFileData | undefined =\n translatedStrings.get(localizedFileKey);\n\n if (!translatedLocFileFromOptions) {\n missingLocales.push(translatedLocaleName);\n } else {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n translatedLocFileFromOptions\n );\n fileInfo.translations.set(translatedLocaleName, translatedLocFileData);\n }\n }\n\n const { resolveMissingTranslatedStrings } = this._options.localizedData;\n\n if (missingLocales.length > 0 && resolveMissingTranslatedStrings) {\n let resolvedTranslatedData: IResolvedMissingTranslations | undefined = undefined;\n try {\n resolvedTranslatedData = await resolveMissingTranslatedStrings(\n missingLocales,\n localizedFileKey,\n context\n );\n } catch (e) {\n context.emitError(e);\n }\n\n if (resolvedTranslatedData) {\n const iterable: Iterable<[string, ILocaleFileData]> =\n resolvedTranslatedData instanceof Map\n ? resolvedTranslatedData.entries()\n : Object.entries(resolvedTranslatedData);\n for (const [resolvedLocaleName, resolvedLocaleData] of iterable) {\n if (resolvedLocaleData) {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n resolvedLocaleData\n );\n fileInfo.translations.set(resolvedLocaleName, translatedLocFileData);\n }\n }\n }\n }\n\n for (const [pseudolocaleName, pseudolocalizer] of this._pseudolocalizers) {\n const pseudolocFileData: Map<string, string> = new Map();\n\n for (const [stringName, stringValue] of locFileData) {\n pseudolocFileData.set(stringName, pseudolocalizer(stringValue));\n }\n\n fileInfo.translations.set(pseudolocaleName, pseudolocFileData);\n }\n\n markEntity(context._module!, true);\n\n return fileInfo.renderedPlaceholders;\n }\n\n /**\n * @public\n */\n public getPlaceholder(localizedFileKey: string, stringName: string): IStringPlaceholder | undefined {\n const file: IFileTranslationInfo | undefined = this._locFiles.get(localizedFileKey);\n if (!file) {\n return undefined;\n }\n return file.placeholders.get(stringName);\n }\n\n /**\n * @beta\n */\n public getCustomDataPlaceholderForValueFunction(\n valueForLocaleFn: ValueForLocaleFn,\n placeholderUniqueId: string\n ): string {\n let placeholder: ICustomDataPlaceholder | undefined =\n this._customDataPlaceholderByUniqueId.get(placeholderUniqueId);\n if (!placeholder) {\n // Get a hash of the unique ID to make sure its value doesn't interfere with our placeholder tokens\n const suffix: string = Buffer.from(placeholderUniqueId, 'utf-8').toString('hex');\n placeholder = {\n value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.CUSTOM_PLACEHOLDER_LABEL}_${suffix}_`,\n suffix,\n valueForLocaleFn\n };\n this._customDataPlaceholderBySuffix.set(suffix, placeholder);\n this._customDataPlaceholderByUniqueId.set(placeholderUniqueId, placeholder);\n } else if (placeholder.valueForLocaleFn !== valueForLocaleFn) {\n throw new Error(\n `${this.getCustomDataPlaceholderForValueFunction.name} has already been called with \"${placeholderUniqueId}\" ` +\n `and a different valueForLocaleFn.`\n );\n }\n\n return placeholder.value;\n }\n\n /**\n * @internal\n */\n public _getStringDataForSerialNumber(suffix: string): IStringPlaceholder | undefined {\n return this._stringPlaceholderBySuffix.get(suffix);\n }\n\n /**\n * @internal\n */\n public _getCustomDataForSerialNumber(suffix: string): ICustomDataPlaceholder | undefined {\n return this._customDataPlaceholderBySuffix.get(suffix);\n }\n\n private _addLocFileAndGetPlaceholders(\n localeName: string,\n localizedFileKey: string,\n localizedFileData: ReadonlyMap<string, string>\n ): IFileTranslationInfo {\n let fileInfo: IFileTranslationInfo | undefined = this._locFiles.get(localizedFileKey);\n if (!fileInfo) {\n fileInfo = {\n placeholders: new Map(),\n translations: new Map(),\n renderedPlaceholders: {}\n };\n this._locFiles.set(localizedFileKey, fileInfo);\n }\n const { placeholders, translations } = fileInfo;\n const locFilePrefix: string = Buffer.from(localizedFileKey, 'utf-8').toString('hex') + '$';\n\n const resultObject: Record<string, string> = {};\n for (const stringName of localizedFileData.keys()) {\n let placeholder: IStringPlaceholder | undefined = placeholders.get(stringName);\n if (!placeholder) {\n const suffix: string = `${locFilePrefix}${Buffer.from(stringName, 'utf-8').toString('hex')}`;\n\n placeholder = {\n value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.STRING_PLACEHOLDER_LABEL}_\\\\_${suffix}_`,\n suffix,\n translations: translations,\n locFilePath: localizedFileKey,\n stringName\n };\n\n placeholders.set(stringName, placeholder);\n this._stringPlaceholderBySuffix.set(suffix, placeholder);\n }\n\n resultObject[stringName] = placeholder.value;\n }\n\n translations.set(localeName, localizedFileData);\n fileInfo.renderedPlaceholders = resultObject;\n\n return fileInfo;\n }\n\n private _initializeAndValidateOptions(\n compiler: Compiler,\n isWebpackDevServer: boolean\n ): { errors: WebpackError[]; warnings: WebpackError[] } {\n const errors: WebpackError[] = [];\n const warnings: WebpackError[] = [];\n\n const { WebpackError } = compiler.webpack;\n const { options: configuration } = compiler;\n\n const LOCALE_NAME_REGEX: RegExp = /[a-z-]/i;\n function ensureValidLocaleName(localeName: string): boolean {\n if (!localeName.match(LOCALE_NAME_REGEX)) {\n errors.push(\n new WebpackError(\n `Invalid locale name: ${localeName}. Locale names may only contain letters and hyphens.`\n )\n );\n return false;\n } else {\n return true;\n }\n }\n\n // START configuration\n if (\n !configuration.output ||\n !configuration.output.filename ||\n typeof configuration.output.filename !== 'string' ||\n configuration.output.filename.indexOf(Constants.LOCALE_FILENAME_TOKEN) === -1\n ) {\n errors.push(\n new WebpackError(\n 'The configuration.output.filename property must be provided, must be a string, and must include ' +\n `the ${Constants.LOCALE_FILENAME_TOKEN} placeholder`\n )\n );\n }\n // END configuration\n\n // START misc options\n // START options.localizedData\n const { localizedData } = this._options;\n if (localizedData) {\n // START options.localizedData.passthroughLocale\n const { passthroughLocale } = localizedData;\n if (passthroughLocale) {\n const { usePassthroughLocale, passthroughLocaleName = 'passthrough' } = passthroughLocale;\n if (usePassthroughLocale) {\n this._passthroughLocaleName = passthroughLocaleName;\n this._translatedLocales.add(passthroughLocaleName);\n }\n }\n // END options.localizedData.passthroughLocale\n\n // START options.localizedData.translatedStrings\n const resolveRelativeToContext: (relative: string) => string = (\n configuration.context?.startsWith('/') ? path.posix.resolve : path.resolve\n ).bind(0, configuration.context!);\n const { translatedStrings } = localizedData;\n this._resolvedTranslatedStringsFromOptions.clear();\n if (translatedStrings) {\n for (const [localeName, locale] of Object.entries(translatedStrings)) {\n if (this._translatedLocales.has(localeName)) {\n errors.push(\n new WebpackError(\n `The locale \"${localeName}\" appears multiple times. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this._translatedLocales.add(localeName);\n const resolvedFromOptionsForLocale: Map<string, ILocaleFileData> = new Map();\n this._resolvedTranslatedStringsFromOptions.set(localeName, resolvedFromOptionsForLocale);\n\n for (const [locFilePath, locFileDataFromOptions] of Object.entries(locale)) {\n const normalizedLocFilePath: string = resolveRelativeToContext(locFilePath);\n\n if (resolvedFromOptionsForLocale.has(normalizedLocFilePath)) {\n errors.push(\n new WebpackError(\n `The localization file path \"${locFilePath}\" appears multiple times in locale ${localeName}. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n const normalizedLocFileDataFromOptions: ILocaleFileData =\n typeof locFileDataFromOptions === 'string'\n ? resolveRelativeToContext(locFileDataFromOptions)\n : locFileDataFromOptions;\n\n resolvedFromOptionsForLocale.set(normalizedLocFilePath, normalizedLocFileDataFromOptions);\n }\n }\n }\n // END options.localizedData.translatedStrings\n\n // START options.localizedData.defaultLocale\n const { defaultLocale } = localizedData;\n if (defaultLocale) {\n const { localeName, fillMissingTranslationStrings } = defaultLocale;\n if (localeName) {\n if (this._translatedLocales.has(localeName)) {\n errors.push(new WebpackError('The default locale is also specified in the translated strings.'));\n return { errors, warnings };\n } else if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this._translatedLocales.add(localeName);\n this._defaultLocale = localeName;\n this._fillMissingTranslationStrings = !!fillMissingTranslationStrings;\n } else {\n errors.push(new WebpackError('Missing default locale name'));\n return { errors, warnings };\n }\n } else {\n errors.push(new WebpackError('Missing default locale options.'));\n return { errors, warnings };\n }\n // END options.localizedData.defaultLocale\n\n // START options.localizedData.pseudoLocales\n const { pseudolocales } = localizedData;\n if (pseudolocales) {\n for (const [pseudolocaleName, pseudoLocaleOpts] of Object.entries(pseudolocales)) {\n if (this._defaultLocale === pseudolocaleName) {\n errors.push(\n new WebpackError(`A pseudolocale (${pseudolocaleName}) name is also the default locale name.`)\n );\n return { errors, warnings };\n }\n\n if (this._translatedLocales.has(pseudolocaleName)) {\n errors.push(\n new WebpackError(\n `A pseudolocale (${pseudolocaleName}) name is also specified in the translated strings.`\n )\n );\n return { errors, warnings };\n }\n\n this._pseudolocalizers.set(pseudolocaleName, getPseudolocalizer(pseudoLocaleOpts));\n this._translatedLocales.add(pseudolocaleName);\n }\n }\n // END options.localizedData.pseudoLocales\n } else if (!isWebpackDevServer) {\n throw new Error('Localized data must be provided unless webpack dev server is running.');\n }\n // END options.localizedData\n\n // START options.noStringsLocaleName\n const { noStringsLocaleName } = this._options;\n if (\n noStringsLocaleName === undefined ||\n noStringsLocaleName === null ||\n !ensureValidLocaleName(noStringsLocaleName)\n ) {\n this._noStringsLocaleName = 'none';\n } else {\n this._noStringsLocaleName = noStringsLocaleName;\n }\n // END options.noStringsLocaleName\n\n // START options.formatLocaleForFilename\n const { formatLocaleForFilename = (localeName: string) => localeName } = this._options;\n this._formatLocaleForFilename = formatLocaleForFilename;\n // END options.formatLocaleForFilename\n return { errors, warnings };\n }\n}\n\nfunction _chunkHasLocalizedModules(\n chunkGraph: ChunkGraph,\n chunk: Chunk,\n runtimeLocaleExpression: string | undefined\n): boolean {\n let chunkHasAnyLocModules: boolean | undefined = getMark(chunk);\n if (chunkHasAnyLocModules === undefined) {\n chunkHasAnyLocModules = false;\n const candidateModules: Iterable<Module> | undefined = chunkGraph.getChunkModulesIterableBySourceType(\n chunk,\n 'javascript'\n );\n if (candidateModules) {\n outer: for (const module of candidateModules) {\n const moduleMark: boolean | undefined = getMark(module);\n if (moduleMark) {\n chunkHasAnyLocModules = true;\n break;\n } else if (moduleMark === false) {\n continue;\n }\n\n // Is this a concatenated module?\n const { _modules: modules } = module as { _modules?: Iterable<Module> };\n if (modules) {\n for (const nestedModule of modules) {\n if (getMark(nestedModule)) {\n markEntity(module, true);\n chunkHasAnyLocModules = true;\n break outer;\n }\n }\n markEntity(module, false);\n }\n }\n }\n\n // If this chunk doesn't directly contain any localized resources, it still\n // needs to be localized if it's an entrypoint chunk (i.e. - it has a runtime)\n // and it loads localized async chunks.\n // In that case, the generated chunk URL generation code needs to contain\n // the locale name.\n if (!chunkHasAnyLocModules && !runtimeLocaleExpression && chunk.hasRuntime()) {\n for (const asyncChunk of chunk.getAllAsyncChunks()) {\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkHasAnyLocModules = true;\n break;\n }\n }\n }\n\n markEntity(chunk, chunkHasAnyLocModules);\n }\n\n return chunkHasAnyLocModules;\n}\n\nfunction convertLocalizationFileToLocData(locFile: ILocalizationFile): ReadonlyMap<string, string> {\n const locFileData: Map<string, string> = new Map();\n for (const [stringName, locFileEntry] of Object.entries(locFile)) {\n locFileData.set(stringName, locFileEntry.value);\n }\n\n return locFileData;\n}\n\nasync function normalizeLocalizedDataAsync(\n context: LoaderContext<{}>,\n localizedData: ILocaleFileData\n): Promise<ReadonlyMap<string, string>> {\n if (typeof localizedData === 'string') {\n // The value is the path to a file. Add it as a file dependency\n context.addDependency(localizedData);\n const content: string = await new Promise((resolve, reject) => {\n // Use context.fs so that the plugin is compatible with overriding compiler.inputFileSystem\n context.fs.readFile(localizedData, (err, data) => {\n if (err) {\n return reject(err);\n } else if (!data) {\n return reject(new Error(`No data in ${localizedData}`));\n }\n resolve(data.toString());\n });\n });\n\n const localizationFile: ILocalizationFile = parseResJson({\n filePath: localizedData,\n content\n });\n\n return convertLocalizationFileToLocData(localizationFile);\n } else {\n return localizedData instanceof Map ? localizedData : new Map(Object.entries(localizedData));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"LocalizationPlugin.js","sourceRoot":"","sources":["../src/LocalizationPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as path from 'node:path';\n\nimport type {\n Asset,\n Chunk,\n ChunkGraph,\n Compilation,\n Compiler,\n LoaderContext,\n Module,\n runtime,\n WebpackError,\n WebpackPluginInstance\n} from 'webpack';\n\nimport { getPseudolocalizer, type ILocalizationFile, parseResJson } from '@rushstack/localization-utilities';\nimport { Async } from '@rushstack/node-core-library/lib/Async';\n\nimport * as Constants from './utilities/Constants';\nimport type {\n ILocalizationPluginOptions,\n ILocalizationStats,\n ILocaleFileData,\n ILocaleFileObject,\n IResolvedMissingTranslations\n} from './interfaces';\nimport type { IAssetPathOptions } from './webpackInterfaces';\nimport { markEntity, getMark } from './utilities/EntityMarker';\nimport { processLocalizedAssetCachedAsync, processNonLocalizedAssetCachedAsync } from './AssetProcessor';\nimport { getHashFunction, type HashFn, updateAssetHashes } from './trueHashes';\nimport { chunkIsJs } from './utilities/chunkUtilities';\n\n/**\n * @public\n */\nexport type ValueForLocaleFn = (locale: string, chunk: Chunk) => string;\n\n/**\n * @public\n */\nexport interface IValuePlaceholderBase {\n /**\n * The literal string that will be injected for later replacement.\n */\n value: string;\n\n /**\n * The identifier for this particular placeholder, for lookup.\n */\n suffix: string;\n}\n\n/**\n * @public\n */\nexport interface IStringPlaceholder extends IValuePlaceholderBase {\n /**\n * The values of this string in each output locale.\n */\n translations: ReadonlyMap<string, ReadonlyMap<string, string>>;\n\n /**\n * The key used to identify the source file containing the string.\n */\n locFilePath: string;\n\n /**\n * The identifier of the string within its original source file.\n */\n stringName: string;\n}\n\n/**\n * @internal\n */\nexport interface ICustomDataPlaceholder extends IValuePlaceholderBase {\n /**\n * The function that will be invoked to get the value for this placeholder.\n * The function will be invoked with the locale name as the first argument.\n */\n valueForLocaleFn: ValueForLocaleFn;\n}\n\nexport interface IFileTranslationInfo {\n placeholders: Map<string, IStringPlaceholder>;\n translations: Map<string, ReadonlyMap<string, string>>;\n renderedPlaceholders: Record<string, string>;\n}\n\nconst PLUGIN_NAME: 'localization' = 'localization';\n\nconst pluginForCompiler: WeakMap<Compiler, LocalizationPlugin> = new WeakMap();\n\n/**\n * Gets the instance of the LocalizationPlugin bound to the specified webpack compiler.\n * Used by loaders.\n */\nexport function getPluginInstance(compiler: Compiler | undefined): LocalizationPlugin {\n const instance: LocalizationPlugin | undefined = compiler && pluginForCompiler.get(compiler);\n if (!instance) {\n throw new Error(`Could not find a LocalizationPlugin instance for the current webpack compiler!`);\n }\n return instance;\n}\n\n/**\n * This plugin facilitates localization in webpack.\n *\n * @public\n */\nexport class LocalizationPlugin implements WebpackPluginInstance {\n readonly #locFiles: Map<string, IFileTranslationInfo> = new Map();\n\n /**\n * @internal\n */\n public readonly _options: ILocalizationPluginOptions;\n readonly #resolvedTranslatedStringsFromOptions: Map<\n string,\n Map<string, ILocaleFileObject | string | ReadonlyMap<string, string>>\n > = new Map();\n readonly #stringPlaceholderBySuffix: Map<string, IStringPlaceholder> = new Map();\n readonly #customDataPlaceholderBySuffix: Map<string, ICustomDataPlaceholder> = new Map();\n readonly #customDataPlaceholderByUniqueId: Map<string, ICustomDataPlaceholder> = new Map();\n #passthroughLocaleName!: string;\n #defaultLocale!: string;\n #noStringsLocaleName!: string;\n #fillMissingTranslationStrings!: boolean;\n /**\n * @remarks\n * Include the `chunk` parameter so that the functions arity is the same as the\n * `ValueForLocaleFn` type.\n */\n #formatLocaleForFilename!: (loc: string, chunk: unknown) => string;\n readonly #pseudolocalizers: Map<string, (str: string) => string> = new Map();\n\n /**\n * The set of locales that have translations provided.\n */\n #translatedLocales: Set<string> = new Set();\n\n public constructor(options: ILocalizationPluginOptions) {\n this._options = options;\n }\n\n /**\n * Apply this plugin to the specified webpack compiler.\n */\n public apply(compiler: Compiler): void {\n pluginForCompiler.set(compiler, this);\n\n // https://github.com/webpack/webpack-dev-server/pull/1929/files#diff-15fb51940da53816af13330d8ce69b4eR66\n const isWebpackDevServer: boolean = process.env.WEBPACK_DEV_SERVER === 'true';\n\n const { errors, warnings } = this.#initializeAndValidateOptions(compiler, isWebpackDevServer);\n\n if (errors.length > 0 || warnings.length > 0) {\n compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n compilation.errors.push(...errors);\n compilation.warnings.push(...warnings);\n });\n\n if (errors.length > 0) {\n // If there are any errors, just pass through the resources in source and don't do any\n // additional configuration\n return;\n }\n }\n\n const { webpack: thisWebpack } = compiler;\n const {\n WebpackError,\n runtime: { GetChunkFilenameRuntimeModule }\n } = thisWebpack;\n\n // Side-channel for async chunk URL generator chunk, since the actual chunk is completely inaccessible\n // from the assetPath hook below when invoked to build the async URL generator\n let chunkWithAsyncURLGenerator: Chunk | undefined;\n\n const originalGenerate: typeof GetChunkFilenameRuntimeModule.prototype.generate =\n GetChunkFilenameRuntimeModule.prototype.generate;\n GetChunkFilenameRuntimeModule.prototype.generate = function (\n this: runtime.GetChunkFilenameRuntimeModule\n ): string | null {\n // `originalGenerate` will invoke `getAssetPath` to produce the async URL generator\n // Need to know the identity of the containing chunk to correctly produce the asset path expression\n chunkWithAsyncURLGenerator = this.chunk;\n const result: string | null = originalGenerate.call(this);\n // Unset after the call finishes because we are no longer generating async URL generators\n chunkWithAsyncURLGenerator = undefined;\n return result;\n };\n\n const asyncGeneratorTest: RegExp = /^\\\" \\+/;\n\n const { runtimeLocaleExpression } = this._options;\n\n compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n let hashFn: HashFn | undefined;\n if (this._options.realContentHash) {\n if (runtimeLocaleExpression) {\n compilation.errors.push(\n new WebpackError(\n `The \"realContentHash\" option cannot be used in conjunction with \"runtimeLocaleExpression\".`\n )\n );\n } else {\n hashFn = getHashFunction({ thisWebpack, compilation });\n }\n } else if (compiler.options.optimization?.realContentHash) {\n compilation.errors.push(\n new thisWebpack.WebpackError(\n `The \\`optimization.realContentHash\\` option is set and the ${LocalizationPlugin.name}'s ` +\n '`realContentHash` option is not set. This will likely produce invalid results. Consider setting the ' +\n `\\`realContentHash\\` option in the ${LocalizationPlugin.name} plugin.`\n )\n );\n }\n\n const chunksWithUrlGenerators: WeakSet<Chunk> = new WeakSet();\n\n compilation.hooks.assetPath.tap(\n PLUGIN_NAME,\n (assetPath: string, options: IAssetPathOptions): string => {\n const { chunkGraph } = compilation;\n\n if (\n options.contentHashType === 'javascript' &&\n assetPath.match(Constants.LOCALE_FILENAME_TOKEN_REGEX)\n ) {\n // Does this look like an async chunk URL generator?\n if (typeof options.chunk?.id === 'string' && options.chunk.id.match(asyncGeneratorTest)) {\n const chunkIdsWithStrings: Set<number | string> = new Set<number | string>();\n const chunkIdsWithoutStrings: Set<number | string> = new Set<number | string>();\n\n const activeChunkWithAsyncUrlGenerator: Chunk | undefined = chunkWithAsyncURLGenerator;\n\n if (!activeChunkWithAsyncUrlGenerator) {\n compilation.errors.push(\n new WebpackError(`No active chunk while constructing async chunk URL generator!`)\n );\n return assetPath;\n }\n\n const asyncChunks: Set<Chunk> = activeChunkWithAsyncUrlGenerator.getAllAsyncChunks();\n for (const asyncChunk of asyncChunks) {\n const chunkId: number | string | null = asyncChunk.id;\n\n if (chunkId === null || chunkId === undefined) {\n throw new Error(`Chunk \"${asyncChunk.name}\"'s ID is null or undefined.`);\n }\n\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkIdsWithStrings.add(chunkId);\n } else {\n chunkIdsWithoutStrings.add(chunkId);\n }\n }\n\n return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, () => {\n // Use a replacer function so that we don't need to escape anything in the return value\n\n // If the runtime chunk is itself localized, forcibly match the locale of the runtime chunk\n // Otherwise prefer the runtime expression if specified\n const localeExpression: string =\n (!_chunkHasLocalizedModules(\n chunkGraph,\n activeChunkWithAsyncUrlGenerator,\n runtimeLocaleExpression\n ) &&\n runtimeLocaleExpression) ||\n Constants.JSONP_PLACEHOLDER;\n if (localeExpression === Constants.JSONP_PLACEHOLDER) {\n chunksWithUrlGenerators.add(activeChunkWithAsyncUrlGenerator);\n }\n\n if (chunkIdsWithStrings.size === 0) {\n return this.#formatLocaleForFilename(this.#noStringsLocaleName, undefined);\n } else if (chunkIdsWithoutStrings.size === 0) {\n return `\" + ${localeExpression} + \"`;\n } else {\n // Generate an object that is used to select between <locale> and <nostrings locale> for each chunk ID\n // Method: pick the smaller set of (localized, non-localized) and map that to 1 (a truthy value)\n // All other IDs map to `undefined` (a falsy value), so we then use the ternary operator to select\n // the appropriate token\n //\n // This can be improved in the future. We can maybe sort the chunks such that the chunks below a certain ID\n // number are localized and the those above are not.\n const chunkMapping: { [chunkId: string]: 1 } = {};\n // Use the map with the fewest values to shorten the expression\n const isLocalizedSmaller: boolean = chunkIdsWithStrings.size <= chunkIdsWithoutStrings.size;\n // These are the ids for which the expression should evaluate to a truthy value\n const smallerSet: Set<number | string> = isLocalizedSmaller\n ? chunkIdsWithStrings\n : chunkIdsWithoutStrings;\n for (const id of smallerSet) {\n chunkMapping[id] = 1;\n }\n\n const noLocaleExpression: string = JSON.stringify(\n this.#formatLocaleForFilename(this.#noStringsLocaleName, undefined)\n );\n\n return `\" + (${JSON.stringify(chunkMapping)}[chunkId]?${\n isLocalizedSmaller ? localeExpression : noLocaleExpression\n }:${isLocalizedSmaller ? noLocaleExpression : localeExpression}) + \"`;\n }\n });\n } else {\n let locale: string | undefined = options.locale;\n if (!locale) {\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n options.chunk as Chunk,\n runtimeLocaleExpression\n );\n // Ensure that the initial name maps to a file that should exist in the final output\n locale = isLocalized ? this.#defaultLocale : this.#noStringsLocaleName;\n }\n return assetPath.replace(\n Constants.LOCALE_FILENAME_TOKEN_REGEX,\n this.#formatLocaleForFilename(locale, undefined)\n );\n }\n } else {\n return assetPath;\n }\n }\n );\n\n const { outputOptions } = compilation;\n\n // For compatibility with minifiers, need to generate the additional assets after the optimize process runs\n compilation.hooks.processAssets.tapPromise(\n {\n name: PLUGIN_NAME,\n // Generating derived assets, but explicitly want to create them *after* asset optimization\n stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1\n },\n async (): Promise<void> => {\n const locales: Set<string> = this.#translatedLocales;\n\n const { chunkGraph, chunks } = compilation;\n const { localizationStats: statsOptions } = this._options;\n\n const filesByChunkName: Map<string, Record<string, string>> | undefined = statsOptions\n ? new Map()\n : undefined;\n const localizedEntryPointNames: string[] = [];\n const localizedChunkNames: string[] = [];\n\n type CacheFacade = ReturnType<Compilation['getCache']>;\n const cache: CacheFacade = compilation.getCache(PLUGIN_NAME);\n\n await Async.forEachAsync(\n chunks,\n async (chunk: Chunk) => {\n if (!chunkIsJs(chunk, chunkGraph)) {\n return;\n }\n\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n chunk,\n runtimeLocaleExpression\n );\n\n const template: Parameters<typeof Compilation.prototype.getAssetPath>[0] =\n chunk.filenameTemplate ||\n (chunk.hasRuntime() ? outputOptions.filename : outputOptions.chunkFilename)!;\n\n const defaultAssetName: string = compilation.getPath(template, {\n chunk,\n contentHashType: 'javascript'\n // Without locale this should return the name of the default asset\n });\n\n const asset: Asset | undefined = compilation.getAsset(defaultAssetName);\n if (!asset) {\n compilation.errors.push(new WebpackError(`Missing expected chunk asset ${defaultAssetName}`));\n return;\n }\n\n if (isLocalized) {\n const localizedAssets: Record<string, string> = await processLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n locales,\n defaultLocale: this.#defaultLocale,\n passthroughLocaleName: this.#passthroughLocaleName,\n fillMissingTranslationStrings: this.#fillMissingTranslationStrings,\n formatLocaleForFilenameFn: this.#formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n filenameTemplate: template\n });\n\n if (filesByChunkName && chunk.name) {\n filesByChunkName.set(chunk.name, localizedAssets);\n (chunk.hasRuntime() ? localizedEntryPointNames : localizedChunkNames).push(chunk.name);\n }\n } else {\n await processNonLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n hasUrlGenerator: chunksWithUrlGenerators.has(chunk),\n noStringsLocaleName: this.#noStringsLocaleName,\n formatLocaleForFilenameFn: this.#formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n fileName: defaultAssetName\n });\n }\n },\n {\n // Only async component is the cache layer\n concurrency: 20\n }\n );\n\n if (hashFn) {\n updateAssetHashes({\n thisWebpack,\n compilation,\n hashFn,\n filesByChunkName\n });\n }\n\n // Since the stats generation doesn't depend on content, do it immediately\n if (statsOptions && filesByChunkName) {\n const localizationStats: ILocalizationStats = {\n entrypoints: {},\n namedChunkGroups: {}\n };\n\n // Sort in lexicographic order to ensure stable output\n localizedChunkNames.sort();\n for (const chunkName of localizedChunkNames) {\n localizationStats.namedChunkGroups[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n // Sort in lexicographic order to ensure stable output\n localizedEntryPointNames.sort();\n for (const chunkName of localizedEntryPointNames) {\n localizationStats.entrypoints[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n const { dropPath, callback } = statsOptions;\n\n if (dropPath) {\n compilation.emitAsset(\n dropPath,\n new compiler.webpack.sources.RawSource(JSON.stringify(localizationStats))\n );\n }\n\n if (callback) {\n try {\n callback(localizationStats, compilation);\n } catch (e) {\n /* swallow errors from the callback */\n }\n }\n }\n }\n );\n });\n }\n\n /**\n * @public\n *\n * @returns An object mapping the string keys to placeholders\n */\n public async addDefaultLocFileAsync(\n context: LoaderContext<{}>,\n localizedFileKey: string,\n localizedResourceData: ILocalizationFile\n ): Promise<Record<string, string>> {\n const locFileData: ReadonlyMap<string, string> = convertLocalizationFileToLocData(localizedResourceData);\n const fileInfo: IFileTranslationInfo = this.#addLocFileAndGetPlaceholders(\n this.#defaultLocale,\n localizedFileKey,\n locFileData\n );\n\n const missingLocales: string[] = [];\n for (const [translatedLocaleName, translatedStrings] of this.#resolvedTranslatedStringsFromOptions) {\n const translatedLocFileFromOptions: ILocaleFileData | undefined =\n translatedStrings.get(localizedFileKey);\n\n if (!translatedLocFileFromOptions) {\n missingLocales.push(translatedLocaleName);\n } else {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n translatedLocFileFromOptions\n );\n fileInfo.translations.set(translatedLocaleName, translatedLocFileData);\n }\n }\n\n const { resolveMissingTranslatedStrings } = this._options.localizedData;\n\n if (missingLocales.length > 0 && resolveMissingTranslatedStrings) {\n let resolvedTranslatedData: IResolvedMissingTranslations | undefined = undefined;\n try {\n resolvedTranslatedData = await resolveMissingTranslatedStrings(\n missingLocales,\n localizedFileKey,\n context\n );\n } catch (e) {\n context.emitError(e);\n }\n\n if (resolvedTranslatedData) {\n const iterable: Iterable<[string, ILocaleFileData]> =\n resolvedTranslatedData instanceof Map\n ? resolvedTranslatedData.entries()\n : Object.entries(resolvedTranslatedData);\n for (const [resolvedLocaleName, resolvedLocaleData] of iterable) {\n if (resolvedLocaleData) {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n resolvedLocaleData\n );\n fileInfo.translations.set(resolvedLocaleName, translatedLocFileData);\n }\n }\n }\n }\n\n for (const [pseudolocaleName, pseudolocalizer] of this.#pseudolocalizers) {\n const pseudolocFileData: Map<string, string> = new Map();\n\n for (const [stringName, stringValue] of locFileData) {\n pseudolocFileData.set(stringName, pseudolocalizer(stringValue));\n }\n\n fileInfo.translations.set(pseudolocaleName, pseudolocFileData);\n }\n\n markEntity(context._module!, true);\n\n return fileInfo.renderedPlaceholders;\n }\n\n /**\n * @public\n */\n public getPlaceholder(localizedFileKey: string, stringName: string): IStringPlaceholder | undefined {\n const file: IFileTranslationInfo | undefined = this.#locFiles.get(localizedFileKey);\n if (!file) {\n return undefined;\n }\n return file.placeholders.get(stringName);\n }\n\n /**\n * @beta\n */\n public getCustomDataPlaceholderForValueFunction(\n valueForLocaleFn: ValueForLocaleFn,\n placeholderUniqueId: string\n ): string {\n let placeholder: ICustomDataPlaceholder | undefined =\n this.#customDataPlaceholderByUniqueId.get(placeholderUniqueId);\n if (!placeholder) {\n // Get a hash of the unique ID to make sure its value doesn't interfere with our placeholder tokens\n const suffix: string = Buffer.from(placeholderUniqueId, 'utf-8').toString('hex');\n placeholder = {\n value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.CUSTOM_PLACEHOLDER_LABEL}_${suffix}_`,\n suffix,\n valueForLocaleFn\n };\n this.#customDataPlaceholderBySuffix.set(suffix, placeholder);\n this.#customDataPlaceholderByUniqueId.set(placeholderUniqueId, placeholder);\n } else if (placeholder.valueForLocaleFn !== valueForLocaleFn) {\n throw new Error(\n `${this.getCustomDataPlaceholderForValueFunction.name} has already been called with \"${placeholderUniqueId}\" ` +\n `and a different valueForLocaleFn.`\n );\n }\n\n return placeholder.value;\n }\n\n /**\n * @internal\n */\n public _getStringDataForSerialNumber(suffix: string): IStringPlaceholder | undefined {\n return this.#stringPlaceholderBySuffix.get(suffix);\n }\n\n /**\n * @internal\n */\n public _getCustomDataForSerialNumber(suffix: string): ICustomDataPlaceholder | undefined {\n return this.#customDataPlaceholderBySuffix.get(suffix);\n }\n\n #addLocFileAndGetPlaceholders(\n localeName: string,\n localizedFileKey: string,\n localizedFileData: ReadonlyMap<string, string>\n ): IFileTranslationInfo {\n let fileInfo: IFileTranslationInfo | undefined = this.#locFiles.get(localizedFileKey);\n if (!fileInfo) {\n fileInfo = {\n placeholders: new Map(),\n translations: new Map(),\n renderedPlaceholders: {}\n };\n this.#locFiles.set(localizedFileKey, fileInfo);\n }\n const { placeholders, translations } = fileInfo;\n const locFilePrefix: string = Buffer.from(localizedFileKey, 'utf-8').toString('hex') + '$';\n\n const resultObject: Record<string, string> = {};\n for (const stringName of localizedFileData.keys()) {\n let placeholder: IStringPlaceholder | undefined = placeholders.get(stringName);\n if (!placeholder) {\n const suffix: string = `${locFilePrefix}${Buffer.from(stringName, 'utf-8').toString('hex')}`;\n\n placeholder = {\n value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.STRING_PLACEHOLDER_LABEL}_\\\\_${suffix}_`,\n suffix,\n translations: translations,\n locFilePath: localizedFileKey,\n stringName\n };\n\n placeholders.set(stringName, placeholder);\n this.#stringPlaceholderBySuffix.set(suffix, placeholder);\n }\n\n resultObject[stringName] = placeholder.value;\n }\n\n translations.set(localeName, localizedFileData);\n fileInfo.renderedPlaceholders = resultObject;\n\n return fileInfo;\n }\n\n #initializeAndValidateOptions(\n compiler: Compiler,\n isWebpackDevServer: boolean\n ): { errors: WebpackError[]; warnings: WebpackError[] } {\n const errors: WebpackError[] = [];\n const warnings: WebpackError[] = [];\n\n const { WebpackError } = compiler.webpack;\n const { options: configuration } = compiler;\n\n const LOCALE_NAME_REGEX: RegExp = /[a-z-]/i;\n function ensureValidLocaleName(localeName: string): boolean {\n if (!localeName.match(LOCALE_NAME_REGEX)) {\n errors.push(\n new WebpackError(\n `Invalid locale name: ${localeName}. Locale names may only contain letters and hyphens.`\n )\n );\n return false;\n } else {\n return true;\n }\n }\n\n // START configuration\n if (\n !configuration.output ||\n !configuration.output.filename ||\n typeof configuration.output.filename !== 'string' ||\n configuration.output.filename.indexOf(Constants.LOCALE_FILENAME_TOKEN) === -1\n ) {\n errors.push(\n new WebpackError(\n 'The configuration.output.filename property must be provided, must be a string, and must include ' +\n `the ${Constants.LOCALE_FILENAME_TOKEN} placeholder`\n )\n );\n }\n // END configuration\n\n // START misc options\n // START options.localizedData\n const { localizedData } = this._options;\n if (localizedData) {\n // START options.localizedData.passthroughLocale\n const { passthroughLocale } = localizedData;\n if (passthroughLocale) {\n const { usePassthroughLocale, passthroughLocaleName = 'passthrough' } = passthroughLocale;\n if (usePassthroughLocale) {\n this.#passthroughLocaleName = passthroughLocaleName;\n this.#translatedLocales.add(passthroughLocaleName);\n }\n }\n // END options.localizedData.passthroughLocale\n\n // START options.localizedData.translatedStrings\n const resolveRelativeToContext: (relative: string) => string = (\n configuration.context?.startsWith('/') ? path.posix.resolve : path.resolve\n ).bind(0, configuration.context!);\n const { translatedStrings } = localizedData;\n this.#resolvedTranslatedStringsFromOptions.clear();\n if (translatedStrings) {\n for (const [localeName, locale] of Object.entries(translatedStrings)) {\n if (this.#translatedLocales.has(localeName)) {\n errors.push(\n new WebpackError(\n `The locale \"${localeName}\" appears multiple times. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this.#translatedLocales.add(localeName);\n const resolvedFromOptionsForLocale: Map<string, ILocaleFileData> = new Map();\n this.#resolvedTranslatedStringsFromOptions.set(localeName, resolvedFromOptionsForLocale);\n\n for (const [locFilePath, locFileDataFromOptions] of Object.entries(locale)) {\n const normalizedLocFilePath: string = resolveRelativeToContext(locFilePath);\n\n if (resolvedFromOptionsForLocale.has(normalizedLocFilePath)) {\n errors.push(\n new WebpackError(\n `The localization file path \"${locFilePath}\" appears multiple times in locale ${localeName}. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n const normalizedLocFileDataFromOptions: ILocaleFileData =\n typeof locFileDataFromOptions === 'string'\n ? resolveRelativeToContext(locFileDataFromOptions)\n : locFileDataFromOptions;\n\n resolvedFromOptionsForLocale.set(normalizedLocFilePath, normalizedLocFileDataFromOptions);\n }\n }\n }\n // END options.localizedData.translatedStrings\n\n // START options.localizedData.defaultLocale\n const { defaultLocale } = localizedData;\n if (defaultLocale) {\n const { localeName, fillMissingTranslationStrings } = defaultLocale;\n if (localeName) {\n if (this.#translatedLocales.has(localeName)) {\n errors.push(new WebpackError('The default locale is also specified in the translated strings.'));\n return { errors, warnings };\n } else if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this.#translatedLocales.add(localeName);\n this.#defaultLocale = localeName;\n this.#fillMissingTranslationStrings = !!fillMissingTranslationStrings;\n } else {\n errors.push(new WebpackError('Missing default locale name'));\n return { errors, warnings };\n }\n } else {\n errors.push(new WebpackError('Missing default locale options.'));\n return { errors, warnings };\n }\n // END options.localizedData.defaultLocale\n\n // START options.localizedData.pseudoLocales\n const { pseudolocales } = localizedData;\n if (pseudolocales) {\n for (const [pseudolocaleName, pseudoLocaleOpts] of Object.entries(pseudolocales)) {\n if (this.#defaultLocale === pseudolocaleName) {\n errors.push(\n new WebpackError(`A pseudolocale (${pseudolocaleName}) name is also the default locale name.`)\n );\n return { errors, warnings };\n }\n\n if (this.#translatedLocales.has(pseudolocaleName)) {\n errors.push(\n new WebpackError(\n `A pseudolocale (${pseudolocaleName}) name is also specified in the translated strings.`\n )\n );\n return { errors, warnings };\n }\n\n this.#pseudolocalizers.set(pseudolocaleName, getPseudolocalizer(pseudoLocaleOpts));\n this.#translatedLocales.add(pseudolocaleName);\n }\n }\n // END options.localizedData.pseudoLocales\n } else if (!isWebpackDevServer) {\n throw new Error('Localized data must be provided unless webpack dev server is running.');\n }\n // END options.localizedData\n\n // START options.noStringsLocaleName\n const { noStringsLocaleName } = this._options;\n if (\n noStringsLocaleName === undefined ||\n noStringsLocaleName === null ||\n !ensureValidLocaleName(noStringsLocaleName)\n ) {\n this.#noStringsLocaleName = 'none';\n } else {\n this.#noStringsLocaleName = noStringsLocaleName;\n }\n // END options.noStringsLocaleName\n\n // START options.formatLocaleForFilename\n const { formatLocaleForFilename = (localeName: string) => localeName } = this._options;\n this.#formatLocaleForFilename = formatLocaleForFilename;\n // END options.formatLocaleForFilename\n return { errors, warnings };\n }\n}\n\nfunction _chunkHasLocalizedModules(\n chunkGraph: ChunkGraph,\n chunk: Chunk,\n runtimeLocaleExpression: string | undefined\n): boolean {\n let chunkHasAnyLocModules: boolean | undefined = getMark(chunk);\n if (chunkHasAnyLocModules === undefined) {\n chunkHasAnyLocModules = false;\n const candidateModules: Iterable<Module> | undefined = chunkGraph.getChunkModulesIterableBySourceType(\n chunk,\n 'javascript'\n );\n if (candidateModules) {\n outer: for (const module of candidateModules) {\n const moduleMark: boolean | undefined = getMark(module);\n if (moduleMark) {\n chunkHasAnyLocModules = true;\n break;\n } else if (moduleMark === false) {\n continue;\n }\n\n // Is this a concatenated module?\n const { _modules: modules } = module as { _modules?: Iterable<Module> };\n if (modules) {\n for (const nestedModule of modules) {\n if (getMark(nestedModule)) {\n markEntity(module, true);\n chunkHasAnyLocModules = true;\n break outer;\n }\n }\n markEntity(module, false);\n }\n }\n }\n\n // If this chunk doesn't directly contain any localized resources, it still\n // needs to be localized if it's an entrypoint chunk (i.e. - it has a runtime)\n // and it loads localized async chunks.\n // In that case, the generated chunk URL generation code needs to contain\n // the locale name.\n if (!chunkHasAnyLocModules && !runtimeLocaleExpression && chunk.hasRuntime()) {\n for (const asyncChunk of chunk.getAllAsyncChunks()) {\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkHasAnyLocModules = true;\n break;\n }\n }\n }\n\n markEntity(chunk, chunkHasAnyLocModules);\n }\n\n return chunkHasAnyLocModules;\n}\n\nfunction convertLocalizationFileToLocData(locFile: ILocalizationFile): ReadonlyMap<string, string> {\n const locFileData: Map<string, string> = new Map();\n for (const [stringName, locFileEntry] of Object.entries(locFile)) {\n locFileData.set(stringName, locFileEntry.value);\n }\n\n return locFileData;\n}\n\nasync function normalizeLocalizedDataAsync(\n context: LoaderContext<{}>,\n localizedData: ILocaleFileData\n): Promise<ReadonlyMap<string, string>> {\n if (typeof localizedData === 'string') {\n // The value is the path to a file. Add it as a file dependency\n context.addDependency(localizedData);\n const content: string = await new Promise((resolve, reject) => {\n // Use context.fs so that the plugin is compatible with overriding compiler.inputFileSystem\n context.fs.readFile(localizedData, (err, data) => {\n if (err) {\n return reject(err);\n } else if (!data) {\n return reject(new Error(`No data in ${localizedData}`));\n }\n resolve(data.toString());\n });\n });\n\n const localizationFile: ILocalizationFile = parseResJson({\n filePath: localizedData,\n content\n });\n\n return convertLocalizationFileToLocData(localizationFile);\n } else {\n return localizedData instanceof Map ? localizedData : new Map(Object.entries(localizedData));\n }\n}\n"]}
|
|
@@ -6,14 +6,14 @@ const PLUGIN_NAME = 'true-hash';
|
|
|
6
6
|
* @public
|
|
7
7
|
*/
|
|
8
8
|
export class TrueHashPlugin {
|
|
9
|
-
|
|
9
|
+
#options;
|
|
10
10
|
constructor(options = {}) {
|
|
11
|
-
this
|
|
11
|
+
this.#options = options;
|
|
12
12
|
}
|
|
13
13
|
apply(compiler) {
|
|
14
14
|
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
15
15
|
const { webpack: thisWebpack } = compiler;
|
|
16
|
-
const { hashFunction, stageOverride = thisWebpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1 } = this
|
|
16
|
+
const { hashFunction, stageOverride = thisWebpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1 } = this.#options;
|
|
17
17
|
const hashFn = hashFunction ??
|
|
18
18
|
getHashFunction({
|
|
19
19
|
thisWebpack,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrueHashPlugin.js","sourceRoot":"","sources":["../src/TrueHashPlugin.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAI3D,OAAO,EAAe,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE/E,MAAM,WAAW,GAAgB,WAAW,CAAC;AAiB7C;;GAEG;AACH,MAAM,OAAO,cAAc;
|
|
1
|
+
{"version":3,"file":"TrueHashPlugin.js","sourceRoot":"","sources":["../src/TrueHashPlugin.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAI3D,OAAO,EAAe,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE/E,MAAM,WAAW,GAAgB,WAAW,CAAC;AAiB7C;;GAEG;AACH,MAAM,OAAO,cAAc;IAChB,QAAQ,CAAyB;IAE1C,YAAmB,UAAkC,EAAE;QACrD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAEM,KAAK,CAAC,QAAkB;QAC7B,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,WAAwB,EAAE,EAAE;YAC3E,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC;YAC1C,MAAM,EAAE,YAAY,EAAE,aAAa,GAAG,WAAW,CAAC,WAAW,CAAC,gCAAgC,GAAG,CAAC,EAAE,GAClG,IAAI,CAAC,QAAQ,CAAC;YAChB,MAAM,MAAM,GACV,YAAY;gBACZ,eAAe,CAAC;oBACd,WAAW;oBACX,WAAW;iBACZ,CAAC,CAAC;YAEL,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CACjC;gBACE,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,aAAa;aACrB,EACD,GAAG,EAAE,CAAC,iBAAiB,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAC9D,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { Compilation, Compiler, WebpackPluginInstance } from 'webpack';\n\nimport { type HashFn, getHashFunction, updateAssetHashes } from './trueHashes';\n\nconst PLUGIN_NAME: 'true-hash' = 'true-hash';\n\n/**\n * @public\n */\nexport interface ITrueHashPluginOptions {\n /**\n * A function that takes the contents of a file and returns a hash.\n */\n hashFunction?: (contents: string | Buffer) => string;\n\n /**\n * Optionally override the process assets stage for this plugin.\n */\n stageOverride?: number;\n}\n\n/**\n * @public\n */\nexport class TrueHashPlugin implements WebpackPluginInstance {\n readonly #options: ITrueHashPluginOptions;\n\n public constructor(options: ITrueHashPluginOptions = {}) {\n this.#options = options;\n }\n\n public apply(compiler: Compiler): void {\n compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n const { webpack: thisWebpack } = compiler;\n const { hashFunction, stageOverride = thisWebpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1 } =\n this.#options;\n const hashFn: HashFn =\n hashFunction ??\n getHashFunction({\n thisWebpack,\n compilation\n });\n\n compilation.hooks.processAssets.tap(\n {\n name: PLUGIN_NAME,\n stage: stageOverride\n },\n () => updateAssetHashes({ thisWebpack, compilation, hashFn })\n );\n });\n }\n}\n"]}
|