@itwin/core-quantity 4.7.0-dev.9 → 4.8.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # Change Log - @itwin/core-quantity
2
2
 
3
- This log was last generated on Wed, 15 May 2024 21:32:22 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 29 May 2024 14:36:43 GMT and should not be manually modified.
4
+
5
+ ## 4.6.1
6
+ Wed, 29 May 2024 14:35:17 GMT
7
+
8
+ _Version update only_
4
9
 
5
10
  ## 4.6.0
6
11
  Mon, 13 May 2024 20:32:51 GMT
@@ -1 +1 @@
1
- {"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,aAAa,EAAuB,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjK,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;GAEG;AACH,oBAAY,UAAU;IACpB,2BAA2B,IAAI;IAC/B,0BAA0B,IAAA;IAC1B,8BAA8B,IAAA;IAC9B,WAAW,IAAA;IACX,oCAAoC,IAAA;IACpC,iBAAiB,IAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,EAAE,EAAE,KAAK,CAAC;IACV,uDAAuD;IACvD,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,EAAE,EAAE,IAAI,CAAC;IACT,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAEtE;;GAEG;AACH,cAAM,UAAU;IACP,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;gBAElB,KAAK,EAAE,MAAM,GAAG,MAAM;IAOlC,IAAW,QAAQ,IAAI,OAAO,CAA2C;IACzE,IAAW,QAAQ,IAAI,OAAO,CAA2C;CAC1E;AA+BD;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAS;WAEd,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,cAAc;WAInE,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,kBAAkB;IAIjF,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAoBzC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAyChC,OAAO,CAAC,MAAM,CAAC,OAAO;IAItB,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAIxC;;OAEG;WACW,0BAA0B,CAAC,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;mBA6IhF,iBAAiB;mBA6BjB,6BAA6B;IA2ElD;;;;OAIG;WACiB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,aAAa,CAAC;IAQlL,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAyCpC,OAAO,CAAC,MAAM,CAAC,+BAA+B;IAqE9C;;;;OAIG;WACW,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,mBAAmB;IAIhG;;;;OAIG;WACW,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,GAAG,mBAAmB;IA+BjI,+HAA+H;WAC3G,gCAAgC,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA4B1L,+HAA+H;WAC3G,yBAAyB,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAgDhO"}
1
+ {"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,aAAa,EAAuB,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjK,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;GAEG;AACH,oBAAY,UAAU;IACpB,2BAA2B,IAAI;IAC/B,0BAA0B,IAAA;IAC1B,8BAA8B,IAAA;IAC9B,WAAW,IAAA;IACX,oCAAoC,IAAA;IACpC,iBAAiB,IAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,EAAE,EAAE,KAAK,CAAC;IACV,uDAAuD;IACvD,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,EAAE,EAAE,IAAI,CAAC;IACT,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAEtE;;GAEG;AACH,cAAM,UAAU;IACP,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;gBAElB,KAAK,EAAE,MAAM,GAAG,MAAM;IAOlC,IAAW,QAAQ,IAAI,OAAO,CAA2C;IACzE,IAAW,QAAQ,IAAI,OAAO,CAA2C;CAC1E;AA+BD;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAS;WAEd,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,cAAc;WAInE,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,kBAAkB;IAIjF,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAoBzC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAyChC,OAAO,CAAC,MAAM,CAAC,OAAO;IAItB,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAIxC;;OAEG;WACW,0BAA0B,CAAC,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;mBA6IhF,iBAAiB;mBA6BjB,6BAA6B;IAkElD;;;;OAIG;WACiB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,aAAa,CAAC;IAQlL,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAyCpC,OAAO,CAAC,MAAM,CAAC,+BAA+B;IAmE9C;;;;OAIG;WACW,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,mBAAmB;IAIhG;;;;OAIG;WACW,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,GAAG,mBAAmB;IA+BjI,+HAA+H;WAC3G,gCAAgC,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA4B1L,+HAA+H;WAC3G,yBAAyB,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAgDhO"}
package/lib/cjs/Parser.js CHANGED
@@ -299,6 +299,10 @@ class Parser {
299
299
  }
300
300
  // common case where single value and single label are supplied
301
301
  if (tokens.length === 2) {
302
+ // unit specification comes before value (like currency)
303
+ if (tokens[1].isNumber && tokens[0].isString) {
304
+ tokens = [tokens[1], tokens[0]];
305
+ }
302
306
  if (tokens[0].isNumber && tokens[1].isString) {
303
307
  const unit = await this.lookupUnitByLabel(tokens[1].value, format, unitsProvider, altUnitLabelsProvider);
304
308
  if (undefined === defaultUnit)
@@ -312,21 +316,6 @@ class Parser {
312
316
  return new Quantity_1.Quantity(defaultUnit, mag);
313
317
  }
314
318
  }
315
- else { // unit specification comes before value (like currency)
316
- if (tokens[1].isNumber && tokens[0].isString) {
317
- const unit = await this.lookupUnitByLabel(tokens[0].value, format, unitsProvider, altUnitLabelsProvider);
318
- if (undefined === defaultUnit)
319
- defaultUnit = unit;
320
- if (defaultUnit && defaultUnit.name === unit.name) {
321
- return new Quantity_1.Quantity(defaultUnit, tokens[1].value);
322
- }
323
- else if (defaultUnit) {
324
- const conversion = await unitsProvider.getConversion(unit, defaultUnit);
325
- const mag = ((tokens[1].value * conversion.factor)) + conversion.offset;
326
- return new Quantity_1.Quantity(defaultUnit, mag);
327
- }
328
- }
329
- }
330
319
  }
331
320
  // common case where there are multiple value/label pairs
332
321
  if (tokens.length % 2 === 0) {
@@ -438,8 +427,16 @@ class Parser {
438
427
  }
439
428
  // common case where single value and single label are supplied
440
429
  if (tokens.length === 2) {
430
+ // unit specification comes before value (like currency)
431
+ if (tokens[1].isNumber && tokens[0].isString) {
432
+ tokens = [tokens[1], tokens[0]];
433
+ }
441
434
  if (tokens[0].isNumber && tokens[1].isString) {
442
- const conversion = Parser.tryFindUnitConversion(tokens[1].value, unitsConversions, defaultUnit);
435
+ let conversion = Parser.tryFindUnitConversion(tokens[1].value, unitsConversions, defaultUnit);
436
+ // if no conversion, ignore value in second token. If we have defaultUnit, use it.
437
+ if (!conversion && defaultUnit) {
438
+ conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);
439
+ }
443
440
  if (conversion) {
444
441
  const value = tokens[0].value * conversion.factor + conversion.offset;
445
442
  return { ok: true, value };
@@ -447,17 +444,6 @@ class Parser {
447
444
  // if no conversion, just return parsed number and ignore value in second token
448
445
  return { ok: true, value: tokens[0].value };
449
446
  }
450
- else { // unit specification comes before value (like currency)
451
- if (tokens[1].isNumber && tokens[0].isString) {
452
- const conversion = Parser.tryFindUnitConversion(tokens[0].value, unitsConversions, defaultUnit);
453
- if (conversion) {
454
- const value = tokens[1].value * conversion.factor + conversion.offset;
455
- return { ok: true, value };
456
- }
457
- // if no conversion, just return parsed number and ignore value in second token
458
- return { ok: true, value: tokens[1].value };
459
- }
460
- }
461
447
  }
462
448
  // common case where there are multiple value/label pairs
463
449
  if (tokens.length % 2 === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { QuantityConstants } from \"./Constants\";\r\nimport { Format } from \"./Formatter/Format\";\r\nimport { FormatTraits, FormatType } from \"./Formatter/FormatEnums\";\r\nimport { AlternateUnitLabelsProvider, PotentialParseUnit, QuantityProps, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"./Interfaces\";\r\nimport { ParserSpec } from \"./ParserSpec\";\r\nimport { Quantity } from \"./Quantity\";\r\n\r\n/** Possible parser errors\r\n * @beta\r\n */\r\nexport enum ParseError {\r\n UnableToGenerateParseTokens = 1,\r\n NoValueOrUnitFoundInString,\r\n UnitLabelSuppliedButNotMatched,\r\n UnknownUnit,\r\n UnableToConvertParseTokensToQuantity,\r\n InvalidParserSpec,\r\n}\r\n\r\n/** Parse error result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParseQuantityError {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: false;\r\n /** The specific error that occurred during parsing. */\r\n error: ParseError;\r\n}\r\n\r\n/** Successful result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParsedQuantity {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: true;\r\n /** The magnitude of the parsed quantity. */\r\n value: number;\r\n}\r\n\r\n/**\r\n * Defines Results of parsing a string input by a user into its desired value type\r\n * @beta\r\n */\r\nexport type QuantityParseResult = ParsedQuantity | ParseQuantityError;\r\n\r\n/** A ParseToken holds either a numeric or string token extracted from a string that represents a quantity value.\r\n * @beta\r\n */\r\nclass ParseToken {\r\n public value: number | string;\r\n\r\n constructor(value: string | number) {\r\n if (typeof value === \"string\")\r\n this.value = value.trim();\r\n else\r\n this.value = value;\r\n }\r\n\r\n public get isString(): boolean { return typeof this.value === \"string\"; }\r\n public get isNumber(): boolean { return typeof this.value === \"number\"; }\r\n}\r\n\r\n/** A ScientificToken holds an index and string representing the exponent.\r\n * @beta\r\n */\r\nclass ScientificToken {\r\n public index: number;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, exponent?: string) {\r\n this.index = index;\r\n if (exponent)\r\n this.exponent = exponent;\r\n }\r\n}\r\n\r\n/** A FractionToken holds an index and the fraction value of numerator / denominator.\r\n * @beta\r\n */\r\nclass FractionToken {\r\n public index: number;\r\n public fraction = 0.0;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, fraction?: number) {\r\n this.index = index;\r\n if (fraction)\r\n this.fraction = fraction;\r\n }\r\n}\r\n\r\n/** A Parser class that is used to break a string that represents a quantity value into tokens.\r\n * @beta\r\n */\r\nexport class Parser {\r\n private static _log = false;\r\n\r\n public static isParsedQuantity(item: QuantityParseResult): item is ParsedQuantity {\r\n return item.ok;\r\n }\r\n\r\n public static isParseError(item: QuantityParseResult): item is ParseQuantityError {\r\n return !item.ok;\r\n }\r\n\r\n private static checkForScientificNotation(index: number, stringToParse: string, uomSeparatorToIgnore: number): ScientificToken {\r\n let exponentString = \"\";\r\n let i = index + 1;\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode) || ((charCode === QuantityConstants.CHAR_MINUS || charCode === QuantityConstants.CHAR_PLUS) && (i === (index + 1)))) {\r\n exponentString = exponentString.concat(stringToParse[i]);\r\n } else {\r\n i = uomSeparatorToIgnore === charCode ? i : i - 1;\r\n break;\r\n }\r\n }\r\n\r\n if (exponentString.length > 1 || ((exponentString.length === 1) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_MINUS) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_PLUS)))\r\n return new ScientificToken(i, exponentString);\r\n\r\n return new ScientificToken(index);\r\n }\r\n\r\n private static checkForFractions(index: number, stringToParse: string, uomSeparatorToIgnore: number, numeratorStr?: string): FractionToken {\r\n let numeratorToken = \"\";\r\n let denominatorToken = \"\";\r\n let processingNumerator = true;\r\n let i = index;\r\n if (numeratorStr && numeratorStr.length > 0) {\r\n numeratorToken = numeratorStr;\r\n processingNumerator = false;\r\n }\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode)) {\r\n if (processingNumerator) {\r\n numeratorToken = numeratorToken.concat(stringToParse[i]);\r\n } else {\r\n denominatorToken = denominatorToken.concat(stringToParse[i]);\r\n }\r\n } else {\r\n if (processingNumerator && (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH)) {\r\n processingNumerator = false;\r\n } else {\r\n if (uomSeparatorToIgnore !== charCode)\r\n i = i - 1; // skip over uom separator after fraction\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (numeratorToken.length > 0 && denominatorToken.length > 0) {\r\n const numerator = parseInt(numeratorToken, 10);\r\n const denominator = parseInt(denominatorToken, 10);\r\n if (denominator > 0)\r\n return new FractionToken(i, numerator / denominator);\r\n return new FractionToken(i);\r\n }\r\n\r\n return new FractionToken(index + 1);\r\n }\r\n\r\n private static isDigit(charCode: number): boolean {\r\n return (charCode >= QuantityConstants.CHAR_DIGIT_ZERO) && (charCode <= QuantityConstants.CHAR_DIGIT_NINE);\r\n }\r\n\r\n private static isDigitOrDecimalSeparator(charCode: number, format: Format): boolean {\r\n return (charCode === format.decimalSeparator.charCodeAt(0)) || Parser.isDigit(charCode);\r\n }\r\n\r\n /** Parse the quantity string and return and array of ParseTokens that represent the component invariant values and unit labels.\r\n * @param quantitySpecification The quantity string to ba parsed.\r\n */\r\n public static parseQuantitySpecification(quantitySpecification: string, format: Format): ParseToken[] {\r\n const tokens: ParseToken[] = [];\r\n const str = quantitySpecification.trim();\r\n let processingNumber = false;\r\n let wipToken = \"\";\r\n let signToken = \"\";\r\n let uomSeparatorToIgnore = 0;\r\n let fractionDashCode = 0;\r\n\r\n const skipCodes: number[] = [format.thousandSeparator.charCodeAt(0)];\r\n\r\n if (format.type === FormatType.Station && format.stationSeparator && format.stationSeparator.length === 1)\r\n skipCodes.push(format.stationSeparator.charCodeAt(0));\r\n\r\n if (format.type === FormatType.Fractional && format.hasFormatTraitSet(FormatTraits.FractionDash)) {\r\n fractionDashCode = QuantityConstants.CHAR_MINUS;\r\n }\r\n\r\n if (format.uomSeparator && format.uomSeparator !== \" \" && format.uomSeparator.length === 1) {\r\n uomSeparatorToIgnore = format.uomSeparator.charCodeAt(0);\r\n skipCodes.push(uomSeparatorToIgnore);\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\r\n for (let i = 0; i < str.length; i++) {\r\n const charCode = str.charCodeAt(i);\r\n if (Parser.isDigitOrDecimalSeparator(charCode, format)) {\r\n if (!processingNumber) {\r\n if (wipToken.length > 0) {\r\n tokens.push(new ParseToken(wipToken));\r\n wipToken = \"\";\r\n }\r\n processingNumber = true;\r\n }\r\n // Decimal separators must be replaced with '.' before converting to a number - parseFloat() only supports '.' as the decimal separator.\r\n const charToAdd = charCode === format.decimalSeparator.charCodeAt(0) ? \".\" : str[i];\r\n wipToken = wipToken.concat(charToAdd);\r\n } else {\r\n if (processingNumber) {\r\n if (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_FRACTION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore, wipToken);\r\n let fraction = fractSymbol.fraction;\r\n i = fractSymbol.index;\r\n if (fractSymbol.fraction !== 0.0) {\r\n wipToken = \"\";\r\n if (signToken.length > 0) {\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(fraction));\r\n processingNumber = false;\r\n continue;\r\n }\r\n } else {\r\n // a space may signify end of number or start of decimal\r\n if (charCode === QuantityConstants.CHAR_SPACE || charCode === fractionDashCode) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore);\r\n let fraction = fractSymbol.fraction;\r\n if (fractSymbol.fraction !== 0.0) {\r\n i = fractSymbol.index;\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n const valueWithFraction = parseFloat(wipToken) + fraction;\r\n tokens.push(new ParseToken(valueWithFraction));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n }\r\n continue;\r\n } else {\r\n // an \"E\" or \"e\" may signify scientific notation\r\n if (charCode === QuantityConstants.CHAR_UPPER_E || charCode === QuantityConstants.CHAR_LOWER_E) {\r\n const exponentSymbol = Parser.checkForScientificNotation(i, str, uomSeparatorToIgnore);\r\n i = exponentSymbol.index;\r\n\r\n if (exponentSymbol.exponent && exponentSymbol.exponent.length > 0) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n wipToken = `${wipToken}e${exponentSymbol.exponent}`;\r\n const scientificValue = Number(wipToken);\r\n tokens.push(new ParseToken(scientificValue));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n continue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ignore any codes in skipCodes\r\n if (skipCodes.findIndex((ref) => ref === charCode) !== -1)\r\n continue;\r\n\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n\r\n wipToken = (i < str.length) ? str[i] : \"\";\r\n processingNumber = false;\r\n } else {\r\n // not processing a number\r\n if ((charCode === QuantityConstants.CHAR_PLUS || charCode === QuantityConstants.CHAR_MINUS)) {\r\n if (0 === tokens.length) // sign token only needed for left most value\r\n signToken = str[i];\r\n continue;\r\n }\r\n\r\n wipToken = wipToken.concat(str[i]);\r\n }\r\n }\r\n }\r\n\r\n // handle case where end of input string is reached.\r\n if (wipToken.length > 0) {\r\n if (processingNumber) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n }\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n } else {\r\n tokens.push(new ParseToken(wipToken));\r\n }\r\n }\r\n\r\n return tokens;\r\n }\r\n\r\n private static async lookupUnitByLabel(unitLabel: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider) {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n const labelToFind = unitLabel.toLowerCase();\r\n // First look in format for a label and matches\r\n if (format.units && format.units.length > 0) {\r\n const formatUnit = format.units.find(([unit, label]) => {\r\n if (label && label.toLowerCase() === labelToFind)\r\n return true;\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // check any alternate labels that may be defined for the Unit\r\n if (alternateLabels && alternateLabels.find((lbl) => lbl.toLowerCase() === labelToFind))\r\n return true;\r\n\r\n return false;\r\n });\r\n if (formatUnit)\r\n return formatUnit[0];\r\n }\r\n\r\n // now try to find a unit from the same family and system\r\n let foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined, defaultUnit ? defaultUnit.system : undefined);\r\n\r\n // if nothing found yet just limit to family\r\n if (!foundUnit.isValid && defaultUnit)\r\n foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined);\r\n return foundUnit;\r\n }\r\n\r\n private static async createQuantityFromParseTokens(tokens: ParseToken[], format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n let defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else {\r\n const unit = await this.lookupUnitByLabel(tokens[0].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n return new Quantity(unit);\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n const unit = await this.lookupUnitByLabel(tokens[1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (defaultUnit && defaultUnit.name === unit.name) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n const mag = ((tokens[0].value as number * conversion.factor)) + conversion.offset;\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n } else { // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n const unit = await this.lookupUnitByLabel(tokens[0].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (defaultUnit && defaultUnit.name === unit.name) {\r\n return new Quantity(defaultUnit, tokens[1].value as number);\r\n } else if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n const mag = ((tokens[1].value as number * conversion.factor)) + conversion.offset;\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const unit = await this.lookupUnitByLabel(tokens[i + 1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (0 === i) {\r\n if (defaultUnit.name === unit.name)\r\n mag = value;\r\n else {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n mag = ((value * conversion.factor)) + conversion.offset;\r\n }\r\n } else {\r\n if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n }\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n\r\n return new Quantity(defaultUnit);\r\n }\r\n\r\n /** Async method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString.\r\n * @param unitsProvider required to look up units that may be specified in inString\r\n */\r\n public static async parseIntoQuantity(inString: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return new Quantity();\r\n\r\n return Parser.createQuantityFromParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider);\r\n }\r\n\r\n /** method to get the Unit Conversion given a unit label */\r\n private static tryFindUnitConversion(unitLabel: string, unitsConversions: UnitConversionSpec[], preferredUnit?: UnitProps): UnitConversionProps | undefined {\r\n if (unitsConversions.length > 0) {\r\n const label = unitLabel.toLocaleLowerCase();\r\n\r\n /* A preferred unit is used to target a unit if a unit label is used in more that one unit definition from the same unit family.\r\n * An example is if \"ft\" is used as the unitLabel and the preferredUnit is \"SURVEY_FT\" since that unit has an alternate label of \"ft\" the\r\n * conversion to \"SURVEY_FT\" is returned. If no preferredUnit is specified then the unit \"FT\" would likely to have been found first.\r\n * If \"in\" is the unit label and \"SURVEY_FT\" is the preferredUnit then conversion to \"SURVEY_IN\" would be returned.\r\n */\r\n if (preferredUnit) {\r\n // if there is a preferred unit defined see if unit label matched it or one of its alternates\r\n const preferredConversion = unitsConversions.find((conversion) => conversion.name === preferredUnit.name);\r\n if (preferredConversion && preferredConversion.parseLabels) {\r\n if (-1 !== preferredConversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return preferredConversion.conversion;\r\n }\r\n // see if we can find a matching unitLabel in any unit within the same system as the preferred unit\r\n const preferredSystemConversions = unitsConversions.filter((conversion) => conversion.system === preferredUnit.system);\r\n for (const conversion of preferredSystemConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n }\r\n }\r\n }\r\n\r\n // if no unit found based on preferredUnit see if an unit label matches\r\n for (const conversion of unitsConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n } else {\r\n // eslint-disable-next-line no-console\r\n console.log(\"ERROR: Parser expects to find parseLabels array populate with all possible unit labels for the unit.\");\r\n }\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private static getQuantityValueFromParseTokens(tokens: ParseToken[], format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n if (defaultUnit) {\r\n const conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n } else {\r\n // if no conversion or no defaultUnit, just return parsed number\r\n return { ok: true, value: tokens[0].value as number };\r\n }\r\n } else {\r\n // only the unit label was specified so assume magnitude of 1\r\n const conversion = Parser.tryFindUnitConversion(tokens[0].value as string, unitsConversions, defaultUnit);\r\n if (undefined !== conversion)\r\n return { ok: true, value: conversion.factor + conversion.offset };\r\n else\r\n return { ok: false, error: ParseError.NoValueOrUnitFoundInString };\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n const conversion = Parser.tryFindUnitConversion(tokens[1].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n // if no conversion, just return parsed number and ignore value in second token\r\n return { ok: true, value: tokens[0].value as number };\r\n } else { // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n const conversion = Parser.tryFindUnitConversion(tokens[0].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[1].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n // if no conversion, just return parsed number and ignore value in second token\r\n return { ok: true, value: tokens[1].value as number };\r\n }\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const conversion = Parser.tryFindUnitConversion(tokens[i + 1].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n return { ok: true, value: mag };\r\n }\r\n\r\n return { ok: false, error: ParseError.UnableToConvertParseTokensToQuantity };\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions.\r\n * @param defaultValue default value to return if parsing is un successful\r\n */\r\n public static parseQuantityString(inString: string, parserSpec: ParserSpec): QuantityParseResult {\r\n return Parser.parseToQuantityValue(inString, parserSpec.format, parserSpec.unitConversions);\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString. Primary unit serves as a default unit if no unit label found in string.\r\n * @param unitsConversions dictionary of conversions used to convert from unit used in inString to output quantity\r\n */\r\n public static parseToQuantityValue(inString: string, format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n // ensure any labels defined in composite unit definition are specified in unitConversions\r\n if (format.units) {\r\n format.units.forEach(([unit, label]) => {\r\n if (label) {\r\n if (unit.label !== label) { // if default unit label does not match composite label ensure the label is in the list of parse labels for the conversion\r\n const unitConversion = unitsConversions.find((conversion) => conversion.name === unit.name);\r\n if (unitConversion && unitConversion.parseLabels && !unitConversion.parseLabels.find((entry) => entry === label))\r\n unitConversion.parseLabels.push(label);\r\n }\r\n }\r\n });\r\n }\r\n\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return { ok: false, error: ParseError.UnableToGenerateParseTokens };\r\n\r\n if (Parser._log) {\r\n // eslint-disable-next-line no-console\r\n console.log(`Parse tokens`);\r\n let i = 0;\r\n for (const token of tokens) {\r\n // eslint-disable-next-line no-console\r\n console.log(` [${i++}] isNumber=${token.isNumber} isString=${token.isString} token=${token.value}`);\r\n }\r\n }\r\n\r\n return Parser.getQuantityValueFromParseTokens(tokens, format, unitsConversions);\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecsForUnit(unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const familyUnits = await unitsProvider.getUnitsByFamily(outUnit.phenomenon);\r\n for (const unit of familyUnits) {\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecs(unitsProvider: UnitsProvider, outUnitName: string, potentialParseUnits: PotentialParseUnit[], altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const outUnit = await unitsProvider.findUnitByName(outUnitName);\r\n if (!outUnit || !outUnit.name || 0 === outUnit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate out unit ${outUnitName}.`);\r\n return unitConversionSpecs;\r\n }\r\n\r\n for (const potentialParseUnit of potentialParseUnits) {\r\n const unit = await unitsProvider.findUnitByName(potentialParseUnit.unitName);\r\n if (!unit || !unit.name || 0 === unit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate potential unit ${potentialParseUnit.unitName}.`);\r\n continue;\r\n }\r\n\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n // add any alternate labels that where provided by caller\r\n if (potentialParseUnit.altLabels) {\r\n potentialParseUnit.altLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,2CAAgD;AAEhD,yDAAmE;AAGnE,yCAAsC;AAEtC;;GAEG;AACH,IAAY,UAOX;AAPD,WAAY,UAAU;IACpB,yFAA+B,CAAA;IAC/B,uFAA0B,CAAA;IAC1B,+FAA8B,CAAA;IAC9B,yDAAW,CAAA;IACX,2GAAoC,CAAA;IACpC,qEAAiB,CAAA;AACnB,CAAC,EAPW,UAAU,0BAAV,UAAU,QAOrB;AA4BD;;GAEG;AACH,MAAM,UAAU;IAGd,YAAY,KAAsB;QAChC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;;YAE1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,IAAW,QAAQ,KAAc,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;IACzE,IAAW,QAAQ,KAAc,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;CAC1E;AAED;;GAEG;AACH,MAAM,eAAe;IAInB,YAAY,KAAa,EAAE,QAAiB;QAFrC,aAAQ,GAAG,EAAE,CAAC;QAGnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,QAAQ;YACV,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,aAAa;IAKjB,YAAY,KAAa,EAAE,QAAiB;QAHrC,aAAQ,GAAG,GAAG,CAAC;QACf,aAAQ,GAAG,EAAE,CAAC;QAGnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,QAAQ;YACV,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACF;AAED;;GAEG;AACH,MAAa,MAAM;IAGV,MAAM,CAAC,gBAAgB,CAAC,IAAyB;QACtD,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;IAEM,MAAM,CAAC,YAAY,CAAC,IAAyB;QAClD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAClB,CAAC;IAEO,MAAM,CAAC,0BAA0B,CAAC,KAAa,EAAE,aAAqB,EAAE,oBAA4B;QAC1G,IAAI,cAAc,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QAElB,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,6BAAiB,CAAC,UAAU,IAAI,QAAQ,KAAK,6BAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjJ,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,CAAC,GAAG,oBAAoB,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClD,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,6BAAiB,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,6BAAiB,CAAC,SAAS,CAAC,CAAC;YACnM,OAAO,IAAI,eAAe,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QAEhD,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAAC,KAAa,EAAE,aAAqB,EAAE,oBAA4B,EAAE,YAAqB;QACxH,IAAI,cAAc,GAAG,EAAE,CAAC;QACxB,IAAI,gBAAgB,GAAG,EAAE,CAAC;QAC1B,IAAI,mBAAmB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,GAAG,KAAK,CAAC;QACd,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,cAAc,GAAG,YAAY,CAAC;YAC9B,mBAAmB,GAAG,KAAK,CAAC;QAC9B,CAAC;QAED,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,IAAI,mBAAmB,EAAE,CAAC;oBACxB,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3D,CAAC;qBAAM,CAAC;oBACN,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,mBAAmB,IAAI,CAAC,QAAQ,KAAK,6BAAiB,CAAC,UAAU,IAAI,QAAQ,KAAK,6BAAiB,CAAC,mBAAmB,IAAI,QAAQ,KAAK,6BAAiB,CAAC,mBAAmB,CAAC,EAAE,CAAC;oBACnL,mBAAmB,GAAG,KAAK,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACN,IAAI,oBAAoB,KAAK,QAAQ;wBACnC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,yCAAyC;oBAEtD,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YAC/C,MAAM,WAAW,GAAG,QAAQ,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,WAAW,GAAG,CAAC;gBACjB,OAAO,IAAI,aAAa,CAAC,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC;YACvD,OAAO,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO,IAAI,aAAa,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACtC,CAAC;IAEO,MAAM,CAAC,OAAO,CAAC,QAAgB;QACrC,OAAO,CAAC,QAAQ,IAAI,6BAAiB,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,IAAI,6BAAiB,CAAC,eAAe,CAAC,CAAC;IAC5G,CAAC;IAEO,MAAM,CAAC,yBAAyB,CAAC,QAAgB,EAAE,MAAc;QACvE,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1F,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,0BAA0B,CAAC,qBAA6B,EAAE,MAAc;QACpF,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,qBAAqB,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAC7B,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,oBAAoB,GAAG,CAAC,CAAC;QAC7B,IAAI,gBAAgB,GAAG,CAAC,CAAC;QAEzB,MAAM,SAAS,GAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAErE,IAAI,MAAM,CAAC,IAAI,KAAK,wBAAU,CAAC,OAAO,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC;YACvG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAExD,IAAI,MAAM,CAAC,IAAI,KAAK,wBAAU,CAAC,UAAU,IAAI,MAAM,CAAC,iBAAiB,CAAC,0BAAY,CAAC,YAAY,CAAC,EAAE,CAAC;YACjG,gBAAgB,GAAG,6BAAiB,CAAC,UAAU,CAAC;QAClD,CAAC;QAED,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,KAAK,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3F,oBAAoB,GAAG,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACzD,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACvC,CAAC;QAED,4DAA4D;QAC5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,MAAM,CAAC,yBAAyB,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxB,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;wBACtC,QAAQ,GAAG,EAAE,CAAC;oBAChB,CAAC;oBACD,gBAAgB,GAAG,IAAI,CAAC;gBAC1B,CAAC;gBACD,wIAAwI;gBACxI,MAAM,SAAS,GAAG,QAAQ,KAAK,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACpF,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACN,IAAI,gBAAgB,EAAE,CAAC;oBACrB,IAAI,QAAQ,KAAK,6BAAiB,CAAC,UAAU,IAAI,QAAQ,KAAK,6BAAiB,CAAC,mBAAmB,IAAI,QAAQ,KAAK,6BAAiB,CAAC,mBAAmB,EAAE,CAAC;wBAC1J,MAAM,WAAW,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,oBAAoB,EAAE,QAAQ,CAAC,CAAC;wBACzF,IAAI,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;wBACpC,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;wBACtB,IAAI,WAAW,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;4BACjC,QAAQ,GAAG,EAAE,CAAC;4BACd,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCACzB,IAAI,SAAS,KAAK,GAAG;oCACnB,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC;gCAE1B,SAAS,GAAG,EAAE,CAAC;4BACjB,CAAC;4BAED,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;4BACtC,gBAAgB,GAAG,KAAK,CAAC;4BACzB,SAAS;wBACX,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,wDAAwD;wBACxD,IAAI,QAAQ,KAAK,6BAAiB,CAAC,UAAU,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;4BAC/E,MAAM,WAAW,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,oBAAoB,CAAC,CAAC;4BAC/E,IAAI,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;4BACpC,IAAI,WAAW,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;gCACjC,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;gCACtB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oCACzB,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;oCAChC,IAAI,SAAS,KAAK,GAAG;wCACnB,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC;oCAE1B,SAAS,GAAG,EAAE,CAAC;gCACjB,CAAC;gCAED,MAAM,iBAAiB,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;gCAC1D,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC;gCAC/C,gBAAgB,GAAG,KAAK,CAAC;gCACzB,QAAQ,GAAG,EAAE,CAAC;4BAChB,CAAC;4BACD,SAAS;wBACX,CAAC;6BAAM,CAAC;4BACN,gDAAgD;4BAChD,IAAI,QAAQ,KAAK,6BAAiB,CAAC,YAAY,IAAI,QAAQ,KAAK,6BAAiB,CAAC,YAAY,EAAE,CAAC;gCAC/F,MAAM,cAAc,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC,EAAE,GAAG,EAAE,oBAAoB,CAAC,CAAC;gCACvF,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC;gCAEzB,IAAI,cAAc,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oCAClE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wCACzB,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;wCAChC,SAAS,GAAG,EAAE,CAAC;oCACjB,CAAC;oCAED,QAAQ,GAAG,GAAG,QAAQ,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;oCACpD,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;oCACzC,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;oCAC7C,gBAAgB,GAAG,KAAK,CAAC;oCACzB,QAAQ,GAAG,EAAE,CAAC;oCACd,SAAS;gCACX,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,gCAAgC;oBAChC,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC;wBACvD,SAAS;oBAEX,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACzB,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;wBAChC,SAAS,GAAG,EAAE,CAAC;oBACjB,CAAC;oBAED,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAElD,QAAQ,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1C,gBAAgB,GAAG,KAAK,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,0BAA0B;oBAC1B,IAAI,CAAC,QAAQ,KAAK,6BAAiB,CAAC,SAAS,IAAI,QAAQ,KAAK,6BAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC5F,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,6CAA6C;4BACpE,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;wBACrB,SAAS;oBACX,CAAC;oBAED,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;QAED,oDAAoD;QACpD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,gBAAgB,EAAE,CAAC;gBACrB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;gBAClC,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAiB,EAAE,MAAc,EAAE,aAA4B,EAAE,qBAAmD;QACzJ,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE7F,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAC5C,+CAA+C;QAC/C,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;gBACrD,IAAI,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,WAAW;oBAC9C,OAAO,IAAI,CAAC;gBACd,MAAM,eAAe,GAAG,qBAAqB,EAAE,sBAAsB,CAAC,IAAI,CAAC,CAAC;gBAC5E,8DAA8D;gBAC9D,IAAI,eAAe,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC;oBACrF,OAAO,IAAI,CAAC;gBAEd,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;YACH,IAAI,UAAU;gBACZ,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QAED,yDAAyD;QACzD,IAAI,SAAS,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAExJ,4CAA4C;QAC5C,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,WAAW;YACnC,SAAS,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACxG,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,MAAoB,EAAE,MAAc,EAAE,aAA4B,EAAE,qBAAmD;QACxK,IAAI,WAAW,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE3F,6CAA6C;QAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACvB,OAAO,IAAI,mBAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,EAAE,MAAM,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;gBACnH,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,+DAA+D;QAC/D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,wDAAwD;YACxD,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC7C,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,EAAE,MAAM,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;gBACnH,IAAI,SAAS,KAAK,WAAW;oBAC3B,WAAW,GAAG,IAAI,CAAC;gBACrB,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;oBAClD,OAAO,IAAI,mBAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,CAAC,CAAC;gBAC9D,CAAC;qBAAM,IAAI,WAAW,EAAE,CAAC;oBACvB,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBACxE,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;oBAClF,OAAO,IAAI,mBAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;QAED,yDAAyD;QACzD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,GAAG,GAAG,GAAG,CAAC;YACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;oBACjD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,CAAC;oBACxC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAe,EAAE,MAAM,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;oBACvH,IAAI,SAAS,KAAK,WAAW;wBAC3B,WAAW,GAAG,IAAI,CAAC;oBACrB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;wBACZ,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;4BAChC,GAAG,GAAG,KAAK,CAAC;6BACT,CAAC;4BACJ,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;4BACxE,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;wBAC1D,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,IAAI,WAAW,EAAE,CAAC;4BAChB,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;4BACxE,IAAI,GAAG,GAAG,GAAG;gCACX,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;;gCAE9D,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;wBAClE,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,IAAI,mBAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,IAAI,mBAAQ,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,MAAc,EAAE,aAA4B,EAAE,qBAAmD;QACvJ,MAAM,MAAM,GAAiB,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YACrB,OAAO,IAAI,mBAAQ,EAAE,CAAC;QAExB,OAAO,MAAM,CAAC,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;IACpG,CAAC;IAED,2DAA2D;IACnD,MAAM,CAAC,qBAAqB,CAAC,SAAiB,EAAE,gBAAsC,EAAE,aAAyB;QACvH,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC;YAE5C;;;;cAIE;YACF,IAAI,aAAa,EAAE,CAAC;gBAClB,6FAA6F;gBAC7F,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC1G,IAAI,mBAAmB,IAAI,mBAAmB,CAAC,WAAW,EAAE,CAAC;oBAC3D,IAAI,CAAC,CAAC,KAAK,mBAAmB,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC;wBAC1E,OAAO,mBAAmB,CAAC,UAAU,CAAC;gBAC1C,CAAC;gBACD,mGAAmG;gBACnG,MAAM,0BAA0B,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC;gBACvH,KAAK,MAAM,UAAU,IAAI,0BAA0B,EAAE,CAAC;oBACpD,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;wBAC3B,IAAI,CAAC,CAAC,KAAK,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC;4BACjE,OAAO,UAAU,CAAC,UAAU,CAAC;oBACjC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,uEAAuE;YACvE,KAAK,MAAM,UAAU,IAAI,gBAAgB,EAAE,CAAC;gBAC1C,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;oBAC3B,IAAI,CAAC,CAAC,KAAK,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC;wBACjE,OAAO,UAAU,CAAC,UAAU,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACN,sCAAsC;oBACtC,OAAO,CAAC,GAAG,CAAC,sGAAsG,CAAC,CAAC;gBACtH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,+BAA+B,CAAC,MAAoB,EAAE,MAAc,EAAE,gBAAsC;QACzH,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7F,6CAA6C;QAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACvB,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,UAAU,GAAG,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;oBAClG,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,KAAK,GAAI,MAAM,CAAC,CAAC,CAAC,CAAC,KAAgB,GAAG,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;wBAClF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;oBAC7B,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,gEAAgE;oBAChE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,EAAE,CAAC;gBACxD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,6DAA6D;gBAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;gBAC1G,IAAI,SAAS,KAAK,UAAU;oBAC1B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;;oBAElE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,0BAA0B,EAAE,CAAC;YACvE,CAAC;QACH,CAAC;QAED,+DAA+D;QAC/D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,wDAAwD;YACxD,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC7C,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC7C,IAAI,UAAU,GAAG,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;gBACxG,kFAAkF;gBAClF,IAAI,CAAC,UAAU,IAAI,WAAW,EAAE,CAAC;oBAC/B,UAAU,GAAG,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;gBAC9F,CAAC;gBACD,IAAI,UAAU,EAAE,CAAC;oBACf,MAAM,KAAK,GAAI,MAAM,CAAC,CAAC,CAAC,CAAC,KAAgB,GAAG,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;oBAClF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;gBAC7B,CAAC;gBACD,+EAA+E;gBAC/E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,EAAE,CAAC;YACxD,CAAC;QACH,CAAC;QAED,yDAAyD;QACzD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,GAAG,GAAG,GAAG,CAAC;YACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;oBACjD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAe,CAAC;oBACxC,MAAM,UAAU,GAAG,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAe,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;oBAC9G,IAAI,UAAU,EAAE,CAAC;wBACf,IAAI,GAAG,GAAG,GAAG;4BACX,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;;4BAE9D,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;oBAClE,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAClC,CAAC;QAED,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,oCAAoC,EAAE,CAAC;IAC/E,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,mBAAmB,CAAC,QAAgB,EAAE,UAAsB;QACxE,OAAO,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IAC9F,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,oBAAoB,CAAC,QAAgB,EAAE,MAAc,EAAE,gBAAsC;QACzG,0FAA0F;QAC1F,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;gBACrC,IAAI,KAAK,EAAE,CAAC;oBACV,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC,0HAA0H;wBACpJ,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC5F,IAAI,cAAc,IAAI,cAAc,CAAC,WAAW,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC;4BAC9G,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC3C,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAiB,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,2BAA2B,EAAE,CAAC;QAEtE,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,sCAAsC;gBACtC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,cAAc,KAAK,CAAC,QAAQ,aAAa,KAAK,CAAC,QAAQ,UAAU,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YACvG,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC,+BAA+B,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAClF,CAAC;IAED,+HAA+H;IACxH,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,aAA4B,EAAE,OAAkB,EAAE,qBAAmD;QACxJ,MAAM,mBAAmB,GAAyB,EAAE,CAAC;QAErD,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC7E,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACpE,MAAM,WAAW,GAAa,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;YAC/D,MAAM,eAAe,GAAG,qBAAqB,EAAE,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC5E,4DAA4D;YAC5D,IAAI,eAAe,EAAE,CAAC;gBACpB,eAAe,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE;oBACxC,MAAM,cAAc,GAAG,KAAK,CAAC,iBAAiB,EAAE,CAAC;oBACjD,IAAI,CAAC,CAAC,KAAK,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,cAAc,CAAC;wBAC/D,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;YACL,CAAC;YAED,mBAAmB,CAAC,IAAI,CAAC;gBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU;gBACV,WAAW;gBACX,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,+HAA+H;IACxH,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,aAA4B,EAAE,WAAmB,EAAE,mBAAyC,EAAE,qBAAmD;QAC7L,MAAM,mBAAmB,GAAyB,EAAE,CAAC;QAErD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC3D,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,uEAAuE,WAAW,GAAG,CAAC,CAAC;YACnG,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QAED,KAAK,MAAM,kBAAkB,IAAI,mBAAmB,EAAE,CAAC;YACrD,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAC7E,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBAClD,sCAAsC;gBACtC,OAAO,CAAC,GAAG,CAAC,6EAA6E,kBAAkB,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACzH,SAAS;YACX,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACpE,MAAM,WAAW,GAAa,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;YAC/D,MAAM,eAAe,GAAG,qBAAqB,EAAE,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC5E,4DAA4D;YAC5D,IAAI,eAAe,EAAE,CAAC;gBACpB,eAAe,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE;oBACxC,MAAM,cAAc,GAAG,KAAK,CAAC,iBAAiB,EAAE,CAAC;oBACjD,IAAI,CAAC,CAAC,KAAK,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,cAAc,CAAC;wBAC/D,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;YACL,CAAC;YAED,yDAAyD;YACzD,IAAI,kBAAkB,CAAC,SAAS,EAAE,CAAC;gBACjC,kBAAkB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE;oBACrD,MAAM,cAAc,GAAG,KAAK,CAAC,iBAAiB,EAAE,CAAC;oBACjD,IAAI,CAAC,CAAC,KAAK,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,cAAc,CAAC;wBAC/D,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;YACL,CAAC;YACD,mBAAmB,CAAC,IAAI,CAAC;gBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU;gBACV,WAAW;gBACX,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,mBAAmB,CAAC;IAC7B,CAAC;;AAnjBH,wBAojBC;AAnjBgB,WAAI,GAAG,KAAK,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { QuantityConstants } from \"./Constants\";\r\nimport { Format } from \"./Formatter/Format\";\r\nimport { FormatTraits, FormatType } from \"./Formatter/FormatEnums\";\r\nimport { AlternateUnitLabelsProvider, PotentialParseUnit, QuantityProps, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"./Interfaces\";\r\nimport { ParserSpec } from \"./ParserSpec\";\r\nimport { Quantity } from \"./Quantity\";\r\n\r\n/** Possible parser errors\r\n * @beta\r\n */\r\nexport enum ParseError {\r\n UnableToGenerateParseTokens = 1,\r\n NoValueOrUnitFoundInString,\r\n UnitLabelSuppliedButNotMatched,\r\n UnknownUnit,\r\n UnableToConvertParseTokensToQuantity,\r\n InvalidParserSpec,\r\n}\r\n\r\n/** Parse error result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParseQuantityError {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: false;\r\n /** The specific error that occurred during parsing. */\r\n error: ParseError;\r\n}\r\n\r\n/** Successful result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParsedQuantity {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: true;\r\n /** The magnitude of the parsed quantity. */\r\n value: number;\r\n}\r\n\r\n/**\r\n * Defines Results of parsing a string input by a user into its desired value type\r\n * @beta\r\n */\r\nexport type QuantityParseResult = ParsedQuantity | ParseQuantityError;\r\n\r\n/** A ParseToken holds either a numeric or string token extracted from a string that represents a quantity value.\r\n * @beta\r\n */\r\nclass ParseToken {\r\n public value: number | string;\r\n\r\n constructor(value: string | number) {\r\n if (typeof value === \"string\")\r\n this.value = value.trim();\r\n else\r\n this.value = value;\r\n }\r\n\r\n public get isString(): boolean { return typeof this.value === \"string\"; }\r\n public get isNumber(): boolean { return typeof this.value === \"number\"; }\r\n}\r\n\r\n/** A ScientificToken holds an index and string representing the exponent.\r\n * @beta\r\n */\r\nclass ScientificToken {\r\n public index: number;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, exponent?: string) {\r\n this.index = index;\r\n if (exponent)\r\n this.exponent = exponent;\r\n }\r\n}\r\n\r\n/** A FractionToken holds an index and the fraction value of numerator / denominator.\r\n * @beta\r\n */\r\nclass FractionToken {\r\n public index: number;\r\n public fraction = 0.0;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, fraction?: number) {\r\n this.index = index;\r\n if (fraction)\r\n this.fraction = fraction;\r\n }\r\n}\r\n\r\n/** A Parser class that is used to break a string that represents a quantity value into tokens.\r\n * @beta\r\n */\r\nexport class Parser {\r\n private static _log = false;\r\n\r\n public static isParsedQuantity(item: QuantityParseResult): item is ParsedQuantity {\r\n return item.ok;\r\n }\r\n\r\n public static isParseError(item: QuantityParseResult): item is ParseQuantityError {\r\n return !item.ok;\r\n }\r\n\r\n private static checkForScientificNotation(index: number, stringToParse: string, uomSeparatorToIgnore: number): ScientificToken {\r\n let exponentString = \"\";\r\n let i = index + 1;\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode) || ((charCode === QuantityConstants.CHAR_MINUS || charCode === QuantityConstants.CHAR_PLUS) && (i === (index + 1)))) {\r\n exponentString = exponentString.concat(stringToParse[i]);\r\n } else {\r\n i = uomSeparatorToIgnore === charCode ? i : i - 1;\r\n break;\r\n }\r\n }\r\n\r\n if (exponentString.length > 1 || ((exponentString.length === 1) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_MINUS) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_PLUS)))\r\n return new ScientificToken(i, exponentString);\r\n\r\n return new ScientificToken(index);\r\n }\r\n\r\n private static checkForFractions(index: number, stringToParse: string, uomSeparatorToIgnore: number, numeratorStr?: string): FractionToken {\r\n let numeratorToken = \"\";\r\n let denominatorToken = \"\";\r\n let processingNumerator = true;\r\n let i = index;\r\n if (numeratorStr && numeratorStr.length > 0) {\r\n numeratorToken = numeratorStr;\r\n processingNumerator = false;\r\n }\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode)) {\r\n if (processingNumerator) {\r\n numeratorToken = numeratorToken.concat(stringToParse[i]);\r\n } else {\r\n denominatorToken = denominatorToken.concat(stringToParse[i]);\r\n }\r\n } else {\r\n if (processingNumerator && (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH)) {\r\n processingNumerator = false;\r\n } else {\r\n if (uomSeparatorToIgnore !== charCode)\r\n i = i - 1; // skip over uom separator after fraction\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (numeratorToken.length > 0 && denominatorToken.length > 0) {\r\n const numerator = parseInt(numeratorToken, 10);\r\n const denominator = parseInt(denominatorToken, 10);\r\n if (denominator > 0)\r\n return new FractionToken(i, numerator / denominator);\r\n return new FractionToken(i);\r\n }\r\n\r\n return new FractionToken(index + 1);\r\n }\r\n\r\n private static isDigit(charCode: number): boolean {\r\n return (charCode >= QuantityConstants.CHAR_DIGIT_ZERO) && (charCode <= QuantityConstants.CHAR_DIGIT_NINE);\r\n }\r\n\r\n private static isDigitOrDecimalSeparator(charCode: number, format: Format): boolean {\r\n return (charCode === format.decimalSeparator.charCodeAt(0)) || Parser.isDigit(charCode);\r\n }\r\n\r\n /** Parse the quantity string and return and array of ParseTokens that represent the component invariant values and unit labels.\r\n * @param quantitySpecification The quantity string to ba parsed.\r\n */\r\n public static parseQuantitySpecification(quantitySpecification: string, format: Format): ParseToken[] {\r\n const tokens: ParseToken[] = [];\r\n const str = quantitySpecification.trim();\r\n let processingNumber = false;\r\n let wipToken = \"\";\r\n let signToken = \"\";\r\n let uomSeparatorToIgnore = 0;\r\n let fractionDashCode = 0;\r\n\r\n const skipCodes: number[] = [format.thousandSeparator.charCodeAt(0)];\r\n\r\n if (format.type === FormatType.Station && format.stationSeparator && format.stationSeparator.length === 1)\r\n skipCodes.push(format.stationSeparator.charCodeAt(0));\r\n\r\n if (format.type === FormatType.Fractional && format.hasFormatTraitSet(FormatTraits.FractionDash)) {\r\n fractionDashCode = QuantityConstants.CHAR_MINUS;\r\n }\r\n\r\n if (format.uomSeparator && format.uomSeparator !== \" \" && format.uomSeparator.length === 1) {\r\n uomSeparatorToIgnore = format.uomSeparator.charCodeAt(0);\r\n skipCodes.push(uomSeparatorToIgnore);\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\r\n for (let i = 0; i < str.length; i++) {\r\n const charCode = str.charCodeAt(i);\r\n if (Parser.isDigitOrDecimalSeparator(charCode, format)) {\r\n if (!processingNumber) {\r\n if (wipToken.length > 0) {\r\n tokens.push(new ParseToken(wipToken));\r\n wipToken = \"\";\r\n }\r\n processingNumber = true;\r\n }\r\n // Decimal separators must be replaced with '.' before converting to a number - parseFloat() only supports '.' as the decimal separator.\r\n const charToAdd = charCode === format.decimalSeparator.charCodeAt(0) ? \".\" : str[i];\r\n wipToken = wipToken.concat(charToAdd);\r\n } else {\r\n if (processingNumber) {\r\n if (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_FRACTION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore, wipToken);\r\n let fraction = fractSymbol.fraction;\r\n i = fractSymbol.index;\r\n if (fractSymbol.fraction !== 0.0) {\r\n wipToken = \"\";\r\n if (signToken.length > 0) {\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(fraction));\r\n processingNumber = false;\r\n continue;\r\n }\r\n } else {\r\n // a space may signify end of number or start of decimal\r\n if (charCode === QuantityConstants.CHAR_SPACE || charCode === fractionDashCode) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore);\r\n let fraction = fractSymbol.fraction;\r\n if (fractSymbol.fraction !== 0.0) {\r\n i = fractSymbol.index;\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n const valueWithFraction = parseFloat(wipToken) + fraction;\r\n tokens.push(new ParseToken(valueWithFraction));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n }\r\n continue;\r\n } else {\r\n // an \"E\" or \"e\" may signify scientific notation\r\n if (charCode === QuantityConstants.CHAR_UPPER_E || charCode === QuantityConstants.CHAR_LOWER_E) {\r\n const exponentSymbol = Parser.checkForScientificNotation(i, str, uomSeparatorToIgnore);\r\n i = exponentSymbol.index;\r\n\r\n if (exponentSymbol.exponent && exponentSymbol.exponent.length > 0) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n wipToken = `${wipToken}e${exponentSymbol.exponent}`;\r\n const scientificValue = Number(wipToken);\r\n tokens.push(new ParseToken(scientificValue));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n continue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ignore any codes in skipCodes\r\n if (skipCodes.findIndex((ref) => ref === charCode) !== -1)\r\n continue;\r\n\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n\r\n wipToken = (i < str.length) ? str[i] : \"\";\r\n processingNumber = false;\r\n } else {\r\n // not processing a number\r\n if ((charCode === QuantityConstants.CHAR_PLUS || charCode === QuantityConstants.CHAR_MINUS)) {\r\n if (0 === tokens.length) // sign token only needed for left most value\r\n signToken = str[i];\r\n continue;\r\n }\r\n\r\n wipToken = wipToken.concat(str[i]);\r\n }\r\n }\r\n }\r\n\r\n // handle case where end of input string is reached.\r\n if (wipToken.length > 0) {\r\n if (processingNumber) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n }\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n } else {\r\n tokens.push(new ParseToken(wipToken));\r\n }\r\n }\r\n\r\n return tokens;\r\n }\r\n\r\n private static async lookupUnitByLabel(unitLabel: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider) {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n const labelToFind = unitLabel.toLowerCase();\r\n // First look in format for a label and matches\r\n if (format.units && format.units.length > 0) {\r\n const formatUnit = format.units.find(([unit, label]) => {\r\n if (label && label.toLowerCase() === labelToFind)\r\n return true;\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // check any alternate labels that may be defined for the Unit\r\n if (alternateLabels && alternateLabels.find((lbl) => lbl.toLowerCase() === labelToFind))\r\n return true;\r\n\r\n return false;\r\n });\r\n if (formatUnit)\r\n return formatUnit[0];\r\n }\r\n\r\n // now try to find a unit from the same family and system\r\n let foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined, defaultUnit ? defaultUnit.system : undefined);\r\n\r\n // if nothing found yet just limit to family\r\n if (!foundUnit.isValid && defaultUnit)\r\n foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined);\r\n return foundUnit;\r\n }\r\n\r\n private static async createQuantityFromParseTokens(tokens: ParseToken[], format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n let defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else {\r\n const unit = await this.lookupUnitByLabel(tokens[0].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n return new Quantity(unit);\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n tokens = [tokens[1], tokens[0]];\r\n }\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n const unit = await this.lookupUnitByLabel(tokens[1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (defaultUnit && defaultUnit.name === unit.name) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n const mag = ((tokens[0].value as number * conversion.factor)) + conversion.offset;\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const unit = await this.lookupUnitByLabel(tokens[i + 1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (0 === i) {\r\n if (defaultUnit.name === unit.name)\r\n mag = value;\r\n else {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n mag = ((value * conversion.factor)) + conversion.offset;\r\n }\r\n } else {\r\n if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n }\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n\r\n return new Quantity(defaultUnit);\r\n }\r\n\r\n /** Async method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString.\r\n * @param unitsProvider required to look up units that may be specified in inString\r\n */\r\n public static async parseIntoQuantity(inString: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return new Quantity();\r\n\r\n return Parser.createQuantityFromParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider);\r\n }\r\n\r\n /** method to get the Unit Conversion given a unit label */\r\n private static tryFindUnitConversion(unitLabel: string, unitsConversions: UnitConversionSpec[], preferredUnit?: UnitProps): UnitConversionProps | undefined {\r\n if (unitsConversions.length > 0) {\r\n const label = unitLabel.toLocaleLowerCase();\r\n\r\n /* A preferred unit is used to target a unit if a unit label is used in more that one unit definition from the same unit family.\r\n * An example is if \"ft\" is used as the unitLabel and the preferredUnit is \"SURVEY_FT\" since that unit has an alternate label of \"ft\" the\r\n * conversion to \"SURVEY_FT\" is returned. If no preferredUnit is specified then the unit \"FT\" would likely to have been found first.\r\n * If \"in\" is the unit label and \"SURVEY_FT\" is the preferredUnit then conversion to \"SURVEY_IN\" would be returned.\r\n */\r\n if (preferredUnit) {\r\n // if there is a preferred unit defined see if unit label matched it or one of its alternates\r\n const preferredConversion = unitsConversions.find((conversion) => conversion.name === preferredUnit.name);\r\n if (preferredConversion && preferredConversion.parseLabels) {\r\n if (-1 !== preferredConversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return preferredConversion.conversion;\r\n }\r\n // see if we can find a matching unitLabel in any unit within the same system as the preferred unit\r\n const preferredSystemConversions = unitsConversions.filter((conversion) => conversion.system === preferredUnit.system);\r\n for (const conversion of preferredSystemConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n }\r\n }\r\n }\r\n\r\n // if no unit found based on preferredUnit see if an unit label matches\r\n for (const conversion of unitsConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n } else {\r\n // eslint-disable-next-line no-console\r\n console.log(\"ERROR: Parser expects to find parseLabels array populate with all possible unit labels for the unit.\");\r\n }\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private static getQuantityValueFromParseTokens(tokens: ParseToken[], format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n if (defaultUnit) {\r\n const conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n } else {\r\n // if no conversion or no defaultUnit, just return parsed number\r\n return { ok: true, value: tokens[0].value as number };\r\n }\r\n } else {\r\n // only the unit label was specified so assume magnitude of 1\r\n const conversion = Parser.tryFindUnitConversion(tokens[0].value as string, unitsConversions, defaultUnit);\r\n if (undefined !== conversion)\r\n return { ok: true, value: conversion.factor + conversion.offset };\r\n else\r\n return { ok: false, error: ParseError.NoValueOrUnitFoundInString };\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n tokens = [tokens[1], tokens[0]];\r\n }\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n let conversion = Parser.tryFindUnitConversion(tokens[1].value as string, unitsConversions, defaultUnit);\r\n // if no conversion, ignore value in second token. If we have defaultUnit, use it.\r\n if (!conversion && defaultUnit) {\r\n conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);\r\n }\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n // if no conversion, just return parsed number and ignore value in second token\r\n return { ok: true, value: tokens[0].value as number };\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const conversion = Parser.tryFindUnitConversion(tokens[i + 1].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n return { ok: true, value: mag };\r\n }\r\n\r\n return { ok: false, error: ParseError.UnableToConvertParseTokensToQuantity };\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions.\r\n * @param defaultValue default value to return if parsing is un successful\r\n */\r\n public static parseQuantityString(inString: string, parserSpec: ParserSpec): QuantityParseResult {\r\n return Parser.parseToQuantityValue(inString, parserSpec.format, parserSpec.unitConversions);\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString. Primary unit serves as a default unit if no unit label found in string.\r\n * @param unitsConversions dictionary of conversions used to convert from unit used in inString to output quantity\r\n */\r\n public static parseToQuantityValue(inString: string, format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n // ensure any labels defined in composite unit definition are specified in unitConversions\r\n if (format.units) {\r\n format.units.forEach(([unit, label]) => {\r\n if (label) {\r\n if (unit.label !== label) { // if default unit label does not match composite label ensure the label is in the list of parse labels for the conversion\r\n const unitConversion = unitsConversions.find((conversion) => conversion.name === unit.name);\r\n if (unitConversion && unitConversion.parseLabels && !unitConversion.parseLabels.find((entry) => entry === label))\r\n unitConversion.parseLabels.push(label);\r\n }\r\n }\r\n });\r\n }\r\n\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return { ok: false, error: ParseError.UnableToGenerateParseTokens };\r\n\r\n if (Parser._log) {\r\n // eslint-disable-next-line no-console\r\n console.log(`Parse tokens`);\r\n let i = 0;\r\n for (const token of tokens) {\r\n // eslint-disable-next-line no-console\r\n console.log(` [${i++}] isNumber=${token.isNumber} isString=${token.isString} token=${token.value}`);\r\n }\r\n }\r\n\r\n return Parser.getQuantityValueFromParseTokens(tokens, format, unitsConversions);\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecsForUnit(unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const familyUnits = await unitsProvider.getUnitsByFamily(outUnit.phenomenon);\r\n for (const unit of familyUnits) {\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecs(unitsProvider: UnitsProvider, outUnitName: string, potentialParseUnits: PotentialParseUnit[], altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const outUnit = await unitsProvider.findUnitByName(outUnitName);\r\n if (!outUnit || !outUnit.name || 0 === outUnit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate out unit ${outUnitName}.`);\r\n return unitConversionSpecs;\r\n }\r\n\r\n for (const potentialParseUnit of potentialParseUnits) {\r\n const unit = await unitsProvider.findUnitByName(potentialParseUnit.unitName);\r\n if (!unit || !unit.name || 0 === unit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate potential unit ${potentialParseUnit.unitName}.`);\r\n continue;\r\n }\r\n\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n // add any alternate labels that where provided by caller\r\n if (potentialParseUnit.altLabels) {\r\n potentialParseUnit.altLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,aAAa,EAAuB,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjK,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;GAEG;AACH,oBAAY,UAAU;IACpB,2BAA2B,IAAI;IAC/B,0BAA0B,IAAA;IAC1B,8BAA8B,IAAA;IAC9B,WAAW,IAAA;IACX,oCAAoC,IAAA;IACpC,iBAAiB,IAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,EAAE,EAAE,KAAK,CAAC;IACV,uDAAuD;IACvD,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,EAAE,EAAE,IAAI,CAAC;IACT,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAEtE;;GAEG;AACH,cAAM,UAAU;IACP,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;gBAElB,KAAK,EAAE,MAAM,GAAG,MAAM;IAOlC,IAAW,QAAQ,IAAI,OAAO,CAA2C;IACzE,IAAW,QAAQ,IAAI,OAAO,CAA2C;CAC1E;AA+BD;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAS;WAEd,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,cAAc;WAInE,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,kBAAkB;IAIjF,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAoBzC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAyChC,OAAO,CAAC,MAAM,CAAC,OAAO;IAItB,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAIxC;;OAEG;WACW,0BAA0B,CAAC,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;mBA6IhF,iBAAiB;mBA6BjB,6BAA6B;IA2ElD;;;;OAIG;WACiB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,aAAa,CAAC;IAQlL,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAyCpC,OAAO,CAAC,MAAM,CAAC,+BAA+B;IAqE9C;;;;OAIG;WACW,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,mBAAmB;IAIhG;;;;OAIG;WACW,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,GAAG,mBAAmB;IA+BjI,+HAA+H;WAC3G,gCAAgC,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA4B1L,+HAA+H;WAC3G,yBAAyB,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAgDhO"}
1
+ {"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,aAAa,EAAuB,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjK,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;GAEG;AACH,oBAAY,UAAU;IACpB,2BAA2B,IAAI;IAC/B,0BAA0B,IAAA;IAC1B,8BAA8B,IAAA;IAC9B,WAAW,IAAA;IACX,oCAAoC,IAAA;IACpC,iBAAiB,IAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,EAAE,EAAE,KAAK,CAAC;IACV,uDAAuD;IACvD,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,EAAE,EAAE,IAAI,CAAC;IACT,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAEtE;;GAEG;AACH,cAAM,UAAU;IACP,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;gBAElB,KAAK,EAAE,MAAM,GAAG,MAAM;IAOlC,IAAW,QAAQ,IAAI,OAAO,CAA2C;IACzE,IAAW,QAAQ,IAAI,OAAO,CAA2C;CAC1E;AA+BD;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAS;WAEd,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,cAAc;WAInE,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,IAAI,kBAAkB;IAIjF,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAoBzC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAyChC,OAAO,CAAC,MAAM,CAAC,OAAO;IAItB,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAIxC;;OAEG;WACW,0BAA0B,CAAC,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;mBA6IhF,iBAAiB;mBA6BjB,6BAA6B;IAkElD;;;;OAIG;WACiB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,aAAa,CAAC;IAQlL,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAyCpC,OAAO,CAAC,MAAM,CAAC,+BAA+B;IAmE9C;;;;OAIG;WACW,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,mBAAmB;IAIhG;;;;OAIG;WACW,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,GAAG,mBAAmB;IA+BjI,+HAA+H;WAC3G,gCAAgC,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA4B1L,+HAA+H;WAC3G,yBAAyB,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,EAAE,qBAAqB,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAgDhO"}
package/lib/esm/Parser.js CHANGED
@@ -296,6 +296,10 @@ export class Parser {
296
296
  }
297
297
  // common case where single value and single label are supplied
298
298
  if (tokens.length === 2) {
299
+ // unit specification comes before value (like currency)
300
+ if (tokens[1].isNumber && tokens[0].isString) {
301
+ tokens = [tokens[1], tokens[0]];
302
+ }
299
303
  if (tokens[0].isNumber && tokens[1].isString) {
300
304
  const unit = await this.lookupUnitByLabel(tokens[1].value, format, unitsProvider, altUnitLabelsProvider);
301
305
  if (undefined === defaultUnit)
@@ -309,21 +313,6 @@ export class Parser {
309
313
  return new Quantity(defaultUnit, mag);
310
314
  }
311
315
  }
312
- else { // unit specification comes before value (like currency)
313
- if (tokens[1].isNumber && tokens[0].isString) {
314
- const unit = await this.lookupUnitByLabel(tokens[0].value, format, unitsProvider, altUnitLabelsProvider);
315
- if (undefined === defaultUnit)
316
- defaultUnit = unit;
317
- if (defaultUnit && defaultUnit.name === unit.name) {
318
- return new Quantity(defaultUnit, tokens[1].value);
319
- }
320
- else if (defaultUnit) {
321
- const conversion = await unitsProvider.getConversion(unit, defaultUnit);
322
- const mag = ((tokens[1].value * conversion.factor)) + conversion.offset;
323
- return new Quantity(defaultUnit, mag);
324
- }
325
- }
326
- }
327
316
  }
328
317
  // common case where there are multiple value/label pairs
329
318
  if (tokens.length % 2 === 0) {
@@ -435,8 +424,16 @@ export class Parser {
435
424
  }
436
425
  // common case where single value and single label are supplied
437
426
  if (tokens.length === 2) {
427
+ // unit specification comes before value (like currency)
428
+ if (tokens[1].isNumber && tokens[0].isString) {
429
+ tokens = [tokens[1], tokens[0]];
430
+ }
438
431
  if (tokens[0].isNumber && tokens[1].isString) {
439
- const conversion = Parser.tryFindUnitConversion(tokens[1].value, unitsConversions, defaultUnit);
432
+ let conversion = Parser.tryFindUnitConversion(tokens[1].value, unitsConversions, defaultUnit);
433
+ // if no conversion, ignore value in second token. If we have defaultUnit, use it.
434
+ if (!conversion && defaultUnit) {
435
+ conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);
436
+ }
440
437
  if (conversion) {
441
438
  const value = tokens[0].value * conversion.factor + conversion.offset;
442
439
  return { ok: true, value };
@@ -444,17 +441,6 @@ export class Parser {
444
441
  // if no conversion, just return parsed number and ignore value in second token
445
442
  return { ok: true, value: tokens[0].value };
446
443
  }
447
- else { // unit specification comes before value (like currency)
448
- if (tokens[1].isNumber && tokens[0].isString) {
449
- const conversion = Parser.tryFindUnitConversion(tokens[0].value, unitsConversions, defaultUnit);
450
- if (conversion) {
451
- const value = tokens[1].value * conversion.factor + conversion.offset;
452
- return { ok: true, value };
453
- }
454
- // if no conversion, just return parsed number and ignore value in second token
455
- return { ok: true, value: tokens[1].value };
456
- }
457
- }
458
444
  }
459
445
  // common case where there are multiple value/label pairs
460
446
  if (tokens.length % 2 === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { QuantityConstants } from \"./Constants\";\r\nimport { Format } from \"./Formatter/Format\";\r\nimport { FormatTraits, FormatType } from \"./Formatter/FormatEnums\";\r\nimport { AlternateUnitLabelsProvider, PotentialParseUnit, QuantityProps, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"./Interfaces\";\r\nimport { ParserSpec } from \"./ParserSpec\";\r\nimport { Quantity } from \"./Quantity\";\r\n\r\n/** Possible parser errors\r\n * @beta\r\n */\r\nexport enum ParseError {\r\n UnableToGenerateParseTokens = 1,\r\n NoValueOrUnitFoundInString,\r\n UnitLabelSuppliedButNotMatched,\r\n UnknownUnit,\r\n UnableToConvertParseTokensToQuantity,\r\n InvalidParserSpec,\r\n}\r\n\r\n/** Parse error result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParseQuantityError {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: false;\r\n /** The specific error that occurred during parsing. */\r\n error: ParseError;\r\n}\r\n\r\n/** Successful result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParsedQuantity {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: true;\r\n /** The magnitude of the parsed quantity. */\r\n value: number;\r\n}\r\n\r\n/**\r\n * Defines Results of parsing a string input by a user into its desired value type\r\n * @beta\r\n */\r\nexport type QuantityParseResult = ParsedQuantity | ParseQuantityError;\r\n\r\n/** A ParseToken holds either a numeric or string token extracted from a string that represents a quantity value.\r\n * @beta\r\n */\r\nclass ParseToken {\r\n public value: number | string;\r\n\r\n constructor(value: string | number) {\r\n if (typeof value === \"string\")\r\n this.value = value.trim();\r\n else\r\n this.value = value;\r\n }\r\n\r\n public get isString(): boolean { return typeof this.value === \"string\"; }\r\n public get isNumber(): boolean { return typeof this.value === \"number\"; }\r\n}\r\n\r\n/** A ScientificToken holds an index and string representing the exponent.\r\n * @beta\r\n */\r\nclass ScientificToken {\r\n public index: number;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, exponent?: string) {\r\n this.index = index;\r\n if (exponent)\r\n this.exponent = exponent;\r\n }\r\n}\r\n\r\n/** A FractionToken holds an index and the fraction value of numerator / denominator.\r\n * @beta\r\n */\r\nclass FractionToken {\r\n public index: number;\r\n public fraction = 0.0;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, fraction?: number) {\r\n this.index = index;\r\n if (fraction)\r\n this.fraction = fraction;\r\n }\r\n}\r\n\r\n/** A Parser class that is used to break a string that represents a quantity value into tokens.\r\n * @beta\r\n */\r\nexport class Parser {\r\n private static _log = false;\r\n\r\n public static isParsedQuantity(item: QuantityParseResult): item is ParsedQuantity {\r\n return item.ok;\r\n }\r\n\r\n public static isParseError(item: QuantityParseResult): item is ParseQuantityError {\r\n return !item.ok;\r\n }\r\n\r\n private static checkForScientificNotation(index: number, stringToParse: string, uomSeparatorToIgnore: number): ScientificToken {\r\n let exponentString = \"\";\r\n let i = index + 1;\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode) || ((charCode === QuantityConstants.CHAR_MINUS || charCode === QuantityConstants.CHAR_PLUS) && (i === (index + 1)))) {\r\n exponentString = exponentString.concat(stringToParse[i]);\r\n } else {\r\n i = uomSeparatorToIgnore === charCode ? i : i - 1;\r\n break;\r\n }\r\n }\r\n\r\n if (exponentString.length > 1 || ((exponentString.length === 1) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_MINUS) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_PLUS)))\r\n return new ScientificToken(i, exponentString);\r\n\r\n return new ScientificToken(index);\r\n }\r\n\r\n private static checkForFractions(index: number, stringToParse: string, uomSeparatorToIgnore: number, numeratorStr?: string): FractionToken {\r\n let numeratorToken = \"\";\r\n let denominatorToken = \"\";\r\n let processingNumerator = true;\r\n let i = index;\r\n if (numeratorStr && numeratorStr.length > 0) {\r\n numeratorToken = numeratorStr;\r\n processingNumerator = false;\r\n }\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode)) {\r\n if (processingNumerator) {\r\n numeratorToken = numeratorToken.concat(stringToParse[i]);\r\n } else {\r\n denominatorToken = denominatorToken.concat(stringToParse[i]);\r\n }\r\n } else {\r\n if (processingNumerator && (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH)) {\r\n processingNumerator = false;\r\n } else {\r\n if (uomSeparatorToIgnore !== charCode)\r\n i = i - 1; // skip over uom separator after fraction\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (numeratorToken.length > 0 && denominatorToken.length > 0) {\r\n const numerator = parseInt(numeratorToken, 10);\r\n const denominator = parseInt(denominatorToken, 10);\r\n if (denominator > 0)\r\n return new FractionToken(i, numerator / denominator);\r\n return new FractionToken(i);\r\n }\r\n\r\n return new FractionToken(index + 1);\r\n }\r\n\r\n private static isDigit(charCode: number): boolean {\r\n return (charCode >= QuantityConstants.CHAR_DIGIT_ZERO) && (charCode <= QuantityConstants.CHAR_DIGIT_NINE);\r\n }\r\n\r\n private static isDigitOrDecimalSeparator(charCode: number, format: Format): boolean {\r\n return (charCode === format.decimalSeparator.charCodeAt(0)) || Parser.isDigit(charCode);\r\n }\r\n\r\n /** Parse the quantity string and return and array of ParseTokens that represent the component invariant values and unit labels.\r\n * @param quantitySpecification The quantity string to ba parsed.\r\n */\r\n public static parseQuantitySpecification(quantitySpecification: string, format: Format): ParseToken[] {\r\n const tokens: ParseToken[] = [];\r\n const str = quantitySpecification.trim();\r\n let processingNumber = false;\r\n let wipToken = \"\";\r\n let signToken = \"\";\r\n let uomSeparatorToIgnore = 0;\r\n let fractionDashCode = 0;\r\n\r\n const skipCodes: number[] = [format.thousandSeparator.charCodeAt(0)];\r\n\r\n if (format.type === FormatType.Station && format.stationSeparator && format.stationSeparator.length === 1)\r\n skipCodes.push(format.stationSeparator.charCodeAt(0));\r\n\r\n if (format.type === FormatType.Fractional && format.hasFormatTraitSet(FormatTraits.FractionDash)) {\r\n fractionDashCode = QuantityConstants.CHAR_MINUS;\r\n }\r\n\r\n if (format.uomSeparator && format.uomSeparator !== \" \" && format.uomSeparator.length === 1) {\r\n uomSeparatorToIgnore = format.uomSeparator.charCodeAt(0);\r\n skipCodes.push(uomSeparatorToIgnore);\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\r\n for (let i = 0; i < str.length; i++) {\r\n const charCode = str.charCodeAt(i);\r\n if (Parser.isDigitOrDecimalSeparator(charCode, format)) {\r\n if (!processingNumber) {\r\n if (wipToken.length > 0) {\r\n tokens.push(new ParseToken(wipToken));\r\n wipToken = \"\";\r\n }\r\n processingNumber = true;\r\n }\r\n // Decimal separators must be replaced with '.' before converting to a number - parseFloat() only supports '.' as the decimal separator.\r\n const charToAdd = charCode === format.decimalSeparator.charCodeAt(0) ? \".\" : str[i];\r\n wipToken = wipToken.concat(charToAdd);\r\n } else {\r\n if (processingNumber) {\r\n if (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_FRACTION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore, wipToken);\r\n let fraction = fractSymbol.fraction;\r\n i = fractSymbol.index;\r\n if (fractSymbol.fraction !== 0.0) {\r\n wipToken = \"\";\r\n if (signToken.length > 0) {\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(fraction));\r\n processingNumber = false;\r\n continue;\r\n }\r\n } else {\r\n // a space may signify end of number or start of decimal\r\n if (charCode === QuantityConstants.CHAR_SPACE || charCode === fractionDashCode) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore);\r\n let fraction = fractSymbol.fraction;\r\n if (fractSymbol.fraction !== 0.0) {\r\n i = fractSymbol.index;\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n const valueWithFraction = parseFloat(wipToken) + fraction;\r\n tokens.push(new ParseToken(valueWithFraction));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n }\r\n continue;\r\n } else {\r\n // an \"E\" or \"e\" may signify scientific notation\r\n if (charCode === QuantityConstants.CHAR_UPPER_E || charCode === QuantityConstants.CHAR_LOWER_E) {\r\n const exponentSymbol = Parser.checkForScientificNotation(i, str, uomSeparatorToIgnore);\r\n i = exponentSymbol.index;\r\n\r\n if (exponentSymbol.exponent && exponentSymbol.exponent.length > 0) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n wipToken = `${wipToken}e${exponentSymbol.exponent}`;\r\n const scientificValue = Number(wipToken);\r\n tokens.push(new ParseToken(scientificValue));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n continue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ignore any codes in skipCodes\r\n if (skipCodes.findIndex((ref) => ref === charCode) !== -1)\r\n continue;\r\n\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n\r\n wipToken = (i < str.length) ? str[i] : \"\";\r\n processingNumber = false;\r\n } else {\r\n // not processing a number\r\n if ((charCode === QuantityConstants.CHAR_PLUS || charCode === QuantityConstants.CHAR_MINUS)) {\r\n if (0 === tokens.length) // sign token only needed for left most value\r\n signToken = str[i];\r\n continue;\r\n }\r\n\r\n wipToken = wipToken.concat(str[i]);\r\n }\r\n }\r\n }\r\n\r\n // handle case where end of input string is reached.\r\n if (wipToken.length > 0) {\r\n if (processingNumber) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n }\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n } else {\r\n tokens.push(new ParseToken(wipToken));\r\n }\r\n }\r\n\r\n return tokens;\r\n }\r\n\r\n private static async lookupUnitByLabel(unitLabel: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider) {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n const labelToFind = unitLabel.toLowerCase();\r\n // First look in format for a label and matches\r\n if (format.units && format.units.length > 0) {\r\n const formatUnit = format.units.find(([unit, label]) => {\r\n if (label && label.toLowerCase() === labelToFind)\r\n return true;\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // check any alternate labels that may be defined for the Unit\r\n if (alternateLabels && alternateLabels.find((lbl) => lbl.toLowerCase() === labelToFind))\r\n return true;\r\n\r\n return false;\r\n });\r\n if (formatUnit)\r\n return formatUnit[0];\r\n }\r\n\r\n // now try to find a unit from the same family and system\r\n let foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined, defaultUnit ? defaultUnit.system : undefined);\r\n\r\n // if nothing found yet just limit to family\r\n if (!foundUnit.isValid && defaultUnit)\r\n foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined);\r\n return foundUnit;\r\n }\r\n\r\n private static async createQuantityFromParseTokens(tokens: ParseToken[], format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n let defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else {\r\n const unit = await this.lookupUnitByLabel(tokens[0].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n return new Quantity(unit);\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n const unit = await this.lookupUnitByLabel(tokens[1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (defaultUnit && defaultUnit.name === unit.name) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n const mag = ((tokens[0].value as number * conversion.factor)) + conversion.offset;\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n } else { // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n const unit = await this.lookupUnitByLabel(tokens[0].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (defaultUnit && defaultUnit.name === unit.name) {\r\n return new Quantity(defaultUnit, tokens[1].value as number);\r\n } else if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n const mag = ((tokens[1].value as number * conversion.factor)) + conversion.offset;\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const unit = await this.lookupUnitByLabel(tokens[i + 1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (0 === i) {\r\n if (defaultUnit.name === unit.name)\r\n mag = value;\r\n else {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n mag = ((value * conversion.factor)) + conversion.offset;\r\n }\r\n } else {\r\n if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n }\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n\r\n return new Quantity(defaultUnit);\r\n }\r\n\r\n /** Async method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString.\r\n * @param unitsProvider required to look up units that may be specified in inString\r\n */\r\n public static async parseIntoQuantity(inString: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return new Quantity();\r\n\r\n return Parser.createQuantityFromParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider);\r\n }\r\n\r\n /** method to get the Unit Conversion given a unit label */\r\n private static tryFindUnitConversion(unitLabel: string, unitsConversions: UnitConversionSpec[], preferredUnit?: UnitProps): UnitConversionProps | undefined {\r\n if (unitsConversions.length > 0) {\r\n const label = unitLabel.toLocaleLowerCase();\r\n\r\n /* A preferred unit is used to target a unit if a unit label is used in more that one unit definition from the same unit family.\r\n * An example is if \"ft\" is used as the unitLabel and the preferredUnit is \"SURVEY_FT\" since that unit has an alternate label of \"ft\" the\r\n * conversion to \"SURVEY_FT\" is returned. If no preferredUnit is specified then the unit \"FT\" would likely to have been found first.\r\n * If \"in\" is the unit label and \"SURVEY_FT\" is the preferredUnit then conversion to \"SURVEY_IN\" would be returned.\r\n */\r\n if (preferredUnit) {\r\n // if there is a preferred unit defined see if unit label matched it or one of its alternates\r\n const preferredConversion = unitsConversions.find((conversion) => conversion.name === preferredUnit.name);\r\n if (preferredConversion && preferredConversion.parseLabels) {\r\n if (-1 !== preferredConversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return preferredConversion.conversion;\r\n }\r\n // see if we can find a matching unitLabel in any unit within the same system as the preferred unit\r\n const preferredSystemConversions = unitsConversions.filter((conversion) => conversion.system === preferredUnit.system);\r\n for (const conversion of preferredSystemConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n }\r\n }\r\n }\r\n\r\n // if no unit found based on preferredUnit see if an unit label matches\r\n for (const conversion of unitsConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n } else {\r\n // eslint-disable-next-line no-console\r\n console.log(\"ERROR: Parser expects to find parseLabels array populate with all possible unit labels for the unit.\");\r\n }\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private static getQuantityValueFromParseTokens(tokens: ParseToken[], format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n if (defaultUnit) {\r\n const conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n } else {\r\n // if no conversion or no defaultUnit, just return parsed number\r\n return { ok: true, value: tokens[0].value as number };\r\n }\r\n } else {\r\n // only the unit label was specified so assume magnitude of 1\r\n const conversion = Parser.tryFindUnitConversion(tokens[0].value as string, unitsConversions, defaultUnit);\r\n if (undefined !== conversion)\r\n return { ok: true, value: conversion.factor + conversion.offset };\r\n else\r\n return { ok: false, error: ParseError.NoValueOrUnitFoundInString };\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n const conversion = Parser.tryFindUnitConversion(tokens[1].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n // if no conversion, just return parsed number and ignore value in second token\r\n return { ok: true, value: tokens[0].value as number };\r\n } else { // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n const conversion = Parser.tryFindUnitConversion(tokens[0].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[1].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n // if no conversion, just return parsed number and ignore value in second token\r\n return { ok: true, value: tokens[1].value as number };\r\n }\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const conversion = Parser.tryFindUnitConversion(tokens[i + 1].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n return { ok: true, value: mag };\r\n }\r\n\r\n return { ok: false, error: ParseError.UnableToConvertParseTokensToQuantity };\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions.\r\n * @param defaultValue default value to return if parsing is un successful\r\n */\r\n public static parseQuantityString(inString: string, parserSpec: ParserSpec): QuantityParseResult {\r\n return Parser.parseToQuantityValue(inString, parserSpec.format, parserSpec.unitConversions);\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString. Primary unit serves as a default unit if no unit label found in string.\r\n * @param unitsConversions dictionary of conversions used to convert from unit used in inString to output quantity\r\n */\r\n public static parseToQuantityValue(inString: string, format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n // ensure any labels defined in composite unit definition are specified in unitConversions\r\n if (format.units) {\r\n format.units.forEach(([unit, label]) => {\r\n if (label) {\r\n if (unit.label !== label) { // if default unit label does not match composite label ensure the label is in the list of parse labels for the conversion\r\n const unitConversion = unitsConversions.find((conversion) => conversion.name === unit.name);\r\n if (unitConversion && unitConversion.parseLabels && !unitConversion.parseLabels.find((entry) => entry === label))\r\n unitConversion.parseLabels.push(label);\r\n }\r\n }\r\n });\r\n }\r\n\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return { ok: false, error: ParseError.UnableToGenerateParseTokens };\r\n\r\n if (Parser._log) {\r\n // eslint-disable-next-line no-console\r\n console.log(`Parse tokens`);\r\n let i = 0;\r\n for (const token of tokens) {\r\n // eslint-disable-next-line no-console\r\n console.log(` [${i++}] isNumber=${token.isNumber} isString=${token.isString} token=${token.value}`);\r\n }\r\n }\r\n\r\n return Parser.getQuantityValueFromParseTokens(tokens, format, unitsConversions);\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecsForUnit(unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const familyUnits = await unitsProvider.getUnitsByFamily(outUnit.phenomenon);\r\n for (const unit of familyUnits) {\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecs(unitsProvider: UnitsProvider, outUnitName: string, potentialParseUnits: PotentialParseUnit[], altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const outUnit = await unitsProvider.findUnitByName(outUnitName);\r\n if (!outUnit || !outUnit.name || 0 === outUnit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate out unit ${outUnitName}.`);\r\n return unitConversionSpecs;\r\n }\r\n\r\n for (const potentialParseUnit of potentialParseUnits) {\r\n const unit = await unitsProvider.findUnitByName(potentialParseUnit.unitName);\r\n if (!unit || !unit.name || 0 === unit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate potential unit ${potentialParseUnit.unitName}.`);\r\n continue;\r\n }\r\n\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n // add any alternate labels that where provided by caller\r\n if (potentialParseUnit.altLabels) {\r\n potentialParseUnit.altLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { QuantityConstants } from \"./Constants\";\r\nimport { Format } from \"./Formatter/Format\";\r\nimport { FormatTraits, FormatType } from \"./Formatter/FormatEnums\";\r\nimport { AlternateUnitLabelsProvider, PotentialParseUnit, QuantityProps, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"./Interfaces\";\r\nimport { ParserSpec } from \"./ParserSpec\";\r\nimport { Quantity } from \"./Quantity\";\r\n\r\n/** Possible parser errors\r\n * @beta\r\n */\r\nexport enum ParseError {\r\n UnableToGenerateParseTokens = 1,\r\n NoValueOrUnitFoundInString,\r\n UnitLabelSuppliedButNotMatched,\r\n UnknownUnit,\r\n UnableToConvertParseTokensToQuantity,\r\n InvalidParserSpec,\r\n}\r\n\r\n/** Parse error result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParseQuantityError {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: false;\r\n /** The specific error that occurred during parsing. */\r\n error: ParseError;\r\n}\r\n\r\n/** Successful result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].\r\n * @beta\r\n */\r\nexport interface ParsedQuantity {\r\n /** Union discriminator for [[QuantityParseResult]]. */\r\n ok: true;\r\n /** The magnitude of the parsed quantity. */\r\n value: number;\r\n}\r\n\r\n/**\r\n * Defines Results of parsing a string input by a user into its desired value type\r\n * @beta\r\n */\r\nexport type QuantityParseResult = ParsedQuantity | ParseQuantityError;\r\n\r\n/** A ParseToken holds either a numeric or string token extracted from a string that represents a quantity value.\r\n * @beta\r\n */\r\nclass ParseToken {\r\n public value: number | string;\r\n\r\n constructor(value: string | number) {\r\n if (typeof value === \"string\")\r\n this.value = value.trim();\r\n else\r\n this.value = value;\r\n }\r\n\r\n public get isString(): boolean { return typeof this.value === \"string\"; }\r\n public get isNumber(): boolean { return typeof this.value === \"number\"; }\r\n}\r\n\r\n/** A ScientificToken holds an index and string representing the exponent.\r\n * @beta\r\n */\r\nclass ScientificToken {\r\n public index: number;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, exponent?: string) {\r\n this.index = index;\r\n if (exponent)\r\n this.exponent = exponent;\r\n }\r\n}\r\n\r\n/** A FractionToken holds an index and the fraction value of numerator / denominator.\r\n * @beta\r\n */\r\nclass FractionToken {\r\n public index: number;\r\n public fraction = 0.0;\r\n public exponent = \"\";\r\n\r\n constructor(index: number, fraction?: number) {\r\n this.index = index;\r\n if (fraction)\r\n this.fraction = fraction;\r\n }\r\n}\r\n\r\n/** A Parser class that is used to break a string that represents a quantity value into tokens.\r\n * @beta\r\n */\r\nexport class Parser {\r\n private static _log = false;\r\n\r\n public static isParsedQuantity(item: QuantityParseResult): item is ParsedQuantity {\r\n return item.ok;\r\n }\r\n\r\n public static isParseError(item: QuantityParseResult): item is ParseQuantityError {\r\n return !item.ok;\r\n }\r\n\r\n private static checkForScientificNotation(index: number, stringToParse: string, uomSeparatorToIgnore: number): ScientificToken {\r\n let exponentString = \"\";\r\n let i = index + 1;\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode) || ((charCode === QuantityConstants.CHAR_MINUS || charCode === QuantityConstants.CHAR_PLUS) && (i === (index + 1)))) {\r\n exponentString = exponentString.concat(stringToParse[i]);\r\n } else {\r\n i = uomSeparatorToIgnore === charCode ? i : i - 1;\r\n break;\r\n }\r\n }\r\n\r\n if (exponentString.length > 1 || ((exponentString.length === 1) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_MINUS) && (exponentString.charCodeAt(0) !== QuantityConstants.CHAR_PLUS)))\r\n return new ScientificToken(i, exponentString);\r\n\r\n return new ScientificToken(index);\r\n }\r\n\r\n private static checkForFractions(index: number, stringToParse: string, uomSeparatorToIgnore: number, numeratorStr?: string): FractionToken {\r\n let numeratorToken = \"\";\r\n let denominatorToken = \"\";\r\n let processingNumerator = true;\r\n let i = index;\r\n if (numeratorStr && numeratorStr.length > 0) {\r\n numeratorToken = numeratorStr;\r\n processingNumerator = false;\r\n }\r\n\r\n for (; i < stringToParse.length; i++) {\r\n const charCode = stringToParse.charCodeAt(i);\r\n if (Parser.isDigit(charCode)) {\r\n if (processingNumerator) {\r\n numeratorToken = numeratorToken.concat(stringToParse[i]);\r\n } else {\r\n denominatorToken = denominatorToken.concat(stringToParse[i]);\r\n }\r\n } else {\r\n if (processingNumerator && (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH)) {\r\n processingNumerator = false;\r\n } else {\r\n if (uomSeparatorToIgnore !== charCode)\r\n i = i - 1; // skip over uom separator after fraction\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (numeratorToken.length > 0 && denominatorToken.length > 0) {\r\n const numerator = parseInt(numeratorToken, 10);\r\n const denominator = parseInt(denominatorToken, 10);\r\n if (denominator > 0)\r\n return new FractionToken(i, numerator / denominator);\r\n return new FractionToken(i);\r\n }\r\n\r\n return new FractionToken(index + 1);\r\n }\r\n\r\n private static isDigit(charCode: number): boolean {\r\n return (charCode >= QuantityConstants.CHAR_DIGIT_ZERO) && (charCode <= QuantityConstants.CHAR_DIGIT_NINE);\r\n }\r\n\r\n private static isDigitOrDecimalSeparator(charCode: number, format: Format): boolean {\r\n return (charCode === format.decimalSeparator.charCodeAt(0)) || Parser.isDigit(charCode);\r\n }\r\n\r\n /** Parse the quantity string and return and array of ParseTokens that represent the component invariant values and unit labels.\r\n * @param quantitySpecification The quantity string to ba parsed.\r\n */\r\n public static parseQuantitySpecification(quantitySpecification: string, format: Format): ParseToken[] {\r\n const tokens: ParseToken[] = [];\r\n const str = quantitySpecification.trim();\r\n let processingNumber = false;\r\n let wipToken = \"\";\r\n let signToken = \"\";\r\n let uomSeparatorToIgnore = 0;\r\n let fractionDashCode = 0;\r\n\r\n const skipCodes: number[] = [format.thousandSeparator.charCodeAt(0)];\r\n\r\n if (format.type === FormatType.Station && format.stationSeparator && format.stationSeparator.length === 1)\r\n skipCodes.push(format.stationSeparator.charCodeAt(0));\r\n\r\n if (format.type === FormatType.Fractional && format.hasFormatTraitSet(FormatTraits.FractionDash)) {\r\n fractionDashCode = QuantityConstants.CHAR_MINUS;\r\n }\r\n\r\n if (format.uomSeparator && format.uomSeparator !== \" \" && format.uomSeparator.length === 1) {\r\n uomSeparatorToIgnore = format.uomSeparator.charCodeAt(0);\r\n skipCodes.push(uomSeparatorToIgnore);\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\r\n for (let i = 0; i < str.length; i++) {\r\n const charCode = str.charCodeAt(i);\r\n if (Parser.isDigitOrDecimalSeparator(charCode, format)) {\r\n if (!processingNumber) {\r\n if (wipToken.length > 0) {\r\n tokens.push(new ParseToken(wipToken));\r\n wipToken = \"\";\r\n }\r\n processingNumber = true;\r\n }\r\n // Decimal separators must be replaced with '.' before converting to a number - parseFloat() only supports '.' as the decimal separator.\r\n const charToAdd = charCode === format.decimalSeparator.charCodeAt(0) ? \".\" : str[i];\r\n wipToken = wipToken.concat(charToAdd);\r\n } else {\r\n if (processingNumber) {\r\n if (charCode === QuantityConstants.CHAR_SLASH || charCode === QuantityConstants.CHAR_FRACTION_SLASH || charCode === QuantityConstants.CHAR_DIVISION_SLASH) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore, wipToken);\r\n let fraction = fractSymbol.fraction;\r\n i = fractSymbol.index;\r\n if (fractSymbol.fraction !== 0.0) {\r\n wipToken = \"\";\r\n if (signToken.length > 0) {\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(fraction));\r\n processingNumber = false;\r\n continue;\r\n }\r\n } else {\r\n // a space may signify end of number or start of decimal\r\n if (charCode === QuantityConstants.CHAR_SPACE || charCode === fractionDashCode) {\r\n const fractSymbol = Parser.checkForFractions(i + 1, str, uomSeparatorToIgnore);\r\n let fraction = fractSymbol.fraction;\r\n if (fractSymbol.fraction !== 0.0) {\r\n i = fractSymbol.index;\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n if (signToken === \"-\")\r\n fraction = 0 - fraction;\r\n\r\n signToken = \"\";\r\n }\r\n\r\n const valueWithFraction = parseFloat(wipToken) + fraction;\r\n tokens.push(new ParseToken(valueWithFraction));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n }\r\n continue;\r\n } else {\r\n // an \"E\" or \"e\" may signify scientific notation\r\n if (charCode === QuantityConstants.CHAR_UPPER_E || charCode === QuantityConstants.CHAR_LOWER_E) {\r\n const exponentSymbol = Parser.checkForScientificNotation(i, str, uomSeparatorToIgnore);\r\n i = exponentSymbol.index;\r\n\r\n if (exponentSymbol.exponent && exponentSymbol.exponent.length > 0) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n wipToken = `${wipToken}e${exponentSymbol.exponent}`;\r\n const scientificValue = Number(wipToken);\r\n tokens.push(new ParseToken(scientificValue));\r\n processingNumber = false;\r\n wipToken = \"\";\r\n continue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ignore any codes in skipCodes\r\n if (skipCodes.findIndex((ref) => ref === charCode) !== -1)\r\n continue;\r\n\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n signToken = \"\";\r\n }\r\n\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n\r\n wipToken = (i < str.length) ? str[i] : \"\";\r\n processingNumber = false;\r\n } else {\r\n // not processing a number\r\n if ((charCode === QuantityConstants.CHAR_PLUS || charCode === QuantityConstants.CHAR_MINUS)) {\r\n if (0 === tokens.length) // sign token only needed for left most value\r\n signToken = str[i];\r\n continue;\r\n }\r\n\r\n wipToken = wipToken.concat(str[i]);\r\n }\r\n }\r\n }\r\n\r\n // handle case where end of input string is reached.\r\n if (wipToken.length > 0) {\r\n if (processingNumber) {\r\n if (signToken.length > 0) {\r\n wipToken = signToken + wipToken;\r\n }\r\n tokens.push(new ParseToken(parseFloat(wipToken)));\r\n } else {\r\n tokens.push(new ParseToken(wipToken));\r\n }\r\n }\r\n\r\n return tokens;\r\n }\r\n\r\n private static async lookupUnitByLabel(unitLabel: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider) {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n const labelToFind = unitLabel.toLowerCase();\r\n // First look in format for a label and matches\r\n if (format.units && format.units.length > 0) {\r\n const formatUnit = format.units.find(([unit, label]) => {\r\n if (label && label.toLowerCase() === labelToFind)\r\n return true;\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // check any alternate labels that may be defined for the Unit\r\n if (alternateLabels && alternateLabels.find((lbl) => lbl.toLowerCase() === labelToFind))\r\n return true;\r\n\r\n return false;\r\n });\r\n if (formatUnit)\r\n return formatUnit[0];\r\n }\r\n\r\n // now try to find a unit from the same family and system\r\n let foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined, defaultUnit ? defaultUnit.system : undefined);\r\n\r\n // if nothing found yet just limit to family\r\n if (!foundUnit.isValid && defaultUnit)\r\n foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined);\r\n return foundUnit;\r\n }\r\n\r\n private static async createQuantityFromParseTokens(tokens: ParseToken[], format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n let defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else {\r\n const unit = await this.lookupUnitByLabel(tokens[0].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n return new Quantity(unit);\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n tokens = [tokens[1], tokens[0]];\r\n }\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n const unit = await this.lookupUnitByLabel(tokens[1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (defaultUnit && defaultUnit.name === unit.name) {\r\n return new Quantity(defaultUnit, tokens[0].value as number);\r\n } else if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n const mag = ((tokens[0].value as number * conversion.factor)) + conversion.offset;\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const unit = await this.lookupUnitByLabel(tokens[i + 1].value as string, format, unitsProvider, altUnitLabelsProvider);\r\n if (undefined === defaultUnit)\r\n defaultUnit = unit;\r\n if (0 === i) {\r\n if (defaultUnit.name === unit.name)\r\n mag = value;\r\n else {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n mag = ((value * conversion.factor)) + conversion.offset;\r\n }\r\n } else {\r\n if (defaultUnit) {\r\n const conversion = await unitsProvider.getConversion(unit, defaultUnit);\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n }\r\n return new Quantity(defaultUnit, mag);\r\n }\r\n\r\n return new Quantity(defaultUnit);\r\n }\r\n\r\n /** Async method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString.\r\n * @param unitsProvider required to look up units that may be specified in inString\r\n */\r\n public static async parseIntoQuantity(inString: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps> {\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return new Quantity();\r\n\r\n return Parser.createQuantityFromParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider);\r\n }\r\n\r\n /** method to get the Unit Conversion given a unit label */\r\n private static tryFindUnitConversion(unitLabel: string, unitsConversions: UnitConversionSpec[], preferredUnit?: UnitProps): UnitConversionProps | undefined {\r\n if (unitsConversions.length > 0) {\r\n const label = unitLabel.toLocaleLowerCase();\r\n\r\n /* A preferred unit is used to target a unit if a unit label is used in more that one unit definition from the same unit family.\r\n * An example is if \"ft\" is used as the unitLabel and the preferredUnit is \"SURVEY_FT\" since that unit has an alternate label of \"ft\" the\r\n * conversion to \"SURVEY_FT\" is returned. If no preferredUnit is specified then the unit \"FT\" would likely to have been found first.\r\n * If \"in\" is the unit label and \"SURVEY_FT\" is the preferredUnit then conversion to \"SURVEY_IN\" would be returned.\r\n */\r\n if (preferredUnit) {\r\n // if there is a preferred unit defined see if unit label matched it or one of its alternates\r\n const preferredConversion = unitsConversions.find((conversion) => conversion.name === preferredUnit.name);\r\n if (preferredConversion && preferredConversion.parseLabels) {\r\n if (-1 !== preferredConversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return preferredConversion.conversion;\r\n }\r\n // see if we can find a matching unitLabel in any unit within the same system as the preferred unit\r\n const preferredSystemConversions = unitsConversions.filter((conversion) => conversion.system === preferredUnit.system);\r\n for (const conversion of preferredSystemConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n }\r\n }\r\n }\r\n\r\n // if no unit found based on preferredUnit see if an unit label matches\r\n for (const conversion of unitsConversions) {\r\n if (conversion.parseLabels) {\r\n if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label))\r\n return conversion.conversion;\r\n } else {\r\n // eslint-disable-next-line no-console\r\n console.log(\"ERROR: Parser expects to find parseLabels array populate with all possible unit labels for the unit.\");\r\n }\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private static getQuantityValueFromParseTokens(tokens: ParseToken[], format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;\r\n // common case where single value is supplied\r\n if (tokens.length === 1) {\r\n if (tokens[0].isNumber) {\r\n if (defaultUnit) {\r\n const conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n } else {\r\n // if no conversion or no defaultUnit, just return parsed number\r\n return { ok: true, value: tokens[0].value as number };\r\n }\r\n } else {\r\n // only the unit label was specified so assume magnitude of 1\r\n const conversion = Parser.tryFindUnitConversion(tokens[0].value as string, unitsConversions, defaultUnit);\r\n if (undefined !== conversion)\r\n return { ok: true, value: conversion.factor + conversion.offset };\r\n else\r\n return { ok: false, error: ParseError.NoValueOrUnitFoundInString };\r\n }\r\n }\r\n\r\n // common case where single value and single label are supplied\r\n if (tokens.length === 2) {\r\n // unit specification comes before value (like currency)\r\n if (tokens[1].isNumber && tokens[0].isString) {\r\n tokens = [tokens[1], tokens[0]];\r\n }\r\n if (tokens[0].isNumber && tokens[1].isString) {\r\n let conversion = Parser.tryFindUnitConversion(tokens[1].value as string, unitsConversions, defaultUnit);\r\n // if no conversion, ignore value in second token. If we have defaultUnit, use it.\r\n if (!conversion && defaultUnit) {\r\n conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit);\r\n }\r\n if (conversion) {\r\n const value = (tokens[0].value as number) * conversion.factor + conversion.offset;\r\n return { ok: true, value };\r\n }\r\n // if no conversion, just return parsed number and ignore value in second token\r\n return { ok: true, value: tokens[0].value as number };\r\n }\r\n }\r\n\r\n // common case where there are multiple value/label pairs\r\n if (tokens.length % 2 === 0) {\r\n let mag = 0.0;\r\n for (let i = 0; i < tokens.length; i = i + 2) {\r\n if (tokens[i].isNumber && tokens[i + 1].isString) {\r\n const value = tokens[i].value as number;\r\n const conversion = Parser.tryFindUnitConversion(tokens[i + 1].value as string, unitsConversions, defaultUnit);\r\n if (conversion) {\r\n if (mag < 0.0)\r\n mag = mag - ((value * conversion.factor)) + conversion.offset;\r\n else\r\n mag = mag + ((value * conversion.factor)) + conversion.offset;\r\n }\r\n }\r\n }\r\n return { ok: true, value: mag };\r\n }\r\n\r\n return { ok: false, error: ParseError.UnableToConvertParseTokensToQuantity };\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions.\r\n * @param defaultValue default value to return if parsing is un successful\r\n */\r\n public static parseQuantityString(inString: string, parserSpec: ParserSpec): QuantityParseResult {\r\n return Parser.parseToQuantityValue(inString, parserSpec.format, parserSpec.unitConversions);\r\n }\r\n\r\n /** Method to generate a Quantity given a string that represents a quantity value and likely a unit label.\r\n * @param inString A string that contains text represent a quantity.\r\n * @param format Defines the likely format of inString. Primary unit serves as a default unit if no unit label found in string.\r\n * @param unitsConversions dictionary of conversions used to convert from unit used in inString to output quantity\r\n */\r\n public static parseToQuantityValue(inString: string, format: Format, unitsConversions: UnitConversionSpec[]): QuantityParseResult {\r\n // ensure any labels defined in composite unit definition are specified in unitConversions\r\n if (format.units) {\r\n format.units.forEach(([unit, label]) => {\r\n if (label) {\r\n if (unit.label !== label) { // if default unit label does not match composite label ensure the label is in the list of parse labels for the conversion\r\n const unitConversion = unitsConversions.find((conversion) => conversion.name === unit.name);\r\n if (unitConversion && unitConversion.parseLabels && !unitConversion.parseLabels.find((entry) => entry === label))\r\n unitConversion.parseLabels.push(label);\r\n }\r\n }\r\n });\r\n }\r\n\r\n const tokens: ParseToken[] = Parser.parseQuantitySpecification(inString, format);\r\n if (tokens.length === 0)\r\n return { ok: false, error: ParseError.UnableToGenerateParseTokens };\r\n\r\n if (Parser._log) {\r\n // eslint-disable-next-line no-console\r\n console.log(`Parse tokens`);\r\n let i = 0;\r\n for (const token of tokens) {\r\n // eslint-disable-next-line no-console\r\n console.log(` [${i++}] isNumber=${token.isNumber} isString=${token.isString} token=${token.value}`);\r\n }\r\n }\r\n\r\n return Parser.getQuantityValueFromParseTokens(tokens, format, unitsConversions);\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecsForUnit(unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const familyUnits = await unitsProvider.getUnitsByFamily(outUnit.phenomenon);\r\n for (const unit of familyUnits) {\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n\r\n /** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */\r\n public static async createUnitConversionSpecs(unitsProvider: UnitsProvider, outUnitName: string, potentialParseUnits: PotentialParseUnit[], altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\r\n const unitConversionSpecs: UnitConversionSpec[] = [];\r\n\r\n const outUnit = await unitsProvider.findUnitByName(outUnitName);\r\n if (!outUnit || !outUnit.name || 0 === outUnit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate out unit ${outUnitName}.`);\r\n return unitConversionSpecs;\r\n }\r\n\r\n for (const potentialParseUnit of potentialParseUnits) {\r\n const unit = await unitsProvider.findUnitByName(potentialParseUnit.unitName);\r\n if (!unit || !unit.name || 0 === unit.name.length) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate potential unit ${potentialParseUnit.unitName}.`);\r\n continue;\r\n }\r\n\r\n const conversion = await unitsProvider.getConversion(unit, outUnit);\r\n const parseLabels: string[] = [unit.label.toLocaleLowerCase()];\r\n const alternateLabels = altUnitLabelsProvider?.getAlternateUnitLabels(unit);\r\n // add any alternate labels that may be defined for the Unit\r\n if (alternateLabels) {\r\n alternateLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n\r\n // add any alternate labels that where provided by caller\r\n if (potentialParseUnit.altLabels) {\r\n potentialParseUnit.altLabels.forEach((label: string) => {\r\n const potentialLabel = label.toLocaleLowerCase();\r\n if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel))\r\n parseLabels.push(label.toLocaleLowerCase());\r\n });\r\n }\r\n unitConversionSpecs.push({\r\n name: unit.name,\r\n label: unit.label,\r\n conversion,\r\n parseLabels,\r\n system: unit.system,\r\n });\r\n }\r\n return unitConversionSpecs;\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/core-quantity",
3
- "version": "4.7.0-dev.9",
3
+ "version": "4.8.0-dev.1",
4
4
  "description": "Quantity parsing, formatting and conversions for iModel.js",
5
5
  "main": "lib/cjs/core-quantity.js",
6
6
  "module": "lib/esm/core-quantity.js",
@@ -35,11 +35,11 @@
35
35
  "rimraf": "^3.0.2",
36
36
  "sinon": "^17.0.1",
37
37
  "typescript": "~5.3.3",
38
- "@itwin/core-bentley": "4.7.0-dev.9",
39
- "@itwin/build-tools": "4.7.0-dev.9"
38
+ "@itwin/build-tools": "4.8.0-dev.1",
39
+ "@itwin/core-bentley": "4.8.0-dev.1"
40
40
  },
41
41
  "peerDependencies": {
42
- "@itwin/core-bentley": "^4.7.0-dev.9"
42
+ "@itwin/core-bentley": "^4.8.0-dev.1"
43
43
  },
44
44
  "nyc": {
45
45
  "extends": "./node_modules/@itwin/build-tools/.nycrc"