@budiauktioner/buildi-primitives 0.2.0 → 0.3.0
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 +56 -0
- package/PARITY.md +7 -7
- package/README.md +18 -1
- package/dist/cjs/contact/phone-number-test-data.js +1 -1
- package/dist/cjs/contact/phone-number-test-data.js.map +1 -1
- package/dist/cjs/contact/phone-number.js +36 -14
- package/dist/cjs/contact/phone-number.js.map +2 -2
- package/dist/cjs/internal/scan-boundaries.js +26 -0
- package/dist/cjs/internal/scan-boundaries.js.map +7 -0
- package/dist/cjs/measurement/area.js +2 -1
- package/dist/cjs/measurement/area.js.map +2 -2
- package/dist/cjs/measurement/data-size.js +1 -1
- package/dist/cjs/measurement/data-size.js.map +1 -1
- package/dist/cjs/measurement/electric-charge.js +1 -1
- package/dist/cjs/measurement/electric-charge.js.map +1 -1
- package/dist/cjs/measurement/electric-current.js +1 -1
- package/dist/cjs/measurement/electric-current.js.map +1 -1
- package/dist/cjs/measurement/energy.js +1 -1
- package/dist/cjs/measurement/energy.js.map +1 -1
- package/dist/cjs/measurement/flow-rate.js +1 -1
- package/dist/cjs/measurement/flow-rate.js.map +1 -1
- package/dist/cjs/measurement/frequency.js +1 -1
- package/dist/cjs/measurement/frequency.js.map +1 -1
- package/dist/cjs/measurement/length.js +1 -1
- package/dist/cjs/measurement/length.js.map +1 -1
- package/dist/cjs/measurement/luminance.js +1 -1
- package/dist/cjs/measurement/luminance.js.map +1 -1
- package/dist/cjs/measurement/luminous-flux.js +4 -1
- package/dist/cjs/measurement/luminous-flux.js.map +2 -2
- package/dist/cjs/measurement/percentage.js +1 -1
- package/dist/cjs/measurement/percentage.js.map +1 -1
- package/dist/cjs/measurement/power.js +7 -3
- package/dist/cjs/measurement/power.js.map +2 -2
- package/dist/cjs/measurement/pressure.js +1 -1
- package/dist/cjs/measurement/pressure.js.map +1 -1
- package/dist/cjs/measurement/rotational-speed.js +1 -1
- package/dist/cjs/measurement/rotational-speed.js.map +1 -1
- package/dist/cjs/measurement/sound-level.js +5 -1
- package/dist/cjs/measurement/sound-level.js.map +2 -2
- package/dist/cjs/measurement/speed.js +1 -1
- package/dist/cjs/measurement/speed.js.map +1 -1
- package/dist/cjs/measurement/temperature.js +1 -1
- package/dist/cjs/measurement/temperature.js.map +2 -2
- package/dist/cjs/measurement/torque.js +1 -1
- package/dist/cjs/measurement/torque.js.map +1 -1
- package/dist/cjs/measurement/voltage.js +1 -1
- package/dist/cjs/measurement/voltage.js.map +1 -1
- package/dist/cjs/measurement/volume.js +1 -1
- package/dist/cjs/measurement/volume.js.map +1 -1
- package/dist/cjs/measurement/weight.js +1 -1
- package/dist/cjs/measurement/weight.js.map +1 -1
- package/dist/cjs/organization/swedish-organization-number.js.map +2 -2
- package/dist/cjs/register-default-text-scanners.js +2 -0
- package/dist/cjs/register-default-text-scanners.js.map +2 -2
- package/dist/cjs/sample-data/index.js +18 -1
- package/dist/cjs/sample-data/index.js.map +2 -2
- package/dist/cjs/text-scanning/text-scan-result.js +3 -0
- package/dist/cjs/text-scanning/text-scan-result.js.map +2 -2
- package/dist/cjs/validation/validation-error-reason.js +6 -1
- package/dist/cjs/validation/validation-error-reason.js.map +2 -2
- package/dist/cjs/vehicle/index.js +4 -0
- package/dist/cjs/vehicle/index.js.map +2 -2
- package/dist/cjs/vehicle/watercraft-identification-number.js +332 -0
- package/dist/cjs/vehicle/watercraft-identification-number.js.map +7 -0
- package/dist/esm/contact/phone-number-test-data.js +1 -1
- package/dist/esm/contact/phone-number-test-data.js.map +1 -1
- package/dist/esm/contact/phone-number.js +36 -14
- package/dist/esm/contact/phone-number.js.map +2 -2
- package/dist/esm/internal/scan-boundaries.js +6 -0
- package/dist/esm/internal/scan-boundaries.js.map +7 -0
- package/dist/esm/measurement/area.js +2 -1
- package/dist/esm/measurement/area.js.map +2 -2
- package/dist/esm/measurement/data-size.js +1 -1
- package/dist/esm/measurement/data-size.js.map +1 -1
- package/dist/esm/measurement/electric-charge.js +1 -1
- package/dist/esm/measurement/electric-charge.js.map +1 -1
- package/dist/esm/measurement/electric-current.js +1 -1
- package/dist/esm/measurement/electric-current.js.map +1 -1
- package/dist/esm/measurement/energy.js +1 -1
- package/dist/esm/measurement/energy.js.map +1 -1
- package/dist/esm/measurement/flow-rate.js +1 -1
- package/dist/esm/measurement/flow-rate.js.map +1 -1
- package/dist/esm/measurement/frequency.js +1 -1
- package/dist/esm/measurement/frequency.js.map +1 -1
- package/dist/esm/measurement/length.js +1 -1
- package/dist/esm/measurement/length.js.map +1 -1
- package/dist/esm/measurement/luminance.js +1 -1
- package/dist/esm/measurement/luminance.js.map +1 -1
- package/dist/esm/measurement/luminous-flux.js +4 -1
- package/dist/esm/measurement/luminous-flux.js.map +2 -2
- package/dist/esm/measurement/percentage.js +1 -1
- package/dist/esm/measurement/percentage.js.map +1 -1
- package/dist/esm/measurement/power.js +7 -3
- package/dist/esm/measurement/power.js.map +2 -2
- package/dist/esm/measurement/pressure.js +1 -1
- package/dist/esm/measurement/pressure.js.map +1 -1
- package/dist/esm/measurement/rotational-speed.js +1 -1
- package/dist/esm/measurement/rotational-speed.js.map +1 -1
- package/dist/esm/measurement/sound-level.js +5 -1
- package/dist/esm/measurement/sound-level.js.map +2 -2
- package/dist/esm/measurement/speed.js +1 -1
- package/dist/esm/measurement/speed.js.map +1 -1
- package/dist/esm/measurement/temperature.js +1 -1
- package/dist/esm/measurement/temperature.js.map +2 -2
- package/dist/esm/measurement/torque.js +1 -1
- package/dist/esm/measurement/torque.js.map +1 -1
- package/dist/esm/measurement/voltage.js +1 -1
- package/dist/esm/measurement/voltage.js.map +1 -1
- package/dist/esm/measurement/volume.js +1 -1
- package/dist/esm/measurement/volume.js.map +1 -1
- package/dist/esm/measurement/weight.js +1 -1
- package/dist/esm/measurement/weight.js.map +1 -1
- package/dist/esm/organization/swedish-organization-number.js.map +2 -2
- package/dist/esm/register-default-text-scanners.js +2 -0
- package/dist/esm/register-default-text-scanners.js.map +2 -2
- package/dist/esm/sample-data/index.js +18 -1
- package/dist/esm/sample-data/index.js.map +2 -2
- package/dist/esm/text-scanning/text-scan-result.js +3 -0
- package/dist/esm/text-scanning/text-scan-result.js.map +2 -2
- package/dist/esm/validation/validation-error-reason.js +6 -1
- package/dist/esm/validation/validation-error-reason.js.map +2 -2
- package/dist/esm/vehicle/index.js +8 -0
- package/dist/esm/vehicle/index.js.map +2 -2
- package/dist/esm/vehicle/watercraft-identification-number.js +315 -0
- package/dist/esm/vehicle/watercraft-identification-number.js.map +7 -0
- package/dist/types/banking/index.d.cts +2 -2
- package/dist/types/banking/index.d.ts +2 -2
- package/dist/types/contact/index.d.cts +1 -1
- package/dist/types/contact/index.d.ts +1 -1
- package/dist/types/index.d.cts +2 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/sample-data/index.d.cts +10 -2
- package/dist/types/sample-data/index.d.ts +10 -2
- package/dist/types/text-scanning/index.d.cts +3 -1
- package/dist/types/text-scanning/index.d.ts +3 -1
- package/dist/types/validation/index.d.cts +4 -0
- package/dist/types/validation/index.d.ts +4 -0
- package/dist/types/vehicle/index.d.cts +2 -0
- package/dist/types/vehicle/index.d.ts +2 -0
- package/dist/types/watercraft-identification-number-Db1I2LQM.d.cts +123 -0
- package/dist/types/watercraft-identification-number-o8B3C6Nx.d.ts +123 -0
- package/package.json +18 -13
- package/dist/types/{swedish-swish-number-CL6Gx_h3.d.cts → swedish-swish-number-Bh-UbVoN.d.cts} +136 -136
- package/dist/types/{swedish-swish-number-DDG3mNDg.d.ts → swedish-swish-number-C2Wccuyr.d.ts} +136 -136
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/contact/phone-number.ts"],
|
|
4
|
-
"sourcesContent": ["import { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { PrimitivesDefaults } from \"../primitives-defaults.js\";\nimport { sanitizeInput } from \"../internal/input-sanitization.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { Country } from \"../geography/index.js\";\nimport { PhoneCallingCode } from \"./phone-calling-code.js\";\n\nconst MAX_INPUT_LENGTH = 50;\nconst URI_PREFIXES = [\"callto:\", \"tel:\", \"sms:\", \"call:\"];\n\nconst TWO_DIGIT_CODES = new Set([\n \"20\",\n \"27\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"36\",\n \"39\",\n \"40\",\n \"41\",\n \"43\",\n \"44\",\n \"45\",\n \"46\",\n \"47\",\n \"48\",\n \"49\",\n \"51\",\n \"52\",\n \"53\",\n \"54\",\n \"55\",\n \"56\",\n \"57\",\n \"58\",\n \"60\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"65\",\n \"66\",\n \"81\",\n \"82\",\n \"84\",\n \"86\",\n \"90\",\n \"91\",\n \"92\",\n \"93\",\n \"94\",\n \"95\",\n \"98\",\n]);\n\nconst LEADING_ZERO_SIGNIFICANT = new Set([\"39\"]);\n\nconst SCAN =\n /(?:(?:\\+|00)\\d{1,3}[\\s-]\\(?\\d{1,4}\\)?[\\s-]?\\d[\\d\\s-]{5,12}\\d)|(?:(?:\\+|00)\\d{7,15})|(?:0\\d{1,3}[\\s-]?\\d[\\d\\s-]{5,10}\\d)/g;\n\n/**\n * A phone number (`telefonnummer`). Stored normalized as `00` + country code +\n * subscriber digits (e.g. `0046701740633`). Use {@link toE164String} for the\n * `+`-prefixed E.164 form.\n */\nexport class PhoneNumber {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Phone Number\",\n localizedName: \"Telefonnummer\",\n emoji: \"\\u{1F4DE}\",\n sources: Object.freeze([\n \"https://pts.se/\",\n \"https://www.itu.int/rec/T-REC-E.164/\",\n \"https://en.wikipedia.org/wiki/E.164\",\n ]),\n });\n\n readonly digits: string;\n readonly countryCallingCode: PhoneCallingCode;\n readonly country: Country | null;\n readonly isSwedish: boolean;\n readonly isMobile: boolean;\n\n private constructor(digits: string, isSwedish: boolean, isMobile: boolean) {\n this.digits = digits;\n this.isSwedish = isSwedish;\n this.isMobile = isMobile;\n this.countryCallingCode = PhoneCallingCode.fromResolvedDigits(resolveCallingCode(digits));\n this.country = Country.tryFindByCallingCode(this.countryCallingCode.value);\n }\n\n get isSwedishTestPhoneNumber(): boolean {\n if (!this.isSwedish) return false;\n const local = this.digits.slice(4);\n return (\n isInPtsRange(local, \"7017406\", 5, 99) ||\n isInPtsRange(local, \"3139006\", 0, 99) ||\n isInPtsRange(local, \"4062804\", 0, 99) ||\n isInPtsRange(local, \"8465004\", 0, 99) ||\n isInPtsRange(local, \"9803192\", 0, 99)\n );\n }\n\n get formatted(): string {\n return this.isSwedish ? this.toLocalString() : this.toDisplayInternationalString();\n }\n\n static tryParse(\n input: string | null | undefined,\n defaultCallingCode?: string | PhoneCallingCode | Country | null,\n ): PhoneNumber | null {\n if (input == null || input.trim() === \"\") return null;\n const dcc = resolveDefaultCallingCode(defaultCallingCode);\n if (!dcc) return null;\n\n let cleaned = sanitizeInput(input).trim();\n if (cleaned.length > MAX_INPUT_LENGTH) return null;\n\n for (const prefix of URI_PREFIXES) {\n if (cleaned.toLowerCase().startsWith(prefix)) {\n cleaned = cleaned.slice(prefix.length).trimStart();\n break;\n }\n }\n\n const hasPlus = cleaned.startsWith(\"+\");\n const withOAs0 = cleaned.replace(/O/g, \"0\");\n const digitsOnly = withOAs0.replace(/[^\\d]/g, \"\");\n if (digitsOnly === \"\") return null;\n\n let e164: string;\n if (hasPlus) {\n if (digitsOnly.length < 7 || digitsOnly.length > 15) return null;\n e164 = stripTrunkZeroAfterCallingCode(digitsOnly);\n } else if (digitsOnly.startsWith(\"00\")) {\n const cn = digitsOnly.slice(2);\n if (cn.length < 7 || cn.length > 15) return null;\n e164 = stripTrunkZeroAfterCallingCode(cn);\n } else if (digitsOnly.startsWith(dcc) && digitsOnly.length >= dcc.length + 7) {\n const subscriber = digitsOnly.slice(dcc.length);\n e164 = dcc + stripSingleTrunkZero(dcc, subscriber);\n } else if (digitsOnly.startsWith(\"0\")) {\n const subscriber = stripSingleTrunkZero(dcc, digitsOnly);\n const total = dcc.length + subscriber.length;\n if (total < 7 || total > 15) return null;\n e164 = dcc + subscriber;\n } else if (dcc === \"46\" && digitsOnly.length === 9 && digitsOnly.startsWith(\"7\")) {\n e164 = \"46\" + digitsOnly;\n } else {\n return null;\n }\n\n if (e164.length < 7 || e164.length > 15) return null;\n const isSwedish = e164.startsWith(\"46\");\n if (isSwedish) {\n const local = e164.slice(2);\n if (local.length < 7 || local.length > 9) return null;\n }\n const isMobile = isSwedish && e164.slice(2).startsWith(\"7\");\n return new PhoneNumber(\"00\" + e164, isSwedish, isMobile);\n }\n\n static parse(\n input: string,\n defaultCallingCode?: string | PhoneCallingCode | Country | null,\n ): PhoneNumber {\n const r = PhoneNumber.tryParse(input, defaultCallingCode);\n if (r === null) throw new Error(\"Invalid phone number.\");\n return r;\n }\n\n static isValid(\n input: string | null | undefined,\n defaultCallingCode?: string | PhoneCallingCode | Country | null,\n ): boolean {\n return PhoneNumber.tryParse(input, defaultCallingCode) !== null;\n }\n\n static format(\n input: string | null | undefined,\n options?: {\n defaultCallingCode?: string | PhoneCallingCode | Country | null;\n fallbackToTrimmedInputWhenInvalid?: boolean;\n },\n ): string | null {\n const dcc =\n resolveDefaultCallingCode(options?.defaultCallingCode) ??\n PrimitivesDefaults.defaultCallingCode;\n const r = PhoneNumber.tryParse(input, dcc);\n if (r) {\n return r.countryCallingCode.value === dcc\n ? r.toLocalString()\n : r.toDisplayInternationalString();\n }\n if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== \"\") {\n return input.trim();\n }\n return null;\n }\n\n static normalize(\n input: string | null | undefined,\n options?: {\n defaultCallingCode?: string | PhoneCallingCode | Country | null;\n fallbackToTrimmedInputWhenInvalid?: boolean;\n },\n ): string | null {\n const r = PhoneNumber.tryParse(input, options?.defaultCallingCode);\n if (r) return r.digits;\n if (options?.fallbackToTrimmedInputWhenInvalid && input != null) {\n const t = input.trim();\n return t.length > 0 ? t : null;\n }\n return null;\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && PhoneNumber.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<PhoneNumber>[] {\n if (!text) return [];\n const out: TextCandidate<PhoneNumber>[] = [];\n SCAN.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = SCAN.exec(text)) !== null) {\n const phone = PhoneNumber.tryParse(m[0]);\n if (!phone) continue;\n out.push(\n new TextCandidate<PhoneNumber>({\n startIndex: m.index,\n length: m[0].length,\n originalText: m[0],\n typeName: \"PhoneNumber\",\n category: TextCandidateCategory.Contact,\n normalizedForm: phone.toNormalizedString(),\n formattedForm: phone.toString(),\n maskedForm: maskPhoneNumber(phone),\n confidence: TextMatchConfidence.Medium,\n value: phone,\n }),\n );\n }\n return out;\n }\n\n toNormalizedString(): string {\n return this.digits;\n }\n\n toLocalString(defaultCallingCode?: PhoneCallingCode | Country): string {\n if (defaultCallingCode) {\n const dcc =\n defaultCallingCode instanceof PhoneCallingCode\n ? defaultCallingCode.value\n : defaultCallingCode.callingCode;\n return this.countryCallingCode.value === dcc\n ? this.toLocalString()\n : this.toDisplayInternationalString();\n }\n const subscriber = this.digits.slice(2 + this.countryCallingCode.value.length);\n if (this.isSwedish) return formatSwedishLocal(\"0\" + subscriber);\n return \"0\" + subscriber;\n }\n\n toE164String(): string {\n return \"+\" + this.digits.slice(2);\n }\n toInternationalString(): string {\n return this.toE164String();\n }\n\n toDisplayInternationalString(): string {\n const subscriber = this.digits.slice(2 + this.countryCallingCode.value.length);\n return (\n \"+\" +\n this.countryCallingCode.value +\n \" \" +\n formatInternationalSubscriberDigits(this.countryCallingCode.value, subscriber)\n );\n }\n\n toString(): string {\n return this.formatted;\n }\n\n equals(other: PhoneNumber | null | undefined): boolean {\n return other != null && this.digits === other.digits;\n }\n compareTo(other: PhoneNumber | null | undefined): number {\n if (other == null) return 1;\n return this.digits < other.digits ? -1 : this.digits > other.digits ? 1 : 0;\n }\n}\n\n/** Mask a phone number, keeping country code and last 4 digits visible. */\nexport function maskPhoneNumber(p: PhoneNumber): string {\n const f = p.toE164String();\n if (f.length <= 5) return f.replace(/\\d/g, \"*\");\n const cc = \"+\" + p.countryCallingCode.value;\n const subscriber = f.slice(cc.length);\n if (subscriber.length <= 4) return cc + \"*\".repeat(subscriber.length);\n return cc + \"*\".repeat(subscriber.length - 4) + subscriber.slice(-4);\n}\n\nfunction resolveDefaultCallingCode(\n d: string | PhoneCallingCode | Country | null | undefined,\n): string | null {\n if (d == null) return PrimitivesDefaults.defaultCallingCode;\n if (typeof d === \"string\") return d;\n if (d instanceof PhoneCallingCode) return d.value;\n return d.callingCode;\n}\n\nfunction resolveCallingCode(digits: string): string {\n return resolveCallingCodeFromE164(digits.slice(2));\n}\n\nfunction resolveCallingCodeFromE164(e164: string): string {\n if (e164.length === 0) return \"\";\n if (e164[0] === \"1\" || e164[0] === \"7\") return e164.slice(0, 1);\n if (e164.length >= 2 && TWO_DIGIT_CODES.has(e164.slice(0, 2))) return e164.slice(0, 2);\n return e164.length >= 3 ? e164.slice(0, 3) : e164;\n}\n\nfunction stripTrunkZeroAfterCallingCode(e164: string): string {\n const cc = resolveCallingCodeFromE164(e164);\n if (cc.length === 0 || cc.length >= e164.length) return e164;\n const subscriber = e164.slice(cc.length);\n return cc + stripSingleTrunkZero(cc, subscriber);\n}\n\nfunction stripSingleTrunkZero(callingCode: string, subscriber: string): string {\n if (subscriber.length === 0 || subscriber[0] !== \"0\") return subscriber;\n if (LEADING_ZERO_SIGNIFICANT.has(callingCode)) return subscriber;\n return subscriber.slice(1);\n}\n\nfunction isInPtsRange(local: string, prefix: string, from: number, to: number): boolean {\n if (!local.startsWith(prefix)) return false;\n const suffix = local.slice(prefix.length);\n if (suffix.length !== 2) return false;\n const n = parseInt(suffix, 10);\n return Number.isFinite(n) && n >= from && n <= to;\n}\n\nfunction formatInternationalSubscriberDigits(callingCode: string, digits: string): string {\n if (callingCode === \"1\" && digits.length === 10) {\n return `${digits.slice(0, 3)} ${digits.slice(3, 6)} ${digits.slice(6, 10)}`;\n }\n switch (digits.length) {\n case 7:\n return `${digits.slice(0, 3)} ${digits.slice(3, 5)} ${digits.slice(5, 7)}`;\n case 8:\n return `${digits.slice(0, 2)} ${digits.slice(2, 4)} ${digits.slice(4, 6)} ${digits.slice(6, 8)}`;\n case 9:\n return `${digits.slice(0, 2)} ${digits.slice(2, 5)} ${digits.slice(5, 7)} ${digits.slice(7, 9)}`;\n case 10:\n return `${digits.slice(0, 2)} ${digits.slice(2, 6)} ${digits.slice(6, 10)}`;\n case 11:\n return `${digits.slice(0, 3)} ${digits.slice(3, 7)} ${digits.slice(7, 11)}`;\n default:\n return digits;\n }\n}\n\nfunction formatSwedishLocal(number: string): string {\n const digits = number.replace(/^0+/, \"\");\n if (digits.length === 9) {\n return `0${digits.slice(0, 3)}-${digits.slice(3, 5)} ${digits.slice(5, 7)} ${digits.slice(7, 9)}`;\n }\n if (digits.length === 7) {\n const area = digits.slice(0, 1);\n const rest = digits.slice(1);\n return `0${area}-${rest.slice(0, 2)} ${rest.slice(2, 4)} ${rest.slice(4, 6)}`;\n }\n if (digits.length === 8) {\n const area = digits.slice(0, 1);\n const rest = digits.slice(1);\n return `0${area}-${rest.slice(0, 2)} ${rest.slice(2, 4)} ${rest.slice(4, 7)}`;\n }\n return number;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { PrimitivesDefaults } from \"../primitives-defaults.js\";\nimport { sanitizeInput } from \"../internal/input-sanitization.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { Country } from \"../geography/index.js\";\nimport { PhoneCallingCode } from \"./phone-calling-code.js\";\n\nconst MAX_INPUT_LENGTH = 50;\nconst URI_PREFIXES = [\"callto:\", \"tel:\", \"sms:\", \"call:\"];\n\nconst TWO_DIGIT_CODES = new Set([\n \"20\",\n \"27\",\n \"30\",\n \"31\",\n \"32\",\n \"33\",\n \"34\",\n \"36\",\n \"39\",\n \"40\",\n \"41\",\n \"43\",\n \"44\",\n \"45\",\n \"46\",\n \"47\",\n \"48\",\n \"49\",\n \"51\",\n \"52\",\n \"53\",\n \"54\",\n \"55\",\n \"56\",\n \"57\",\n \"58\",\n \"60\",\n \"61\",\n \"62\",\n \"63\",\n \"64\",\n \"65\",\n \"66\",\n \"81\",\n \"82\",\n \"84\",\n \"86\",\n \"90\",\n \"91\",\n \"92\",\n \"93\",\n \"94\",\n \"95\",\n \"98\",\n]);\n\nconst LEADING_ZERO_SIGNIFICANT = new Set([\"39\"]);\n\nconst SCAN =\n /(?:(?:\\+|00)\\d{1,3}[\\s-]\\(?\\d{1,4}\\)?[\\s-]?\\d[\\d\\s-]{5,12}\\d)|(?:(?:\\+|00)\\d{7,15})|(?:0\\d{1,3}[\\s-]?\\d[\\d\\s-]{5,10}\\d)/g;\n\n/**\n * A phone number (`telefonnummer`). Stored normalized as `00` + country code +\n * subscriber digits (e.g. `0046701740633`). Use {@link toE164String} for the\n * `+`-prefixed E.164 form.\n */\nexport class PhoneNumber {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Phone Number\",\n localizedName: \"Telefonnummer\",\n emoji: \"\\u{1F4DE}\",\n sources: Object.freeze([\n \"https://pts.se/\",\n \"https://www.itu.int/rec/T-REC-E.164/\",\n \"https://en.wikipedia.org/wiki/E.164\",\n ]),\n });\n\n readonly digits: string;\n readonly countryCallingCode: PhoneCallingCode;\n readonly country: Country | null;\n readonly isSwedish: boolean;\n readonly isMobile: boolean;\n\n private constructor(digits: string, isSwedish: boolean, isMobile: boolean) {\n this.digits = digits;\n this.isSwedish = isSwedish;\n this.isMobile = isMobile;\n this.countryCallingCode = PhoneCallingCode.fromResolvedDigits(resolveCallingCode(digits));\n this.country = Country.tryFindByCallingCode(this.countryCallingCode.value);\n }\n\n get isSwedishTestPhoneNumber(): boolean {\n if (!this.isSwedish) return false;\n const local = this.digits.slice(4);\n return (\n isInPtsRange(local, \"7017406\", 5, 99) ||\n isInPtsRange(local, \"3139006\", 0, 99) ||\n isInPtsRange(local, \"4062804\", 0, 99) ||\n isInPtsRange(local, \"8465004\", 0, 99) ||\n isInPtsRange(local, \"9803192\", 0, 99)\n );\n }\n\n get formatted(): string {\n return this.isSwedish ? this.toLocalString() : this.toDisplayInternationalString();\n }\n\n static tryParse(\n input: string | null | undefined,\n defaultCallingCode?: string | PhoneCallingCode | Country | null,\n ): PhoneNumber | null {\n if (input == null || input.trim() === \"\") return null;\n const dcc = resolveDefaultCallingCode(defaultCallingCode);\n if (!dcc) return null;\n\n let cleaned = sanitizeInput(input).trim();\n if (cleaned.length > MAX_INPUT_LENGTH) return null;\n\n for (const prefix of URI_PREFIXES) {\n if (cleaned.toLowerCase().startsWith(prefix)) {\n cleaned = cleaned.slice(prefix.length).trimStart();\n break;\n }\n }\n\n const hasPlus = cleaned.startsWith(\"+\");\n const withOAs0 = cleaned.replace(/O/g, \"0\");\n const digitsOnly = withOAs0.replace(/[^\\d]/g, \"\");\n if (digitsOnly === \"\") return null;\n\n let e164: string;\n if (hasPlus) {\n if (digitsOnly.length < 7 || digitsOnly.length > 15) return null;\n e164 = stripTrunkZeroAfterCallingCode(digitsOnly);\n } else if (digitsOnly.startsWith(\"00\")) {\n const cn = digitsOnly.slice(2);\n if (cn.length < 7 || cn.length > 15) return null;\n e164 = stripTrunkZeroAfterCallingCode(cn);\n } else if (digitsOnly.startsWith(dcc) && digitsOnly.length >= dcc.length + 7) {\n const subscriber = digitsOnly.slice(dcc.length);\n e164 = dcc + stripSingleTrunkZero(dcc, subscriber);\n } else if (digitsOnly.startsWith(\"0\")) {\n const subscriber = stripSingleTrunkZero(dcc, digitsOnly);\n const total = dcc.length + subscriber.length;\n if (total < 7 || total > 15) return null;\n e164 = dcc + subscriber;\n } else if (dcc === \"46\" && digitsOnly.length === 9 && digitsOnly.startsWith(\"7\")) {\n e164 = \"46\" + digitsOnly;\n } else {\n return null;\n }\n\n if (e164.length < 7 || e164.length > 15) return null;\n const isSwedish = e164.startsWith(\"46\");\n if (isSwedish) {\n const local = e164.slice(2);\n if (local.length < 7 || local.length > 9) return null;\n }\n const isMobile = isSwedish && e164.slice(2).startsWith(\"7\");\n return new PhoneNumber(\"00\" + e164, isSwedish, isMobile);\n }\n\n static parse(\n input: string,\n defaultCallingCode?: string | PhoneCallingCode | Country | null,\n ): PhoneNumber {\n const r = PhoneNumber.tryParse(input, defaultCallingCode);\n if (r === null) throw new Error(\"Invalid phone number.\");\n return r;\n }\n\n static isValid(\n input: string | null | undefined,\n defaultCallingCode?: string | PhoneCallingCode | Country | null,\n ): boolean {\n return PhoneNumber.tryParse(input, defaultCallingCode) !== null;\n }\n\n static format(\n input: string | null | undefined,\n options?: {\n defaultCallingCode?: string | PhoneCallingCode | Country | null;\n fallbackToTrimmedInputWhenInvalid?: boolean;\n },\n ): string | null {\n const dcc =\n resolveDefaultCallingCode(options?.defaultCallingCode) ??\n PrimitivesDefaults.defaultCallingCode;\n const r = PhoneNumber.tryParse(input, dcc);\n if (r) {\n return r.countryCallingCode.value === dcc\n ? r.toLocalString()\n : r.toDisplayInternationalString();\n }\n if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== \"\") {\n return input.trim();\n }\n return null;\n }\n\n static normalize(\n input: string | null | undefined,\n options?: {\n defaultCallingCode?: string | PhoneCallingCode | Country | null;\n fallbackToTrimmedInputWhenInvalid?: boolean;\n },\n ): string | null {\n const r = PhoneNumber.tryParse(input, options?.defaultCallingCode);\n if (r) return r.digits;\n if (options?.fallbackToTrimmedInputWhenInvalid && input != null) {\n const t = input.trim();\n return t.length > 0 ? t : null;\n }\n return null;\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && PhoneNumber.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<PhoneNumber>[] {\n if (!text) return [];\n const out: TextCandidate<PhoneNumber>[] = [];\n SCAN.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = SCAN.exec(text)) !== null) {\n const phone = PhoneNumber.tryParse(m[0]);\n if (!phone) continue;\n out.push(\n new TextCandidate<PhoneNumber>({\n startIndex: m.index,\n length: m[0].length,\n originalText: m[0],\n typeName: \"PhoneNumber\",\n category: TextCandidateCategory.Contact,\n normalizedForm: phone.toNormalizedString(),\n formattedForm: phone.toString(),\n maskedForm: maskPhoneNumber(phone),\n confidence: TextMatchConfidence.Medium,\n value: phone,\n }),\n );\n }\n return out;\n }\n\n toNormalizedString(): string {\n return this.digits;\n }\n\n toLocalString(defaultCallingCode?: PhoneCallingCode | Country): string {\n if (defaultCallingCode) {\n const dcc =\n defaultCallingCode instanceof PhoneCallingCode\n ? defaultCallingCode.value\n : defaultCallingCode.callingCode;\n return this.countryCallingCode.value === dcc\n ? this.toLocalString()\n : this.toDisplayInternationalString();\n }\n const subscriber = this.digits.slice(2 + this.countryCallingCode.value.length);\n if (this.isSwedish) return formatSwedishLocal(subscriber);\n return \"0\" + subscriber;\n }\n\n toE164String(): string {\n return \"+\" + this.digits.slice(2);\n }\n toInternationalString(): string {\n return this.toE164String();\n }\n\n toDisplayInternationalString(): string {\n const subscriber = this.digits.slice(2 + this.countryCallingCode.value.length);\n if (this.isSwedish) return formatSwedishInternational(subscriber);\n return (\n \"+\" +\n this.countryCallingCode.value +\n \" \" +\n formatInternationalSubscriberDigits(this.countryCallingCode.value, subscriber)\n );\n }\n\n toString(): string {\n return this.formatted;\n }\n\n equals(other: PhoneNumber | null | undefined): boolean {\n return other != null && this.digits === other.digits;\n }\n compareTo(other: PhoneNumber | null | undefined): number {\n if (other == null) return 1;\n return this.digits < other.digits ? -1 : this.digits > other.digits ? 1 : 0;\n }\n}\n\n/** Mask a phone number, keeping country code and last 4 digits visible. */\nexport function maskPhoneNumber(p: PhoneNumber): string {\n const f = p.toE164String();\n if (f.length <= 5) return f.replace(/\\d/g, \"*\");\n const cc = \"+\" + p.countryCallingCode.value;\n const subscriber = f.slice(cc.length);\n if (subscriber.length <= 4) return cc + \"*\".repeat(subscriber.length);\n return cc + \"*\".repeat(subscriber.length - 4) + subscriber.slice(-4);\n}\n\nfunction resolveDefaultCallingCode(\n d: string | PhoneCallingCode | Country | null | undefined,\n): string | null {\n if (d == null) return PrimitivesDefaults.defaultCallingCode;\n if (typeof d === \"string\") return d;\n if (d instanceof PhoneCallingCode) return d.value;\n return d.callingCode;\n}\n\nfunction resolveCallingCode(digits: string): string {\n return resolveCallingCodeFromE164(digits.slice(2));\n}\n\nfunction resolveCallingCodeFromE164(e164: string): string {\n if (e164.length === 0) return \"\";\n if (e164[0] === \"1\" || e164[0] === \"7\") return e164.slice(0, 1);\n if (e164.length >= 2 && TWO_DIGIT_CODES.has(e164.slice(0, 2))) return e164.slice(0, 2);\n return e164.length >= 3 ? e164.slice(0, 3) : e164;\n}\n\nfunction stripTrunkZeroAfterCallingCode(e164: string): string {\n const cc = resolveCallingCodeFromE164(e164);\n if (cc.length === 0 || cc.length >= e164.length) return e164;\n const subscriber = e164.slice(cc.length);\n return cc + stripSingleTrunkZero(cc, subscriber);\n}\n\nfunction stripSingleTrunkZero(callingCode: string, subscriber: string): string {\n if (subscriber.length === 0 || subscriber[0] !== \"0\") return subscriber;\n if (LEADING_ZERO_SIGNIFICANT.has(callingCode)) return subscriber;\n return subscriber.slice(1);\n}\n\nfunction isInPtsRange(local: string, prefix: string, from: number, to: number): boolean {\n if (!local.startsWith(prefix)) return false;\n const suffix = local.slice(prefix.length);\n if (suffix.length !== 2) return false;\n const n = parseInt(suffix, 10);\n return Number.isFinite(n) && n >= from && n <= to;\n}\n\nfunction formatInternationalSubscriberDigits(callingCode: string, digits: string): string {\n if (callingCode === \"1\" && digits.length === 10) {\n return `${digits.slice(0, 3)} ${digits.slice(3, 6)} ${digits.slice(6, 10)}`;\n }\n switch (digits.length) {\n case 7:\n return `${digits.slice(0, 3)} ${digits.slice(3, 5)} ${digits.slice(5, 7)}`;\n case 8:\n return `${digits.slice(0, 2)} ${digits.slice(2, 4)} ${digits.slice(4, 6)} ${digits.slice(6, 8)}`;\n case 9:\n return `${digits.slice(0, 2)} ${digits.slice(2, 5)} ${digits.slice(5, 7)} ${digits.slice(7, 9)}`;\n case 10:\n return `${digits.slice(0, 2)} ${digits.slice(2, 6)} ${digits.slice(6, 10)}`;\n case 11:\n return `${digits.slice(0, 3)} ${digits.slice(3, 7)} ${digits.slice(7, 11)}`;\n default:\n return digits;\n }\n}\n\n// Two-digit national destination codes (NDCs) from PTS's numbering plan. 8 (Stockholm) is the\n// only one-digit NDC; every NDC not listed here is three digits.\nconst SWEDISH_TWO_DIGIT_DESTINATION_CODES = new Set([\n ...\"11 13 16 18 19 21 23 26 31 33 35 36 40 42 44 46 54 60 63 90\".split(\" \"),\n ...\"10 20 70 71 72 73 74 75 76 77 79 99\".split(\" \"),\n]);\n\n// 900 (premium rate) is the only three-digit NDC that starts with a two-digit NDC (90, Ume\u00E5).\nconst SWEDISH_THREE_DIGIT_DESTINATION_CODES_OVERRIDING_TWO_DIGIT = new Set([\"900\"]);\n\nfunction swedishDestinationCodeLength(nationalSignificantNumber: string): number {\n if (nationalSignificantNumber.startsWith(\"8\")) return 1;\n if (\n SWEDISH_THREE_DIGIT_DESTINATION_CODES_OVERRIDING_TWO_DIGIT.has(\n nationalSignificantNumber.slice(0, 3),\n )\n ) {\n return 3;\n }\n if (SWEDISH_TWO_DIGIT_DESTINATION_CODES.has(nationalSignificantNumber.slice(0, 2))) return 2;\n return 3;\n}\n\n/**\n * Groups a Swedish subscriber number as recommended by Svenska skrivregler:\n * `NN NN`, `NNN NN`, `NN NN NN`, `NNN NN NN` and `NNN NNN NN`.\n */\nfunction groupSwedishSubscriberNumber(subscriber: string): string {\n if (subscriber.length === 8) {\n return `${subscriber.slice(0, 3)} ${subscriber.slice(3, 6)} ${subscriber.slice(6)}`;\n }\n const firstGroupLength = subscriber.length % 2 === 1 ? 3 : 2;\n const groups = [subscriber.slice(0, firstGroupLength)];\n for (let i = firstGroupLength; i < subscriber.length; i += 2) {\n groups.push(subscriber.slice(i, i + 2));\n }\n return groups.join(\" \");\n}\n\nfunction splitSwedishNationalNumber(nationalSignificantNumber: string): [string, string] {\n const length = swedishDestinationCodeLength(nationalSignificantNumber);\n return [nationalSignificantNumber.slice(0, length), nationalSignificantNumber.slice(length)];\n}\n\nfunction formatSwedishLocal(nationalSignificantNumber: string): string {\n const [destinationCode, subscriber] = splitSwedishNationalNumber(nationalSignificantNumber);\n return `0${destinationCode}-${groupSwedishSubscriberNumber(subscriber)}`;\n}\n\nfunction formatSwedishInternational(nationalSignificantNumber: string): string {\n const [destinationCode, subscriber] = splitSwedishNationalNumber(nationalSignificantNumber);\n return `+46 ${destinationCode} ${groupSwedishSubscriberNumber(subscriber)}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/internal/scan-boundaries.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The Unicode-aware equivalent of a trailing `\\b` for the scanner patterns.\n *\n * JavaScript's `\\b` and `\\w` are ASCII-only even under `/u`, so `24 m` inside\n * `24 m\u00E5nader` looks like a complete match. .NET's are Unicode-aware, and .NET\n * is the behavioural spec.\n *\n * Where a unit ends in a letter or digit \u2014 which is all of them but one \u2014\n * `(?![\\p{L}\\p{N}_])` says the same thing, and the patterns use that directly.\n * This constant exists for the sound level `dB(A)` form, which ends in `)`. A\n * word boundary is a *transition*, not a plain lookahead: after a non-word\n * character it demands that the next character *be* a word character. That is\n * why .NET reads `69 dB(A) vid drift` as `69 dB` rather than `69 dB(A)`, and\n * the vectors generated from it expect exactly that.\n *\n * Internal; not re-exported publicly.\n */\n\nconst WORD = String.raw`[\\p{L}\\p{N}_]`;\n\nexport const WORD_BOUNDARY = String.raw`(?:(?<=${WORD})(?!${WORD})|(?<!${WORD})(?=${WORD}))`;\n"],
|
|
5
|
+
"mappings": "AAkBA,MAAM,OAAO,OAAO;AAEb,MAAM,gBAAgB,OAAO,aAAa,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,IAAI;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -4,8 +4,9 @@ import { TextCandidate } from "../text-scanning/text-candidate.js";
|
|
|
4
4
|
import { TextCandidateCategory } from "../text-scanning/text-candidate-category.js";
|
|
5
5
|
import { TextMatchConfidence } from "../text-scanning/text-match-confidence.js";
|
|
6
6
|
import { AreaUnit } from "./area-unit.js";
|
|
7
|
+
const B = String.raw`(?![\p{L}\p{N}_])`;
|
|
7
8
|
const SCAN_PATTERN = new RegExp(
|
|
8
|
-
String.raw`(
|
|
9
|
+
String.raw`(?<![\p{L}\p{N}_])(?:[+-]\s*)?\d+[0-9 .,]*\s*(?:(?:mm|cm|km|m)(?:²|2)|ha${B}|hectare${B}|hectares${B}|hektar${B}|acre${B}|acres${B}|sq\s*ft${B}|sq\s*in${B}|sq\s*yd${B}|kvadrat(?:millimeter|centimeter|meter|kilometer|fot|tum|yard)${B})`,
|
|
9
10
|
"giu"
|
|
10
11
|
);
|
|
11
12
|
class Area extends Quantity {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/measurement/area.ts"],
|
|
4
|
-
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { AreaUnit } from \"./area-unit.js\";\n\n/** Options for {@link Area.format} and {@link Area.normalize}. */\nexport interface AreaFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: AreaUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(
|
|
5
|
-
"mappings": "AAAA,SAAS,eAAe;AAExB,SAAS,UAAU,wBAAwB;AAE3C,SAAS,qBAAqB;AAC9B,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,gBAAgB;
|
|
4
|
+
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { AreaUnit } from \"./area-unit.js\";\n\n/** Options for {@link Area.format} and {@link Area.normalize}. */\nexport interface AreaFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: AreaUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\n// Only the spelled-out units take a boundary; the `m\u00B2` and `m2` forms end in a\n// character that already terminates the match, as in .NET.\nconst B = String.raw`(?![\\p{L}\\p{N}_])`;\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(?<![\\p{L}\\p{N}_])(?:[+-]\\s*)?\\d+[0-9 .,]*\\s*(?:(?:mm|cm|km|m)(?:\u00B2|2)|ha${B}|hectare${B}|hectares${B}|hektar${B}|acre${B}|acres${B}|sq\\s*ft${B}|sq\\s*in${B}|sq\\s*yd${B}|kvadrat(?:millimeter|centimeter|meter|kilometer|fot|tum|yard)${B})`,\n \"giu\",\n);\n\n/**\n * A area stored internally in square meters,\n * parsed from any supported unit and convertible between all of them.\n */\nexport class Area extends Quantity<AreaUnit> {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Area\",\n localizedName: \"Yta\",\n emoji: \"\uD83D\uDCD0\",\n sources: Object.freeze([\n \"https://www.bipm.org/en/measurement-units/si-base-units\",\n \"https://en.wikipedia.org/wiki/Conversion_of_units\",\n ]),\n });\n\n protected get units(): MeasurementUnitIndex<AreaUnit> {\n return AreaUnit.index;\n }\n\n protected withBaseValue(baseValue: Decimal, unit: AreaUnit): this {\n return new Area(baseValue, unit) as this;\n }\n\n get squareMillimeters(): number {\n return this.in(AreaUnit.SquareMillimeter);\n }\n get squareCentimeters(): number {\n return this.in(AreaUnit.SquareCentimeter);\n }\n get squareMeters(): number {\n return this.in(AreaUnit.SquareMeter);\n }\n get squareKilometers(): number {\n return this.in(AreaUnit.SquareKilometer);\n }\n get hectares(): number {\n return this.in(AreaUnit.Hectare);\n }\n get acres(): number {\n return this.in(AreaUnit.Acre);\n }\n get squareFeet(): number {\n return this.in(AreaUnit.SquareFoot);\n }\n get squareInches(): number {\n return this.in(AreaUnit.SquareInch);\n }\n get squareYards(): number {\n return this.in(AreaUnit.SquareYard);\n }\n\n /** Creates a area from a value and unit. */\n static create(value: number | Decimal, unit: AreaUnit): Area {\n AreaUnit.index.assertOwns(unit);\n const amount = value instanceof Decimal ? value : Area.decimalOf(value);\n return new Area(unit.toBase(amount), unit);\n }\n\n static fromSquareMillimeters(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.SquareMillimeter);\n }\n static fromSquareCentimeters(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.SquareCentimeter);\n }\n static fromSquareMeters(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.SquareMeter);\n }\n static fromSquareKilometers(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.SquareKilometer);\n }\n static fromHectares(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.Hectare);\n }\n static fromAcres(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.Acre);\n }\n static fromSquareFeet(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.SquareFoot);\n }\n static fromSquareInches(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.SquareInch);\n }\n static fromSquareYards(value: number | Decimal): Area {\n return Area.create(value, AreaUnit.SquareYard);\n }\n\n static tryParse(input: string | null | undefined): Area | null {\n const parsed = tryParseQuantity(input, AreaUnit.index);\n return parsed === null ? null : new Area(parsed.baseValue, parsed.unit);\n }\n\n static parse(input: string): Area {\n const result = Area.tryParse(input);\n if (result === null) throw new Error(\"Invalid area.\");\n return result;\n }\n\n static isValid(input: string | null | undefined): boolean {\n return Area.tryParse(input) !== null;\n }\n\n /** Display form in the parsed unit, or `null` when the input is invalid. */\n static format(input: string | null | undefined, options?: AreaFormatOptions): string | null {\n const parsed = Area.tryParse(input);\n if (parsed !== null) {\n if (options?.unit !== undefined || options?.decimals !== undefined) {\n return parsed.toStringInUnit(options.unit ?? parsed.originalUnit, options.decimals);\n }\n return parsed.toString();\n }\n return Area.fallback(input, options);\n }\n\n /** The value in square meters, or `null` when the input is invalid. */\n static normalize(input: string | null | undefined, options?: AreaFormatOptions): string | null {\n const parsed = Area.tryParse(input);\n if (parsed !== null) return parsed.toNormalizedString();\n return Area.fallback(input, options);\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && Area.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<Area>[] {\n if (!text) return [];\n\n const out: TextCandidate<Area>[] = [];\n const pattern = new RegExp(SCAN_PATTERN.source, SCAN_PATTERN.flags);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const value = Area.tryParse(match[0]);\n if (value === null) continue;\n out.push(\n new TextCandidate<Area>({\n startIndex: match.index,\n length: match[0].length,\n originalText: match[0],\n typeName: \"Area\",\n category: TextCandidateCategory.Measurement,\n normalizedForm: value.toNormalizedString(),\n formattedForm: value.toString(),\n maskedForm: maskArea(value),\n confidence: TextMatchConfidence.Medium,\n value,\n }),\n );\n }\n\n return out;\n }\n\n private static fallback(\n input: string | null | undefined,\n options?: AreaFormatOptions,\n ): string | null {\n if (options?.fallbackToTrimmedInputWhenInvalid !== true) return null;\n if (input == null) return null;\n const trimmed = input.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private static decimalOf(value: number): Decimal {\n const parsed = Decimal.fromNumber(value);\n if (parsed === null) throw new Error(`Value cannot be represented as a area: ${value}`);\n return parsed;\n }\n}\n\n/** Returns a masked area, e.g. `10 m\u00B2` becomes `*** m\u00B2`. */\nexport function maskArea(value: Area): string {\n return `*** ${value.originalUnit.symbol}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ import { TextCandidateCategory } from "../text-scanning/text-candidate-category.
|
|
|
5
5
|
import { TextMatchConfidence } from "../text-scanning/text-match-confidence.js";
|
|
6
6
|
import { DataSizeUnit } from "./data-size-unit.js";
|
|
7
7
|
const SCAN_PATTERN = new RegExp(
|
|
8
|
-
String.raw`(
|
|
8
|
+
String.raw`(?<![\p{L}\p{N}_])(?:[+-]\s*)?\d+[0-9 .,]*\s*(?:exbibytes|exbibyte|exabytes|exabyte|pebibytes|pebibyte|petabytes|petabyte|tebibytes|tebibyte|terabytes|terabyte|gibibytes|gibibyte|gigabytes|gigabyte|mebibytes|mebibyte|megabytes|megabyte|kibibytes|kibibyte|kilobytes|kilobyte|EiB|PiB|TiB|GiB|MiB|KiB|EB|PB|TB|GB|MB|KB|bytes|byte|B)(?![\p{L}\p{N}_])`,
|
|
9
9
|
"giu"
|
|
10
10
|
);
|
|
11
11
|
class DataSize extends Quantity {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/measurement/data-size.ts"],
|
|
4
|
-
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { DataSizeUnit } from \"./data-size-unit.js\";\n\n/** Options for {@link DataSize.format} and {@link DataSize.normalize}. */\nexport interface DataSizeFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: DataSizeUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(
|
|
4
|
+
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { DataSizeUnit } from \"./data-size-unit.js\";\n\n/** Options for {@link DataSize.format} and {@link DataSize.normalize}. */\nexport interface DataSizeFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: DataSizeUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(?<![\\p{L}\\p{N}_])(?:[+-]\\s*)?\\d+[0-9 .,]*\\s*(?:exbibytes|exbibyte|exabytes|exabyte|pebibytes|pebibyte|petabytes|petabyte|tebibytes|tebibyte|terabytes|terabyte|gibibytes|gibibyte|gigabytes|gigabyte|mebibytes|mebibyte|megabytes|megabyte|kibibytes|kibibyte|kilobytes|kilobyte|EiB|PiB|TiB|GiB|MiB|KiB|EB|PB|TB|GB|MB|KB|bytes|byte|B)(?![\\p{L}\\p{N}_])`,\n \"giu\",\n);\n\n/**\n * A data size stored internally in bytes,\n * parsed from any supported unit and convertible between all of them.\n */\nexport class DataSize extends Quantity<DataSizeUnit> {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Data Size\",\n localizedName: \"Datastorlek\",\n emoji: \"\uD83D\uDCBE\",\n sources: Object.freeze([\n \"https://www.bipm.org/en/publications/si-brochure\",\n \"https://www.iec.ch/standardsonline/iec-standard/iec-60027-2\",\n ]),\n });\n\n protected get units(): MeasurementUnitIndex<DataSizeUnit> {\n return DataSizeUnit.index;\n }\n\n protected withBaseValue(baseValue: Decimal, unit: DataSizeUnit): this {\n return new DataSize(baseValue, unit) as this;\n }\n\n get bytes(): number {\n return this.in(DataSizeUnit.Byte);\n }\n get kilobytes(): number {\n return this.in(DataSizeUnit.Kilobyte);\n }\n get megabytes(): number {\n return this.in(DataSizeUnit.Megabyte);\n }\n get gigabytes(): number {\n return this.in(DataSizeUnit.Gigabyte);\n }\n get terabytes(): number {\n return this.in(DataSizeUnit.Terabyte);\n }\n get petabytes(): number {\n return this.in(DataSizeUnit.Petabyte);\n }\n get exabytes(): number {\n return this.in(DataSizeUnit.Exabyte);\n }\n get kibibytes(): number {\n return this.in(DataSizeUnit.Kibibyte);\n }\n get mebibytes(): number {\n return this.in(DataSizeUnit.Mebibyte);\n }\n get gibibytes(): number {\n return this.in(DataSizeUnit.Gibibyte);\n }\n get tebibytes(): number {\n return this.in(DataSizeUnit.Tebibyte);\n }\n get pebibytes(): number {\n return this.in(DataSizeUnit.Pebibyte);\n }\n get exbibytes(): number {\n return this.in(DataSizeUnit.Exbibyte);\n }\n\n /** Creates a data size from a value and unit. */\n static create(value: number | Decimal, unit: DataSizeUnit): DataSize {\n DataSizeUnit.index.assertOwns(unit);\n const amount = value instanceof Decimal ? value : DataSize.decimalOf(value);\n return new DataSize(unit.toBase(amount), unit);\n }\n\n static fromBytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Byte);\n }\n static fromKilobytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Kilobyte);\n }\n static fromMegabytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Megabyte);\n }\n static fromGigabytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Gigabyte);\n }\n static fromTerabytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Terabyte);\n }\n static fromPetabytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Petabyte);\n }\n static fromExabytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Exabyte);\n }\n static fromKibibytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Kibibyte);\n }\n static fromMebibytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Mebibyte);\n }\n static fromGibibytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Gibibyte);\n }\n static fromTebibytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Tebibyte);\n }\n static fromPebibytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Pebibyte);\n }\n static fromExbibytes(value: number | Decimal): DataSize {\n return DataSize.create(value, DataSizeUnit.Exbibyte);\n }\n\n static tryParse(input: string | null | undefined): DataSize | null {\n const parsed = tryParseQuantity(input, DataSizeUnit.index);\n return parsed === null ? null : new DataSize(parsed.baseValue, parsed.unit);\n }\n\n static parse(input: string): DataSize {\n const result = DataSize.tryParse(input);\n if (result === null) throw new Error(\"Invalid data size.\");\n return result;\n }\n\n static isValid(input: string | null | undefined): boolean {\n return DataSize.tryParse(input) !== null;\n }\n\n /** Display form in the parsed unit, or `null` when the input is invalid. */\n static format(input: string | null | undefined, options?: DataSizeFormatOptions): string | null {\n const parsed = DataSize.tryParse(input);\n if (parsed !== null) {\n if (options?.unit !== undefined || options?.decimals !== undefined) {\n return parsed.toStringInUnit(options.unit ?? parsed.originalUnit, options.decimals);\n }\n return parsed.toString();\n }\n return DataSize.fallback(input, options);\n }\n\n /** The value in bytes, or `null` when the input is invalid. */\n static normalize(\n input: string | null | undefined,\n options?: DataSizeFormatOptions,\n ): string | null {\n const parsed = DataSize.tryParse(input);\n if (parsed !== null) return parsed.toNormalizedString();\n return DataSize.fallback(input, options);\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && DataSize.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<DataSize>[] {\n if (!text) return [];\n\n const out: TextCandidate<DataSize>[] = [];\n const pattern = new RegExp(SCAN_PATTERN.source, SCAN_PATTERN.flags);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const value = DataSize.tryParse(match[0]);\n if (value === null) continue;\n out.push(\n new TextCandidate<DataSize>({\n startIndex: match.index,\n length: match[0].length,\n originalText: match[0],\n typeName: \"DataSize\",\n category: TextCandidateCategory.Measurement,\n normalizedForm: value.toNormalizedString(),\n formattedForm: value.toString(),\n maskedForm: maskDataSize(value),\n confidence: TextMatchConfidence.Medium,\n value,\n }),\n );\n }\n\n return out;\n }\n\n private static fallback(\n input: string | null | undefined,\n options?: DataSizeFormatOptions,\n ): string | null {\n if (options?.fallbackToTrimmedInputWhenInvalid !== true) return null;\n if (input == null) return null;\n const trimmed = input.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private static decimalOf(value: number): Decimal {\n const parsed = Decimal.fromNumber(value);\n if (parsed === null) throw new Error(`Value cannot be represented as a data size: ${value}`);\n return parsed;\n }\n}\n\n/** Returns a masked data size, e.g. `10 B` becomes `*** B`. */\nexport function maskDataSize(value: DataSize): string {\n return `*** ${value.originalUnit.symbol}`;\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ import { TextCandidateCategory } from "../text-scanning/text-candidate-category.
|
|
|
5
5
|
import { TextMatchConfidence } from "../text-scanning/text-match-confidence.js";
|
|
6
6
|
import { ElectricChargeUnit } from "./electric-charge-unit.js";
|
|
7
7
|
const SCAN_PATTERN = new RegExp(
|
|
8
|
-
String.raw`(
|
|
8
|
+
String.raw`(?<![\p{L}\p{N}_])(?:[+-]\s*)?\d+[0-9 .,]*\s*(?:mAh|Ah|C)(?![\p{L}\p{N}_])`,
|
|
9
9
|
"giu"
|
|
10
10
|
);
|
|
11
11
|
class ElectricCharge extends Quantity {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/measurement/electric-charge.ts"],
|
|
4
|
-
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { ElectricChargeUnit } from \"./electric-charge-unit.js\";\n\n/** Options for {@link ElectricCharge.format} and {@link ElectricCharge.normalize}. */\nexport interface ElectricChargeFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: ElectricChargeUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(
|
|
4
|
+
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { ElectricChargeUnit } from \"./electric-charge-unit.js\";\n\n/** Options for {@link ElectricCharge.format} and {@link ElectricCharge.normalize}. */\nexport interface ElectricChargeFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: ElectricChargeUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(?<![\\p{L}\\p{N}_])(?:[+-]\\s*)?\\d+[0-9 .,]*\\s*(?:mAh|Ah|C)(?![\\p{L}\\p{N}_])`,\n \"giu\",\n);\n\n/**\n * A electric charge stored internally in ampere-hours,\n * parsed from any supported unit and convertible between all of them.\n */\nexport class ElectricCharge extends Quantity<ElectricChargeUnit> {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Electric Charge\",\n localizedName: \"Elektrisk laddning\",\n emoji: \"\uD83D\uDD0B\",\n sources: Object.freeze([\n \"https://www.bipm.org/en/measurement-units/si-derived-units\",\n \"https://en.wikipedia.org/wiki/Ampere-hour\",\n ]),\n });\n\n protected get units(): MeasurementUnitIndex<ElectricChargeUnit> {\n return ElectricChargeUnit.index;\n }\n\n protected withBaseValue(baseValue: Decimal, unit: ElectricChargeUnit): this {\n return new ElectricCharge(baseValue, unit) as this;\n }\n\n get milliampereHours(): number {\n return this.in(ElectricChargeUnit.MilliampereHour);\n }\n get ampereHours(): number {\n return this.in(ElectricChargeUnit.AmpereHour);\n }\n get coulombs(): number {\n return this.in(ElectricChargeUnit.Coulomb);\n }\n\n /** Creates a electric charge from a value and unit. */\n static create(value: number | Decimal, unit: ElectricChargeUnit): ElectricCharge {\n ElectricChargeUnit.index.assertOwns(unit);\n const amount = value instanceof Decimal ? value : ElectricCharge.decimalOf(value);\n return new ElectricCharge(unit.toBase(amount), unit);\n }\n\n static fromMilliampereHours(value: number | Decimal): ElectricCharge {\n return ElectricCharge.create(value, ElectricChargeUnit.MilliampereHour);\n }\n static fromAmpereHours(value: number | Decimal): ElectricCharge {\n return ElectricCharge.create(value, ElectricChargeUnit.AmpereHour);\n }\n static fromCoulombs(value: number | Decimal): ElectricCharge {\n return ElectricCharge.create(value, ElectricChargeUnit.Coulomb);\n }\n\n static tryParse(input: string | null | undefined): ElectricCharge | null {\n const parsed = tryParseQuantity(input, ElectricChargeUnit.index);\n return parsed === null ? null : new ElectricCharge(parsed.baseValue, parsed.unit);\n }\n\n static parse(input: string): ElectricCharge {\n const result = ElectricCharge.tryParse(input);\n if (result === null) throw new Error(\"Invalid electric charge.\");\n return result;\n }\n\n static isValid(input: string | null | undefined): boolean {\n return ElectricCharge.tryParse(input) !== null;\n }\n\n /** Display form in the parsed unit, or `null` when the input is invalid. */\n static format(\n input: string | null | undefined,\n options?: ElectricChargeFormatOptions,\n ): string | null {\n const parsed = ElectricCharge.tryParse(input);\n if (parsed !== null) {\n if (options?.unit !== undefined || options?.decimals !== undefined) {\n return parsed.toStringInUnit(options.unit ?? parsed.originalUnit, options.decimals);\n }\n return parsed.toString();\n }\n return ElectricCharge.fallback(input, options);\n }\n\n /** The value in ampere-hours, or `null` when the input is invalid. */\n static normalize(\n input: string | null | undefined,\n options?: ElectricChargeFormatOptions,\n ): string | null {\n const parsed = ElectricCharge.tryParse(input);\n if (parsed !== null) return parsed.toNormalizedString();\n return ElectricCharge.fallback(input, options);\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && ElectricCharge.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<ElectricCharge>[] {\n if (!text) return [];\n\n const out: TextCandidate<ElectricCharge>[] = [];\n const pattern = new RegExp(SCAN_PATTERN.source, SCAN_PATTERN.flags);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const value = ElectricCharge.tryParse(match[0]);\n if (value === null) continue;\n out.push(\n new TextCandidate<ElectricCharge>({\n startIndex: match.index,\n length: match[0].length,\n originalText: match[0],\n typeName: \"ElectricCharge\",\n category: TextCandidateCategory.Measurement,\n normalizedForm: value.toNormalizedString(),\n formattedForm: value.toString(),\n maskedForm: maskElectricCharge(value),\n confidence: TextMatchConfidence.Medium,\n value,\n }),\n );\n }\n\n return out;\n }\n\n private static fallback(\n input: string | null | undefined,\n options?: ElectricChargeFormatOptions,\n ): string | null {\n if (options?.fallbackToTrimmedInputWhenInvalid !== true) return null;\n if (input == null) return null;\n const trimmed = input.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private static decimalOf(value: number): Decimal {\n const parsed = Decimal.fromNumber(value);\n if (parsed === null)\n throw new Error(`Value cannot be represented as a electric charge: ${value}`);\n return parsed;\n }\n}\n\n/** Returns a masked electric charge, e.g. `10 Ah` becomes `*** Ah`. */\nexport function maskElectricCharge(value: ElectricCharge): string {\n return `*** ${value.originalUnit.symbol}`;\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ import { TextCandidateCategory } from "../text-scanning/text-candidate-category.
|
|
|
5
5
|
import { TextMatchConfidence } from "../text-scanning/text-match-confidence.js";
|
|
6
6
|
import { ElectricCurrentUnit } from "./electric-current-unit.js";
|
|
7
7
|
const SCAN_PATTERN = new RegExp(
|
|
8
|
-
String.raw`(
|
|
8
|
+
String.raw`(?<![\p{L}\p{N}_])(?:[+-]\s*)?\d+[0-9 .,]*\s*(?:µA|uA|mA|kA|A)(?![\p{L}\p{N}_])`,
|
|
9
9
|
"giu"
|
|
10
10
|
);
|
|
11
11
|
class ElectricCurrent extends Quantity {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/measurement/electric-current.ts"],
|
|
4
|
-
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { ElectricCurrentUnit } from \"./electric-current-unit.js\";\n\n/** Options for {@link ElectricCurrent.format} and {@link ElectricCurrent.normalize}. */\nexport interface ElectricCurrentFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: ElectricCurrentUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(
|
|
4
|
+
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { ElectricCurrentUnit } from \"./electric-current-unit.js\";\n\n/** Options for {@link ElectricCurrent.format} and {@link ElectricCurrent.normalize}. */\nexport interface ElectricCurrentFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: ElectricCurrentUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(?<![\\p{L}\\p{N}_])(?:[+-]\\s*)?\\d+[0-9 .,]*\\s*(?:\u00B5A|uA|mA|kA|A)(?![\\p{L}\\p{N}_])`,\n \"giu\",\n);\n\n/**\n * A electric current stored internally in amperes,\n * parsed from any supported unit and convertible between all of them.\n */\nexport class ElectricCurrent extends Quantity<ElectricCurrentUnit> {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Electric Current\",\n localizedName: \"Elektrisk str\u00F6m\",\n emoji: \"\u26A1\",\n sources: Object.freeze([\n \"https://www.bipm.org/en/measurement-units/si-base-units\",\n \"https://en.wikipedia.org/wiki/Ampere\",\n ]),\n });\n\n protected get units(): MeasurementUnitIndex<ElectricCurrentUnit> {\n return ElectricCurrentUnit.index;\n }\n\n protected withBaseValue(baseValue: Decimal, unit: ElectricCurrentUnit): this {\n return new ElectricCurrent(baseValue, unit) as this;\n }\n\n get microamperes(): number {\n return this.in(ElectricCurrentUnit.Microampere);\n }\n get milliamperes(): number {\n return this.in(ElectricCurrentUnit.Milliampere);\n }\n get amperes(): number {\n return this.in(ElectricCurrentUnit.Ampere);\n }\n get kiloamperes(): number {\n return this.in(ElectricCurrentUnit.Kiloampere);\n }\n\n /** Creates a electric current from a value and unit. */\n static create(value: number | Decimal, unit: ElectricCurrentUnit): ElectricCurrent {\n ElectricCurrentUnit.index.assertOwns(unit);\n const amount = value instanceof Decimal ? value : ElectricCurrent.decimalOf(value);\n return new ElectricCurrent(unit.toBase(amount), unit);\n }\n\n static fromMicroamperes(value: number | Decimal): ElectricCurrent {\n return ElectricCurrent.create(value, ElectricCurrentUnit.Microampere);\n }\n static fromMilliamperes(value: number | Decimal): ElectricCurrent {\n return ElectricCurrent.create(value, ElectricCurrentUnit.Milliampere);\n }\n static fromAmperes(value: number | Decimal): ElectricCurrent {\n return ElectricCurrent.create(value, ElectricCurrentUnit.Ampere);\n }\n static fromKiloamperes(value: number | Decimal): ElectricCurrent {\n return ElectricCurrent.create(value, ElectricCurrentUnit.Kiloampere);\n }\n\n static tryParse(input: string | null | undefined): ElectricCurrent | null {\n const parsed = tryParseQuantity(input, ElectricCurrentUnit.index);\n return parsed === null ? null : new ElectricCurrent(parsed.baseValue, parsed.unit);\n }\n\n static parse(input: string): ElectricCurrent {\n const result = ElectricCurrent.tryParse(input);\n if (result === null) throw new Error(\"Invalid electric current.\");\n return result;\n }\n\n static isValid(input: string | null | undefined): boolean {\n return ElectricCurrent.tryParse(input) !== null;\n }\n\n /** Display form in the parsed unit, or `null` when the input is invalid. */\n static format(\n input: string | null | undefined,\n options?: ElectricCurrentFormatOptions,\n ): string | null {\n const parsed = ElectricCurrent.tryParse(input);\n if (parsed !== null) {\n if (options?.unit !== undefined || options?.decimals !== undefined) {\n return parsed.toStringInUnit(options.unit ?? parsed.originalUnit, options.decimals);\n }\n return parsed.toString();\n }\n return ElectricCurrent.fallback(input, options);\n }\n\n /** The value in amperes, or `null` when the input is invalid. */\n static normalize(\n input: string | null | undefined,\n options?: ElectricCurrentFormatOptions,\n ): string | null {\n const parsed = ElectricCurrent.tryParse(input);\n if (parsed !== null) return parsed.toNormalizedString();\n return ElectricCurrent.fallback(input, options);\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && ElectricCurrent.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<ElectricCurrent>[] {\n if (!text) return [];\n\n const out: TextCandidate<ElectricCurrent>[] = [];\n const pattern = new RegExp(SCAN_PATTERN.source, SCAN_PATTERN.flags);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const value = ElectricCurrent.tryParse(match[0]);\n if (value === null) continue;\n out.push(\n new TextCandidate<ElectricCurrent>({\n startIndex: match.index,\n length: match[0].length,\n originalText: match[0],\n typeName: \"ElectricCurrent\",\n category: TextCandidateCategory.Measurement,\n normalizedForm: value.toNormalizedString(),\n formattedForm: value.toString(),\n maskedForm: maskElectricCurrent(value),\n confidence: TextMatchConfidence.Medium,\n value,\n }),\n );\n }\n\n return out;\n }\n\n private static fallback(\n input: string | null | undefined,\n options?: ElectricCurrentFormatOptions,\n ): string | null {\n if (options?.fallbackToTrimmedInputWhenInvalid !== true) return null;\n if (input == null) return null;\n const trimmed = input.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private static decimalOf(value: number): Decimal {\n const parsed = Decimal.fromNumber(value);\n if (parsed === null)\n throw new Error(`Value cannot be represented as a electric current: ${value}`);\n return parsed;\n }\n}\n\n/** Returns a masked electric current, e.g. `10 A` becomes `*** A`. */\nexport function maskElectricCurrent(value: ElectricCurrent): string {\n return `*** ${value.originalUnit.symbol}`;\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ import { TextCandidateCategory } from "../text-scanning/text-candidate-category.
|
|
|
5
5
|
import { TextMatchConfidence } from "../text-scanning/text-match-confidence.js";
|
|
6
6
|
import { EnergyUnit } from "./energy-unit.js";
|
|
7
7
|
const SCAN_PATTERN = new RegExp(
|
|
8
|
-
String.raw`(
|
|
8
|
+
String.raw`(?<![\p{L}\p{N}_])(?:[+-]\s*)?\d+[0-9 .,]*\s*(?:TWh|GWh|MWh|kWh|TJ|GJ|MJ|kJ|kcal|Wh|BTU|cal|J)(?![\p{L}\p{N}_])`,
|
|
9
9
|
"giu"
|
|
10
10
|
);
|
|
11
11
|
class Energy extends Quantity {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/measurement/energy.ts"],
|
|
4
|
-
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { EnergyUnit } from \"./energy-unit.js\";\n\n/** Options for {@link Energy.format} and {@link Energy.normalize}. */\nexport interface EnergyFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: EnergyUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(
|
|
4
|
+
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { EnergyUnit } from \"./energy-unit.js\";\n\n/** Options for {@link Energy.format} and {@link Energy.normalize}. */\nexport interface EnergyFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: EnergyUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(?<![\\p{L}\\p{N}_])(?:[+-]\\s*)?\\d+[0-9 .,]*\\s*(?:TWh|GWh|MWh|kWh|TJ|GJ|MJ|kJ|kcal|Wh|BTU|cal|J)(?![\\p{L}\\p{N}_])`,\n \"giu\",\n);\n\n/**\n * A energy stored internally in joules,\n * parsed from any supported unit and convertible between all of them.\n */\nexport class Energy extends Quantity<EnergyUnit> {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Energy\",\n localizedName: \"Energi\",\n emoji: \"\u26A1\",\n sources: Object.freeze([\n \"https://www.bipm.org/en/measurement-units/si-derived-units\",\n \"https://en.wikipedia.org/wiki/Conversion_of_units\",\n ]),\n });\n\n protected get units(): MeasurementUnitIndex<EnergyUnit> {\n return EnergyUnit.index;\n }\n\n protected withBaseValue(baseValue: Decimal, unit: EnergyUnit): this {\n return new Energy(baseValue, unit) as this;\n }\n\n get joules(): number {\n return this.in(EnergyUnit.Joule);\n }\n get kilojoules(): number {\n return this.in(EnergyUnit.Kilojoule);\n }\n get megajoules(): number {\n return this.in(EnergyUnit.Megajoule);\n }\n get gigajoules(): number {\n return this.in(EnergyUnit.Gigajoule);\n }\n get terajoules(): number {\n return this.in(EnergyUnit.Terajoule);\n }\n get wattHours(): number {\n return this.in(EnergyUnit.WattHour);\n }\n get kilowattHours(): number {\n return this.in(EnergyUnit.KilowattHour);\n }\n get megawattHours(): number {\n return this.in(EnergyUnit.MegawattHour);\n }\n get gigawattHours(): number {\n return this.in(EnergyUnit.GigawattHour);\n }\n get terawattHours(): number {\n return this.in(EnergyUnit.TerawattHour);\n }\n get calories(): number {\n return this.in(EnergyUnit.Calorie);\n }\n get kilocalories(): number {\n return this.in(EnergyUnit.Kilocalorie);\n }\n get btus(): number {\n return this.in(EnergyUnit.Btu);\n }\n\n /** Creates a energy from a value and unit. */\n static create(value: number | Decimal, unit: EnergyUnit): Energy {\n EnergyUnit.index.assertOwns(unit);\n const amount = value instanceof Decimal ? value : Energy.decimalOf(value);\n return new Energy(unit.toBase(amount), unit);\n }\n\n static fromJoules(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Joule);\n }\n static fromKilojoules(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Kilojoule);\n }\n static fromMegajoules(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Megajoule);\n }\n static fromGigajoules(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Gigajoule);\n }\n static fromTerajoules(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Terajoule);\n }\n static fromWattHours(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.WattHour);\n }\n static fromKilowattHours(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.KilowattHour);\n }\n static fromMegawattHours(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.MegawattHour);\n }\n static fromGigawattHours(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.GigawattHour);\n }\n static fromTerawattHours(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.TerawattHour);\n }\n static fromCalories(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Calorie);\n }\n static fromKilocalories(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Kilocalorie);\n }\n static fromBtus(value: number | Decimal): Energy {\n return Energy.create(value, EnergyUnit.Btu);\n }\n\n static tryParse(input: string | null | undefined): Energy | null {\n const parsed = tryParseQuantity(input, EnergyUnit.index);\n return parsed === null ? null : new Energy(parsed.baseValue, parsed.unit);\n }\n\n static parse(input: string): Energy {\n const result = Energy.tryParse(input);\n if (result === null) throw new Error(\"Invalid energy.\");\n return result;\n }\n\n static isValid(input: string | null | undefined): boolean {\n return Energy.tryParse(input) !== null;\n }\n\n /** Display form in the parsed unit, or `null` when the input is invalid. */\n static format(input: string | null | undefined, options?: EnergyFormatOptions): string | null {\n const parsed = Energy.tryParse(input);\n if (parsed !== null) {\n if (options?.unit !== undefined || options?.decimals !== undefined) {\n return parsed.toStringInUnit(options.unit ?? parsed.originalUnit, options.decimals);\n }\n return parsed.toString();\n }\n return Energy.fallback(input, options);\n }\n\n /** The value in joules, or `null` when the input is invalid. */\n static normalize(input: string | null | undefined, options?: EnergyFormatOptions): string | null {\n const parsed = Energy.tryParse(input);\n if (parsed !== null) return parsed.toNormalizedString();\n return Energy.fallback(input, options);\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && Energy.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<Energy>[] {\n if (!text) return [];\n\n const out: TextCandidate<Energy>[] = [];\n const pattern = new RegExp(SCAN_PATTERN.source, SCAN_PATTERN.flags);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const value = Energy.tryParse(match[0]);\n if (value === null) continue;\n out.push(\n new TextCandidate<Energy>({\n startIndex: match.index,\n length: match[0].length,\n originalText: match[0],\n typeName: \"Energy\",\n category: TextCandidateCategory.Measurement,\n normalizedForm: value.toNormalizedString(),\n formattedForm: value.toString(),\n maskedForm: maskEnergy(value),\n confidence: TextMatchConfidence.Medium,\n value,\n }),\n );\n }\n\n return out;\n }\n\n private static fallback(\n input: string | null | undefined,\n options?: EnergyFormatOptions,\n ): string | null {\n if (options?.fallbackToTrimmedInputWhenInvalid !== true) return null;\n if (input == null) return null;\n const trimmed = input.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private static decimalOf(value: number): Decimal {\n const parsed = Decimal.fromNumber(value);\n if (parsed === null) throw new Error(`Value cannot be represented as a energy: ${value}`);\n return parsed;\n }\n}\n\n/** Returns a masked energy, e.g. `10 J` becomes `*** J`. */\nexport function maskEnergy(value: Energy): string {\n return `*** ${value.originalUnit.symbol}`;\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ import { TextCandidateCategory } from "../text-scanning/text-candidate-category.
|
|
|
5
5
|
import { TextMatchConfidence } from "../text-scanning/text-match-confidence.js";
|
|
6
6
|
import { FlowRateUnit } from "./flow-rate-unit.js";
|
|
7
7
|
const SCAN_PATTERN = new RegExp(
|
|
8
|
-
String.raw`(
|
|
8
|
+
String.raw`(?<![\p{L}\p{N}_])(?:[+-]\s*)?\d+[0-9 .,]*\s*(?:m[³3]/(?:h|min|tim)|l/(?:s|min|h|timme)|gal/min|gpm)(?![\p{L}\p{N}_])`,
|
|
9
9
|
"giu"
|
|
10
10
|
);
|
|
11
11
|
class FlowRate extends Quantity {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/measurement/flow-rate.ts"],
|
|
4
|
-
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { FlowRateUnit } from \"./flow-rate-unit.js\";\n\n/** Options for {@link FlowRate.format} and {@link FlowRate.normalize}. */\nexport interface FlowRateFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: FlowRateUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(
|
|
4
|
+
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { FlowRateUnit } from \"./flow-rate-unit.js\";\n\n/** Options for {@link FlowRate.format} and {@link FlowRate.normalize}. */\nexport interface FlowRateFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: FlowRateUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(?<![\\p{L}\\p{N}_])(?:[+-]\\s*)?\\d+[0-9 .,]*\\s*(?:m[\u00B33]/(?:h|min|tim)|l/(?:s|min|h|timme)|gal/min|gpm)(?![\\p{L}\\p{N}_])`,\n \"giu\",\n);\n\n/**\n * A flow rate stored internally in liters per minute,\n * parsed from any supported unit and convertible between all of them.\n */\nexport class FlowRate extends Quantity<FlowRateUnit> {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Flow Rate\",\n localizedName: \"Fl\u00F6de\",\n emoji: \"\uD83C\uDF0A\",\n sources: Object.freeze([\"https://en.wikipedia.org/wiki/Volumetric_flow_rate\"]),\n });\n\n protected get units(): MeasurementUnitIndex<FlowRateUnit> {\n return FlowRateUnit.index;\n }\n\n protected withBaseValue(baseValue: Decimal, unit: FlowRateUnit): this {\n return new FlowRate(baseValue, unit) as this;\n }\n\n get litersPerSecond(): number {\n return this.in(FlowRateUnit.LitersPerSecond);\n }\n get litersPerMinute(): number {\n return this.in(FlowRateUnit.LitersPerMinute);\n }\n get litersPerHour(): number {\n return this.in(FlowRateUnit.LitersPerHour);\n }\n get cubicMetersPerHour(): number {\n return this.in(FlowRateUnit.CubicMetersPerHour);\n }\n get cubicMetersPerMinute(): number {\n return this.in(FlowRateUnit.CubicMetersPerMinute);\n }\n get gallonsPerMinute(): number {\n return this.in(FlowRateUnit.GallonsPerMinute);\n }\n\n /** Creates a flow rate from a value and unit. */\n static create(value: number | Decimal, unit: FlowRateUnit): FlowRate {\n FlowRateUnit.index.assertOwns(unit);\n const amount = value instanceof Decimal ? value : FlowRate.decimalOf(value);\n return new FlowRate(unit.toBase(amount), unit);\n }\n\n static fromLitersPerSecond(value: number | Decimal): FlowRate {\n return FlowRate.create(value, FlowRateUnit.LitersPerSecond);\n }\n static fromLitersPerMinute(value: number | Decimal): FlowRate {\n return FlowRate.create(value, FlowRateUnit.LitersPerMinute);\n }\n static fromLitersPerHour(value: number | Decimal): FlowRate {\n return FlowRate.create(value, FlowRateUnit.LitersPerHour);\n }\n static fromCubicMetersPerHour(value: number | Decimal): FlowRate {\n return FlowRate.create(value, FlowRateUnit.CubicMetersPerHour);\n }\n static fromCubicMetersPerMinute(value: number | Decimal): FlowRate {\n return FlowRate.create(value, FlowRateUnit.CubicMetersPerMinute);\n }\n static fromGallonsPerMinute(value: number | Decimal): FlowRate {\n return FlowRate.create(value, FlowRateUnit.GallonsPerMinute);\n }\n\n static tryParse(input: string | null | undefined): FlowRate | null {\n const parsed = tryParseQuantity(input, FlowRateUnit.index);\n return parsed === null ? null : new FlowRate(parsed.baseValue, parsed.unit);\n }\n\n static parse(input: string): FlowRate {\n const result = FlowRate.tryParse(input);\n if (result === null) throw new Error(\"Invalid flow rate.\");\n return result;\n }\n\n static isValid(input: string | null | undefined): boolean {\n return FlowRate.tryParse(input) !== null;\n }\n\n /** Display form in the parsed unit, or `null` when the input is invalid. */\n static format(input: string | null | undefined, options?: FlowRateFormatOptions): string | null {\n const parsed = FlowRate.tryParse(input);\n if (parsed !== null) {\n if (options?.unit !== undefined || options?.decimals !== undefined) {\n return parsed.toStringInUnit(options.unit ?? parsed.originalUnit, options.decimals);\n }\n return parsed.toString();\n }\n return FlowRate.fallback(input, options);\n }\n\n /** The value in liters per minute, or `null` when the input is invalid. */\n static normalize(\n input: string | null | undefined,\n options?: FlowRateFormatOptions,\n ): string | null {\n const parsed = FlowRate.tryParse(input);\n if (parsed !== null) return parsed.toNormalizedString();\n return FlowRate.fallback(input, options);\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && FlowRate.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<FlowRate>[] {\n if (!text) return [];\n\n const out: TextCandidate<FlowRate>[] = [];\n const pattern = new RegExp(SCAN_PATTERN.source, SCAN_PATTERN.flags);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const value = FlowRate.tryParse(match[0]);\n if (value === null) continue;\n out.push(\n new TextCandidate<FlowRate>({\n startIndex: match.index,\n length: match[0].length,\n originalText: match[0],\n typeName: \"FlowRate\",\n category: TextCandidateCategory.Measurement,\n normalizedForm: value.toNormalizedString(),\n formattedForm: value.toString(),\n maskedForm: maskFlowRate(value),\n confidence: TextMatchConfidence.Medium,\n value,\n }),\n );\n }\n\n return out;\n }\n\n private static fallback(\n input: string | null | undefined,\n options?: FlowRateFormatOptions,\n ): string | null {\n if (options?.fallbackToTrimmedInputWhenInvalid !== true) return null;\n if (input == null) return null;\n const trimmed = input.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private static decimalOf(value: number): Decimal {\n const parsed = Decimal.fromNumber(value);\n if (parsed === null) throw new Error(`Value cannot be represented as a flow rate: ${value}`);\n return parsed;\n }\n}\n\n/** Returns a masked flow rate, e.g. `10 L/min` becomes `*** L/min`. */\nexport function maskFlowRate(value: FlowRate): string {\n return `*** ${value.originalUnit.symbol}`;\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ import { TextCandidateCategory } from "../text-scanning/text-candidate-category.
|
|
|
5
5
|
import { TextMatchConfidence } from "../text-scanning/text-match-confidence.js";
|
|
6
6
|
import { FrequencyUnit } from "./frequency-unit.js";
|
|
7
7
|
const SCAN_PATTERN = new RegExp(
|
|
8
|
-
String.raw`(
|
|
8
|
+
String.raw`(?<![\p{L}\p{N}_])(?:[+-]\s*)?\d+[0-9 .,]*\s*(?:THz|GHz|MHz|kHz|Hz|rpm|rev/min|varv/min|r/min)(?![\p{L}\p{N}_])`,
|
|
9
9
|
"giu"
|
|
10
10
|
);
|
|
11
11
|
class Frequency extends Quantity {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/measurement/frequency.ts"],
|
|
4
|
-
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { FrequencyUnit } from \"./frequency-unit.js\";\n\n/** Options for {@link Frequency.format} and {@link Frequency.normalize}. */\nexport interface FrequencyFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: FrequencyUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(
|
|
4
|
+
"sourcesContent": ["import { Decimal } from \"../internal/decimal.js\";\nimport type { MeasurementUnitIndex } from \"../internal/measurement-unit.js\";\nimport { Quantity, tryParseQuantity } from \"../internal/quantity.js\";\nimport type { PrimitiveTypeInfo } from \"../primitive-type-info.js\";\nimport { TextCandidate } from \"../text-scanning/text-candidate.js\";\nimport { TextCandidateCategory } from \"../text-scanning/text-candidate-category.js\";\nimport { TextMatchConfidence } from \"../text-scanning/text-match-confidence.js\";\nimport { FrequencyUnit } from \"./frequency-unit.js\";\n\n/** Options for {@link Frequency.format} and {@link Frequency.normalize}. */\nexport interface FrequencyFormatOptions {\n fallbackToTrimmedInputWhenInvalid?: boolean;\n /** Convert to this unit instead of preserving the parsed one. */\n unit?: FrequencyUnit;\n /** Round to this many fractional digits, away from zero. */\n decimals?: number;\n}\n\nconst SCAN_PATTERN = new RegExp(\n String.raw`(?<![\\p{L}\\p{N}_])(?:[+-]\\s*)?\\d+[0-9 .,]*\\s*(?:THz|GHz|MHz|kHz|Hz|rpm|rev/min|varv/min|r/min)(?![\\p{L}\\p{N}_])`,\n \"giu\",\n);\n\n/**\n * A frequency stored internally in hertz,\n * parsed from any supported unit and convertible between all of them.\n */\nexport class Frequency extends Quantity<FrequencyUnit> {\n static readonly typeInfo: PrimitiveTypeInfo = Object.freeze({\n englishName: \"Frequency\",\n localizedName: \"Frekvens\",\n emoji: \"\uD83D\uDCE1\",\n sources: Object.freeze([\n \"https://www.bipm.org/en/measurement-units/si-derived-units\",\n \"https://en.wikipedia.org/wiki/Conversion_of_units\",\n ]),\n });\n\n protected get units(): MeasurementUnitIndex<FrequencyUnit> {\n return FrequencyUnit.index;\n }\n\n protected withBaseValue(baseValue: Decimal, unit: FrequencyUnit): this {\n return new Frequency(baseValue, unit) as this;\n }\n\n get hertz(): number {\n return this.in(FrequencyUnit.Hertz);\n }\n get kilohertz(): number {\n return this.in(FrequencyUnit.Kilohertz);\n }\n get megahertz(): number {\n return this.in(FrequencyUnit.Megahertz);\n }\n get gigahertz(): number {\n return this.in(FrequencyUnit.Gigahertz);\n }\n get terahertz(): number {\n return this.in(FrequencyUnit.Terahertz);\n }\n get rpm(): number {\n return this.in(FrequencyUnit.RevolutionsPerMinute);\n }\n\n /** Creates a frequency from a value and unit. */\n static create(value: number | Decimal, unit: FrequencyUnit): Frequency {\n FrequencyUnit.index.assertOwns(unit);\n const amount = value instanceof Decimal ? value : Frequency.decimalOf(value);\n return new Frequency(unit.toBase(amount), unit);\n }\n\n static fromHertz(value: number | Decimal): Frequency {\n return Frequency.create(value, FrequencyUnit.Hertz);\n }\n static fromKilohertz(value: number | Decimal): Frequency {\n return Frequency.create(value, FrequencyUnit.Kilohertz);\n }\n static fromMegahertz(value: number | Decimal): Frequency {\n return Frequency.create(value, FrequencyUnit.Megahertz);\n }\n static fromGigahertz(value: number | Decimal): Frequency {\n return Frequency.create(value, FrequencyUnit.Gigahertz);\n }\n static fromTerahertz(value: number | Decimal): Frequency {\n return Frequency.create(value, FrequencyUnit.Terahertz);\n }\n static fromRpm(value: number | Decimal): Frequency {\n return Frequency.create(value, FrequencyUnit.RevolutionsPerMinute);\n }\n\n static tryParse(input: string | null | undefined): Frequency | null {\n const parsed = tryParseQuantity(input, FrequencyUnit.index);\n return parsed === null ? null : new Frequency(parsed.baseValue, parsed.unit);\n }\n\n static parse(input: string): Frequency {\n const result = Frequency.tryParse(input);\n if (result === null) throw new Error(\"Invalid frequency.\");\n return result;\n }\n\n static isValid(input: string | null | undefined): boolean {\n return Frequency.tryParse(input) !== null;\n }\n\n /** Display form in the parsed unit, or `null` when the input is invalid. */\n static format(input: string | null | undefined, options?: FrequencyFormatOptions): string | null {\n const parsed = Frequency.tryParse(input);\n if (parsed !== null) {\n if (options?.unit !== undefined || options?.decimals !== undefined) {\n return parsed.toStringInUnit(options.unit ?? parsed.originalUnit, options.decimals);\n }\n return parsed.toString();\n }\n return Frequency.fallback(input, options);\n }\n\n /** The value in hertz, or `null` when the input is invalid. */\n static normalize(\n input: string | null | undefined,\n options?: FrequencyFormatOptions,\n ): string | null {\n const parsed = Frequency.tryParse(input);\n if (parsed !== null) return parsed.toNormalizedString();\n return Frequency.fallback(input, options);\n }\n\n static isNormalized(input: string | null | undefined): boolean {\n return input != null && Frequency.normalize(input) === input;\n }\n\n static findCandidatesInText(text: string): readonly TextCandidate<Frequency>[] {\n if (!text) return [];\n\n const out: TextCandidate<Frequency>[] = [];\n const pattern = new RegExp(SCAN_PATTERN.source, SCAN_PATTERN.flags);\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n const value = Frequency.tryParse(match[0]);\n if (value === null) continue;\n out.push(\n new TextCandidate<Frequency>({\n startIndex: match.index,\n length: match[0].length,\n originalText: match[0],\n typeName: \"Frequency\",\n category: TextCandidateCategory.Measurement,\n normalizedForm: value.toNormalizedString(),\n formattedForm: value.toString(),\n maskedForm: maskFrequency(value),\n confidence: TextMatchConfidence.Medium,\n value,\n }),\n );\n }\n\n return out;\n }\n\n private static fallback(\n input: string | null | undefined,\n options?: FrequencyFormatOptions,\n ): string | null {\n if (options?.fallbackToTrimmedInputWhenInvalid !== true) return null;\n if (input == null) return null;\n const trimmed = input.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private static decimalOf(value: number): Decimal {\n const parsed = Decimal.fromNumber(value);\n if (parsed === null) throw new Error(`Value cannot be represented as a frequency: ${value}`);\n return parsed;\n }\n}\n\n/** Returns a masked frequency, e.g. `10 Hz` becomes `*** Hz`. */\nexport function maskFrequency(value: Frequency): string {\n return `*** ${value.originalUnit.symbol}`;\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|