@lacspace/nepali-match 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nepali-utils/src/index.ts","../src/districts.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @lacspace/nepali-utils — everyday Nepal helpers: NPR currency formatting,\n * Nepali (South-Asian) digit grouping, Devanagari numerals, amount-in-words,\n * common validators, and province data. Zero-dependency, isomorphic.\n */\n\nconst DEVANAGARI = [\"०\", \"१\", \"२\", \"३\", \"४\", \"५\", \"६\", \"७\", \"८\", \"९\"] as const;\n\n/** Convert Arabic numerals to Devanagari: `\"2081\"` → `\"२०८१\"`. */\nexport function toDevanagari(input: string | number): string {\n return String(input).replace(/[0-9]/g, (d) => DEVANAGARI[Number(d)]!);\n}\n\n/** Convert Devanagari numerals to Arabic: `\"२०८१\"` → `\"2081\"`. */\nexport function fromDevanagari(input: string): string {\n return input.replace(/[०-९]/g, (d) => String(DEVANAGARI.indexOf(d as (typeof DEVANAGARI)[number])));\n}\n\n/**\n * Group a number with the South-Asian (Nepali) system: the last three digits,\n * then groups of two. `1234567` → `\"12,34,567\"`; decimals are kept: `2587.25` → `\"2,587.25\"`.\n */\nexport function groupNepali(value: number | string): string {\n const str = String(value).trim();\n const negative = str.startsWith(\"-\");\n const sign = negative ? \"-\" : \"\";\n const [intRaw = \"\", ...decs] = str.split(\".\");\n const s = intRaw.replace(/[^\\d]/g, \"\");\n const dec = decs.length ? \".\" + decs.join(\"\").replace(/[^\\d]/g, \"\") : \"\";\n if (s.length <= 3) return sign + s + dec;\n const last3 = s.slice(-3);\n const rest = s.slice(0, -3);\n return sign + rest.replace(/\\B(?=(\\d{2})+(?!\\d))/g, \",\") + \",\" + last3 + dec;\n}\n\nexport interface FormatNprOptions {\n /** Show a symbol/prefix. Default `\"Rs. \"`. Use `\"\"` for none. */\n symbol?: string;\n /** Number of decimal places. Default `2`. */\n decimals?: number;\n /** Render digits in Devanagari. Default `false`. */\n devanagari?: boolean;\n}\n\n/**\n * Format an amount as Nepalese Rupees with South-Asian grouping.\n * `formatNPR(1234567.5)` → `\"Rs. 12,34,567.50\"`.\n */\nexport function formatNPR(amount: number, options: FormatNprOptions = {}): string {\n const { symbol = \"Rs. \", decimals = 2, devanagari = false } = options;\n const negative = amount < 0;\n const fixed = Math.abs(amount).toFixed(decimals);\n const [intPart, decPart] = fixed.split(\".\");\n let out = groupNepali(intPart!);\n if (decPart) out += \".\" + decPart;\n if (devanagari) out = toDevanagari(out);\n return (negative ? \"-\" : \"\") + symbol + out;\n}\n\nconst ONES = [\n \"\", \"One\", \"Two\", \"Three\", \"Four\", \"Five\", \"Six\", \"Seven\", \"Eight\", \"Nine\",\n \"Ten\", \"Eleven\", \"Twelve\", \"Thirteen\", \"Fourteen\", \"Fifteen\", \"Sixteen\",\n \"Seventeen\", \"Eighteen\", \"Nineteen\",\n];\nconst TENS = [\"\", \"\", \"Twenty\", \"Thirty\", \"Forty\", \"Fifty\", \"Sixty\", \"Seventy\", \"Eighty\", \"Ninety\"];\n\nfunction twoDigitWords(n: number): string {\n if (n < 20) return ONES[n]!;\n const t = Math.floor(n / 10);\n const o = n % 10;\n return TENS[t]! + (o ? \" \" + ONES[o] : \"\");\n}\n\n/**\n * Amount in words using the South-Asian system (Thousand, Lakh, Crore, Arab, Kharab, Neel, Padma) —\n * perfect for invoices. `numberToWords(1234567)` →\n * `\"Twelve Lakh Thirty Four Thousand Five Hundred Sixty Seven\"`.\n */\nexport function numberToWords(value: number): string {\n let n = Math.floor(Math.abs(value));\n if (n === 0) return \"Zero\";\n const parts: string[] = [];\n const units: [number, string][] = [\n [1e15, \"Padma\"],\n [1e13, \"Neel\"],\n [1e11, \"Kharab\"],\n [1e9, \"Arab\"],\n [1e7, \"Crore\"],\n [1e5, \"Lakh\"],\n [1e3, \"Thousand\"],\n [1e2, \"Hundred\"],\n ];\n for (const [size, name] of units) {\n if (n >= size) {\n const count = Math.floor(n / size);\n // Hundreds are 1–9; middle units take two digits; the top (Padma) unit can\n // itself run into the hundreds/thousands, so render its count recursively.\n const words = size === 100 ? ONES[count]! : count >= 100 ? numberToWords(count) : twoDigitWords(count);\n parts.push(words + \" \" + name);\n n %= size;\n }\n }\n if (n > 0) parts.push(twoDigitWords(n));\n return (value < 0 ? \"Minus \" : \"\") + parts.join(\" \");\n}\n\n/**\n * An amount for the amount-in-words helpers: a number (fine up to ~13 rupee\n * digits), a decimal string (`\"99999999999999.01\"`, grouping commas allowed),\n * or exact integer parts `{ rupees, paisa }`. Strings and parts avoid float\n * drift, so the paisa is always exact.\n */\nexport type AmountInput = number | string | { rupees: number; paisa?: number; negative?: boolean };\n\n/** Split an {@link AmountInput} into exact integer rupees + paisa (0–99) and a sign. */\nexport function splitAmount(input: AmountInput): { rupees: number; paisa: number; negative: boolean } {\n let negative = false, rupees: number, paisa: number;\n if (typeof input === \"number\") {\n if (!Number.isFinite(input)) throw new RangeError(\"amount must be finite\");\n negative = input < 0;\n const a = Math.abs(input);\n rupees = Math.floor(a);\n paisa = Math.round((a - rupees) * 100);\n } else if (typeof input === \"string\") {\n const m = /^\\s*(-)?\\s*(?:rs\\.?|npr|रु\\.?|रू\\.?)?\\s*([\\d,]*)(?:\\.(\\d*))?\\s*$/i.exec(fromDevanagari(input));\n if (!m || (!m[2] && !m[3])) throw new RangeError(`not a decimal amount: ${input}`);\n negative = !!m[1];\n const intDigits = (m[2] || \"0\").replace(/,/g, \"\");\n rupees = Number(intDigits);\n const frac = (m[3] || \"\").padEnd(3, \"0\");\n paisa = Number(frac.slice(0, 2)) + (Number(frac[2]) >= 5 ? 1 : 0); // round half up on the 3rd decimal\n } else {\n rupees = Math.trunc(Math.abs(input.rupees));\n paisa = Math.round(Math.abs(input.paisa ?? 0));\n negative = !!input.negative || input.rupees < 0;\n if (paisa > 99) { rupees += Math.floor(paisa / 100); paisa %= 100; }\n }\n if (paisa === 100) { rupees += 1; paisa = 0; }\n if (!Number.isSafeInteger(rupees)) throw new RangeError(\"rupees exceed Number.MAX_SAFE_INTEGER\");\n return { rupees, paisa, negative: negative && (rupees > 0 || paisa > 0) };\n}\n\n/** `numberToWords` plus a \"Rupees … only\" wrapper for invoices. Accepts a number, decimal string or `{ rupees, paisa }`. */\nexport function amountInWords(amount: AmountInput): string {\n const { rupees, paisa, negative } = splitAmount(amount);\n let out = \"Rupees \" + numberToWords(rupees);\n if (paisa > 0) out += \" and \" + numberToWords(paisa) + \" Paisa\";\n return (negative ? \"Minus \" : \"\") + out + \" Only\";\n}\n\n/** Parse a formatted NPR/Nepali-grouped string back to a number (inverse of {@link formatNPR}). */\nexport function ungroupNepali(input: string | number): number {\n let s = fromDevanagari(String(input)).trim();\n const negative = s.startsWith(\"-\");\n s = s.replace(/₹|rs\\.?|npr|रू\\.?|रु\\.?/gi, \"\"); // strip currency symbols (incl. the dot in \"Rs.\")\n s = s.replace(/[^\\d.]/g, \"\"); // drop grouping commas, spaces, everything else\n if (s === \"\") return NaN;\n const num = Number(s);\n return negative && !Number.isNaN(num) ? -num : num;\n}\n\n/** Alias of {@link ungroupNepali} — parse an NPR string to a number. */\nexport const parseNPR = ungroupNepali;\n\nfunction trimNum(n: number): string {\n return Number(n.toFixed(2)).toString();\n}\n\nexport interface CompactNprOptions {\n symbol?: string;\n /** Use Nepali scale words (हजार/लाख/करोड/अरब/खरब). Default false (K/Lakh/Cr/Arab/Kharab). */\n nepali?: boolean;\n /** Render digits in Devanagari. Default false. */\n devanagari?: boolean;\n /**\n * Word style. \"short\" (default): K/Lakh/Cr/Arab/Kharab, हजार/लाख/करोड/अरब/खरब.\n * \"long\": Thousand/Lakh/Crore/Arba/Kharba, हजार/लाख/करोड/अर्ब/खर्ब (newsroom spelling).\n */\n style?: \"short\" | \"long\";\n /** Fixed decimal places (e.g. 2 → \"4.29\"). Default: up to 2, trailing zeros trimmed. */\n decimals?: number;\n}\n\n/** Compact NPR: `formatCompactNPR(1234567)` → `\"Rs. 12.35 Lakh\"`. */\nexport function formatCompactNPR(amount: number, options: CompactNprOptions = {}): string {\n const { symbol = \"Rs. \", nepali = false, devanagari = false, style = \"short\", decimals } = options;\n const negative = amount < 0;\n const a = Math.abs(amount);\n const long = style === \"long\";\n const units: [number, string, string][] = [\n [1e15, \"Padma\", \"पद्म\"],\n [1e13, \"Neel\", \"नील\"],\n [1e11, long ? \"Kharba\" : \"Kharab\", long ? \"खर्ब\" : \"खरब\"],\n [1e9, long ? \"Arba\" : \"Arab\", long ? \"अर्ब\" : \"अरब\"],\n [1e7, long ? \"Crore\" : \"Cr\", \"करोड\"],\n [1e5, \"Lakh\", \"लाख\"],\n [1e3, long ? \"Thousand\" : \"K\", \"हजार\"],\n ];\n const num = (n: number) => (decimals === undefined ? trimNum(n) : n.toFixed(decimals));\n let out: string;\n const u = units.find(([size]) => a >= size);\n if (u) out = `${num(a / u[0])} ${nepali ? u[2] : u[1]}`;\n else out = num(a);\n if (devanagari) out = toDevanagari(out);\n return (negative ? \"-\" : \"\") + symbol + out;\n}\n\n/* ------------------------------ land-area units ------------------------------ */\n\nexport type LandUnit = \"ropani\" | \"aana\" | \"paisa\" | \"daam\" | \"bigha\" | \"kattha\" | \"dhur\" | \"sqm\" | \"sqft\";\n\nconst SQFT = 0.09290304; // exact: 1 international foot = 0.3048 m\nconst ROPANI = 5476 * SQFT; // 508.73704704 m²\nconst BIGHA = 72900 * SQFT; // 6772.631616 m²\n\n/**\n * Area of one unit in square metres (hilly = ropani system, terai = bigha system).\n * Every sub-unit is derived from its parent (ropani/16/64/256, bigha/20/400), so\n * unit ratios are exact and `convertLand(1, \"ropani\", \"daam\")` is exactly 256.\n */\nexport const LAND_UNIT_SQM: Record<LandUnit, number> = {\n ropani: ROPANI,\n aana: ROPANI / 16,\n paisa: ROPANI / 64,\n daam: ROPANI / 256,\n bigha: BIGHA,\n kattha: BIGHA / 20,\n dhur: BIGHA / 400,\n sqm: 1,\n sqft: SQFT,\n};\n\n/** Total square metres from a mixed measure, e.g. `{ ropani: 2, aana: 3 }` or `{ bigha: 1, kattha: 5 }`. */\nexport function landToSqMeters(measure: Partial<Record<LandUnit, number>>): number {\n let m2 = 0;\n for (const [unit, value] of Object.entries(measure)) m2 += (value ?? 0) * LAND_UNIT_SQM[unit as LandUnit];\n return m2;\n}\n\n/** Convert an area between any two land units. */\nexport function convertLand(value: number, from: LandUnit, to: LandUnit): number {\n return (value * LAND_UNIT_SQM[from]) / LAND_UNIT_SQM[to];\n}\n\n/**\n * Break square metres into the hilly system: `{ ropani, aana, paisa, daam }`.\n * Rounds to the nearest whole daam first, then carries daam → paisa → aana →\n * ropani, so `4 daam` never appears (it is `1 paisa`) and float noise from\n * `landToSqMeters` cannot leave a unit one short.\n */\nexport interface LandBreakdownOptions {\n /** Decimal places kept on the smallest unit (daam / dhur). Default `0` (whole units). */\n decimals?: number;\n}\n\nconst roundTo = (n: number, d: number) => { const f = 10 ** d; return Math.round(n * f) / f; };\n\nexport function sqMetersToRopani(m2: number, options: LandBreakdownOptions = {}): { ropani: number; aana: number; paisa: number; daam: number } {\n const d = Math.max(0, Math.min(6, Math.floor(options.decimals ?? 0)));\n const neg = m2 < 0 ? -1 : 1;\n const total = roundTo(Math.abs(m2) / LAND_UNIT_SQM.daam, d); // daam, rounded once\n const ropani = Math.floor(total / 256 + 1e-9);\n const aana = Math.floor((total - ropani * 256) / 16 + 1e-9);\n const paisa = Math.floor((total - ropani * 256 - aana * 16) / 4 + 1e-9);\n const daam = roundTo(total - ropani * 256 - aana * 16 - paisa * 4, d);\n const z = (v: number) => (v === 0 ? 0 : neg * v);\n return { ropani: z(ropani), aana: z(aana), paisa: z(paisa), daam: z(daam) };\n}\n\n/**\n * Break square metres into the terai system: `{ bigha, kattha, dhur }`.\n * Rounds to the nearest whole dhur first, then carries dhur → kattha → bigha,\n * so `20 dhur` becomes `1 kattha` and `20 kattha` becomes `1 bigha`.\n */\nexport function sqMetersToBigha(m2: number, options: LandBreakdownOptions = {}): { bigha: number; kattha: number; dhur: number } {\n const d = Math.max(0, Math.min(6, Math.floor(options.decimals ?? 0)));\n const neg = m2 < 0 ? -1 : 1;\n const total = roundTo(Math.abs(m2) / LAND_UNIT_SQM.dhur, d); // dhur, rounded once\n const bigha = Math.floor(total / 400 + 1e-9);\n const kattha = Math.floor((total - bigha * 400) / 20 + 1e-9);\n const dhur = roundTo(total - bigha * 400 - kattha * 20, d);\n const z = (v: number) => (v === 0 ? 0 : neg * v);\n return { bigha: z(bigha), kattha: z(kattha), dhur: z(dhur) };\n}\n\n/** `\"2-3-1-0\"` ropani-aana-paisa-daam from square metres. */\nexport function formatRopani(m2: number): string {\n const r = sqMetersToRopani(m2);\n return `${r.ropani}-${r.aana}-${r.paisa}-${r.daam}`;\n}\n\n/** `\"1-5-0\"` bigha-kattha-dhur from square metres. */\nexport function formatBigha(m2: number): string {\n const b = sqMetersToBigha(m2);\n return `${b.bigha}-${b.kattha}-${b.dhur}`;\n}\n\n/* ------------------------------ phone & validators ------------------------------ */\n\n/** Normalize a Nepali mobile to canonical `+9779XXXXXXXXX`, or null if invalid. */\nexport function normalizeMobile(input: string): string | null {\n let s = fromDevanagari(input).replace(/[\\s-]/g, \"\");\n // Strip the country code only when a full 10-digit number follows it, so a\n // 10-digit mobile that itself starts with 977 is not mangled.\n const m = /^\\+?977(\\d{10})$/.exec(s);\n if (m) s = m[1]!;\n else if (s.startsWith(\"+\")) return null;\n return /^9[678]\\d{8}$/.test(s) ? `+977${s}` : null;\n}\n\nexport type Carrier = \"Ntc\" | \"Ncell\" | \"Smart Cell\" | \"UTL\" | \"unknown\";\n\n/**\n * Three-digit mobile prefixes (after +977) per carrier. Nepal Telecom and Ncell\n * are the only live mobile operators (2026); Smart Cell and UTL prefixes are\n * kept so old numbers still resolve, flagged by `CARRIER_STATUS`.\n */\nexport const CARRIER_PREFIXES: Record<Exclude<Carrier, \"unknown\">, readonly string[]> = {\n Ntc: [\"984\", \"985\", \"986\", \"974\", \"975\", \"976\"],\n Ncell: [\"980\", \"981\", \"982\", \"970\"],\n \"Smart Cell\": [\"961\", \"962\", \"988\"],\n UTL: [\"972\"],\n};\n\n/** Whether a carrier still operates a mobile network (NTA licence status, 2026). */\nexport const CARRIER_STATUS: Record<Exclude<Carrier, \"unknown\">, \"active\" | \"defunct\"> = {\n Ntc: \"active\",\n Ncell: \"active\",\n \"Smart Cell\": \"defunct\",\n UTL: \"defunct\",\n};\n\n/** Detect the carrier of a Nepali mobile number (see {@link CARRIER_PREFIXES}). */\nexport function getCarrier(input: string): Carrier {\n const n = normalizeMobile(input);\n if (!n) return \"unknown\";\n const p = n.slice(4, 7); // three digits after +977\n for (const [carrier, prefixes] of Object.entries(CARRIER_PREFIXES)) if (prefixes.includes(p)) return carrier as Carrier;\n return \"unknown\";\n}\n\n/** True for a valid Nepali mobile number (10 digits starting 96–98, optional +977). */\nexport function isValidNepaliMobile(input: string): boolean {\n return normalizeMobile(input) !== null; // one rule for both, so they always agree\n}\n\n/** True for a plausible Nepal landline (area code + number, e.g. 01-4XXXXXX). */\nexport function isValidLandline(input: string): boolean {\n const s = fromDevanagari(input).replace(/[\\s-]/g, \"\");\n return /^0\\d{7,9}$/.test(s);\n}\n\n/** True for a valid Nepal PAN / VAT number (9 digits). */\nexport function isValidPAN(input: string): boolean {\n return /^\\d{9}$/.test(fromDevanagari(input).trim());\n}\n\n/** True for a valid Nepal VAT number (9 digits — same format as PAN). */\nexport const isValidVAT = isValidPAN;\n\n/* ------------------------------ Nepali amount in words ------------------------------ */\n\nconst NEPALI_0_99 = [\n \"शून्य\", \"एक\", \"दुई\", \"तीन\", \"चार\", \"पाँच\", \"छ\", \"सात\", \"आठ\", \"नौ\",\n \"दस\", \"एघार\", \"बाह्र\", \"तेह्र\", \"चौध\", \"पन्ध्र\", \"सोह्र\", \"सत्र\", \"अठार\", \"उन्नाइस\",\n \"बीस\", \"एक्काइस\", \"बाइस\", \"तेइस\", \"चौबिस\", \"पच्चिस\", \"छब्बिस\", \"सत्ताइस\", \"अठ्ठाइस\", \"उनन्तिस\",\n \"तिस\", \"एकतिस\", \"बत्तिस\", \"तेत्तिस\", \"चौँतिस\", \"पैँतिस\", \"छत्तिस\", \"सैँतिस\", \"अठतिस\", \"उनन्चालिस\",\n \"चालिस\", \"एकचालिस\", \"बयालिस\", \"त्रिचालिस\", \"चवालिस\", \"पैँतालिस\", \"छयालिस\", \"सतचालिस\", \"अठचालिस\", \"उनन्चास\",\n \"पचास\", \"एकाउन्न\", \"बाउन्न\", \"त्रिपन्न\", \"चवन्न\", \"पचपन्न\", \"छपन्न\", \"सन्ताउन्न\", \"अन्ठाउन्न\", \"उनन्साठी\",\n \"साठी\", \"एकसट्ठी\", \"बयसट्ठी\", \"त्रिसट्ठी\", \"चौंसट्ठी\", \"पैंसट्ठी\", \"छयसट्ठी\", \"सतसट्ठी\", \"अठसट्ठी\", \"उनन्सत्तरी\",\n \"सत्तरी\", \"एकहत्तर\", \"बहत्तर\", \"त्रिहत्तर\", \"चौहत्तर\", \"पचहत्तर\", \"छयहत्तर\", \"सतहत्तर\", \"अठहत्तर\", \"उनासी\",\n \"असी\", \"एकासी\", \"बयासी\", \"त्रियासी\", \"चौरासी\", \"पचासी\", \"छयासी\", \"सतासी\", \"अठासी\", \"उनान्नब्बे\",\n \"नब्बे\", \"एकानब्बे\", \"बयानब्बे\", \"त्रियानब्बे\", \"चौरानब्बे\", \"पन्चानब्बे\", \"छयानब्बे\", \"सन्तानब्बे\", \"अन्ठानब्बे\", \"उनान्सय\",\n];\n\n/**\n * Amount in words in Nepali (Devanagari), South-Asian scale.\n * `numberToWordsNepali(1234567)` → `\"बाह्र लाख चौँतिस हजार पाँच सय सतसट्ठी\"`.\n */\nexport function numberToWordsNepali(value: number): string {\n let n = Math.floor(Math.abs(value));\n if (n === 0) return NEPALI_0_99[0]!;\n const parts: string[] = [];\n const units: [number, string][] = [\n [1e15, \"पद्म\"],\n [1e13, \"नील\"],\n [1e11, \"खरब\"],\n [1e9, \"अरब\"],\n [1e7, \"करोड\"],\n [1e5, \"लाख\"],\n [1e3, \"हजार\"],\n [1e2, \"सय\"],\n ];\n for (const [size, name] of units) {\n if (n >= size) {\n const count = Math.floor(n / size);\n // NEPALI_0_99 only covers 0–99; the top (पद्म) unit can exceed that, so\n // render its count recursively.\n const words = count >= 100 ? numberToWordsNepali(count) : NEPALI_0_99[count]!;\n parts.push(`${words} ${name}`);\n n %= size;\n }\n }\n if (n > 0) parts.push(NEPALI_0_99[n]!);\n return (value < 0 ? \"माइनस \" : \"\") + parts.join(\" \");\n}\n\n/** `numberToWordsNepali` plus a \"रुपैयाँ … मात्र\" wrapper. Accepts a number, decimal string or `{ rupees, paisa }`. */\nexport function amountInWordsNepali(amount: AmountInput): string {\n const { rupees, paisa, negative } = splitAmount(amount);\n let out = \"रुपैयाँ \" + numberToWordsNepali(rupees);\n if (paisa > 0) out += \" र \" + numberToWordsNepali(paisa) + \" पैसा\";\n return (negative ? \"माइनस \" : \"\") + out + \" मात्र\";\n}\n\nexport interface Province {\n number: number;\n name: string;\n nameNp: string;\n capital: string;\n /** Capital in Nepali (Devanagari). */\n capitalNp: string;\n}\n\n/** Nepal's seven federal provinces. */\nexport const PROVINCES: readonly Province[] = [\n { number: 1, name: \"Koshi\", nameNp: \"कोशी\", capital: \"Biratnagar\", capitalNp: \"विराटनगर\" },\n { number: 2, name: \"Madhesh\", nameNp: \"मधेश\", capital: \"Janakpur\", capitalNp: \"जनकपुर\" },\n { number: 3, name: \"Bagmati\", nameNp: \"बागमती\", capital: \"Hetauda\", capitalNp: \"हेटौँडा\" },\n { number: 4, name: \"Gandaki\", nameNp: \"गण्डकी\", capital: \"Pokhara\", capitalNp: \"पोखरा\" },\n { number: 5, name: \"Lumbini\", nameNp: \"लुम्बिनी\", capital: \"Deukhuri\", capitalNp: \"देउखुरी\" },\n { number: 6, name: \"Karnali\", nameNp: \"कर्णाली\", capital: \"Birendranagar\", capitalNp: \"वीरेन्द्रनगर\" },\n { number: 7, name: \"Sudurpashchim\", nameNp: \"सुदूरपश्चिम\", capital: \"Godawari\", capitalNp: \"गोदावरी\" },\n];\n\nexport interface District {\n name: string;\n nameNp: string;\n /** Province number 1–7. */\n province: number;\n /** Other accepted spellings/names (English or Nepali), matched by {@link findDistrict}. */\n aliases?: readonly string[];\n}\n\n/** Nepal's 77 districts, with their province number. */\nexport const DISTRICTS: readonly District[] = [\n // Koshi (1)\n { name: \"Bhojpur\", nameNp: \"भोजपुर\", province: 1 },\n { name: \"Dhankuta\", nameNp: \"धनकुटा\", province: 1 },\n { name: \"Ilam\", nameNp: \"इलाम\", province: 1 },\n { name: \"Jhapa\", nameNp: \"झापा\", province: 1 },\n { name: \"Khotang\", nameNp: \"खोटाङ\", province: 1 },\n { name: \"Morang\", nameNp: \"मोरङ\", province: 1 },\n { name: \"Okhaldhunga\", nameNp: \"ओखलढुंगा\", province: 1 },\n { name: \"Panchthar\", nameNp: \"पाँचथर\", province: 1 },\n { name: \"Sankhuwasabha\", nameNp: \"संखुवासभा\", province: 1 },\n { name: \"Solukhumbu\", nameNp: \"सोलुखुम्बु\", province: 1 },\n { name: \"Sunsari\", nameNp: \"सुनसरी\", province: 1 },\n { name: \"Taplejung\", nameNp: \"ताप्लेजुङ\", province: 1 },\n { name: \"Terhathum\", nameNp: \"तेह्रथुम\", province: 1 },\n { name: \"Udayapur\", nameNp: \"उदयपुर\", province: 1 },\n // Madhesh (2)\n { name: \"Bara\", nameNp: \"बारा\", province: 2 },\n { name: \"Dhanusha\", nameNp: \"धनुषा\", province: 2 },\n { name: \"Mahottari\", nameNp: \"महोत्तरी\", province: 2 },\n { name: \"Parsa\", nameNp: \"पर्सा\", province: 2 },\n { name: \"Rautahat\", nameNp: \"रौतहट\", province: 2 },\n { name: \"Saptari\", nameNp: \"सप्तरी\", province: 2 },\n { name: \"Sarlahi\", nameNp: \"सर्लाही\", province: 2 },\n { name: \"Siraha\", nameNp: \"सिरहा\", province: 2 },\n // Bagmati (3)\n { name: \"Bhaktapur\", nameNp: \"भक्तपुर\", province: 3 },\n { name: \"Chitwan\", nameNp: \"चितवन\", province: 3 },\n { name: \"Dhading\", nameNp: \"धादिङ\", province: 3 },\n { name: \"Dolakha\", nameNp: \"दोलखा\", province: 3 },\n { name: \"Kathmandu\", nameNp: \"काठमाडौं\", province: 3 },\n { name: \"Kavrepalanchok\", nameNp: \"काभ्रेपलाञ्चोक\", province: 3 },\n { name: \"Lalitpur\", nameNp: \"ललितपुर\", province: 3 },\n { name: \"Makwanpur\", nameNp: \"मकवानपुर\", province: 3 },\n { name: \"Nuwakot\", nameNp: \"नुवाकोट\", province: 3 },\n { name: \"Ramechhap\", nameNp: \"रामेछाप\", province: 3 },\n { name: \"Rasuwa\", nameNp: \"रसुवा\", province: 3 },\n { name: \"Sindhuli\", nameNp: \"सिन्धुली\", province: 3 },\n { name: \"Sindhupalchok\", nameNp: \"सिन्धुपाल्चोक\", province: 3 },\n // Gandaki (4)\n { name: \"Baglung\", nameNp: \"बागलुङ\", province: 4 },\n { name: \"Gorkha\", nameNp: \"गोरखा\", province: 4 },\n { name: \"Kaski\", nameNp: \"कास्की\", province: 4 },\n { name: \"Lamjung\", nameNp: \"लमजुङ\", province: 4 },\n { name: \"Manang\", nameNp: \"मनाङ\", province: 4 },\n { name: \"Mustang\", nameNp: \"मुस्ताङ\", province: 4 },\n { name: \"Myagdi\", nameNp: \"म्याग्दी\", province: 4 },\n { name: \"Nawalparasi East\", nameNp: \"नवलपरासी (बर्दघाट सुस्ता पूर्व)\", province: 4, aliases: [\"Nawalpur\", \"नवलपुर\", \"Nawalparasi (East of Bardaghat Susta)\", \"Nawalparasi (Bardaghat Susta East)\", \"Nawalparasi Purba\", \"नवलपरासी पूर्व\"] },\n { name: \"Parbat\", nameNp: \"पर्वत\", province: 4 },\n { name: \"Syangja\", nameNp: \"स्याङ्जा\", province: 4 },\n { name: \"Tanahun\", nameNp: \"तनहुँ\", province: 4 },\n // Lumbini (5)\n { name: \"Arghakhanchi\", nameNp: \"अर्घाखाँची\", province: 5 },\n { name: \"Banke\", nameNp: \"बाँके\", province: 5 },\n { name: \"Bardiya\", nameNp: \"बर्दिया\", province: 5 },\n { name: \"Dang\", nameNp: \"दाङ\", province: 5 },\n { name: \"Eastern Rukum\", nameNp: \"पूर्वी रुकुम\", province: 5, aliases: [\"Rukum East\", \"Rukum Purba\", \"रुकुम पूर्व\"] },\n { name: \"Gulmi\", nameNp: \"गुल्मी\", province: 5 },\n { name: \"Kapilvastu\", nameNp: \"कपिलवस्तु\", province: 5 },\n { name: \"Nawalparasi West\", nameNp: \"नवलपरासी (बर्दघाट सुस्ता पश्चिम)\", province: 5, aliases: [\"Parasi\", \"परासी\", \"Nawalparasi (West of Bardaghat Susta)\", \"Nawalparasi (Bardaghat Susta West)\", \"Nawalparasi Paschim\", \"नवलपरासी पश्चिम\"] },\n { name: \"Palpa\", nameNp: \"पाल्पा\", province: 5 },\n { name: \"Pyuthan\", nameNp: \"प्युठान\", province: 5 },\n { name: \"Rolpa\", nameNp: \"रोल्पा\", province: 5 },\n { name: \"Rupandehi\", nameNp: \"रूपन्देही\", province: 5 },\n // Karnali (6)\n { name: \"Dailekh\", nameNp: \"दैलेख\", province: 6 },\n { name: \"Dolpa\", nameNp: \"डोल्पा\", province: 6 },\n { name: \"Humla\", nameNp: \"हुम्ला\", province: 6 },\n { name: \"Jajarkot\", nameNp: \"जाजरकोट\", province: 6 },\n { name: \"Jumla\", nameNp: \"जुम्ला\", province: 6 },\n { name: \"Kalikot\", nameNp: \"कालिकोट\", province: 6 },\n { name: \"Mugu\", nameNp: \"मुगु\", province: 6 },\n { name: \"Salyan\", nameNp: \"सल्यान\", province: 6 },\n { name: \"Surkhet\", nameNp: \"सुर्खेत\", province: 6 },\n { name: \"Western Rukum\", nameNp: \"पश्चिमी रुकुम\", province: 6, aliases: [\"Rukum West\", \"Rukum Paschim\", \"रुकुम पश्चिम\"] },\n // Sudurpashchim (7)\n { name: \"Achham\", nameNp: \"अछाम\", province: 7 },\n { name: \"Baitadi\", nameNp: \"बैतडी\", province: 7 },\n { name: \"Bajhang\", nameNp: \"बझाङ\", province: 7 },\n { name: \"Bajura\", nameNp: \"बाजुरा\", province: 7 },\n { name: \"Dadeldhura\", nameNp: \"डडेल्धुरा\", province: 7 },\n { name: \"Darchula\", nameNp: \"दार्चुला\", province: 7 },\n { name: \"Doti\", nameNp: \"डोटी\", province: 7 },\n { name: \"Kailali\", nameNp: \"कैलाली\", province: 7 },\n { name: \"Kanchanpur\", nameNp: \"कञ्चनपुर\", province: 7 },\n];\n\n/** Districts in a given province (1–7). */\nexport function districtsByProvince(province: number): District[] {\n return DISTRICTS.filter((d) => d.province === province);\n}\n\n/** Find a district by English or Nepali name or any alias (case-insensitive). */\nexport function findDistrict(name: string): District | undefined {\n const raw = name.trim();\n const q = raw.toLowerCase();\n return DISTRICTS.find(\n (d) => d.name.toLowerCase() === q || d.nameNp === raw || (d.aliases ?? []).some((a) => a.toLowerCase() === q),\n );\n}\n\n/* ------------------------------------------------------------------------- *\n * New in 1.4.0 — Neel/Padma scale, `{ decimals }` on land breakdowns, stricter plate\n * grammar (province word + Pradesh/Province, province number 1–7 only), and\n * isValidNepaliMobile ≡ normalizeMobile.\n * New in 1.3.0 — Kharab scale, \"र\"/\"ra\" rupee–paisa separator, exact land-unit\n * ratios with carry-correct ropani/bigha breakdowns, Ncell 970 + carrier status,\n * Devanagari digits in landline/PAN validators, Nepali province capitals,\n * district aliases (official Nawalparasi East/West), embossed plate shapes.\n * New in 1.2.0 — Roman (transliterated) amount-in-words, integer-paisa NPR\n * format/parse, digit-conversion aliases, extra shape validators, and\n * province lookup helpers. See `./extras`.\n * ------------------------------------------------------------------------- */\nexport * from \"./extras\";\n\n/* 1.6.0: Nepal Standard Time (UTC+05:45) helpers. */\nexport * from \"./time\";\n","/**\n * Ready-made terms for Nepal's 77 districts (names from @lacspace/nepali-utils), with the\n * spellings that actually turn up in copy: काठमाण्डौ, Kavre/काभ्रे, Rukum East/रुकुम पूर्व …\n */\nimport { DISTRICTS } from \"@lacspace/nepali-utils\";\nimport type { TermInput } from \"./index.js\";\n\nexport interface DistrictTerm {\n id: string;\n en: string[];\n ne: string[];\n province: number;\n /** The Nepali name is also an everyday word (पर्वत = mountain): confirm with context before tagging. */\n ambiguous?: boolean;\n caseSensitive: true;\n}\n\nconst ALIASES: Record<string, { en?: string[]; ne?: string[] }> = {\n Kathmandu: { en: [\"Katmandu\"], ne: [\"काठमाण्डौ\", \"काठमान्डु\"] },\n Kavrepalanchok: { en: [\"Kavre\", \"Kabhre\", \"Kabhrepalanchok\", \"Kavrepalanchowk\"], ne: [\"काभ्रे\", \"काभ्रेपलान्चोक\"] },\n Sindhupalchok: { en: [\"Sindhupalchowk\"] },\n \"Nawalparasi East\": { en: [\"Nawalparasi (East)\", \"East Nawalparasi\", \"Nawalpur\"], ne: [\"नवलपरासी पूर्व\", \"पूर्वी नवलपरासी\", \"नवलपुर\"] },\n \"Nawalparasi West\": { en: [\"Nawalparasi (West)\", \"West Nawalparasi\"], ne: [\"नवलपरासी पश्चिम\", \"पश्चिमी नवलपरासी\"] },\n \"Eastern Rukum\": { en: [\"Rukum East\", \"East Rukum\", \"Rukum (East)\"], ne: [\"रुकुम पूर्व\"] },\n \"Western Rukum\": { en: [\"Rukum West\", \"West Rukum\", \"Rukum (West)\"], ne: [\"रुकुम पश्चिम\"] },\n Tanahun: { en: [\"Tanahu\"], ne: [\"तनहु\"] },\n Dhanusha: { en: [\"Dhanusa\"] },\n Kapilvastu: { en: [\"Kapilbastu\"], ne: [\"कपिलबस्तु\"] },\n Makwanpur: { en: [\"Makawanpur\"] },\n Sankhuwasabha: { en: [\"Sankhuwasava\"] },\n Terhathum: { en: [\"Tehrathum\"], ne: [\"तेहथुम\"] },\n Okhaldhunga: { ne: [\"ओखलढुङ्गा\"] },\n Syangja: { en: [\"Syanja\"], ne: [\"स्याङजा\"] },\n Achham: { en: [\"Accham\"] },\n Udayapur: { en: [\"Udaypur\"] },\n Bardiya: { en: [\"Bardia\"] },\n Ilam: { en: [\"Illam\"] },\n Baglung: { ne: [\"बाग्लुङ\"] },\n Rupandehi: { ne: [\"रुपन्देही\"] },\n Dadeldhura: { ne: [\"डँडेलधुरा\"] },\n Mahottari: { ne: [\"महोतरी\"] },\n};\n\n/** District whose Nepali name is a common word. */\nconst AMBIGUOUS = new Set([\"Parbat\"]);\n\nconst slug = (s: string): string => s.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-|-$/g, \"\");\n\n/** Every district as a {@link TermInput}: ids are slugs (\"nawalparasi-east\"), English is exact-case. */\nexport function districtTerms(): DistrictTerm[] {\n return DISTRICTS.map((d) => {\n const extra = ALIASES[d.name] ?? {};\n const ne = new Set<string>([d.nameNp, ...(extra.ne ?? [])]);\n for (const n of [...ne]) if (n.endsWith(\"ङ\")) ne.add(n.slice(0, -1) + \"ंग\"); // मोरङ / मोरंग\n return {\n id: slug(d.name),\n en: [d.name, ...(extra.en ?? [])],\n ne: [...ne],\n province: d.province,\n ...(AMBIGUOUS.has(d.name) ? { ambiguous: true } : {}),\n caseSensitive: true,\n } satisfies DistrictTerm & TermInput;\n });\n}\n","/**\n * Nepali / English matching for names and keywords in running text.\n *\n * normaliseNe fold spelling variants (chandrabindu, half nasals, long/short vowels, nukta, ZWJ)\n * createMatcher whole-word matching that lets Nepali postpositions follow a word\n * (झापाको → Jhapa) but nothing else (पर्वतारोही ≠ Parbat), and keeps short\n * English acronyms case-sensitive (SEE ≠ \"see\")\n * near two terms within N characters, optionally in the same sentence\n *\n * Every match carries offsets into the ORIGINAL text, so callers can highlight or cut.\n */\n\nexport const VERSION = \"1.0.0\";\n\nexport interface NormaliseOptions {\n /** Also fold श/ष → स, व → ब and ण → न. Default false. */\n loose?: boolean;\n /** Devanagari digits ०-९ → 0-9. Default true. */\n digits?: boolean;\n}\n\n/** Normalised text plus, for each output char, the index of the input char it came from. */\ninterface Mapped {\n text: string;\n map: number[];\n}\n\nconst NUKTA = 0x093c;\nconst HALANT = 0x094d;\nconst NASALS = new Set([0x0919, 0x091e, 0x0923, 0x0928, 0x092e]); // ङ ञ ण न म\nconst DROP = new Set([NUKTA, 0x200c, 0x200d, 0x00ad, 0xfeff]);\nconst FOLD: Record<number, number> = {\n 0x0901: 0x0902, // ँ → ं\n 0x0908: 0x0907, // ई → इ\n 0x090a: 0x0909, // ऊ → उ\n 0x0940: 0x093f, // ी → ि\n 0x0942: 0x0941, // ू → ु\n};\nconst LOOSE: Record<number, number> = {\n 0x0936: 0x0938, // श → स\n 0x0937: 0x0938, // ष → स\n 0x0935: 0x092c, // व → ब\n 0x0923: 0x0928, // ण → न\n};\n\nconst isConsonant = (c: number): boolean => (c >= 0x0915 && c <= 0x0939) || (c >= 0x0958 && c <= 0x095f);\n\nfunction mapNormalise(input: string, opts: NormaliseOptions = {}): Mapped {\n const digits = opts.digits !== false;\n // NFC per char would lose the map; NFC first, then map onto the NFC string.\n const s = input.normalize(\"NFC\");\n const out: string[] = [];\n const map: number[] = [];\n const push = (ch: string, i: number): void => {\n out.push(ch);\n map.push(i);\n };\n // Next code point index after i, skipping chars we drop anyway.\n const next = (i: number): number => {\n let j = i + 1;\n while (j < s.length && DROP.has(s.charCodeAt(j))) j++;\n return j;\n };\n let lastSpace = false;\n for (let i = 0; i < s.length; i++) {\n let c = s.charCodeAt(i);\n if (DROP.has(c)) continue;\n if (/\\s/.test(s[i]!)) {\n if (!lastSpace) push(\" \", i);\n lastSpace = true;\n continue;\n }\n lastSpace = false;\n // Half nasal + consonant → anusvara: चन्द्र → चंद्र, सम्म → संम.\n if (NASALS.has(c)) {\n const h = next(i);\n if (s.charCodeAt(h) === HALANT) {\n const k = next(h);\n if (k < s.length && isConsonant(s.charCodeAt(k))) {\n push(\"ं\", i);\n i = h;\n continue;\n }\n }\n }\n if (FOLD[c] !== undefined) c = FOLD[c]!;\n if (opts.loose && LOOSE[c] !== undefined) c = LOOSE[c]!;\n if (digits && c >= 0x0966 && c <= 0x096f) c = 0x30 + (c - 0x0966);\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {\n push(s[i]!, i);\n push(s[i + 1]!, i + 1);\n i++;\n continue;\n }\n push(String.fromCharCode(c), i);\n }\n return { text: out.join(\"\"), map };\n}\n\n/**\n * Fold Nepali spelling variants so equivalent spellings compare equal:\n * NFC; chandrabindu → anusvara; half nasal + consonant → anusvara; ई/ी → इ/ि and ऊ/ू → उ/ु;\n * nukta, ZWJ, ZWNJ and soft hyphens removed; Devanagari digits → ASCII; whitespace collapsed.\n * Latin text passes through unchanged (case included).\n */\nexport function normaliseNe(text: string, opts: NormaliseOptions = {}): string {\n return mapNormalise(text, opts).text;\n}\n/** US spelling alias. */\nexport const normalizeNe = normaliseNe;\n\n/**\n * Words that may be glued to the end of a Nepali name without making it a different word.\n * Matching allows a chain of up to three (जिल्लाहरूमा, काठमाडौंबाटै).\n */\nexport const POSTPOSITIONS: readonly string[] = [\n \"मा\", \"मै\", \"को\", \"का\", \"की\", \"के\", \"कै\", \"ले\", \"लाई\", \"बाट\", \"बाटै\", \"सँग\", \"संग\", \"सित\",\n \"देखि\", \"देखिनै\", \"सम्म\", \"सम्मै\", \"तिर\", \"तर्फ\", \"भित्र\", \"बाहिर\", \"माथि\", \"मुनि\", \"नजिक\", \"पछि\",\n \"अघि\", \"अगाडि\", \"पारि\", \"वारि\", \"द्वारा\", \"हरू\", \"हरु\", \"नै\", \"भर\", \"भरि\", \"वासी\", \"बासी\",\n \"स्थित\", \"निवासी\",\n];\n\nconst isNeLetter = (c: number): boolean => (c >= 0x0900 && c <= 0x0963) || (c >= 0x0971 && c <= 0x097f);\nconst isWordChar = (ch: string | undefined): boolean => !!ch && /[\\p{L}\\p{M}\\p{N}]/u.test(ch);\nconst hasDevanagari = (s: string): boolean => /[ऀ-ॿ]/.test(s);\n\n/** A term to look for: a plain string, or an id with English and/or Nepali spellings. */\nexport type TermInput =\n | string\n | {\n id?: string;\n en?: string | readonly string[];\n ne?: string | readonly string[];\n /** Extra spellings in either script. */\n aliases?: readonly string[];\n /** English case rule for this term. Default \"auto\": all-caps terms up to 5 letters are exact-case. */\n caseSensitive?: boolean | \"auto\";\n };\n\nexport interface MatchOptions extends NormaliseOptions {\n /** Default English case rule. Default \"auto\". */\n caseSensitive?: boolean | \"auto\";\n /** Allow Nepali postpositions after a word. Default true. */\n postpositions?: boolean;\n /** Extra suffixes to allow on top of {@link POSTPOSITIONS}. */\n extraSuffixes?: readonly string[];\n /** Keep overlapping matches; by default the longest wins. */\n overlaps?: boolean;\n}\n\nexport interface Match {\n /** The term's id (or the spelling itself for plain-string terms). */\n id: string;\n /** The spelling that matched, as given. */\n term: string;\n lang: \"ne\" | \"en\";\n /** Offsets into the original text; `text` is `original.slice(index, end)`, suffix included. */\n index: number;\n end: number;\n text: string;\n /** The postposition chain after the word, normalised (e.g. \"मा\", \"हरुमा\"). */\n suffix?: string;\n}\n\ninterface Variant {\n id: string;\n term: string;\n lang: \"ne\" | \"en\";\n key: string; // normalised (ne) or raw (en)\n re?: RegExp; // en\n}\n\nconst escapeRe = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\nfunction autoCase(term: string): boolean {\n const letters = term.replace(/[^\\p{L}]/gu, \"\");\n return letters.length >= 2 && letters.length <= 5 && letters === letters.toUpperCase() && letters !== letters.toLowerCase();\n}\n\nexport interface Matcher {\n /** Every match in `text`, in order of position. */\n find(text: string): Match[];\n /** True when any term (or the term with this id) occurs. */\n test(text: string, id?: string): boolean;\n /** Distinct ids found, in order of first appearance. */\n ids(text: string): string[];\n readonly size: number;\n}\n\n/** Compile a set of terms once; reuse the matcher across many texts. */\nexport function createMatcher(terms: readonly TermInput[], opts: MatchOptions = {}): Matcher {\n const nopts: NormaliseOptions = { loose: opts.loose, digits: opts.digits };\n const suffixes = opts.postpositions === false\n ? []\n : [...new Set([...POSTPOSITIONS, ...(opts.extraSuffixes ?? [])].map((s) => normaliseNe(s, nopts)))].sort((a, b) => b.length - a.length);\n const variants: Variant[] = [];\n for (const t of terms) {\n const obj = typeof t === \"string\" ? { id: t, aliases: [t] } : t;\n const list = (v: string | readonly string[] | undefined): string[] => (v === undefined ? [] : typeof v === \"string\" ? [v] : [...v]);\n const spellings = [...list(obj.en), ...list(obj.ne), ...(obj.aliases ?? [])].map((s) => s.trim()).filter(Boolean);\n const id = obj.id ?? spellings[0] ?? \"\";\n for (const sp of new Set(spellings)) {\n if (hasDevanagari(sp)) {\n variants.push({ id, term: sp, lang: \"ne\", key: normaliseNe(sp, nopts) });\n } else {\n const rule = obj.caseSensitive ?? opts.caseSensitive ?? \"auto\";\n const exact = rule === \"auto\" ? autoCase(sp) : rule;\n const body = sp.split(/\\s+/).map(escapeRe).join(\"\\\\s+\");\n variants.push({ id, term: sp, lang: \"en\", key: sp, re: new RegExp(body, exact ? \"gu\" : \"giu\") });\n }\n }\n }\n\n // Length of the postposition chain at `pos`, or -1 when the word continues with other letters.\n const suffixEnd = (s: string, pos: number, depth: number): number => {\n if (pos >= s.length || !isNeLetter(s.charCodeAt(pos))) return pos;\n if (depth >= 3) return -1;\n for (const suf of suffixes) {\n if (s.startsWith(suf, pos)) {\n const e = suffixEnd(s, pos + suf.length, depth + 1);\n if (e >= 0) return e;\n }\n }\n return -1;\n };\n\n const find = (text: string): Match[] => {\n const { text: n, map } = mapNormalise(text, nopts);\n const toOrig = (i: number): number => (i >= map.length ? text.normalize(\"NFC\").length : map[i]!);\n const nfc = text.normalize(\"NFC\");\n const found: Match[] = [];\n for (const v of variants) {\n if (v.lang === \"ne\") {\n if (!v.key) continue;\n let at = n.indexOf(v.key);\n while (at >= 0) {\n const before = n[at - 1];\n if (!isWordChar(before)) {\n const wordEnd = at + v.key.length;\n const end = suffixEnd(n, wordEnd, 0);\n const after = n[end];\n if (end >= 0 && !isWordChar(after)) {\n const s = toOrig(at);\n const e = end >= n.length ? nfc.length : toOrig(end);\n found.push({ id: v.id, term: v.term, lang: \"ne\", index: s, end: e, text: nfc.slice(s, e), ...(end > wordEnd ? { suffix: n.slice(wordEnd, end) } : {}) });\n }\n }\n at = n.indexOf(v.key, at + 1);\n }\n } else {\n v.re!.lastIndex = 0;\n for (const m of n.matchAll(v.re!)) {\n const at = m.index!;\n const end = at + m[0].length;\n if (isWordChar(n[at - 1]) || isWordChar(n[end])) continue;\n const s = toOrig(at);\n const e = end >= n.length ? nfc.length : toOrig(end);\n found.push({ id: v.id, term: v.term, lang: \"en\", index: s, end: e, text: nfc.slice(s, e) });\n }\n }\n }\n found.sort((a, b) => a.index - b.index || b.end - a.end);\n if (opts.overlaps) return found;\n const kept: Match[] = [];\n let reach = -1;\n for (const m of found) {\n if (m.index >= reach) {\n kept.push(m);\n reach = m.end;\n }\n }\n return kept;\n };\n\n return {\n find,\n test: (text, id) => find(text).some((m) => id === undefined || m.id === id),\n ids: (text) => [...new Set(find(text).map((m) => m.id))],\n get size() { return variants.length; },\n };\n}\n\n/** One-off: every match of `terms` in `text`. Compile with {@link createMatcher} for repeated use. */\nexport function findTerms(text: string, terms: TermInput | readonly TermInput[], opts?: MatchOptions): Match[] {\n return createMatcher(Array.isArray(terms) ? (terms as TermInput[]) : [terms as TermInput], opts).find(text);\n}\n\n/** One-off: does `term` occur in `text` as a whole word (Nepali postpositions allowed)? */\nexport function contains(text: string, term: TermInput | readonly TermInput[], opts?: MatchOptions): boolean {\n return findTerms(text, term, opts).length > 0;\n}\n\n/**\n * Split a Nepali word into its stem and trailing postpositions:\n * `splitSuffix(\"जिल्लाहरूमा\")` → `{ stem: \"जिल्ला\", suffixes: [\"हरु\", \"मा\"] }` (suffixes normalised).\n * Only splits when the whole tail is postpositions; the stem keeps the original spelling.\n */\nexport function splitSuffix(word: string): { stem: string; suffixes: string[] } {\n const { text: n, map } = mapNormalise(word.trim());\n const sufs = [...new Set(POSTPOSITIONS.map((s) => normaliseNe(s)))].sort((a, b) => b.length - a.length);\n const nfc = word.trim().normalize(\"NFC\");\n let end = n.length;\n const out: string[] = [];\n while (out.length < 3) {\n const hit = sufs.find((s) => end - s.length >= 2 && n.slice(end - s.length, end) === s);\n if (!hit) break;\n out.unshift(hit);\n end -= hit.length;\n }\n return { stem: nfc.slice(0, end >= n.length ? nfc.length : map[end]), suffixes: out };\n}\n\nexport interface NearOptions extends MatchOptions {\n /** Max characters between the end of one match and the start of the other. Default 60. */\n maxChars?: number;\n /** Require both in the same sentence (। ॥ . ? ! or a newline ends one). Default true. */\n sameSentence?: boolean;\n}\n\nexport interface NearResult {\n a: Match;\n b: Match;\n /** Characters between the two matches (0 when adjacent). */\n gap: number;\n}\n\n// \"ने.क.पा.\" / \"U.S.\": a token with an inner dot is an abbreviation, not a sentence end.\nconst dottedAbbr = (s: string, i: number): boolean => {\n let j = i - 1;\n while (j >= 0 && !/\\s/.test(s[j]!)) j--;\n return s.slice(j + 1, i).includes(\".\");\n};\n\n/** Sentence boundaries as [start, end) offsets into the NFC text. \".\" ends a sentence only before a space or the end. */\nexport function sentenceSpans(text: string): [number, number][] {\n const s = text.normalize(\"NFC\");\n const spans: [number, number][] = [];\n let start = 0;\n for (let i = 0; i < s.length; i++) {\n const ch = s[i]!;\n const end = ch === \"।\" || ch === \"॥\" || ch === \"?\" || ch === \"!\" || ch === \"\\n\" || (ch === \".\" && (i + 1 >= s.length || /\\s/.test(s[i + 1]!)) && !dottedAbbr(s, i));\n if (end) {\n spans.push([start, i + 1]);\n start = i + 1;\n }\n }\n if (start < s.length) spans.push([start, s.length]);\n return spans;\n}\n\n/**\n * The closest pair of an `a` match and a `b` match within `maxChars` of each other\n * (in either order), or null. With `sameSentence` (default) the pair must share a sentence.\n */\nexport function near(\n text: string,\n a: TermInput | readonly TermInput[],\n b: TermInput | readonly TermInput[],\n maxCharsOrOpts: number | NearOptions = {},\n sameSentence?: boolean,\n): NearResult | null {\n const opts: NearOptions = typeof maxCharsOrOpts === \"number\" ? { maxChars: maxCharsOrOpts } : { ...maxCharsOrOpts };\n if (sameSentence !== undefined) opts.sameSentence = sameSentence;\n const max = opts.maxChars ?? 60;\n const same = opts.sameSentence !== false;\n const am = findTerms(text, a, opts);\n const bm = findTerms(text, b, opts);\n if (!am.length || !bm.length) return null;\n const spans = same ? sentenceSpans(text) : [];\n const sentenceOf = (i: number): number => spans.findIndex(([s, e]) => i >= s && i < e);\n let best: NearResult | null = null;\n for (const x of am) {\n for (const y of bm) {\n if (x.index < y.end && y.index < x.end) continue; // same span of text\n const gap = x.end <= y.index ? y.index - x.end : x.index - y.end;\n if (gap > max) continue;\n if (same && sentenceOf(x.index) !== sentenceOf(y.index)) continue;\n if (!best || gap < best.gap) best = { a: x, b: y, gap };\n }\n }\n return best;\n}\n\nexport { districtTerms, type DistrictTerm } from \"./districts.js\";\n"]}
@@ -0,0 +1,122 @@
1
+ interface DistrictTerm {
2
+ id: string;
3
+ en: string[];
4
+ ne: string[];
5
+ province: number;
6
+ /** The Nepali name is also an everyday word (पर्वत = mountain): confirm with context before tagging. */
7
+ ambiguous?: boolean;
8
+ caseSensitive: true;
9
+ }
10
+ /** Every district as a {@link TermInput}: ids are slugs ("nawalparasi-east"), English is exact-case. */
11
+ declare function districtTerms(): DistrictTerm[];
12
+
13
+ /**
14
+ * Nepali / English matching for names and keywords in running text.
15
+ *
16
+ * normaliseNe fold spelling variants (chandrabindu, half nasals, long/short vowels, nukta, ZWJ)
17
+ * createMatcher whole-word matching that lets Nepali postpositions follow a word
18
+ * (झापाको → Jhapa) but nothing else (पर्वतारोही ≠ Parbat), and keeps short
19
+ * English acronyms case-sensitive (SEE ≠ "see")
20
+ * near two terms within N characters, optionally in the same sentence
21
+ *
22
+ * Every match carries offsets into the ORIGINAL text, so callers can highlight or cut.
23
+ */
24
+ declare const VERSION = "1.0.0";
25
+ interface NormaliseOptions {
26
+ /** Also fold श/ष → स, व → ब and ण → न. Default false. */
27
+ loose?: boolean;
28
+ /** Devanagari digits ०-९ → 0-9. Default true. */
29
+ digits?: boolean;
30
+ }
31
+ /**
32
+ * Fold Nepali spelling variants so equivalent spellings compare equal:
33
+ * NFC; chandrabindu → anusvara; half nasal + consonant → anusvara; ई/ी → इ/ि and ऊ/ू → उ/ु;
34
+ * nukta, ZWJ, ZWNJ and soft hyphens removed; Devanagari digits → ASCII; whitespace collapsed.
35
+ * Latin text passes through unchanged (case included).
36
+ */
37
+ declare function normaliseNe(text: string, opts?: NormaliseOptions): string;
38
+ /** US spelling alias. */
39
+ declare const normalizeNe: typeof normaliseNe;
40
+ /**
41
+ * Words that may be glued to the end of a Nepali name without making it a different word.
42
+ * Matching allows a chain of up to three (जिल्लाहरूमा, काठमाडौंबाटै).
43
+ */
44
+ declare const POSTPOSITIONS: readonly string[];
45
+ /** A term to look for: a plain string, or an id with English and/or Nepali spellings. */
46
+ type TermInput = string | {
47
+ id?: string;
48
+ en?: string | readonly string[];
49
+ ne?: string | readonly string[];
50
+ /** Extra spellings in either script. */
51
+ aliases?: readonly string[];
52
+ /** English case rule for this term. Default "auto": all-caps terms up to 5 letters are exact-case. */
53
+ caseSensitive?: boolean | "auto";
54
+ };
55
+ interface MatchOptions extends NormaliseOptions {
56
+ /** Default English case rule. Default "auto". */
57
+ caseSensitive?: boolean | "auto";
58
+ /** Allow Nepali postpositions after a word. Default true. */
59
+ postpositions?: boolean;
60
+ /** Extra suffixes to allow on top of {@link POSTPOSITIONS}. */
61
+ extraSuffixes?: readonly string[];
62
+ /** Keep overlapping matches; by default the longest wins. */
63
+ overlaps?: boolean;
64
+ }
65
+ interface Match {
66
+ /** The term's id (or the spelling itself for plain-string terms). */
67
+ id: string;
68
+ /** The spelling that matched, as given. */
69
+ term: string;
70
+ lang: "ne" | "en";
71
+ /** Offsets into the original text; `text` is `original.slice(index, end)`, suffix included. */
72
+ index: number;
73
+ end: number;
74
+ text: string;
75
+ /** The postposition chain after the word, normalised (e.g. "मा", "हरुमा"). */
76
+ suffix?: string;
77
+ }
78
+ interface Matcher {
79
+ /** Every match in `text`, in order of position. */
80
+ find(text: string): Match[];
81
+ /** True when any term (or the term with this id) occurs. */
82
+ test(text: string, id?: string): boolean;
83
+ /** Distinct ids found, in order of first appearance. */
84
+ ids(text: string): string[];
85
+ readonly size: number;
86
+ }
87
+ /** Compile a set of terms once; reuse the matcher across many texts. */
88
+ declare function createMatcher(terms: readonly TermInput[], opts?: MatchOptions): Matcher;
89
+ /** One-off: every match of `terms` in `text`. Compile with {@link createMatcher} for repeated use. */
90
+ declare function findTerms(text: string, terms: TermInput | readonly TermInput[], opts?: MatchOptions): Match[];
91
+ /** One-off: does `term` occur in `text` as a whole word (Nepali postpositions allowed)? */
92
+ declare function contains(text: string, term: TermInput | readonly TermInput[], opts?: MatchOptions): boolean;
93
+ /**
94
+ * Split a Nepali word into its stem and trailing postpositions:
95
+ * `splitSuffix("जिल्लाहरूमा")` → `{ stem: "जिल्ला", suffixes: ["हरु", "मा"] }` (suffixes normalised).
96
+ * Only splits when the whole tail is postpositions; the stem keeps the original spelling.
97
+ */
98
+ declare function splitSuffix(word: string): {
99
+ stem: string;
100
+ suffixes: string[];
101
+ };
102
+ interface NearOptions extends MatchOptions {
103
+ /** Max characters between the end of one match and the start of the other. Default 60. */
104
+ maxChars?: number;
105
+ /** Require both in the same sentence (। ॥ . ? ! or a newline ends one). Default true. */
106
+ sameSentence?: boolean;
107
+ }
108
+ interface NearResult {
109
+ a: Match;
110
+ b: Match;
111
+ /** Characters between the two matches (0 when adjacent). */
112
+ gap: number;
113
+ }
114
+ /** Sentence boundaries as [start, end) offsets into the NFC text. "." ends a sentence only before a space or the end. */
115
+ declare function sentenceSpans(text: string): [number, number][];
116
+ /**
117
+ * The closest pair of an `a` match and a `b` match within `maxChars` of each other
118
+ * (in either order), or null. With `sameSentence` (default) the pair must share a sentence.
119
+ */
120
+ declare function near(text: string, a: TermInput | readonly TermInput[], b: TermInput | readonly TermInput[], maxCharsOrOpts?: number | NearOptions, sameSentence?: boolean): NearResult | null;
121
+
122
+ export { type DistrictTerm, type Match, type MatchOptions, type Matcher, type NearOptions, type NearResult, type NormaliseOptions, POSTPOSITIONS, type TermInput, VERSION, contains, createMatcher, districtTerms, findTerms, near, normaliseNe, normalizeNe, sentenceSpans, splitSuffix };
@@ -0,0 +1,122 @@
1
+ interface DistrictTerm {
2
+ id: string;
3
+ en: string[];
4
+ ne: string[];
5
+ province: number;
6
+ /** The Nepali name is also an everyday word (पर्वत = mountain): confirm with context before tagging. */
7
+ ambiguous?: boolean;
8
+ caseSensitive: true;
9
+ }
10
+ /** Every district as a {@link TermInput}: ids are slugs ("nawalparasi-east"), English is exact-case. */
11
+ declare function districtTerms(): DistrictTerm[];
12
+
13
+ /**
14
+ * Nepali / English matching for names and keywords in running text.
15
+ *
16
+ * normaliseNe fold spelling variants (chandrabindu, half nasals, long/short vowels, nukta, ZWJ)
17
+ * createMatcher whole-word matching that lets Nepali postpositions follow a word
18
+ * (झापाको → Jhapa) but nothing else (पर्वतारोही ≠ Parbat), and keeps short
19
+ * English acronyms case-sensitive (SEE ≠ "see")
20
+ * near two terms within N characters, optionally in the same sentence
21
+ *
22
+ * Every match carries offsets into the ORIGINAL text, so callers can highlight or cut.
23
+ */
24
+ declare const VERSION = "1.0.0";
25
+ interface NormaliseOptions {
26
+ /** Also fold श/ष → स, व → ब and ण → न. Default false. */
27
+ loose?: boolean;
28
+ /** Devanagari digits ०-९ → 0-9. Default true. */
29
+ digits?: boolean;
30
+ }
31
+ /**
32
+ * Fold Nepali spelling variants so equivalent spellings compare equal:
33
+ * NFC; chandrabindu → anusvara; half nasal + consonant → anusvara; ई/ी → इ/ि and ऊ/ू → उ/ु;
34
+ * nukta, ZWJ, ZWNJ and soft hyphens removed; Devanagari digits → ASCII; whitespace collapsed.
35
+ * Latin text passes through unchanged (case included).
36
+ */
37
+ declare function normaliseNe(text: string, opts?: NormaliseOptions): string;
38
+ /** US spelling alias. */
39
+ declare const normalizeNe: typeof normaliseNe;
40
+ /**
41
+ * Words that may be glued to the end of a Nepali name without making it a different word.
42
+ * Matching allows a chain of up to three (जिल्लाहरूमा, काठमाडौंबाटै).
43
+ */
44
+ declare const POSTPOSITIONS: readonly string[];
45
+ /** A term to look for: a plain string, or an id with English and/or Nepali spellings. */
46
+ type TermInput = string | {
47
+ id?: string;
48
+ en?: string | readonly string[];
49
+ ne?: string | readonly string[];
50
+ /** Extra spellings in either script. */
51
+ aliases?: readonly string[];
52
+ /** English case rule for this term. Default "auto": all-caps terms up to 5 letters are exact-case. */
53
+ caseSensitive?: boolean | "auto";
54
+ };
55
+ interface MatchOptions extends NormaliseOptions {
56
+ /** Default English case rule. Default "auto". */
57
+ caseSensitive?: boolean | "auto";
58
+ /** Allow Nepali postpositions after a word. Default true. */
59
+ postpositions?: boolean;
60
+ /** Extra suffixes to allow on top of {@link POSTPOSITIONS}. */
61
+ extraSuffixes?: readonly string[];
62
+ /** Keep overlapping matches; by default the longest wins. */
63
+ overlaps?: boolean;
64
+ }
65
+ interface Match {
66
+ /** The term's id (or the spelling itself for plain-string terms). */
67
+ id: string;
68
+ /** The spelling that matched, as given. */
69
+ term: string;
70
+ lang: "ne" | "en";
71
+ /** Offsets into the original text; `text` is `original.slice(index, end)`, suffix included. */
72
+ index: number;
73
+ end: number;
74
+ text: string;
75
+ /** The postposition chain after the word, normalised (e.g. "मा", "हरुमा"). */
76
+ suffix?: string;
77
+ }
78
+ interface Matcher {
79
+ /** Every match in `text`, in order of position. */
80
+ find(text: string): Match[];
81
+ /** True when any term (or the term with this id) occurs. */
82
+ test(text: string, id?: string): boolean;
83
+ /** Distinct ids found, in order of first appearance. */
84
+ ids(text: string): string[];
85
+ readonly size: number;
86
+ }
87
+ /** Compile a set of terms once; reuse the matcher across many texts. */
88
+ declare function createMatcher(terms: readonly TermInput[], opts?: MatchOptions): Matcher;
89
+ /** One-off: every match of `terms` in `text`. Compile with {@link createMatcher} for repeated use. */
90
+ declare function findTerms(text: string, terms: TermInput | readonly TermInput[], opts?: MatchOptions): Match[];
91
+ /** One-off: does `term` occur in `text` as a whole word (Nepali postpositions allowed)? */
92
+ declare function contains(text: string, term: TermInput | readonly TermInput[], opts?: MatchOptions): boolean;
93
+ /**
94
+ * Split a Nepali word into its stem and trailing postpositions:
95
+ * `splitSuffix("जिल्लाहरूमा")` → `{ stem: "जिल्ला", suffixes: ["हरु", "मा"] }` (suffixes normalised).
96
+ * Only splits when the whole tail is postpositions; the stem keeps the original spelling.
97
+ */
98
+ declare function splitSuffix(word: string): {
99
+ stem: string;
100
+ suffixes: string[];
101
+ };
102
+ interface NearOptions extends MatchOptions {
103
+ /** Max characters between the end of one match and the start of the other. Default 60. */
104
+ maxChars?: number;
105
+ /** Require both in the same sentence (। ॥ . ? ! or a newline ends one). Default true. */
106
+ sameSentence?: boolean;
107
+ }
108
+ interface NearResult {
109
+ a: Match;
110
+ b: Match;
111
+ /** Characters between the two matches (0 when adjacent). */
112
+ gap: number;
113
+ }
114
+ /** Sentence boundaries as [start, end) offsets into the NFC text. "." ends a sentence only before a space or the end. */
115
+ declare function sentenceSpans(text: string): [number, number][];
116
+ /**
117
+ * The closest pair of an `a` match and a `b` match within `maxChars` of each other
118
+ * (in either order), or null. With `sameSentence` (default) the pair must share a sentence.
119
+ */
120
+ declare function near(text: string, a: TermInput | readonly TermInput[], b: TermInput | readonly TermInput[], maxCharsOrOpts?: number | NearOptions, sameSentence?: boolean): NearResult | null;
121
+
122
+ export { type DistrictTerm, type Match, type MatchOptions, type Matcher, type NearOptions, type NearResult, type NormaliseOptions, POSTPOSITIONS, type TermInput, VERSION, contains, createMatcher, districtTerms, findTerms, near, normaliseNe, normalizeNe, sentenceSpans, splitSuffix };