kordoc 2.7.2 → 2.8.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.
Files changed (57) hide show
  1. package/README.md +450 -450
  2. package/dist/{chunk-4NWDJGAU.js → chunk-3QA624ON.js} +52 -25
  3. package/dist/chunk-3QA624ON.js.map +1 -0
  4. package/dist/{chunk-MEPHGCPQ.js → chunk-5CJGKKMZ.js} +1 -1
  5. package/dist/chunk-5CJGKKMZ.js.map +1 -0
  6. package/dist/{chunk-LB7E2KDF.js → chunk-DLQY6FJH.js} +2 -2
  7. package/dist/chunk-DLQY6FJH.js.map +1 -0
  8. package/dist/{chunk-Y476BOHI.cjs → chunk-HXWPJPRO.cjs} +2 -2
  9. package/dist/chunk-HXWPJPRO.cjs.map +1 -0
  10. package/dist/chunk-MOL7MDBG.js +0 -0
  11. package/dist/chunk-MUOQXDZ4.cjs.map +1 -1
  12. package/dist/{chunk-4SK2PDMQ.js → chunk-XSF3N6GU.js} +2 -2
  13. package/dist/chunk-XSF3N6GU.js.map +1 -0
  14. package/dist/cli.js +4 -4
  15. package/dist/cli.js.map +1 -1
  16. package/dist/{detect-RI2MQ33K.js → detect-PJZMUL2Z.js} +2 -2
  17. package/dist/formula-JCNF43NE.js +0 -0
  18. package/dist/formula-XGG6ZP42.cjs.map +1 -1
  19. package/dist/index.cjs +160 -133
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +28 -2
  22. package/dist/index.d.ts +28 -2
  23. package/dist/index.js +50 -23
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp.js +5 -5
  26. package/dist/mcp.js.map +1 -1
  27. package/dist/page-range-3C7UGGEK.cjs.map +1 -1
  28. package/dist/page-range-737B4EZW.js +0 -0
  29. package/dist/{parser-7OFQ67QL.cjs → parser-LKF6PGPD.cjs} +16 -16
  30. package/dist/parser-LKF6PGPD.cjs.map +1 -0
  31. package/dist/{parser-QMMQ7Y7R.js → parser-UCO6WPUW.js} +3 -3
  32. package/dist/parser-UCO6WPUW.js.map +1 -0
  33. package/dist/{parser-DJCMY3OO.js → parser-ZQQM6J7T.js} +3 -3
  34. package/dist/parser-ZQQM6J7T.js.map +1 -0
  35. package/dist/{provider-AKROB7WQ.js → provider-7H4CPZYS.js} +1 -1
  36. package/dist/provider-7H4CPZYS.js.map +1 -0
  37. package/dist/{provider-2SEHU2FM.js → provider-WPIYEALY.js} +1 -1
  38. package/dist/provider-WPIYEALY.js.map +1 -0
  39. package/dist/{provider-SNONEZNW.cjs → provider-YN2SSK4X.cjs} +1 -1
  40. package/dist/provider-YN2SSK4X.cjs.map +1 -0
  41. package/dist/setup-57FB3LSP.js +0 -0
  42. package/dist/{watch-FVMVIZ5Q.js → watch-MRHNFJPC.js} +4 -4
  43. package/dist/watch-MRHNFJPC.js.map +1 -0
  44. package/package.json +98 -98
  45. package/dist/chunk-4NWDJGAU.js.map +0 -1
  46. package/dist/chunk-4SK2PDMQ.js.map +0 -1
  47. package/dist/chunk-LB7E2KDF.js.map +0 -1
  48. package/dist/chunk-MEPHGCPQ.js.map +0 -1
  49. package/dist/chunk-Y476BOHI.cjs.map +0 -1
  50. package/dist/parser-7OFQ67QL.cjs.map +0 -1
  51. package/dist/parser-DJCMY3OO.js.map +0 -1
  52. package/dist/parser-QMMQ7Y7R.js.map +0 -1
  53. package/dist/provider-2SEHU2FM.js.map +0 -1
  54. package/dist/provider-AKROB7WQ.js.map +0 -1
  55. package/dist/provider-SNONEZNW.cjs.map +0 -1
  56. package/dist/watch-FVMVIZ5Q.js.map +0 -1
  57. /package/dist/{detect-RI2MQ33K.js.map → detect-PJZMUL2Z.js.map} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/detect.ts","../src/hwp5/cfb-lenient.ts","../src/hwpx/parser.ts","../src/hwpx/com-fallback.ts","../src/hwpx/equation.ts","../src/hwp5/record.ts","../src/hwp5/aes.ts","../src/hwp5/crypto.ts","../src/hwp5/equation.ts","../src/hwp5/parser.ts","../src/hwp3/parser.ts","../src/hwp3/johab-symbols.ts","../src/hwp3/johab.ts","../src/hwp3/reader.ts","../src/hwp3/records.ts","../src/hwp5/sentinel.ts","../src/xlsx/parser.ts","../src/xls/record.ts","../src/xls/encoding.ts","../src/xls/sst.ts","../src/xls/cell.ts","../src/xls/parser.ts","../src/docx/parser.ts","../src/docx/equation.ts","../src/hwpml/parser.ts","../src/form/recognize.ts","../src/form/match.ts","../src/form/filler.ts","../src/form/filler-hwpx.ts","../src/hwpx/generator.ts","../src/diff/text-diff.ts","../src/diff/compare.ts","../src/print/renderer.ts"],"sourcesContent":["/**\n * kordoc — 모두 파싱해버리겠다\n *\n * HWP, HWPX, PDF → Markdown 변환 통합 라이브러리\n */\n\nimport { readFile } from \"fs/promises\"\nimport { detectFormat, detectOle2Format, detectZipFormat, isHwpxFile, isOldHwpFile, isPdfFile, isZipFile } from \"./detect.js\"\nimport { parseHwpxDocument } from \"./hwpx/parser.js\"\nimport { parseHwp5Document } from \"./hwp5/parser.js\"\nimport { parseHwp3Document } from \"./hwp3/parser.js\"\nimport { isComFallbackAvailable, extractTextViaCom, comResultToParseResult } from \"./hwpx/com-fallback.js\"\nimport { isDistributionSentinel } from \"./hwp5/sentinel.js\"\n// pdfjs-dist는 optional peer dep (37MB) — PDF 안 쓰는 사용자를 위해 dynamic import\n// import { parsePdfDocument } from \"./pdf/parser.js\"\nimport { parseXlsxDocument } from \"./xlsx/parser.js\"\nimport { parseXlsDocument } from \"./xls/parser.js\"\nimport { parseDocxDocument } from \"./docx/parser.js\"\nimport { parseHwpmlDocument } from \"./hwpml/parser.js\"\nimport type { ParseResult, ParseOptions } from \"./types.js\"\nimport { classifyError, toArrayBuffer } from \"./utils.js\"\nimport { fillFormFields } from \"./form/filler.js\"\nimport type { FillResult } from \"./form/filler.js\"\nimport { fillHwpx } from \"./form/filler-hwpx.js\"\nimport type { HwpxFillResult } from \"./form/filler-hwpx.js\"\nimport { blocksToMarkdown } from \"./table/builder.js\"\nimport { markdownToHwpx } from \"./hwpx/generator.js\"\n\n// ─── 메인 API ────────────────────────────────────────\n\n/**\n * 파일 버퍼를 자동 감지하여 Markdown으로 변환\n *\n * @example\n * ```ts\n * import { parse } from \"kordoc\"\n * // 파일 경로로 파싱\n * const result = await parse(\"document.hwp\")\n * // 또는 Buffer로 파싱\n * const result = await parse(buffer)\n * ```\n */\nexport async function parse(input: string | ArrayBuffer | Buffer, options?: ParseOptions): Promise<ParseResult> {\n let buffer: ArrayBuffer\n // 파일 경로 입력 시 filePath를 options에 자동 설정 (DRM COM fallback에 필요)\n const opts = typeof input === \"string\" && !options?.filePath\n ? { ...options, filePath: input }\n : options\n if (typeof input === \"string\") {\n try {\n const buf = await readFile(input)\n buffer = toArrayBuffer(buf)\n } catch (err) {\n const msg = err instanceof Error && \"code\" in err && (err as NodeJS.ErrnoException).code === \"ENOENT\"\n ? `파일을 찾을 수 없습니다: ${input}`\n : `파일 읽기 실패: ${input}`\n return { success: false, fileType: \"unknown\", error: msg, code: \"PARSE_ERROR\" }\n }\n } else if (Buffer.isBuffer(input)) {\n buffer = toArrayBuffer(input)\n } else {\n buffer = input\n }\n\n if (!buffer || buffer.byteLength === 0) {\n return { success: false, fileType: \"unknown\", error: \"빈 버퍼이거나 유효하지 않은 입력입니다.\", code: \"EMPTY_INPUT\" }\n }\n const format = detectFormat(buffer)\n\n switch (format) {\n case \"hwpx\": {\n // ZIP 기반 포맷 세분화: HWPX, XLSX, DOCX 구분\n const zipFormat = await detectZipFormat(buffer)\n if (zipFormat === \"xlsx\") return parseXlsx(buffer, opts)\n if (zipFormat === \"docx\") return parseDocx(buffer, opts)\n return parseHwpx(buffer, opts)\n }\n case \"hwp\": {\n // OLE2 기반 포맷 세분화: HWP 5.x vs XLS (Excel 97-2003)\n const ole2Format = detectOle2Format(buffer)\n if (ole2Format === \"xls\") return parseXls(buffer, opts)\n return parseHwp(buffer, opts)\n }\n case \"hwp3\":\n return parseHwp3(buffer, opts)\n case \"hwpml\":\n return parseHwpml(buffer, opts)\n case \"pdf\":\n return parsePdf(buffer, opts)\n default:\n return { success: false, fileType: \"unknown\", error: \"지원하지 않는 파일 형식입니다.\", code: \"UNSUPPORTED_FORMAT\" }\n }\n}\n\n/** HWP 3.x (구버전 한컴 워드프로세서) 파일을 Markdown 으로 변환. */\nexport async function parseHwp3(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n try {\n const { markdown, blocks, metadata, outline, warnings } = parseHwp3Document(buffer, options)\n return { success: true, fileType: \"hwp3\", markdown, blocks, metadata, outline, warnings }\n } catch (err) {\n return { success: false, fileType: \"hwp3\", error: err instanceof Error ? err.message : \"HWP3 파싱 실패\", code: classifyError(err) }\n }\n}\n\n// ─── 포맷별 API ──────────────────────────────────────\n\n/** HWPX 파일을 Markdown으로 변환 */\nexport async function parseHwpx(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n try {\n const { markdown, blocks, metadata, outline, warnings, images } = await parseHwpxDocument(buffer, options)\n return { success: true, fileType: \"hwpx\", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : undefined }\n } catch (err) {\n return { success: false, fileType: \"hwpx\", error: err instanceof Error ? err.message : \"HWPX 파싱 실패\", code: classifyError(err) }\n }\n}\n\n/** HWP 5.x 바이너리 파일을 Markdown으로 변환 */\nexport async function parseHwp(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n try {\n const { markdown, blocks, metadata, outline, warnings, images } = parseHwp5Document(Buffer.from(buffer), options)\n\n // 배포용 HWP 5.x 감지 — 본문이 \"상위 버전의 배포용 문서입니다...\" 플레이스홀더뿐이면\n // COM fallback으로 재시도 (Windows + 한컴오피스 환경에서만). 이슈 #25 대응.\n if (isDistributionSentinel(markdown) && isComFallbackAvailable() && options?.filePath) {\n try {\n const { pages, pageCount, warnings: comWarns } = extractTextViaCom(options.filePath)\n if (pages.some(p => p && p.trim().length > 0)) {\n const com = comResultToParseResult(pages, pageCount, comWarns)\n return {\n success: true,\n fileType: \"hwp\",\n markdown: com.markdown,\n blocks: com.blocks,\n metadata: com.metadata,\n warnings: com.warnings,\n }\n }\n } catch {\n // COM 실패 시 기존 결과(경고 문자열 포함) 그대로 반환\n }\n }\n\n return { success: true, fileType: \"hwp\", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : undefined }\n } catch (err) {\n return { success: false, fileType: \"hwp\", error: err instanceof Error ? err.message : \"HWP 파싱 실패\", code: classifyError(err) }\n }\n}\n\n/** PDF 파일에서 텍스트를 추출하여 Markdown으로 변환 */\nexport async function parsePdf(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n let parsePdfDocument: typeof import(\"./pdf/parser.js\").parsePdfDocument\n try {\n const mod = await import(\"./pdf/parser.js\")\n parsePdfDocument = mod.parsePdfDocument\n } catch {\n return {\n success: false, fileType: \"pdf\",\n error: \"PDF 파싱에 pdfjs-dist가 필요합니다. 설치: npm install pdfjs-dist\",\n code: \"MISSING_DEPENDENCY\",\n }\n }\n try {\n const { markdown, blocks, metadata, outline, warnings, isImageBased } = await parsePdfDocument(buffer, options)\n return { success: true, fileType: \"pdf\", markdown, blocks, metadata, outline, warnings, isImageBased }\n } catch (err) {\n const isImageBased = err instanceof Error && \"isImageBased\" in err ? true : undefined\n return { success: false, fileType: \"pdf\", error: err instanceof Error ? err.message : \"PDF 파싱 실패\", code: classifyError(err), isImageBased }\n }\n}\n\n/** XLSX 파일을 Markdown으로 변환 */\nexport async function parseXlsx(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n try {\n const { markdown, blocks, metadata, warnings } = await parseXlsxDocument(buffer, options)\n return { success: true, fileType: \"xlsx\", markdown, blocks, metadata, warnings }\n } catch (err) {\n return { success: false, fileType: \"xlsx\", error: err instanceof Error ? err.message : \"XLSX 파싱 실패\", code: classifyError(err) }\n }\n}\n\n/** XLS (Excel 97-2003) 파일을 Markdown으로 변환 */\nexport async function parseXls(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n try {\n const { markdown, blocks, metadata, warnings } = await parseXlsDocument(buffer, options)\n return { success: true, fileType: \"xls\", markdown, blocks, metadata, warnings }\n } catch (err) {\n return { success: false, fileType: \"xls\", error: err instanceof Error ? err.message : \"XLS 파싱 실패\", code: classifyError(err) }\n }\n}\n\n/** DOCX 파일을 Markdown으로 변환 */\nexport async function parseDocx(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n try {\n const { markdown, blocks, metadata, outline, warnings, images } = await parseDocxDocument(buffer, options)\n return { success: true, fileType: \"docx\", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : undefined }\n } catch (err) {\n return { success: false, fileType: \"docx\", error: err instanceof Error ? err.message : \"DOCX 파싱 실패\", code: classifyError(err) }\n }\n}\n\n/** HWPML (XML 기반 한컴 문서) 파일을 Markdown으로 변환 */\nexport async function parseHwpml(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\n try {\n const { markdown, blocks, metadata, outline, warnings } = parseHwpmlDocument(buffer, options)\n return { success: true, fileType: \"hwpml\", markdown, blocks, metadata, outline, warnings }\n } catch (err) {\n return { success: false, fileType: \"hwpml\", error: err instanceof Error ? err.message : \"HWPML 파싱 실패\", code: classifyError(err) }\n }\n}\n\n// ─── 서식 채우기 API ────────────────────────────────\n\n/**\n * 서식 채우기 출력 포맷\n * - \"markdown\": 마크다운 텍스트\n * - \"hwpx\": 새로 생성한 HWPX (스타일 초기화)\n * - \"hwpx-preserve\": 원본 HWPX ZIP 직접 수정 (스타일 100% 보존, HWPX 입력만 가능)\n */\nexport type FillOutputFormat = \"markdown\" | \"hwpx\" | \"hwpx-preserve\"\n\n/** 서식 채우기 결과 */\nexport interface FillFormOutput {\n /** 채워진 문서 (markdown: string, hwpx/hwpx-preserve: ArrayBuffer) */\n output: string | ArrayBuffer\n /** 출력 포맷 */\n format: FillOutputFormat\n /** 채우기 상세 — filled 필드 목록 + unmatched 라벨 */\n fill: { filled: import(\"./types.js\").FormField[]; unmatched: string[] }\n}\n\n/**\n * 서식 문서를 파싱하여 필드를 채우고, 원하는 포맷으로 출력.\n *\n * - \"hwpx-preserve\": HWPX 입력 → 원본 ZIP XML 직접 수정 (테두리/폰트/병합 등 100% 보존)\n * - \"hwpx\": 아무 포맷 → IRBlock → Markdown → HWPX 생성 (스타일 초기화됨)\n * - \"markdown\": 아무 포맷 → IRBlock → Markdown\n *\n * @example\n * ```ts\n * // HWPX 원본 스타일 보존 채우기\n * const result = await fillForm(\"신청서.hwpx\", { \"성명\": \"홍길동\" }, \"hwpx-preserve\")\n * writeFileSync(\"결과.hwpx\", Buffer.from(result.output as ArrayBuffer))\n *\n * // 아무 포맷 → 마크다운 채우기\n * const result = await fillForm(\"신청서.hwp\", { \"성명\": \"홍길동\" })\n * console.log(result.output) // 채워진 마크다운\n * ```\n */\nexport async function fillForm(\n input: string | ArrayBuffer | Buffer,\n values: Record<string, string>,\n outputFormat: FillOutputFormat = \"markdown\",\n): Promise<FillFormOutput> {\n // 입력 버퍼 준비\n let buffer: ArrayBuffer\n if (typeof input === \"string\") {\n const buf = await readFile(input)\n buffer = toArrayBuffer(buf)\n } else if (Buffer.isBuffer(input)) {\n buffer = toArrayBuffer(input)\n } else {\n buffer = input\n }\n\n // hwpx-preserve: 원본 HWPX ZIP 직접 수정 (스타일 보존)\n if (outputFormat === \"hwpx-preserve\") {\n const format = detectFormat(buffer)\n // detectFormat은 ZIP이면 \"hwpx\" 반환 (XLSX/DOCX 포함), 세분화 필요\n if (format === \"hwpx\") {\n const zipFormat = await detectZipFormat(buffer)\n if (zipFormat !== \"hwpx\") {\n throw new Error(`hwpx-preserve 포맷은 HWPX 입력만 지원합니다 (감지된 포맷: ${zipFormat})`)\n }\n } else {\n throw new Error(`hwpx-preserve 포맷은 HWPX 입력만 지원합니다 (감지된 포맷: ${format})`)\n }\n const hwpxResult = await fillHwpx(buffer, values)\n return {\n output: hwpxResult.buffer,\n format: \"hwpx-preserve\",\n fill: { filled: hwpxResult.filled, unmatched: hwpxResult.unmatched },\n }\n }\n\n // 일반 경로: parse → IRBlock → fill → output\n const parsed = await parse(buffer)\n if (!parsed.success) {\n throw new Error(`서식 파싱 실패: ${parsed.error}`)\n }\n\n const fill = fillFormFields(parsed.blocks, values)\n const markdown = blocksToMarkdown(fill.blocks)\n\n if (outputFormat === \"hwpx\") {\n const hwpxBuffer = await markdownToHwpx(markdown)\n return { output: hwpxBuffer, format: \"hwpx\", fill }\n }\n\n return { output: markdown, format: \"markdown\", fill }\n}\n\n// ─── 게임체인저 API ─────────────────────────────────\n\nexport { compare, diffBlocks } from \"./diff/compare.js\"\nexport { extractFormFields, isLabelCell } from \"./form/recognize.js\"\nexport { fillFormFields } from \"./form/filler.js\"\nexport type { FillResult } from \"./form/filler.js\"\nexport { fillHwpx } from \"./form/filler-hwpx.js\"\nexport type { HwpxFillResult } from \"./form/filler-hwpx.js\"\nexport { markdownToHwpx } from \"./hwpx/generator.js\"\nexport { renderHtml, markdownToPdf, blocksToPdf } from \"./print/renderer.js\"\nexport type { PrintPreset, PrintOptions, PageMargin } from \"./print/renderer.js\"\n\n// ─── Re-exports ──────────────────────────────────────\n\nexport { detectFormat, detectOle2Format, detectZipFormat, isHwpxFile, isOldHwpFile, isPdfFile, isZipFile } from \"./detect.js\"\nexport type {\n ParseResult, ParseSuccess, ParseFailure, FileType,\n IRBlock, IRBlockType, IRTable, IRCell, CellContext,\n BoundingBox, InlineStyle, ImageData, ExtractedImage,\n DocumentMetadata, ParseOptions, ErrorCode,\n ParseWarning, WarningCode, OutlineItem,\n DiffResult, BlockDiff, CellDiff, DiffChangeType,\n FormField, FormResult,\n OcrProvider, WatchOptions,\n} from \"./types.js\"\nexport { blocksToMarkdown } from \"./table/builder.js\"\nexport { VERSION } from \"./utils.js\"\n","/** 매직 바이트 기반 파일 포맷 감지 */\n\nimport JSZip from \"jszip\"\nimport type { FileType } from \"./types.js\"\nimport { parseLenientCfb } from \"./hwp5/cfb-lenient.js\"\n\n/** 매직 바이트 뷰 생성 (복사 없이 view) */\nfunction magicBytes(buffer: ArrayBuffer): Uint8Array {\n return new Uint8Array(buffer, 0, Math.min(4, buffer.byteLength))\n}\n\n/** ZIP 파일 여부: PK\\x03\\x04 */\nexport function isZipFile(buffer: ArrayBuffer): boolean {\n const b = magicBytes(buffer)\n return b[0] === 0x50 && b[1] === 0x4b && b[2] === 0x03 && b[3] === 0x04\n}\n\n/** HWPX (ZIP 기반 한컴 문서): PK\\x03\\x04 — 하위 호환용 */\nexport function isHwpxFile(buffer: ArrayBuffer): boolean {\n return isZipFile(buffer)\n}\n\n/** HWP 5.x (OLE2 바이너리 한컴 문서): \\xD0\\xCF\\x11\\xE0 */\nexport function isOldHwpFile(buffer: ArrayBuffer): boolean {\n const b = magicBytes(buffer)\n return b[0] === 0xd0 && b[1] === 0xcf && b[2] === 0x11 && b[3] === 0xe0\n}\n\n/**\n * HWP 3.x (한글 워드프로세서 3.0): \"HWP Document File V3.00 \\x1A\\x01\\x02\\x03\\x04\\x05\" 30 byte.\n * CFB(OLE2) 컨테이너 아닌 단일 binary stream — isOldHwpFile 과 magic 이 다르다.\n */\nconst HWP3_PREFIX = new TextEncoder().encode(\"HWP Document File V3.00\")\nexport function isHwp3File(buffer: ArrayBuffer): boolean {\n if (buffer.byteLength < HWP3_PREFIX.length) return false\n const head = new Uint8Array(buffer, 0, HWP3_PREFIX.length)\n for (let i = 0; i < HWP3_PREFIX.length; i++) {\n if (head[i] !== HWP3_PREFIX[i]) return false\n }\n return true\n}\n\n/** PDF 문서: %PDF */\nexport function isPdfFile(buffer: ArrayBuffer): boolean {\n const b = magicBytes(buffer)\n return b[0] === 0x25 && b[1] === 0x50 && b[2] === 0x44 && b[3] === 0x46\n}\n\n/** HWPML (XML 기반 한컴 문서): <?xml ... <HWPML */\nexport function isHwpmlFile(buffer: ArrayBuffer): boolean {\n const bytes = new Uint8Array(buffer, 0, Math.min(512, buffer.byteLength))\n const head = new TextDecoder(\"utf-8\", { fatal: false }).decode(bytes).replace(/^\\uFEFF/, \"\")\n return head.trimStart().startsWith(\"<?xml\") && head.includes(\"<HWPML\")\n}\n\n/** 동기 포맷 감지 — ZIP은 모두 \"hwpx\"로 반환 (하위 호환) */\nexport function detectFormat(buffer: ArrayBuffer): FileType {\n if (buffer.byteLength < 4) return \"unknown\"\n if (isHwp3File(buffer)) return \"hwp3\"\n if (isZipFile(buffer)) return \"hwpx\"\n if (isOldHwpFile(buffer)) return \"hwp\"\n if (isPdfFile(buffer)) return \"pdf\"\n if (isHwpmlFile(buffer)) return \"hwpml\"\n return \"unknown\"\n}\n\n/**\n * OLE2 컨테이너 내부 스트림 기반 포맷 세분화.\n * HWP 5.x, XLS 모두 OLE2이므로 스트림 이름으로 구분.\n * - \"Workbook\" 또는 \"Book\" → 'xls'\n * - 그 외 (FileHeader 등) → 'hwp'\n */\nexport function detectOle2Format(buffer: ArrayBuffer): \"hwp\" | \"xls\" | \"unknown\" {\n try {\n const cfb = parseLenientCfb(Buffer.from(buffer))\n const names = cfb.entries().map(e => e.name)\n if (names.includes(\"Workbook\") || names.includes(\"Book\")) return \"xls\"\n if (names.includes(\"FileHeader\")) return \"hwp\"\n // FileHeader 없어도 BodyText/DocInfo 있으면 hwp\n if (names.some(n => n === \"DocInfo\" || n.startsWith(\"Section\"))) return \"hwp\"\n return \"unknown\"\n } catch {\n return \"unknown\"\n }\n}\n\n/**\n * ZIP 내부 구조 기반 포맷 세분화.\n * HWPX, XLSX, DOCX 모두 ZIP이므로 내부 파일로 구분.\n */\nexport async function detectZipFormat(buffer: ArrayBuffer): Promise<\"hwpx\" | \"xlsx\" | \"docx\" | \"unknown\"> {\n try {\n const zip = await JSZip.loadAsync(buffer)\n // XLSX: xl/workbook.xml\n if (zip.file(\"xl/workbook.xml\")) return \"xlsx\"\n // DOCX: word/document.xml\n if (zip.file(\"word/document.xml\")) return \"docx\"\n // HWPX: Contents/ 또는 content.hpf 또는 mimetype\n if (zip.file(\"Contents/content.hpf\") || zip.file(\"mimetype\")) return \"hwpx\"\n // 기타 ZIP 내에 section 파일이 있으면 HWPX로 추정\n const hasSection = Object.keys(zip.files).some(f => f.startsWith(\"Contents/\"))\n if (hasSection) return \"hwpx\"\n return \"unknown\"\n } catch {\n return \"unknown\"\n }\n}\n","/**\n * Lenient CFB (Compound File Binary / OLE2) 파서.\n *\n * 표준 cfb 모듈이 FAT 검증 실패로 거부하는 손상된 HWP 파일을 열기 위한 폴백.\n * 직접 헤더/FAT/디렉토리를 파싱하여 스트림 데이터를 추출.\n *\n * 참조: rhwp (MIT) src/parser/cfb_reader.rs (LenientCfbReader)\n * 참조: MS-CFB spec (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb)\n */\n\nimport { decompressStream } from \"./record.js\"\n\n// ── 상수 ──\n\nconst CFB_MAGIC = Buffer.from([0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1])\nconst END_OF_CHAIN = 0xfffffffe\nconst FREE_SECT = 0xffffffff\n\n/** 순환 감지용 최대 체인 길이 */\nconst MAX_CHAIN_LENGTH = 1_000_000\n/** 최대 디렉토리 엔트리 수 */\nconst MAX_DIR_ENTRIES = 100_000\n/** 최대 스트림 크기 (100MB) */\nconst MAX_STREAM_SIZE = 100 * 1024 * 1024\n\n// ── 디렉토리 엔트리 ──\n\ninterface DirEntry {\n name: string\n type: number // 0=unknown, 1=storage, 2=stream, 5=root\n startSector: number\n size: number\n}\n\n// ── CFB 컨테이너 ──\n\nexport interface LenientCfbContainer {\n /** 이름 기반 스트림 탐색 */\n findStream(path: string): Buffer | null\n /** 디렉토리 엔트리 목록 */\n entries(): DirEntry[]\n}\n\n// ── 구현 ──\n\nexport function parseLenientCfb(data: Buffer): LenientCfbContainer {\n if (data.length < 512) throw new Error(\"CFB 파일이 너무 짧습니다 (최소 512바이트)\")\n if (!data.subarray(0, 8).equals(CFB_MAGIC)) throw new Error(\"CFB 매직 바이트 불일치\")\n\n // ── 헤더 파싱 ──\n\n const sectorSizeShift = data.readUInt16LE(30)\n if (sectorSizeShift < 7 || sectorSizeShift > 16) throw new Error(\"유효하지 않은 섹터 크기 시프트: \" + sectorSizeShift)\n const sectorSize = 1 << sectorSizeShift // 보통 512\n const miniSectorSizeShift = data.readUInt16LE(32)\n if (miniSectorSizeShift > 16) throw new Error(\"유효하지 않은 미니 섹터 크기 시프트: \" + miniSectorSizeShift)\n const miniSectorSize = 1 << miniSectorSizeShift // 보통 64\n\n const fatSectorCount = data.readUInt32LE(44)\n if (fatSectorCount > 10000) throw new Error(\"FAT 섹터 수가 너무 많습니다: \" + fatSectorCount)\n const firstDirSector = data.readUInt32LE(48)\n const miniStreamCutoff = data.readUInt32LE(56) // 보통 4096\n const firstMiniFatSector = data.readUInt32LE(60)\n const miniFatSectorCount = data.readUInt32LE(64)\n const firstDifatSector = data.readUInt32LE(68)\n const difatSectorCount = data.readUInt32LE(72)\n\n // ── 유틸 ──\n\n function sectorOffset(id: number): number {\n return 512 + id * sectorSize\n }\n\n function readSectorData(id: number): Buffer {\n const off = sectorOffset(id)\n if (off + sectorSize > data.length) return Buffer.alloc(0)\n return data.subarray(off, off + sectorSize)\n }\n\n // ── DIFAT → FAT 섹터 목록 ──\n\n const fatSectors: number[] = []\n\n // 헤더 내 DIFAT (최대 109개)\n for (let i = 0; i < 109 && fatSectors.length < fatSectorCount; i++) {\n const sid = data.readUInt32LE(76 + i * 4)\n if (sid === FREE_SECT || sid === END_OF_CHAIN) break\n fatSectors.push(sid)\n }\n\n // 추가 DIFAT 섹터 체인\n let difatSector = firstDifatSector\n const visitedDifat = new Set<number>()\n for (let d = 0; d < difatSectorCount && difatSector !== END_OF_CHAIN && difatSector !== FREE_SECT; d++) {\n if (visitedDifat.has(difatSector)) break\n visitedDifat.add(difatSector)\n\n const buf = readSectorData(difatSector)\n const entriesPerSector = (sectorSize / 4) - 1 // 마지막 4바이트는 다음 DIFAT 포인터\n for (let i = 0; i < entriesPerSector && fatSectors.length < fatSectorCount; i++) {\n const sid = buf.readUInt32LE(i * 4)\n if (sid === FREE_SECT || sid === END_OF_CHAIN) continue\n fatSectors.push(sid)\n }\n difatSector = buf.readUInt32LE(entriesPerSector * 4)\n }\n\n // ── FAT 테이블 구축 ──\n\n const entriesPerFatSector = sectorSize / 4\n const fatTable = new Uint32Array(fatSectors.length * entriesPerFatSector)\n\n for (let fi = 0; fi < fatSectors.length; fi++) {\n const buf = readSectorData(fatSectors[fi])\n for (let i = 0; i < entriesPerFatSector; i++) {\n fatTable[fi * entriesPerFatSector + i] = i * 4 + 3 < buf.length\n ? buf.readUInt32LE(i * 4)\n : FREE_SECT\n }\n }\n\n // ── 체인 리더 (순환 방지) ──\n\n function readChain(startSector: number, maxBytes: number): Buffer {\n if (startSector === END_OF_CHAIN || startSector === FREE_SECT) return Buffer.alloc(0)\n if (maxBytes > MAX_STREAM_SIZE) throw new Error(\"스트림이 너무 큽니다\")\n\n const chunks: Buffer[] = []\n let current = startSector\n let totalRead = 0\n const visited = new Set<number>()\n\n while (current !== END_OF_CHAIN && current !== FREE_SECT && totalRead < maxBytes) {\n if (visited.has(current)) break // 순환 감지\n if (visited.size > MAX_CHAIN_LENGTH) break\n visited.add(current)\n\n const buf = readSectorData(current)\n const remaining = maxBytes - totalRead\n chunks.push(remaining < sectorSize ? buf.subarray(0, remaining) : buf)\n totalRead += Math.min(buf.length, remaining)\n\n current = current < fatTable.length ? fatTable[current] : END_OF_CHAIN\n }\n\n return Buffer.concat(chunks)\n }\n\n // ── Mini-FAT 테이블 ──\n\n let miniFatTable: Uint32Array | null = null\n\n function getMiniFatTable(): Uint32Array {\n if (miniFatTable) return miniFatTable\n\n if (miniFatSectorCount === 0 || firstMiniFatSector === END_OF_CHAIN) {\n miniFatTable = new Uint32Array(0)\n return miniFatTable\n }\n\n const miniFatData = readChain(firstMiniFatSector, miniFatSectorCount * sectorSize)\n const entries = miniFatData.length / 4\n miniFatTable = new Uint32Array(entries)\n for (let i = 0; i < entries; i++) {\n miniFatTable[i] = miniFatData.readUInt32LE(i * 4)\n }\n return miniFatTable\n }\n\n // ── 디렉토리 엔트리 파싱 ──\n\n const dirData = readChain(firstDirSector, MAX_DIR_ENTRIES * 128)\n const dirEntries: DirEntry[] = []\n\n for (let offset = 0; offset + 128 <= dirData.length && dirEntries.length < MAX_DIR_ENTRIES; offset += 128) {\n const nameLen = dirData.readUInt16LE(offset + 64) // 바이트 수 (null 포함)\n if (nameLen <= 0 || nameLen > 64) {\n dirEntries.push({ name: \"\", type: 0, startSector: 0, size: 0 })\n continue\n }\n\n const nameBytes = nameLen - 2 // null terminator 제외\n const name = nameBytes > 0\n ? dirData.subarray(offset, offset + nameBytes).toString(\"utf16le\")\n : \"\"\n\n const type = dirData[offset + 66]\n const startSector = dirData.readUInt32LE(offset + 116)\n // CFBv3에서는 size가 u32 (offset 120), v4에서는 u64\n const size = dirData.readUInt32LE(offset + 120)\n\n dirEntries.push({ name, type, startSector, size })\n }\n\n // ── Root 엔트리에서 미니 스트림 추출 ──\n\n let miniStreamData: Buffer | null = null\n\n function getMiniStream(): Buffer {\n if (miniStreamData) return miniStreamData\n const root = dirEntries[0]\n if (!root || root.type !== 5) {\n miniStreamData = Buffer.alloc(0)\n return miniStreamData\n }\n miniStreamData = readChain(root.startSector, root.size || MAX_STREAM_SIZE)\n return miniStreamData\n }\n\n // ── 미니 스트림에서 읽기 ──\n\n function readMiniStream(startSector: number, size: number): Buffer {\n const mft = getMiniFatTable()\n const ms = getMiniStream()\n if (mft.length === 0 || ms.length === 0) return Buffer.alloc(0)\n\n const chunks: Buffer[] = []\n let current = startSector\n let totalRead = 0\n const visited = new Set<number>()\n\n while (current !== END_OF_CHAIN && current !== FREE_SECT && totalRead < size) {\n if (visited.has(current)) break\n if (visited.size > MAX_CHAIN_LENGTH) break\n visited.add(current)\n\n const off = current * miniSectorSize\n const remaining = size - totalRead\n const chunkSize = Math.min(miniSectorSize, remaining)\n if (off + chunkSize <= ms.length) {\n chunks.push(ms.subarray(off, off + chunkSize))\n }\n totalRead += chunkSize\n\n current = current < mft.length ? mft[current] : END_OF_CHAIN\n }\n\n return Buffer.concat(chunks)\n }\n\n // ── 스트림 읽기 (일반/미니 자동 분기) ──\n\n function readStreamData(entry: DirEntry): Buffer {\n if (entry.size === 0) return Buffer.alloc(0)\n if (entry.size < miniStreamCutoff) {\n const miniResult = readMiniStream(entry.startSector, entry.size)\n // 미니스트림이 비어있으면 일반 체인으로 폴백 (lenient)\n if (miniResult.length > 0) return miniResult\n }\n return readChain(entry.startSector, entry.size)\n }\n\n // ── 경로 기반 탐색 ──\n\n // 전체 경로 맵 구축 (간이: 이름 기반 flat lookup)\n // HWP 파일의 디렉토리 구조는 보통 1~2 depth이므로 이름 매칭으로 충분\n function findEntryByPath(path: string): DirEntry | null {\n // \"/FileHeader\" → \"FileHeader\"\n // \"/BodyText/Section0\" → path component matching\n const parts = path.replace(/^\\//, \"\").split(\"/\")\n\n if (parts.length === 1) {\n // 단일 이름 매칭\n return dirEntries.find(e => e.name === parts[0] && e.type === 2) ?? null\n }\n\n // 2-depth: storage/stream\n // HWP 구조: Root/BodyText/Section0, Root/DocInfo, Root/BinData/BIN0001 등\n const storageName = parts[0]\n const streamName = parts.slice(1).join(\"/\")\n\n // 디렉토리 구조 대신 이름 패턴으로 찾기 (lenient)\n for (const e of dirEntries) {\n if (e.type === 2 && e.name === streamName) {\n // 부모 확인은 생략 (lenient) — 중복 이름 시 첫 번째 반환\n return e\n }\n }\n\n // 정확한 이름이 아닌 경우 (ViewText/Section0 등)\n const lastPart = parts[parts.length - 1]\n return dirEntries.find(e => e.type === 2 && e.name === lastPart) ?? null\n }\n\n // ── 공개 API ──\n\n return {\n findStream(path: string): Buffer | null {\n // \\005 prefix 처리 (SummaryInformation)\n const normalized = path.replace(/^\\//, \"\")\n const entry = findEntryByPath(normalized)\n if (!entry || entry.type !== 2) return null\n const stream = readStreamData(entry)\n return stream.length > 0 ? stream : null\n },\n\n entries(): DirEntry[] {\n return dirEntries.filter(e => e.type === 2) // stream만\n },\n }\n}\n","/**\n * HWPX 파서 — manifest 멀티섹션, colSpan/rowSpan, 중첩테이블\n *\n * lexdiff 기반 + edu-facility-ai 손상ZIP 복구\n */\n\nimport JSZip from \"jszip\"\nimport { inflateRawSync } from \"zlib\"\nimport { DOMParser } from \"@xmldom/xmldom\"\nimport { buildTable, convertTableToText, blocksToMarkdown, MAX_COLS, MAX_ROWS } from \"../table/builder.js\"\nimport type { CellContext, IRBlock, DocumentMetadata, InternalParseResult, ParseOptions, ParseWarning, OutlineItem, InlineStyle, ExtractedImage } from \"../types.js\"\nimport { HEADING_RATIO_H1, HEADING_RATIO_H2, HEADING_RATIO_H3 } from \"../types.js\"\nimport { KordocError, isPathTraversal, sanitizeHref, precheckZipSize, stripDtd } from \"../utils.js\"\n// 테스트 호환성 re-export\nexport { precheckZipSize } from \"../utils.js\"\nimport { parsePageRange } from \"../page-range.js\"\nimport { isComFallbackAvailable, isEncryptedHwpx, extractTextViaCom, comResultToParseResult } from \"./com-fallback.js\"\nimport { hmlToLatex } from \"./equation.js\"\n\n/** 압축 해제 최대 크기 (100MB) — ZIP bomb 방지 */\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\n/** 손상 ZIP 복구 시 최대 엔트리 수 */\nconst MAX_ZIP_ENTRIES = 500\n\n/** colSpan/rowSpan을 안전한 범위로 클램핑 */\nfunction clampSpan(val: number, max: number): number {\n return Math.max(1, Math.min(val, max))\n}\n\n/** XML DOM 재귀 최대 깊이 — 악성 파일의 스택 오버플로 방지 */\nconst MAX_XML_DEPTH = 200\n\ninterface TableState { rows: CellContext[][]; currentRow: CellContext[]; cell: CellContext | null }\n\n/** walk 함수들이 공유하는 파싱 컨텍스트 — 개별 optional 파라미터를 하나로 묶어 시그니처 안정화 */\ninterface WalkCtx {\n styleMap?: HwpxStyleMap\n warnings?: ParseWarning[]\n sectionNum?: number\n counter?: { count: number }\n}\n\n/** xmldom DOMParser 생성 — onError 콜백으로 malformed XML 경고 수집 */\nfunction createXmlParser(warnings?: ParseWarning[]): DOMParser {\n return new DOMParser({\n onError(level: \"warn\" | \"error\" | \"fatalError\", msg: string) {\n if (level === \"fatalError\") throw new KordocError(`XML 파싱 실패: ${msg}`)\n warnings?.push({ code: \"MALFORMED_XML\", message: `XML ${level === \"warn\" ? \"경고\" : \"오류\"}: ${msg}` })\n },\n })\n}\n\n// ─── HWPX 스타일 정보 ──────────────────────────────\n\ninterface HwpxCharProperty {\n fontSize?: number // 단위: pt (hwpx는 centi-pt → /100)\n bold?: boolean\n italic?: boolean\n fontName?: string\n}\n\ninterface HwpxStyleMap {\n charProperties: Map<string, HwpxCharProperty> // id → property\n styles: Map<string, { name: string; charPrId?: string; paraPrId?: string }> // id → style\n}\n\n/** head.xml 또는 header.xml에서 스타일 정보 추출 */\nasync function extractHwpxStyles(zip: JSZip, decompressed?: { total: number }): Promise<HwpxStyleMap> {\n const result: HwpxStyleMap = {\n charProperties: new Map(),\n styles: new Map(),\n }\n\n const headerPaths = [\"Contents/header.xml\", \"header.xml\", \"Contents/head.xml\", \"head.xml\"]\n for (const hp of headerPaths) {\n const hpLower = hp.toLowerCase()\n const file = zip.file(hp) || Object.values(zip.files).find(f => f.name.toLowerCase() === hpLower) || null\n if (!file) continue\n\n try {\n const xml = await file.async(\"text\")\n if (decompressed) {\n decompressed.total += xml.length * 2\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\n }\n const parser = createXmlParser()\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\n if (!doc.documentElement) continue\n\n // charProperties 파싱\n parseCharProperties(doc, result.charProperties)\n // styles 파싱\n parseStyleElements(doc, result.styles)\n break\n } catch { continue }\n }\n\n return result\n}\n\nfunction parseCharProperties(doc: Document, map: Map<string, HwpxCharProperty>): void {\n // <hh:charPr> 또는 <charPr> 요소 탐색\n const tagNames = [\"hh:charPr\", \"charPr\", \"hp:charPr\"]\n for (const tagName of tagNames) {\n const elements = doc.getElementsByTagName(tagName)\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i]\n const id = el.getAttribute(\"id\") || el.getAttribute(\"IDRef\") || \"\"\n if (!id) continue\n\n const prop: HwpxCharProperty = {}\n\n // height 속성 (centi-pt 단위)\n const height = el.getAttribute(\"height\")\n if (height) {\n const parsedHeight = parseInt(height, 10)\n if (!isNaN(parsedHeight) && parsedHeight > 0) {\n prop.fontSize = parsedHeight / 100\n }\n }\n\n // bold/italic\n const bold = el.getAttribute(\"bold\")\n if (bold === \"true\" || bold === \"1\") prop.bold = true\n const italic = el.getAttribute(\"italic\")\n if (italic === \"true\" || italic === \"1\") prop.italic = true\n\n // 하위 요소에서 fontface 탐색\n const fontFaces = el.getElementsByTagName(\"*\")\n for (let j = 0; j < fontFaces.length; j++) {\n const ff = fontFaces[j]\n const localTag = (ff.tagName || \"\").replace(/^[^:]+:/, \"\")\n if (localTag === \"fontface\" || localTag === \"fontRef\") {\n const face = ff.getAttribute(\"face\") || ff.getAttribute(\"FontFace\")\n if (face) { prop.fontName = face; break }\n }\n }\n\n map.set(id, prop)\n }\n }\n}\n\nfunction parseStyleElements(doc: Document, map: Map<string, { name: string; charPrId?: string; paraPrId?: string }>): void {\n const tagNames = [\"hh:style\", \"style\", \"hp:style\"]\n for (const tagName of tagNames) {\n const elements = doc.getElementsByTagName(tagName)\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i]\n const id = el.getAttribute(\"id\") || el.getAttribute(\"IDRef\") || String(i)\n const name = el.getAttribute(\"name\") || el.getAttribute(\"engName\") || \"\"\n const charPrId = el.getAttribute(\"charPrIDRef\") || undefined\n const paraPrId = el.getAttribute(\"paraPrIDRef\") || undefined\n map.set(id, { name, charPrId, paraPrId })\n }\n }\n}\n\n// stripDtd는 utils.js에서 import\n\nexport async function parseHwpxDocument(buffer: ArrayBuffer, options?: ParseOptions): Promise<InternalParseResult> {\n // Best-effort 사전 검증 — CD 선언 크기 기반 (위조 가능, 실제 방어는 per-file 누적 체크)\n precheckZipSize(buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES)\n\n let zip: JSZip\n\n try {\n zip = await JSZip.loadAsync(buffer)\n } catch {\n return extractFromBrokenZip(buffer)\n }\n\n // loadAsync 후 실제 엔트리 수 검증 — CD 위조와 무관한 진짜 방어선\n const actualEntryCount = Object.keys(zip.files).length\n if (actualEntryCount > MAX_ZIP_ENTRIES) {\n throw new KordocError(\"ZIP 엔트리 수 초과 (ZIP bomb 의심)\")\n }\n\n // ── DRM 감지: manifest.xml에 encryption-data가 있으면 COM fallback ──\n const manifestFile = zip.file(\"META-INF/manifest.xml\")\n if (manifestFile) {\n const manifestXml = await manifestFile.async(\"text\")\n if (isEncryptedHwpx(manifestXml)) {\n // 파일 경로가 options에 있으면 COM fallback 시도\n if (isComFallbackAvailable() && options?.filePath) {\n const { pages, pageCount, warnings } = extractTextViaCom(options.filePath)\n if (pages.some(p => p && p.trim().length > 0)) {\n return comResultToParseResult(pages, pageCount, warnings)\n }\n }\n throw new KordocError(\"DRM 암호화된 HWPX 파일입니다. Windows + 한컴 오피스 설치 시 자동 추출됩니다.\")\n }\n }\n\n // ZIP 전체 파일 누적 압축해제 크기 추적 (비섹션 파일 포함)\n const decompressed = { total: 0 }\n\n // 메타데이터 추출 (best-effort)\n const metadata: DocumentMetadata = {}\n await extractHwpxMetadata(zip, metadata, decompressed)\n\n // 스타일 정보 추출 (best-effort)\n const styleMap = await extractHwpxStyles(zip, decompressed)\n const warnings: ParseWarning[] = []\n\n const sectionPaths = await resolveSectionPaths(zip)\n if (sectionPaths.length === 0) throw new KordocError(\"HWPX에서 섹션 파일을 찾을 수 없습니다\")\n\n metadata.pageCount = sectionPaths.length\n\n // 페이지 범위 필터링 (섹션 단위 근사치)\n const pageFilter = options?.pages ? parsePageRange(options.pages, sectionPaths.length) : null\n const totalTarget = pageFilter ? pageFilter.size : sectionPaths.length\n const blocks: IRBlock[] = []\n const nestedTableCounter = { count: 0 }\n let parsedSections = 0\n for (let si = 0; si < sectionPaths.length; si++) {\n if (pageFilter && !pageFilter.has(si + 1)) continue\n const file = zip.file(sectionPaths[si])\n if (!file) continue\n try {\n const xml = await file.async(\"text\")\n decompressed.total += xml.length * 2\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\n blocks.push(...parseSectionXml(xml, styleMap, warnings, si + 1, nestedTableCounter))\n parsedSections++\n options?.onProgress?.(parsedSections, totalTarget)\n } catch (secErr) {\n if (secErr instanceof KordocError) throw secErr\n warnings.push({ page: si + 1, message: `섹션 ${si + 1} 파싱 실패: ${secErr instanceof Error ? secErr.message : \"알 수 없는 오류\"}`, code: \"PARTIAL_PARSE\" })\n }\n }\n\n // 이미지 블록에서 ZIP 바이너리 추출\n const images = await extractImagesFromZip(zip, blocks, decompressed, warnings)\n\n // 스타일 기반 헤딩 감지\n detectHwpxHeadings(blocks, styleMap)\n\n // outline 구축\n const outline: OutlineItem[] = blocks\n .filter(b => b.type === \"heading\" && b.level && b.text)\n .map(b => ({ level: b.level!, text: b.text!, pageNumber: b.pageNumber }))\n\n const markdown = blocksToMarkdown(blocks)\n return { markdown, blocks, metadata, outline: outline.length > 0 ? outline : undefined, warnings: warnings.length > 0 ? warnings : undefined, images: images.length > 0 ? images : undefined }\n}\n\n// ─── 이미지 추출 ───────────────────────────────────\n\n/** 확장자 → MIME 타입 */\nfunction imageExtToMime(ext: string): string {\n switch (ext.toLowerCase()) {\n case \"jpg\": case \"jpeg\": return \"image/jpeg\"\n case \"png\": return \"image/png\"\n case \"gif\": return \"image/gif\"\n case \"bmp\": return \"image/bmp\"\n case \"tif\": case \"tiff\": return \"image/tiff\"\n case \"wmf\": return \"image/wmf\"\n case \"emf\": return \"image/emf\"\n case \"svg\": return \"image/svg+xml\"\n default: return \"application/octet-stream\"\n }\n}\n\n/** MIME → 확장자 */\nfunction mimeToExt(mime: string): string {\n if (mime.includes(\"jpeg\")) return \"jpg\"\n if (mime.includes(\"png\")) return \"png\"\n if (mime.includes(\"gif\")) return \"gif\"\n if (mime.includes(\"bmp\")) return \"bmp\"\n if (mime.includes(\"tiff\")) return \"tif\"\n if (mime.includes(\"wmf\")) return \"wmf\"\n if (mime.includes(\"emf\")) return \"emf\"\n if (mime.includes(\"svg\")) return \"svg\"\n return \"bin\"\n}\n\n/** blocks에서 type=\"image\" 블록의 참조를 ZIP에서 실제 바이너리로 변환 */\nasync function extractImagesFromZip(\n zip: JSZip,\n blocks: IRBlock[],\n decompressed: { total: number },\n warnings?: ParseWarning[],\n): Promise<ExtractedImage[]> {\n const images: ExtractedImage[] = []\n let imageIndex = 0\n\n for (const block of blocks) {\n if (block.type !== \"image\" || !block.text) continue\n\n const ref = block.text\n // BinData/ 폴더 내에서 참조 파일 찾기\n // HWPX binaryItemIDRef는 확장자 없이 오는 경우가 많음 (예: \"image1\" → \"BinData/image1.bmp\")\n const candidates = [\n `BinData/${ref}`,\n `Contents/BinData/${ref}`,\n ref, // 절대 경로일 수도 있음\n ]\n\n // 확장자 없는 ref인 경우 ZIP에서 매칭 파일 탐색\n let resolvedPath: string | null = null\n if (!ref.includes(\".\")) {\n const prefixes = [`BinData/${ref}`, `Contents/BinData/${ref}`]\n for (const prefix of prefixes) {\n const match = zip.file(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\.[a-zA-Z0-9]+$`))\n if (match.length > 0) { resolvedPath = match[0].name; break }\n }\n }\n\n let found = false\n const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates\n for (const path of allCandidates) {\n if (isPathTraversal(path)) continue\n const file = zip.file(path)\n if (!file) continue\n\n try {\n const data = await file.async(\"uint8array\")\n decompressed.total += data.length\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\n\n const actualPath = path\n const ext = actualPath.includes(\".\") ? (actualPath.split(\".\").pop() || \"png\") : \"png\"\n const mimeType = imageExtToMime(ext)\n imageIndex++\n const filename = `image_${String(imageIndex).padStart(3, \"0\")}.${mimeToExt(mimeType)}`\n\n images.push({ filename, data, mimeType })\n // 블록 텍스트를 참조 파일명으로 교체\n block.text = filename\n block.imageData = { data, mimeType, filename: ref }\n found = true\n break\n } catch (err) {\n if (err instanceof KordocError) throw err\n // 개별 이미지 실패는 경고로 처리\n }\n }\n\n if (!found) {\n warnings?.push({ page: block.pageNumber, message: `이미지 파일 없음: ${ref}`, code: \"SKIPPED_IMAGE\" })\n // image 블록을 paragraph로 전환 (참조만 남김)\n block.type = \"paragraph\"\n block.text = `[이미지: ${ref}]`\n }\n }\n\n return images\n}\n\n// ─── 메타데이터 추출 (best-effort) ───────────────────\n\n/**\n * HWPX ZIP 내 메타데이터 파일에서 Dublin Core 정보 추출.\n * 표준 경로: meta.xml, docProps/core.xml, META-INF/container.xml\n */\nasync function extractHwpxMetadata(zip: JSZip, metadata: DocumentMetadata, decompressed?: { total: number }): Promise<void> {\n try {\n // meta.xml (HWPX 표준) 또는 docProps/core.xml (OOXML 호환)\n const metaPaths = [\"meta.xml\", \"META-INF/meta.xml\", \"docProps/core.xml\"]\n for (const mp of metaPaths) {\n const file = zip.file(mp) || Object.values(zip.files).find(f => f.name.toLowerCase() === mp.toLowerCase()) || null\n if (!file) continue\n const xml = await file.async(\"text\")\n if (decompressed) {\n decompressed.total += xml.length * 2\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\n }\n parseDublinCoreMetadata(xml, metadata)\n if (metadata.title || metadata.author) return\n }\n } catch {\n // best-effort\n }\n}\n\n/** Dublin Core (dc:) 메타데이터 XML 파싱 */\nfunction parseDublinCoreMetadata(xml: string, metadata: DocumentMetadata): void {\n const parser = createXmlParser()\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\n if (!doc.documentElement) return\n\n const getText = (tagNames: string[]): string | undefined => {\n for (const tag of tagNames) {\n const els = doc.getElementsByTagName(tag)\n if (els.length > 0) {\n const text = els[0].textContent?.trim()\n if (text) return text\n }\n }\n return undefined\n }\n\n metadata.title = metadata.title || getText([\"dc:title\", \"title\"])\n metadata.author = metadata.author || getText([\"dc:creator\", \"creator\", \"cp:lastModifiedBy\"])\n metadata.description = metadata.description || getText([\"dc:description\", \"description\", \"dc:subject\", \"subject\"])\n metadata.createdAt = metadata.createdAt || getText([\"dcterms:created\", \"meta:creation-date\"])\n metadata.modifiedAt = metadata.modifiedAt || getText([\"dcterms:modified\", \"meta:date\"])\n\n const keywords = getText([\"dc:keyword\", \"cp:keywords\", \"meta:keyword\"])\n if (keywords && !metadata.keywords) {\n metadata.keywords = keywords.split(/[,;]/).map(k => k.trim()).filter(Boolean)\n }\n}\n\n/** 메타데이터만 추출 (전체 파싱 없이) — MCP parse_metadata용 */\nexport async function extractHwpxMetadataOnly(buffer: ArrayBuffer): Promise<DocumentMetadata> {\n let zip: JSZip\n try {\n zip = await JSZip.loadAsync(buffer)\n } catch {\n throw new KordocError(\"HWPX ZIP을 열 수 없습니다\")\n }\n\n const metadata: DocumentMetadata = {}\n await extractHwpxMetadata(zip, metadata)\n\n const sectionPaths = await resolveSectionPaths(zip)\n metadata.pageCount = sectionPaths.length\n\n return metadata\n}\n\n// ─── 손상 ZIP 복구 (edu-facility-ai에서 포팅) ──────────\n\nfunction extractFromBrokenZip(buffer: ArrayBuffer): InternalParseResult {\n const data = new Uint8Array(buffer)\n const view = new DataView(buffer)\n let pos = 0\n const blocks: IRBlock[] = []\n const warnings: ParseWarning[] = [\n { code: \"BROKEN_ZIP_RECOVERY\", message: \"손상된 ZIP 구조 — Local File Header 기반 복구 모드\" },\n ]\n let totalDecompressed = 0\n let entryCount = 0\n let sectionNum = 0\n const nestedTableCounter = { count: 0 }\n\n while (pos < data.length - 30) {\n // PK\\x03\\x04 시그니처 확인 — 미매칭 시 다음 PK 시그니처까지 스캔 (중간 손상 복구)\n if (data[pos] !== 0x50 || data[pos + 1] !== 0x4b || data[pos + 2] !== 0x03 || data[pos + 3] !== 0x04) {\n pos++\n while (pos < data.length - 30) {\n if (data[pos] === 0x50 && data[pos + 1] === 0x4b && data[pos + 2] === 0x03 && data[pos + 3] === 0x04) break\n pos++\n }\n continue\n }\n\n if (++entryCount > MAX_ZIP_ENTRIES) break\n\n const method = view.getUint16(pos + 8, true)\n const compSize = view.getUint32(pos + 18, true)\n const nameLen = view.getUint16(pos + 26, true)\n const extraLen = view.getUint16(pos + 28, true)\n\n // nameLen 상한 — 비정상 값에 의한 대규모 버퍼 할당 방지\n if (nameLen > 1024 || extraLen > 65535) { pos += 30 + nameLen + extraLen; continue }\n\n const fileStart = pos + 30 + nameLen + extraLen\n // 범위 초과 검증 — OOB 및 무한 루프 방지\n if (fileStart + compSize > data.length) break\n if (compSize === 0 && method !== 0) { pos = fileStart; continue }\n\n const nameBytes = data.slice(pos + 30, pos + 30 + nameLen)\n const name = new TextDecoder().decode(nameBytes)\n\n // 경로 순회 방지 — 상위 디렉토리 참조 및 절대 경로 차단\n if (isPathTraversal(name)) { pos = fileStart + compSize; continue }\n const fileData = data.slice(fileStart, fileStart + compSize)\n pos = fileStart + compSize\n\n if (!name.toLowerCase().includes(\"section\") || !name.endsWith(\".xml\")) continue\n\n try {\n let content: string\n if (method === 0) {\n content = new TextDecoder().decode(fileData)\n } else if (method === 8) {\n const decompressed = inflateRawSync(Buffer.from(fileData), { maxOutputLength: MAX_DECOMPRESS_SIZE })\n content = new TextDecoder().decode(decompressed)\n } else {\n continue\n }\n totalDecompressed += content.length * 2\n if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new KordocError(\"압축 해제 크기 초과\")\n sectionNum++\n blocks.push(...parseSectionXml(content, undefined, warnings, sectionNum, nestedTableCounter))\n } catch {\n continue\n }\n }\n\n if (blocks.length === 0) throw new KordocError(\"손상된 HWPX에서 섹션 데이터를 복구할 수 없습니다\")\n const markdown = blocksToMarkdown(blocks)\n return { markdown, blocks, warnings: warnings.length > 0 ? warnings : undefined }\n}\n\n// ─── Manifest 해석 ───────────────────────────────────\n\nasync function resolveSectionPaths(zip: JSZip): Promise<string[]> {\n const manifestPaths = [\"Contents/content.hpf\", \"content.hpf\"]\n for (const mp of manifestPaths) {\n const mpLower = mp.toLowerCase()\n const file = zip.file(mp) || Object.values(zip.files).find(f => f.name.toLowerCase() === mpLower) || null\n if (!file) continue\n const xml = await file.async(\"text\")\n const paths = parseSectionPathsFromManifest(xml)\n if (paths.length > 0) return paths\n }\n\n // fallback: section*.xml 직접 검색\n const sectionFiles = zip.file(/[Ss]ection\\d+\\.xml$/)\n return sectionFiles.map(f => f.name).sort()\n}\n\nfunction parseSectionPathsFromManifest(xml: string): string[] {\n const parser = createXmlParser()\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\n const items = doc.getElementsByTagName(\"opf:item\")\n const spine = doc.getElementsByTagName(\"opf:itemref\")\n\n const isSectionId = (id: string) => /^s/i.test(id) || id.toLowerCase().includes(\"section\")\n const idToHref = new Map<string, string>()\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const id = item.getAttribute(\"id\") || \"\"\n let href = item.getAttribute(\"href\") || \"\"\n const mediaType = item.getAttribute(\"media-type\") || \"\"\n if (!isSectionId(id) && !mediaType.includes(\"xml\")) continue\n if (!href.startsWith(\"/\") && !href.startsWith(\"Contents/\") && isSectionId(id))\n href = \"Contents/\" + href\n idToHref.set(id, href)\n }\n\n if (spine.length > 0) {\n const ordered: string[] = []\n for (let i = 0; i < spine.length; i++) {\n const href = idToHref.get(spine[i].getAttribute(\"idref\") || \"\")\n if (href) ordered.push(href)\n }\n if (ordered.length > 0) return ordered\n }\n return Array.from(idToHref.entries())\n .filter(([id]) => isSectionId(id))\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([, href]) => href)\n}\n\n// ─── 헤딩 감지 (스타일 기반) ────────────────────────\n\n/** HWPX 스타일 기반 헤딩 감지 */\nfunction detectHwpxHeadings(blocks: IRBlock[], styleMap: HwpxStyleMap): void {\n // 본문 폰트 크기 결정\n let baseFontSize = 0\n const sizeFreq = new Map<number, number>()\n for (const b of blocks) {\n if (b.style?.fontSize) {\n sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + 1)\n }\n }\n let maxCount = 0\n for (const [size, count] of sizeFreq) {\n if (count > maxCount) { maxCount = count; baseFontSize = size }\n }\n\n for (const block of blocks) {\n if (block.type !== \"paragraph\" || !block.text) continue\n const text = block.text.trim()\n if (text.length === 0 || text.length > 200 || /^\\d+$/.test(text)) continue\n\n let level = 0\n\n // 폰트 크기 기반\n if (baseFontSize > 0 && block.style?.fontSize) {\n const ratio = block.style.fontSize / baseFontSize\n if (ratio >= HEADING_RATIO_H1) level = 1\n else if (ratio >= HEADING_RATIO_H2) level = 2\n else if (ratio >= HEADING_RATIO_H3) level = 3\n }\n\n // \"제N조/장/절\" 패턴 — 균등배분 공백 허용 (\"제 1 장\" → \"제1장\")\n const compactText = text.replace(/\\s+/g, \"\")\n if (/^제\\d+[조장절편]/.test(compactText) && text.length <= 50) {\n if (level === 0) level = 3\n }\n\n if (level > 0) {\n block.type = \"heading\"\n block.level = level\n }\n }\n}\n\n// ─── 섹션 XML 파싱 ──────────────────────────────────\n\n/** 중첩 테이블 마커 생성 — 순번 + 첫 행 힌트(있는 경우) */\nfunction makeNestedTableMarker(counter: { count: number }, rows: CellContext[][]): string {\n counter.count++\n const firstRow = rows[0] ?? []\n const hint = firstRow.map(c => c.text.trim().replace(/\\n/g, \" \")).filter(Boolean).join(\" | \")\n const hintChars = [...hint]\n const truncated = hintChars.length > 60 ? hintChars.slice(0, 60).join(\"\") + \"…\" : hint\n return truncated\n ? `[중첩 테이블 #${counter.count}: ${truncated}]`\n : `[중첩 테이블 #${counter.count}]`\n}\n\n/**\n * 중첩 테이블 처리 공통 로직 — walkSection/walkParagraphChildren 중복 제거\n * 큰 중첩 테이블(≥3행, ≥2열)은 별도 블록으로 분리, 작은 것은 텍스트로 평탄화.\n * 두 경우 모두 부모 셀에 마커 삽입. parentTable을 반환하여 tableCtx 갱신에 사용.\n */\nfunction handleNestedTable(\n newTable: TableState,\n tableStack: TableState[],\n blocks: IRBlock[],\n ctx: WalkCtx\n): TableState {\n const parentTable = tableStack.pop()!\n let nestedCols = 0\n for (const r of newTable.rows) if (r.length > nestedCols) nestedCols = r.length\n if (newTable.rows.length >= 3 && nestedCols >= 2) {\n blocks.push({ type: \"table\", table: buildTable(newTable.rows), pageNumber: ctx.sectionNum })\n if (parentTable.cell) {\n const marker = ctx.counter ? makeNestedTableMarker(ctx.counter, newTable.rows) : \"[중첩 테이블]\"\n parentTable.cell.text += (parentTable.cell.text ? \"\\n\" : \"\") + marker\n }\n } else {\n const nestedText = convertTableToText(newTable.rows)\n if (parentTable.cell) {\n const marker = ctx.counter ? makeNestedTableMarker(ctx.counter, newTable.rows) : \"[중첩 테이블]\"\n parentTable.cell.text += (parentTable.cell.text ? \"\\n\" : \"\") + marker + \"\\n\" + nestedText\n }\n }\n return parentTable\n}\n\nfunction parseSectionXml(xml: string, styleMap?: HwpxStyleMap, warnings?: ParseWarning[], sectionNum?: number, counter?: { count: number }): IRBlock[] {\n const parser = createXmlParser(warnings)\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\n if (!doc.documentElement) return []\n\n const blocks: IRBlock[] = []\n const ctx: WalkCtx = { styleMap, warnings, sectionNum, counter }\n walkSection(doc.documentElement, blocks, null, [], ctx)\n return blocks\n}\n\n/** pic/shape 요소에서 이미지 참조 경로 추출 (binaryItemIDRef 또는 href) */\nfunction extractImageRef(el: Element): string | null {\n // HWPX: <hp:imgRect> 또는 <hp:img> 내 binaryItemIDRef 속성\n // 또는 하위에서 img 관련 속성 탐색\n const children = el.childNodes\n if (!children) return null\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as Element\n if (child.nodeType !== 1) continue\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\n if (tag === \"imgRect\" || tag === \"img\" || tag === \"imgClip\") {\n const ref = child.getAttribute(\"binaryItemIDRef\") || child.getAttribute(\"href\") || \"\"\n if (ref) return ref\n }\n // lineShape > imgRect 같은 중첩 구조\n const nested = extractImageRef(child)\n if (nested) return nested\n }\n // 직접 속성 체크\n const directRef = el.getAttribute(\"binaryItemIDRef\") || \"\"\n if (directRef) return directRef\n return null\n}\n\nfunction walkSection(\n node: Node, blocks: IRBlock[],\n tableCtx: TableState | null, tableStack: TableState[],\n ctx: WalkCtx, depth: number = 0\n): void {\n if (depth > MAX_XML_DEPTH) return\n const children = node.childNodes\n if (!children) return\n\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType !== 1) continue\n\n const tag = el.tagName || el.localName || \"\"\n const localTag = tag.replace(/^[^:]+:/, \"\")\n\n switch (localTag) {\n case \"tbl\": {\n if (tableCtx) tableStack.push(tableCtx)\n const newTable: TableState = { rows: [], currentRow: [], cell: null }\n walkSection(el, blocks, newTable, tableStack, ctx, depth + 1)\n\n if (newTable.rows.length > 0) {\n if (tableStack.length > 0) {\n tableCtx = handleNestedTable(newTable, tableStack, blocks, ctx)\n } else {\n blocks.push({ type: \"table\", table: buildTable(newTable.rows), pageNumber: ctx.sectionNum })\n tableCtx = null\n }\n } else {\n tableCtx = tableStack.length > 0 ? tableStack.pop()! : null\n }\n break\n }\n\n case \"tr\":\n if (tableCtx) {\n tableCtx.currentRow = []\n walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1)\n if (tableCtx.currentRow.length > 0) tableCtx.rows.push(tableCtx.currentRow)\n tableCtx.currentRow = []\n }\n break\n\n case \"tc\":\n if (tableCtx) {\n tableCtx.cell = { text: \"\", colSpan: 1, rowSpan: 1 }\n walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1)\n if (tableCtx.cell) {\n tableCtx.currentRow.push(tableCtx.cell)\n tableCtx.cell = null\n }\n }\n break\n\n case \"cellAddr\":\n if (tableCtx?.cell) {\n const ca = parseInt(el.getAttribute(\"colAddr\") || \"\", 10)\n const ra = parseInt(el.getAttribute(\"rowAddr\") || \"\", 10)\n if (!isNaN(ca)) tableCtx.cell.colAddr = ca\n if (!isNaN(ra)) tableCtx.cell.rowAddr = ra\n }\n break\n\n case \"cellSpan\":\n if (tableCtx?.cell) {\n const rawCs = parseInt(el.getAttribute(\"colSpan\") || \"1\", 10)\n const cs = isNaN(rawCs) ? 1 : rawCs\n const rawRs = parseInt(el.getAttribute(\"rowSpan\") || \"1\", 10)\n const rs = isNaN(rawRs) ? 1 : rawRs\n tableCtx.cell.colSpan = clampSpan(cs, MAX_COLS)\n tableCtx.cell.rowSpan = clampSpan(rs, MAX_ROWS)\n }\n break\n\n case \"p\": {\n const { text, href, footnote, style } = extractParagraphInfo(el, ctx.styleMap)\n if (text) {\n if (tableCtx?.cell) {\n tableCtx.cell.text += (tableCtx.cell.text ? \"\\n\" : \"\") + text\n } else if (!tableCtx) {\n const block: IRBlock = { type: \"paragraph\", text, pageNumber: ctx.sectionNum }\n if (style) block.style = style\n if (href) block.href = href\n if (footnote) block.footnoteText = footnote\n blocks.push(block)\n }\n }\n // <p> 내부의 <tbl>만 별도 처리 — extractParagraphInfo가 이미 텍스트를 추출했으므로\n // 전체 walkSection 재귀 대신 테이블/이미지 자식만 선택적으로 처리\n tableCtx = walkParagraphChildren(el, blocks, tableCtx, tableStack, ctx, depth + 1)\n break\n }\n\n // 이미지/그림 — 경로 추출 또는 경고\n case \"pic\": case \"shape\": case \"drawingObject\": {\n const imgRef = extractImageRef(el)\n if (imgRef) {\n blocks.push({ type: \"image\", text: imgRef, pageNumber: ctx.sectionNum })\n } else if (ctx.warnings && ctx.sectionNum) {\n ctx.warnings.push({ page: ctx.sectionNum, message: `스킵된 요소: ${localTag}`, code: \"SKIPPED_IMAGE\" })\n }\n break\n }\n\n default:\n walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1)\n break\n }\n }\n}\n\n/** <p> 내부에서 텍스트가 아닌 구조적 자식만 처리 (tbl, pic, shape). tableCtx 반환으로 상태 전파 */\nfunction walkParagraphChildren(\n node: Node, blocks: IRBlock[],\n tableCtx: TableState | null, tableStack: TableState[],\n ctx: WalkCtx, depth: number = 0\n): TableState | null {\n if (depth > MAX_XML_DEPTH) return tableCtx\n const children = node.childNodes\n if (!children) return tableCtx\n const walkChildren = (parent: Node, d: number) => {\n if (d > MAX_XML_DEPTH) return\n const kids = parent.childNodes\n if (!kids) return\n for (let i = 0; i < kids.length; i++) {\n const el = kids[i] as Element\n if (el.nodeType !== 1) continue\n const tag = el.tagName || el.localName || \"\"\n const localTag = tag.replace(/^[^:]+:/, \"\")\n\n if (localTag === \"tbl\") {\n // 테이블은 walkSection으로 위임\n if (tableCtx) tableStack.push(tableCtx)\n const newTable: TableState = { rows: [], currentRow: [], cell: null }\n walkSection(el, blocks, newTable, tableStack, ctx, d + 1)\n if (newTable.rows.length > 0) {\n if (tableStack.length > 0) {\n tableCtx = handleNestedTable(newTable, tableStack, blocks, ctx)\n } else {\n blocks.push({ type: \"table\", table: buildTable(newTable.rows), pageNumber: ctx.sectionNum })\n tableCtx = null\n }\n } else {\n tableCtx = tableStack.length > 0 ? tableStack.pop()! : null\n }\n } else if (localTag === \"pic\" || localTag === \"shape\" || localTag === \"drawingObject\") {\n // 도형/이미지 안에 drawText(글상자)가 있으면 텍스트 추출 우선\n const drawTextChild = findDescendant(el, \"drawText\")\n if (drawTextChild) {\n extractDrawTextBlocks(drawTextChild, blocks, ctx.styleMap, ctx.sectionNum)\n } else {\n const imgRef = extractImageRef(el)\n if (imgRef) {\n blocks.push({ type: \"image\", text: imgRef, pageNumber: ctx.sectionNum })\n } else if (ctx.warnings && ctx.sectionNum) {\n ctx.warnings.push({ page: ctx.sectionNum, message: `스킵된 요소: ${localTag}`, code: \"SKIPPED_IMAGE\" })\n }\n }\n } else if (localTag === \"drawText\") {\n // 글상자(TextBox) 안 텍스트 추출 — <hp:p> 순회\n extractDrawTextBlocks(el, blocks, ctx.styleMap, ctx.sectionNum)\n } else if (localTag === \"r\" || localTag === \"run\" || localTag === \"ctrl\"\n || localTag === \"rect\" || localTag === \"ellipse\" || localTag === \"polygon\"\n || localTag === \"line\" || localTag === \"arc\" || localTag === \"curve\"\n || localTag === \"connectLine\" || localTag === \"container\") {\n // <hp:run>, <hp:ctrl>, 도형 요소 내부에 테이블/이미지/글상자가 포함될 수 있음 — 재귀\n walkChildren(el, d + 1)\n } else if (localTag === \"run\") {\n tableCtx = walkParagraphChildren(el, blocks, tableCtx, tableStack, ctx, depth + 1)\n }\n }\n }\n walkChildren(node, depth)\n return tableCtx\n}\n\n/** 자손에서 특정 태그명의 첫 번째 요소 탐색 (최대 깊이 5) */\nfunction findDescendant(node: Node, targetTag: string, depth = 0): Element | null {\n if (depth > 5) return null\n const children = node.childNodes\n if (!children) return null\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as Element\n if (child.nodeType !== 1) continue\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\n if (tag === targetTag) return child\n const found = findDescendant(child, targetTag, depth + 1)\n if (found) return found\n }\n return null\n}\n\n/** drawText(글상자) 내부의 <p> 요소들에서 텍스트를 추출하여 paragraph 블록 생성 */\nfunction extractDrawTextBlocks(drawTextNode: Node, blocks: IRBlock[], styleMap?: HwpxStyleMap, sectionNum?: number): void {\n const children = drawTextNode.childNodes\n if (!children) return\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as Element\n if (child.nodeType !== 1) continue\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\n if (tag === \"subList\" || tag === \"p\" || tag === \"para\") {\n // subList 안의 <p>들을 순회\n if (tag === \"subList\") {\n extractDrawTextBlocks(child, blocks, styleMap, sectionNum)\n } else {\n const info = extractParagraphInfo(child, styleMap)\n const text = info.text.trim()\n if (text) {\n blocks.push({ type: \"paragraph\", text, style: info.style ?? undefined, pageNumber: sectionNum })\n }\n }\n }\n }\n}\n\ninterface ParagraphInfo {\n text: string\n href?: string\n footnote?: string\n style?: InlineStyle\n}\n\nfunction extractParagraphInfo(para: Element, styleMap?: HwpxStyleMap): ParagraphInfo {\n let text = \"\"\n let href: string | undefined\n let footnote: string | undefined\n let charPrId: string | undefined\n\n // 문단의 스타일 참조 → charPr로 간접 조회\n // HWPX <p>에는 paraPrIDRef/styleIDRef가 있고, charPrIDRef는 <r> 요소에 있음\n // 여기서는 일단 null — <r> 요소에서 charPrIDRef를 가져옴\n\n const walk = (node: Node) => {\n const children = node.childNodes\n if (!children) return\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as Element\n if (child.nodeType === 3) { text += child.textContent || \"\"; continue }\n if (child.nodeType !== 1) continue\n\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\n switch (tag) {\n case \"t\": walk(child); break // 자식 순회 (tab 등 하위 요소 처리)\n case \"tab\": {\n const leader = child.getAttribute(\"leader\")\n if (leader && leader !== \"0\") {\n // 목차 리더 탭 (점선/실선 등) — 뒤에 페이지번호가 오므로 이후 텍스트 무시\n text += \"\\x1F\" // 특수 마커: 이후 텍스트 제거용\n } else {\n text += \"\\t\"\n }\n break\n }\n case \"br\":\n if ((child.getAttribute(\"type\") || \"line\") === \"line\") text += \"\\n\"\n break\n case \"fwSpace\": case \"hwSpace\": text += \" \"; break\n case \"tbl\": break // 테이블은 walkSection에서 처리\n\n // 하이퍼링크\n case \"hyperlink\": {\n const url = child.getAttribute(\"url\") || child.getAttribute(\"href\") || \"\"\n if (url) {\n // XSS 방지: 추출 시점에서 href 살균\n const safe = sanitizeHref(url)\n if (safe) href = safe\n }\n // 하이퍼링크 내 텍스트 추출\n walk(child)\n break\n }\n\n // 각주/미주\n case \"footNote\": case \"endNote\": case \"fn\": case \"en\": {\n const noteText = extractTextFromNode(child)\n if (noteText) footnote = (footnote ? footnote + \"; \" : \"\") + noteText\n break\n }\n\n // 제어 요소 — 필드, 컨트롤, 매개변수 등 스킵\n case \"ctrl\": case \"fieldBegin\": case \"fieldEnd\":\n case \"parameters\": case \"stringParam\": case \"integerParam\":\n case \"boolParam\": case \"floatParam\":\n case \"secPr\": // 섹션 속성 (페이지 설정 등)\n case \"colPr\": // 다단 속성\n case \"linesegarray\": case \"lineseg\": // 레이아웃 정보\n // 도형/이미지 요소 — 대체텍스트(\"사각형입니다.\" 등) 누출 방지\n case \"pic\": case \"shape\": case \"drawingObject\":\n case \"shapeComment\": case \"drawText\":\n break\n\n // 수식: <hp:equation> 내부의 <hp:script> 에 HULK-style equation\n // 스크립트가 담겨 있음. hml-equation-parser 로 LaTeX 변환 후 `$...$`\n // 로 래핑. 실패/빈 스크립트면 무시 (대체 텍스트 누출 방지).\n case \"equation\": {\n const script = findChildByLocalName(child, \"script\")\n const raw = script ? extractTextFromNode(script) : \"\"\n if (raw.trim()) {\n try {\n const latex = hmlToLatex(raw).trim()\n if (latex) text += \" $\" + latex + \"$ \"\n } catch {\n // 변환 실패 시 조용히 드롭 — 텍스트 품질이 우선\n }\n }\n break\n }\n\n // run 요소에서 charPrIDRef 추출\n case \"r\": {\n const runCharPr = child.getAttribute(\"charPrIDRef\")\n if (runCharPr && !charPrId) charPrId = runCharPr\n walk(child)\n break\n }\n\n default: walk(child); break\n }\n }\n }\n walk(para)\n\n // 목차 리더 마커(\\x1F) 이후 텍스트(페이지번호) 제거\n const leaderIdx = text.indexOf(\"\\x1F\")\n if (leaderIdx >= 0) text = text.substring(0, leaderIdx)\n\n let cleanText = text.replace(/[ \\t]+/g, \" \").trim()\n\n // 한글 이미지 OLE 대체 텍스트 필터링 (\"그림입니다. 원본 그림의 이름: ...\")\n if (/^그림입니다\\.?\\s*원본\\s*그림의\\s*(이름|크기)/.test(cleanText)) cleanText = \"\"\n // 멀티라인으로 삽입된 OLE 대체 텍스트도 제거\n cleanText = cleanText.replace(/그림입니다\\.?\\s*원본\\s*그림의\\s*(이름|크기)[^\\n]*(\\n[^\\n]*원본\\s*그림의\\s*(이름|크기)[^\\n]*)*/g, \"\").trim()\n // HWP 도형/개체 대체텍스트 제거 (\"사각형입니다.\", \"개체 입니다.\" 등)\n // NOTE: \"수식\" 은 제거 목록에서 빠져있음 — <hp:equation> 파싱으로 LaTeX 본문이 이미\n // `$...$` 형태로 삽입되기 때문에 여기서 지울 alt-text 는 존재하지 않는다.\n cleanText = cleanText.replace(/(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|선|직선|곡선|화살표|오각형|육각형|팔각형|별|십자|구름|마름모|도넛|평행사변형|사다리꼴|개체|그리기\\s?개체|묶음\\s?개체|글상자|표|그림|OLE\\s?개체)\\s?입니다\\.?/g, \"\").trim()\n\n // 스타일 정보 조회\n let style: InlineStyle | undefined\n if (styleMap && charPrId) {\n const charProp = styleMap.charProperties.get(charPrId)\n if (charProp) {\n style = {}\n if (charProp.fontSize) style.fontSize = charProp.fontSize\n if (charProp.bold) style.bold = true\n if (charProp.italic) style.italic = true\n if (charProp.fontName) style.fontName = charProp.fontName\n if (!style.fontSize && !style.bold && !style.italic) style = undefined\n }\n }\n\n return { text: cleanText, href, footnote, style }\n}\n\n/** 자식 중 지정된 localName(접두사 제거)을 가진 첫 번째 Element 반환 */\nfunction findChildByLocalName(parent: Element, name: string): Element | null {\n const children = parent.childNodes\n if (!children) return null\n for (let i = 0; i < children.length; i++) {\n const ch = children[i] as Element\n if (ch.nodeType !== 1) continue\n const tag = (ch.tagName || ch.localName || \"\").replace(/^[^:]+:/, \"\")\n if (tag === name) return ch\n }\n return null\n}\n\n/** 노드 내 모든 텍스트를 재귀적으로 추출 */\nfunction extractTextFromNode(node: Node): string {\n let result = \"\"\n const children = node.childNodes\n if (!children) return result\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (child.nodeType === 3) result += child.textContent || \"\"\n else if (child.nodeType === 1) result += extractTextFromNode(child)\n }\n return result.trim()\n}\n","/**\n * HWPX DRM 문서 COM fallback — 한컴 오피스 COM API (GetPageText) 활용\n *\n * DRM 암호화된 HWPX 파일을 한컴 오피스의 HWPFrame.HwpObject COM으로 열어\n * 페이지별 텍스트를 추출한다. Windows + 한컴 오피스 설치 필수.\n *\n * 흐름: manifest.xml에 encryption-data 발견 → COM으로 Open → GetPageText(1..N) → Markdown\n */\n\nimport { execFileSync } from \"child_process\"\nimport { platform } from \"os\"\nimport type { InternalParseResult, ParseWarning, DocumentMetadata, IRBlock } from \"../types.js\"\n\n/** COM fallback 사용 가능 여부 (Windows만) */\nexport function isComFallbackAvailable(): boolean {\n return platform() === \"win32\"\n}\n\n/** manifest.xml 내용에서 encryption-data 존재 여부 확인 */\nexport function isEncryptedHwpx(manifestXml: string): boolean {\n return manifestXml.includes(\"encryption-data\")\n}\n\n/**\n * COM API로 DRM HWPX 파일의 텍스트를 추출\n * @param filePath 디스크 상의 HWPX 파일 절대 경로\n */\nexport function extractTextViaCom(filePath: string): { pages: string[]; pageCount: number; warnings: ParseWarning[] } {\n if (!isComFallbackAvailable()) {\n throw new Error(\"COM fallback은 Windows에서만 사용 가능합니다\")\n }\n\n // PowerShell 스크립트를 인라인으로 실행\n //\n // 핵심 우회: 파일을 %TEMP%로 복사한 뒤 해당 경로로 Open.\n // 한컴 오피스는 파일 경로가 \"신뢰 영역\"(사용자 Temp/AppData 등) 밖일 때\n // FilePathChecker가 경고 팝업을 띄운다. FilePathCheckerModuleExample DLL이\n // 등록된 개발 환경에서는 RegisterModule이 작동해 경고가 억제되지만, 일반\n // 사용자 환경에는 해당 DLL이 없다.\n // %TEMP% 하위 경로로 복사하면 신뢰 영역 규칙에 의해 경고가 나오지 않아\n // DLL 등록 없이도 안정적으로 DRM 텍스트를 추출할 수 있다.\n //\n // - RegisterModule: 보안 경고 1차 억제(DLL 없어도 해가 없음)\n // - GetPageText: DRM 우회 텍스트 추출\n // filePath를 single-quote로 이스케이프 (내부 ' → '')\n const escaped = filePath.replace(/'/g, \"''\")\n const ps1 = `\n[Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n$ErrorActionPreference = 'Stop'\n\n$src = '${escaped}'\n$tmpDir = Join-Path $env:TEMP ('hwp-com-' + [guid]::NewGuid().ToString('N'))\n[void](New-Item -ItemType Directory -Path $tmpDir -Force)\n$tmpFile = Join-Path $tmpDir (Split-Path $src -Leaf)\nCopy-Item -LiteralPath $src -Destination $tmpFile -Force\n\ntry {\n $hwp = New-Object -ComObject HWPFrame.HwpObject\n $hwp.RegisterModule('FilePathCheckerModule', 'FilePathCheckerModuleExample') | Out-Null\n $hwp.Open($tmpFile, '', '') | Out-Null\n $pc = $hwp.PageCount\n $result = @{ pageCount = $pc; pages = @() }\n for ($p = 1; $p -le $pc; $p++) {\n $t = $hwp.GetPageText($p, 0)\n $result.pages += @($t)\n }\n $hwp.Clear(1) | Out-Null\n try { $hwp.Quit() | Out-Null } catch { }\n [System.Runtime.InteropServices.Marshal]::ReleaseComObject($hwp) | Out-Null\n [GC]::Collect()\n [GC]::WaitForPendingFinalizers()\n $result | ConvertTo-Json -Depth 3 -Compress\n} catch {\n @{ error = $_.Exception.Message } | ConvertTo-Json -Compress\n} finally {\n # 임시 파일 정리 + 좀비 Hwp.exe 방지용 garbage collect\n try { Remove-Item -LiteralPath $tmpDir -Recurse -Force -ErrorAction SilentlyContinue } catch { }\n [GC]::Collect()\n [GC]::WaitForPendingFinalizers()\n}\n`\n\n const stdout = execFileSync(\"powershell\", [\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-ExecutionPolicy\", \"Bypass\",\n \"-Command\", ps1,\n ], {\n encoding: \"utf-8\",\n timeout: 120_000, // 2분 타임아웃\n windowsHide: true,\n maxBuffer: 50 * 1024 * 1024, // 50MB\n })\n\n // COM 메서드 반환값 등 JSON 앞의 garbage 제거\n const trimmed = stdout.trim()\n const jsonStart = trimmed.indexOf(\"{\")\n if (jsonStart < 0) throw new Error(`COM 출력에 JSON이 없습니다: ${trimmed.slice(0, 200)}`)\n const json = JSON.parse(trimmed.slice(jsonStart))\n if (json.error) {\n throw new Error(`COM 텍스트 추출 실패: ${json.error}`)\n }\n\n const warnings: ParseWarning[] = []\n const pages: string[] = Array.isArray(json.pages) ? json.pages : []\n const pageCount: number = json.pageCount ?? pages.length\n\n if (pages.length === 0) {\n warnings.push({ message: \"COM으로 텍스트를 추출하지 못했습니다\", code: \"COM_EMPTY\" })\n }\n\n return { pages, pageCount, warnings }\n}\n\n/**\n * COM 추출 결과를 InternalParseResult로 변환\n */\nexport function comResultToParseResult(\n pages: string[],\n pageCount: number,\n warnings: ParseWarning[],\n): InternalParseResult {\n const blocks: IRBlock[] = []\n const lines: string[] = []\n\n for (let i = 0; i < pages.length; i++) {\n const text = (pages[i] ?? \"\").trim()\n if (!text) continue\n\n // 페이지 텍스트를 paragraph 블록들로 변환\n const paragraphs = text.split(/\\n/)\n for (const para of paragraphs) {\n const trimmed = para.trim()\n if (!trimmed) continue\n blocks.push({ type: \"paragraph\", text: trimmed, pageNumber: i + 1 })\n lines.push(trimmed)\n }\n }\n\n const markdown = lines.join(\"\\n\\n\")\n const metadata: DocumentMetadata = { pageCount }\n\n warnings.push({\n message: \"DRM 문서: 한컴 COM API로 텍스트 추출 (서식/표 정보 제한적)\",\n code: \"DRM_COM_FALLBACK\",\n })\n\n return {\n markdown,\n blocks,\n metadata,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n","/**\n * HWPX/HWP equation script → LaTeX\n *\n * Ported from hml-equation-parser (Python, Apache 2.0)\n * https://github.com/OpenBapul/hml-equation-parser\n * Copyright 2018 Open Bapul\n * See THIRD_PARTY/hml-equation-parser.txt for the full license.\n *\n * Entry point: `hmlToLatex(script)`.\n *\n * Notes:\n * - The input is the raw text of <hp:script> inside <hp:equation>, i.e.\n * Hancom's mini equation language (\"HULK-style\"). Example:\n * x = { -b +- SQRT { b^2 -4ac } } over {2a}\n * is converted to:\n * x = \\frac { -b +- \\sqrt { b^2 -4ac } }{2a}\n * - The algorithm is a direct port of hulkEqParser.py / hulkReplaceMethod.py\n * with the same 5-pass rewrite (frac → rootOf → matrix → bar → brace).\n */\n\ninterface MatrixMapping {\n begin: string\n end: string\n removeOutterBrackets: boolean\n}\n\n// ─── convertMap (from convertMap.json) ────────────────────────────────────\n// Single-token replacements (applied to each whitespace-delimited token).\nconst CONVERT_MAP: Record<string, string> = {\n TIMES: \"\\\\times\", times: \"\\\\times\",\n LEFT: \"\\\\left\", RIGHT: \"\\\\right\",\n under: \"\\\\underline\",\n SMALLSUM: \"\\\\sum\", sum: \"\\\\sum\",\n SMALLPROD: \"\\\\prod\", prod: \"\\\\prod\",\n SMALLINTER: \"\\\\cap\",\n CUP: \"\\\\cup\",\n OPLUS: \"\\\\oplus\", OMINUS: \"\\\\ominus\", OTIMES: \"\\\\otimes\", ODIV: \"\\\\oslash\", ODOT: \"\\\\odot\",\n LOR: \"\\\\lor\", LAND: \"\\\\land\",\n SUBSET: \"\\\\subset\", SUPERSET: \"\\\\supset\", SUBSETEQ: \"\\\\subseteq\", SUPSETEQ: \"\\\\supseteq\",\n IN: \"\\\\in\", OWNS: \"\\\\owns\", NOTIN: \"\\\\notin\",\n LEQ: \"\\\\leq\", GEQ: \"\\\\geq\",\n \"<<\": \"\\\\ll\", \">>\": \"\\\\gg\", \"<<<\": \"\\\\lll\", \">>>\": \"\\\\ggg\",\n PREC: \"\\\\prec\", SUCC: \"\\\\succ\",\n UPLUS: \"\\\\uplus\",\n \"±\": \"\\\\pm\", \"-+\": \"\\\\mp\", \"÷\": \"\\\\div\",\n CIRC: \"\\\\circ\", BULLET: \"\\\\bullet\", DEG: \" ^\\\\circ\",\n AST: \"\\\\ast\", STAR: \"\\\\bigstar\", BIGCIRC: \"\\\\bigcirc\",\n EMPTYSET: \"\\\\emptyset\",\n THEREFORE: \"\\\\therefore\", BECAUSE: \"\\\\because\", EXIST: \"\\\\exists\",\n \"!=\": \"\\\\neq\",\n SMCOPROD: \"\\\\coprod\", coprod: \"\\\\coprod\",\n SQCAP: \"\\\\sqcap\", SQCUP: \"\\\\sqcup\",\n SQSUBSET: \"\\\\sqsubset\", SQSUBSETEQ: \"\\\\sqsubseteq\",\n BIGSQCUP: \"\\\\bigsqcup\",\n BIGOPLUS: \"\\\\bigoplus\", BIGOTIMES: \"\\\\bigotimes\", BIGODOT: \"\\\\bigodot\", BIGUPLUS: \"\\\\biguplus\",\n inter: \"\\\\bigcap\", union: \"\\\\bigcup\",\n BIGOMINUS: \"{\\\\Large\\\\ominus}\", BIGODIV: \"{\\\\Large\\\\oslash}\",\n UNDEROVER: \"\",\n SIM: \"\\\\sim\", APPROX: \"\\\\approx\", SIMEQ: \"\\\\simeq\", CONG: \"\\\\cong\",\n \"==\": \"\\\\equiv\",\n DIAMOND: \"\\\\diamond\", FORALL: \"\\\\forall\",\n prime: \"'\", Partial: \"\\\\partial\", INF: \"\\\\infty\", PROPTO: \"\\\\propto\",\n lim: \"\\\\lim\", Lim: \"\\\\lim\",\n larrow: \"\\\\leftarrow\", \"->\": \"\\\\rightarrow\",\n uparrow: \"\\\\uparrow\", downarrow: \"\\\\downarrow\",\n LARROW: \"\\\\Leftarrow\", RARROW: \"\\\\Rightarrow\",\n UPARROW: \"\\\\Uparrow\", DOWNARROW: \"\\\\Downarrow\",\n udarrow: \"\\\\updownarrow\",\n \"<->\": \"\\\\leftrightarrow\",\n UDARROW: \"\\\\Updownarrow\", LRARROW: \"\\\\Leftrightarrow\",\n NWARROW: \"\\\\nwarrow\", SEARROW: \"\\\\searrow\", NEARROW: \"\\\\nearrow\", SWARROW: \"\\\\swarrow\",\n HOOKLEFT: \"\\\\hookleftarrow\", HOOKRIGHT: \"\\\\hookrightarrow\",\n PVER: \"\\\\|\", MAPSTO: \"\\\\mapsto\",\n CDOTS: \"\\\\cdots\", LDOTS: \"\\\\ldots\", VDOTS: \"\\\\vdots\", DDOTS: \"\\\\ddots\",\n DAGGER: \"\\\\dagger\", DDAGGER: \"\\\\ddagger\", DOTEQ: \"\\\\doteq\",\n image: \"\\\\fallingdotseq\", REIMAGE: \"\\\\risingdotseq\",\n ASYMP: \"\\\\asymp\", ISO: \"\\\\Bumpeq\",\n DSUM: \"\\\\dotplus\", XOR: \"\\\\veebar\",\n TRIANGLE: \"\\\\triangle\", NABLA: \"\\\\nabla\",\n ANGLE: \"\\\\angle\", MSANGLE: \"\\\\measuredangle\", SANGLE: \"\\\\sphericalangle\",\n VDASH: \"\\\\vdash\", DASHV: \"\\\\dashv\",\n BOT: \"\\\\bot\", TOP: \"\\\\top\", MODELS: \"\\\\models\",\n LAPLACE: \"\\\\mathcal{L}\",\n CENTIGRADE: \"^{\\\\circ}C\", FAHRENHEIT: \"^{\\\\circ}F\",\n LSLANT: \"\\\\diagup\", RSLANT: \"\\\\diagdown\",\n\n sqrt: \"\\\\sqrt\",\n int: \"\\\\int\", dint: \"\\\\iint\", tint: \"\\\\iiint\", oint: \"\\\\oint\",\n\n alpha: \"\\\\alpha\", beta: \"\\\\beta\", gamma: \"\\\\gamma\", delta: \"\\\\delta\",\n epsilon: \"\\\\epsilon\", zeta: \"\\\\zeta\", eta: \"\\\\eta\", theta: \"\\\\theta\",\n iota: \"\\\\iota\", kappa: \"\\\\kappa\", lambda: \"\\\\lambda\", mu: \"\\\\mu\",\n nu: \"\\\\nu\", xi: \"\\\\xi\", omicron: \"\\\\omicron\", pi: \"\\\\pi\",\n rho: \"\\\\rho\", sigma: \"\\\\sigma\", tau: \"\\\\tau\", upsilon: \"\\\\upsilon\",\n phi: \"\\\\phi\", chi: \"\\\\chi\", psi: \"\\\\psi\", omega: \"\\\\omega\",\n ALPHA: \"A\", BETA: \"B\", GAMMA: \"\\\\Gamma\", DELTA: \"\\\\Delta\",\n EPSILON: \"E\", ZETA: \"Z\", ETA: \"H\", THETA: \"\\\\Theta\",\n IOTA: \"I\", KAPPA: \"K\", LAMBDA: \"\\\\Lambda\", MU: \"M\",\n NU: \"N\", XI: \"\\\\Xi\", OMICRON: \"O\", PI: \"\\\\Pi\",\n RHO: \"P\", SIGMA: \"\\\\Sigma\", TAU: \"T\", UPSILON: \"\\\\Upsilon\",\n PHI: \"\\\\Phi\", CHI: \"X\", PSI: \"\\\\Psi\", OMEGA: \"\\\\Omega\",\n\n \"⌈\": \"\\\\lceil\", \"⌉\": \"\\\\rceil\",\n \"⌊\": \"\\\\lfloor\", \"⌋\": \"\\\\rfloor\",\n \"∥\": \"\\\\|\",\n \"⊐\": \"\\\\sqsupset\", \"⊒\": \"\\\\sqsupseteq\",\n\n odint: \"\\\\mathop ∯\",\n otint: \"\\\\mathop ∰\",\n BIGSQCAP: \"\\\\mathop ⨅\",\n ATT: \"\\\\mathop ※\",\n HUND: \"\\\\mathop ‰\",\n THOU: \"\\\\mathop ‱\",\n IDENTICAL: \"\\\\mathop ∷\",\n RTANGLE: \"\\\\mathop ⊾\",\n BASE: \"\\\\mathop ⌂\",\n BENZENE: \"\\\\mathop ⌬\",\n}\n\n// Tokens rewritten to a HULK-prefixed marker, then expanded in second passes.\nconst MIDDLE_CONVERT_MAP: Record<string, string> = {\n matrix: \"HULKMATRIX\",\n pmatrix: \"HULKPMATRIX\",\n bmatrix: \"HULKBMATRIX\",\n dmatrix: \"HULKDMATRIX\",\n eqalign: \"HULKEQALIGN\",\n cases: \"HULKCASE\",\n vec: \"HULKVEC\",\n dyad: \"HULKDYAD\",\n acute: \"HULKACUTE\",\n grave: \"HULKGRAVE\",\n dot: \"HULKDOT\",\n ddot: \"HULKDDOT\",\n bar: \"HULKBAR\",\n hat: \"HULKHAT\",\n check: \"HULKCHECK\",\n arch: \"HULKARCH\",\n tilde: \"HULKTILDE\",\n BOX: \"HULKBOX\",\n OVERBRACE: \"HULKOVERBRACE\",\n UNDERBRACE: \"HULKUNDERBRACE\",\n}\n\nconst BAR_CONVERT_MAP: Record<string, string> = {\n HULKVEC: \"\\\\overrightarrow\",\n HULKDYAD: \"\\\\overleftrightarrow\",\n HULKACUTE: \"\\\\acute\",\n HULKGRAVE: \"\\\\grave\",\n HULKDOT: \"\\\\dot\",\n HULKDDOT: \"\\\\ddot\",\n HULKBAR: \"\\\\overline\",\n HULKHAT: \"\\\\widehat\",\n HULKCHECK: \"\\\\check\",\n HULKARCH: \"\\\\overset{\\\\frown}\",\n HULKTILDE: \"\\\\widetilde\",\n HULKBOX: \"\\\\boxed\",\n}\n\nconst MATRIX_CONVERT_MAP: Record<string, MatrixMapping> = {\n HULKMATRIX: { begin: \"\\\\begin{matrix}\", end: \"\\\\end{matrix}\", removeOutterBrackets: true },\n HULKPMATRIX: { begin: \"\\\\begin{pmatrix}\", end: \"\\\\end{pmatrix}\", removeOutterBrackets: true },\n HULKBMATRIX: { begin: \"\\\\begin{bmatrix}\", end: \"\\\\end{bmatrix}\", removeOutterBrackets: true },\n HULKDMATRIX: { begin: \"\\\\begin{vmatrix}\", end: \"\\\\end{vmatrix}\", removeOutterBrackets: true },\n HULKCASE: { begin: \"\\\\begin{cases}\", end: \"\\\\end{cases}\", removeOutterBrackets: true },\n HULKEQALIGN: { begin: \"\\\\eqalign{\", end: \"}\", removeOutterBrackets: false },\n}\n\nconst BRACE_CONVERT_MAP: Record<string, string> = {\n HULKOVERBRACE: \"\\\\overbrace\",\n HULKUNDERBRACE: \"\\\\underbrace\",\n}\n\n// ─── Bracket scanning helpers ─────────────────────────────────────────────\n\n/**\n * Find a matching `{...}` pair at/after `startIdx` (direction=1) or before\n * (direction=0). Returns [start, end) such that eqString.slice(start, end)\n * is the full bracketed substring including the `{` and `}`.\n * Throws when no matching bracket exists.\n */\nfunction findBrackets(eqString: string, startIdx: number, direction: 0 | 1): [number, number] {\n if (direction === 1) {\n const startCur = eqString.indexOf(\"{\", startIdx)\n if (startCur === -1) throw new Error(\"cannot find bracket\")\n let bracketCount = 1\n for (let i = startCur + 1; i < eqString.length; i++) {\n const ch = eqString[i]\n if (ch === \"{\") bracketCount += 1\n else if (ch === \"}\") bracketCount -= 1\n if (bracketCount === 0) return [startCur, i + 1]\n }\n throw new Error(\"cannot find bracket\")\n }\n\n // direction=0: reverse the string (and swap braces) then reuse dir=1 search.\n const reversed = Array.from(eqString).reverse()\n for (let i = 0; i < reversed.length; i++) {\n if (reversed[i] === \"{\") reversed[i] = \"}\"\n else if (reversed[i] === \"}\") reversed[i] = \"{\"\n }\n const flipped = reversed.join(\"\")\n const newStartIdx = flipped.length - (startIdx + 1)\n const [s, e] = findBrackets(flipped, newStartIdx, 1)\n return [flipped.length - e, flipped.length - s]\n}\n\n/**\n * From a cursor inside a bracketed group, walk backward to the enclosing\n * `{` and return the outer `{...}` span.\n */\nfunction findOutterBrackets(eqString: string, startIdx: number): [number, number] {\n let idx = startIdx\n while (true) {\n idx -= 1\n if (idx < 0) throw new Error(\"cannot find bracket\")\n if (eqString[idx] === \"{\") break\n }\n return findBrackets(eqString, idx, 1)\n}\n\n// ─── Rewrite passes ───────────────────────────────────────────────────────\n\n/** `{1} over {2}` → `\\frac{1}{2}` */\nfunction replaceFrac(eqString: string): string {\n const hmlFrac = \"over\"\n while (true) {\n const cursor = eqString.indexOf(hmlFrac)\n if (cursor === -1) break\n try {\n const [numStart, numEnd] = findBrackets(eqString, cursor, 0)\n const numerator = eqString.slice(numStart, numEnd)\n const beforeFrac = eqString.slice(0, numStart)\n const afterFrac = eqString.slice(cursor + hmlFrac.length)\n eqString = beforeFrac + \"\\\\frac\" + numerator + afterFrac\n } catch {\n return eqString\n }\n }\n return eqString\n}\n\n/** `root {1} of {2}` → `\\sqrt[1]{2}` */\nfunction replaceRootOf(eqString: string): string {\n while (true) {\n const rootCursor = eqString.indexOf(\"root\")\n if (rootCursor === -1) break\n try {\n const ofCursor = eqString.indexOf(\"of\")\n if (ofCursor === -1) return eqString\n const elem1 = findBrackets(eqString, rootCursor, 1)\n const elem2 = findBrackets(eqString, ofCursor, 1)\n const e1 = eqString.slice(elem1[0] + 1, elem1[1] - 1)\n const e2 = eqString.slice(elem2[0] + 1, elem2[1] - 1)\n eqString =\n eqString.slice(0, rootCursor) +\n \"\\\\sqrt\" +\n \"[\" + e1 + \"]\" +\n \"{\" + e2 + \"}\" +\n eqString.slice(elem2[1] + 1)\n } catch {\n return eqString\n }\n }\n return eqString\n}\n\n/** matrix/pmatrix/bmatrix/dmatrix/cases/eqalign expansion. */\nfunction replaceAllMatrix(eqString: string): string {\n const replaceElements = (bracketStr: string): string => {\n let inner = bracketStr.slice(1, -1) // strip outer `{` `}`\n inner = inner.replace(/#/g, \" \\\\\\\\ \")\n inner = inner.replace(/&amp;/g, \"&\")\n return inner\n }\n\n const replaceMatrix = (input: string, matStr: string, matElem: MatrixMapping): string => {\n while (true) {\n const cursor = input.indexOf(matStr)\n if (cursor === -1) break\n try {\n const [eStart, eEnd] = findBrackets(input, cursor, 1)\n const elem = replaceElements(input.slice(eStart, eEnd))\n let beforeMat: string\n let afterMat: string\n if (matElem.removeOutterBrackets) {\n const [bStart, bEnd] = findOutterBrackets(input, cursor)\n beforeMat = input.slice(0, bStart)\n afterMat = input.slice(bEnd)\n } else {\n beforeMat = input.slice(0, cursor)\n afterMat = input.slice(eEnd)\n }\n input = beforeMat + matElem.begin + elem + matElem.end + afterMat\n } catch {\n return input\n }\n }\n return input\n }\n\n for (const [matKey, matElem] of Object.entries(MATRIX_CONVERT_MAP)) {\n eqString = replaceMatrix(eqString, matKey, matElem)\n }\n return eqString\n}\n\n/** vec/hat/bar/dot/ddot/tilde/… (HULK-prefixed) → LaTeX accent. */\nfunction replaceAllBar(eqString: string): string {\n const replaceBar = (input: string, barStr: string, barElem: string): string => {\n while (true) {\n const cursor = input.indexOf(barStr)\n if (cursor === -1) break\n try {\n const [eStart, eEnd] = findBrackets(input, cursor, 1)\n const [bStart, bEnd] = findOutterBrackets(input, cursor)\n const elem = input.slice(eStart, eEnd)\n const beforeBar = input.slice(0, bStart)\n const afterBar = input.slice(bEnd)\n input = beforeBar + barElem + elem + afterBar\n } catch {\n return input\n }\n }\n return input\n }\n\n for (const [barKey, barElem] of Object.entries(BAR_CONVERT_MAP)) {\n eqString = replaceBar(eqString, barKey, barElem)\n }\n return eqString\n}\n\n/** overbrace/underbrace: `BRACE {body} {label}` → `\\overbrace{body}^{label}` */\nfunction replaceAllBrace(eqString: string): string {\n const replaceBrace = (input: string, braceStr: string, braceElem: string): string => {\n while (true) {\n const cursor = input.indexOf(braceStr)\n if (cursor === -1) break\n try {\n const [eStart1, eEnd1] = findBrackets(input, cursor, 1)\n const [eStart2, eEnd2] = findBrackets(input, eEnd1, 1)\n const elem1 = input.slice(eStart1, eEnd1)\n const elem2 = input.slice(eStart2, eEnd2)\n const beforeBrace = input.slice(0, cursor)\n const afterBrace = input.slice(eEnd2)\n input = beforeBrace + braceElem + elem1 + \"^\" + elem2 + afterBrace\n } catch {\n return input\n }\n }\n return input\n }\n\n for (const [braceKey, braceElem] of Object.entries(BRACE_CONVERT_MAP)) {\n eqString = replaceBrace(eqString, braceKey, braceElem)\n }\n return eqString\n}\n\n/** After single-token pass, fix `\\left {` → `\\left \\{` and `\\right }` → `\\right \\}`. */\nfunction replaceBracket(strList: string[]): string[] {\n for (let i = 0; i < strList.length; i++) {\n if (strList[i] === \"{\" && i > 0 && strList[i - 1] === \"\\\\left\") strList[i] = \"\\\\{\"\n if (strList[i] === \"}\" && i > 0 && strList[i - 1] === \"\\\\right\") strList[i] = \"\\\\}\"\n }\n return strList\n}\n\n/**\n * Convert an HWPX equation script (mini Hancom equation language) to LaTeX.\n * Returns the converted LaTeX body (without `$` delimiters).\n */\nexport function hmlToLatex(hmlEqStr: string): string {\n if (!hmlEqStr) return \"\"\n\n let s = hmlEqStr.replace(/`/g, \" \")\n s = s.replace(/\\{/g, \" { \").replace(/\\}/g, \" } \").replace(/&/g, \" & \")\n\n let tokens = s.split(\" \")\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i]\n if (t in CONVERT_MAP) tokens[i] = CONVERT_MAP[t]\n else if (t in MIDDLE_CONVERT_MAP) tokens[i] = MIDDLE_CONVERT_MAP[t]\n }\n tokens = tokens.filter(tok => tok.length !== 0)\n tokens = replaceBracket(tokens)\n\n let out = tokens.join(\" \")\n out = replaceFrac(out)\n out = replaceRootOf(out)\n out = replaceAllMatrix(out)\n out = replaceAllBar(out)\n out = replaceAllBrace(out)\n\n return out\n}\n","/** HWP 5.x 레코드 리더, UTF-16LE 텍스트 추출, 스트림 압축해제 */\n\nimport { inflateRawSync, inflateSync } from \"zlib\"\nimport { KordocError } from \"../utils.js\"\n\n// ─── 레코드 태그 상수 ────────────────────────────────\n\nexport const TAG_PARA_HEADER = 0x0042\nexport const TAG_PARA_TEXT = 0x0043\nexport const TAG_CHAR_SHAPE = 0x0044\nexport const TAG_PARA_SHAPE = 0x0045\nexport const TAG_CTRL_HEADER = 0x0047\nexport const TAG_LIST_HEADER = 0x0048\nexport const TAG_TABLE = 0x004d\nexport const TAG_EQEDIT = 0x0058\n\n// DocInfo 태그 (스타일 정보 해석용) — HWPTAG_BEGIN(0x0010) 기준\nexport const TAG_ID_MAPPINGS = 0x0011 // HWPTAG_BEGIN + 1\nexport const TAG_FACE_NAME = 0x0013 // HWPTAG_BEGIN + 3\nexport const TAG_DOC_CHAR_SHAPE = 0x0015 // HWPTAG_BEGIN + 5\nexport const TAG_DOC_PARA_SHAPE = 0x0019 // HWPTAG_BEGIN + 9\nexport const TAG_DOC_STYLE = 0x001a // HWPTAG_BEGIN + 10\n\n// 특수 문자 코드 (UTF-16LE) — HWP 5.0 바이너리 스펙 + rhwp 검증\n// 3가지 카테고리: char(2바이트), inline(16바이트), extended(16바이트)\n// char: 0, 13, 24-31 — 제어문자만, 확장 데이터 없음\n// inline: 4-9, 19-20 — 제어문자(2) + 확장(14) = 16바이트\n// extended: 1-3, 10-12, 14-18, 21-23 — 제어문자(2) + 확장(14) = 16바이트\nconst CHAR_LINE = 0x0000 // char: 줄바꿈\nconst CHAR_SECTION_BREAK = 0x000a // extended: 구역/단 정의 (14바이트 확장 데이터)\nconst CHAR_PARA = 0x000d // char: 문단 끝\nconst CHAR_TAB = 0x0009 // inline: 탭\nconst CHAR_HYPHEN = 0x001e // char: 하이픈\nconst CHAR_NBSP = 0x001f // char: 비분리 공백\nconst CHAR_FIXED_NBSP = 0x0018 // char: 고정 비분리 공백\nconst CHAR_FIXED_WIDTH = 0x0019 // char: 고정폭 공백\n\n// FileHeader 플래그\nexport const FLAG_COMPRESSED = 1 << 0\nexport const FLAG_ENCRYPTED = 1 << 1\nexport const FLAG_DISTRIBUTION = 1 << 2\nexport const FLAG_DRM = 1 << 4\n\n// ─── 레코드 구조 ─────────────────────────────────────\n\nexport interface HwpRecord {\n tagId: number\n level: number\n size: number\n data: Buffer\n}\n\nexport interface HwpFileHeader {\n signature: string\n versionMajor: number\n flags: number\n}\n\n// ─── 레코드 리더 ─────────────────────────────────────\n\n/** 최대 레코드 수 — 비정상 파일에 의한 메모리 폭주 방지 */\nconst MAX_RECORDS = 500_000\n\nexport function readRecords(data: Buffer): HwpRecord[] {\n const records: HwpRecord[] = []\n let offset = 0\n\n while (offset + 4 <= data.length && records.length < MAX_RECORDS) {\n const header = data.readUInt32LE(offset)\n offset += 4\n\n const tagId = header & 0x3ff\n const level = (header >> 10) & 0x3ff\n let size = (header >> 20) & 0xfff\n\n // 확장 크기\n if (size === 0xfff) {\n if (offset + 4 > data.length) break\n size = data.readUInt32LE(offset)\n offset += 4\n }\n\n if (offset + size > data.length) break\n records.push({ tagId, level, size, data: data.subarray(offset, offset + size) })\n offset += size\n }\n\n return records\n}\n\n// ─── 스트림 압축 해제 ────────────────────────────────\n\n/** 압축 해제 최대 크기 (100MB) — decompression bomb 방지 */\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\n\nexport function decompressStream(data: Buffer): Buffer {\n const opts = { maxOutputLength: MAX_DECOMPRESS_SIZE }\n if (data.length >= 2 && data[0] === 0x78) {\n try { return inflateSync(data, opts) } catch { /* fallback to raw */ }\n }\n return inflateRawSync(data, opts)\n}\n\n// ─── FileHeader 파싱 ─────────────────────────────────\n\nexport function parseFileHeader(data: Buffer): HwpFileHeader {\n if (data.length < 40) throw new KordocError(\"FileHeader가 너무 짧습니다 (최소 40바이트)\")\n const sig = data.subarray(0, 32).toString(\"utf8\").replace(/\\0+$/, \"\")\n return {\n signature: sig,\n versionMajor: data[35],\n flags: data.readUInt32LE(36),\n }\n}\n\n// ─── 스타일 정보 구조 ────────────────────────────────\n\n/** DocInfo에서 추출한 문단 모양 (PARA_SHAPE) */\nexport interface HwpParaShape {\n /** 개요 수준: 0=본문, 1-7=개요수준 1-7 (heading 계층) */\n outlineLevel: number\n}\n\n/** DocInfo에서 추출한 글자 모양 (CHAR_SHAPE) */\nexport interface HwpCharShape {\n /** 글꼴 크기 (단위: 0.1pt, 예: 100 = 10pt) */\n fontSize: number\n /**\n * 속성 플래그 (HWP5 바이너리 스펙 1.1 기준):\n * bit 0 = italic, bit 1 = bold, bit 2 = underline, bit 3 = outline\n * 검증 완료: 공식 스펙 + pyhwp/hwp.js 등 오픈소스 파서와 일치 (v1.7)\n */\n attrFlags: number\n}\n\n/** DocInfo에서 추출한 스타일 */\nexport interface HwpStyle {\n name: string\n /** 한글 이름 (UTF-16LE) */\n nameKo: string\n /** 연결된 charShape 인덱스 */\n charShapeId: number\n /** 연결된 paraShape 인덱스 */\n paraShapeId: number\n /** 스타일 타입: 0=paragraph, 1=character */\n type: number\n}\n\n/** DocInfo 파싱 결과 */\nexport interface HwpDocInfo {\n charShapes: HwpCharShape[]\n paraShapes: HwpParaShape[]\n styles: HwpStyle[]\n}\n\n/** DocInfo 레코드들에서 스타일 정보 추출 */\nexport function parseDocInfo(records: HwpRecord[]): HwpDocInfo {\n const charShapes: HwpCharShape[] = []\n const paraShapes: HwpParaShape[] = []\n const styles: HwpStyle[] = []\n\n for (const rec of records) {\n // PARA_SHAPE — 문단 모양 (개요 수준 추출)\n // 첫 4바이트(u32) 비트 팩: bits 25-27 = 개요 수준 (0=본문, 1-7=heading)\n if (rec.tagId === TAG_DOC_PARA_SHAPE && rec.data.length >= 4) {\n const flags = rec.data.readUInt32LE(0)\n const outlineLevel = (flags >> 25) & 0x07 // bits 25-27 → 3bit (0-7)\n paraShapes.push({ outlineLevel })\n }\n\n if (rec.tagId === TAG_DOC_CHAR_SHAPE && rec.data.length >= 18) {\n // HWP5 CHAR_SHAPE 구조 (바이너리 스펙 1.1 기준):\n // faceId: 7개 언어 * u16 = 14바이트 (offset 0-13)\n // ratio: 7개 언어 * u8 = 7바이트 (offset 14-20)\n // spacing: 7개 언어 * s8 = 7바이트 (offset 21-27)\n // relSize: 7개 언어 * u8 = 7바이트 (offset 28-34)\n // charOffset: 7개 언어 * s8 = 7바이트 (offset 35-41)\n // baseSize: u32 at offset 42 (단위: 0.1pt)\n // attrFlags: u32 at offset 46 (bit0=italic, bit1=bold) — 공식 스펙 검증 완료\n if (rec.data.length >= 50) {\n const fontSize = rec.data.readUInt32LE(42) // 단위: 0.1pt\n const attrFlags = rec.data.readUInt32LE(46)\n charShapes.push({ fontSize, attrFlags })\n } else {\n // 짧은 레코드 — 스타일 정보 없음\n charShapes.push({ fontSize: 0, attrFlags: 0 })\n }\n }\n\n if (rec.tagId === TAG_DOC_STYLE && rec.data.length >= 8) {\n try {\n // STYLE 구조: nameLen(u16) + name(UTF-16LE) + nameKoLen(u16) + nameKo(UTF-16LE)\n // + type(u8) + nextStyleId(u16) + langId(s16) + paraShapeId(u16) + charShapeId(u16)\n let offset = 0\n const nameLen = rec.data.readUInt16LE(offset); offset += 2\n const nameBytes = nameLen * 2\n const name = nameBytes > 0 && offset + nameBytes <= rec.data.length\n ? rec.data.subarray(offset, offset + nameBytes).toString(\"utf16le\")\n : \"\"\n offset += nameBytes\n\n let nameKo = \"\"\n if (offset + 2 <= rec.data.length) {\n const nameKoLen = rec.data.readUInt16LE(offset); offset += 2\n const nameKoBytes = nameKoLen * 2\n if (nameKoBytes > 0 && offset + nameKoBytes <= rec.data.length) {\n nameKo = rec.data.subarray(offset, offset + nameKoBytes).toString(\"utf16le\")\n }\n offset += nameKoBytes\n }\n\n // type(u8) + nextStyleId(u16) + langId(s16) + paraShapeId(u16) + charShapeId(u16)\n const type = offset < rec.data.length ? rec.data.readUInt8(offset) : 0; offset += 1\n offset += 2 // nextStyleId\n offset += 2 // langId\n const paraShapeId = offset + 2 <= rec.data.length ? rec.data.readUInt16LE(offset) : 0; offset += 2\n const charShapeId = offset + 2 <= rec.data.length ? rec.data.readUInt16LE(offset) : 0\n\n styles.push({ name, nameKo, charShapeId, paraShapeId, type })\n } catch {\n // 파싱 실패 — 스킵\n }\n }\n }\n\n return { charShapes, paraShapes, styles }\n}\n\n// ─── UTF-16LE 텍스트 추출 (21가지 제어문자 처리) ─────\n\nexport type InlineControlResolver = (ctrlId: string) => string | null | undefined\n\nexport function extractText(data: Buffer): string {\n return extractTextWithControls(data)\n}\n\nexport function extractTextWithControls(data: Buffer, resolveControl?: InlineControlResolver): string {\n let result = \"\"\n let i = 0\n\n while (i + 1 < data.length) {\n const ch = data.readUInt16LE(i)\n i += 2\n\n switch (ch) {\n // ── char 타입 (2바이트만, 확장 데이터 없음) ──\n case CHAR_LINE: result += \"\\n\"; break\n case CHAR_SECTION_BREAK: { // 구역/단 정의 또는 일부 inline control 래퍼\n // 일부 HWP5 문서는 수식 placeholder를 0x000a + 0x000b + ctrlId + payload + 0x000b로 저장한다.\n if (i + 16 <= data.length && data.readUInt16LE(i) === 0x000b) {\n const ctrlId = data.subarray(i + 2, i + 6).toString(\"ascii\")\n const replacement = resolveControl?.(ctrlId)\n if (replacement) result += replacement\n i += 16\n break\n }\n result += \"\\n\"\n if (i + 14 <= data.length) i += 14\n break\n }\n case CHAR_PARA: break // 문단 끝\n case CHAR_HYPHEN: result += \"-\"; break\n case CHAR_NBSP: result += \" \"; break\n case CHAR_FIXED_NBSP: result += \"\\u00a0\"; break // 진짜 NBSP\n case CHAR_FIXED_WIDTH: result += \" \"; break // 고정폭 공백\n\n // ── inline 타입 (2바이트 + 14바이트 확장) ──\n case CHAR_TAB:\n result += \"\\t\"\n if (i + 14 <= data.length) i += 14\n break\n\n default:\n if (ch >= 0x0001 && ch <= 0x001f) {\n // rhwp 기준 3-카테고리 분류:\n // extended(1-3, 11-12, 14-18, 21-23) + inline(4-9, 19-20) → 14바이트 스킵\n // char(24-31) → 스킵 없음 (이미 switch에서 24,25,30,31 처리됨)\n const isExtended = (ch >= 1 && ch <= 3) || (ch >= 11 && ch <= 12) || (ch >= 14 && ch <= 18) || (ch >= 21 && ch <= 23)\n const isInline = (ch >= 4 && ch <= 9) || (ch >= 19 && ch <= 20)\n if ((isExtended || isInline) && i + 14 <= data.length) {\n const ctrlId = data.subarray(i, i + 4).toString(\"ascii\")\n const replacement = resolveControl?.(ctrlId)\n if (replacement) result += replacement\n i += 14\n }\n } else if (ch >= 0x0020) {\n // UTF-16 surrogate pair 처리 (BMP 외 문자: 이모지, CJK 확장 등)\n if (ch >= 0xd800 && ch <= 0xdbff && i + 1 < data.length) {\n const lo = data.readUInt16LE(i)\n if (lo >= 0xdc00 && lo <= 0xdfff) {\n i += 2\n const codePoint = ((ch - 0xd800) << 10) + (lo - 0xdc00) + 0x10000\n result += String.fromCodePoint(codePoint)\n break\n }\n }\n result += String.fromCharCode(ch)\n }\n break\n }\n }\n\n return result\n}\n\n/** HWP5 EQEDIT(0x58) 레코드에서 한글 수식 스크립트 원문 추출 */\nexport function extractEquationText(data: Buffer): string | null {\n if (data.length < 6) return null\n\n const scriptLength = data.readUInt16LE(4)\n const scriptStart = 6\n const scriptEnd = scriptStart + scriptLength * 2\n if (scriptLength <= 0 || scriptEnd > data.length) return null\n\n const equation = data.subarray(scriptStart, scriptEnd).toString(\"utf16le\").replace(/\\0+/g, \"\").trim()\n return equation || null\n}\n","/**\n * AES-128 ECB 순수 JS 구현 — 배포용 HWP 복호화 전용.\n * 외부 의존성 없음 (kordoc 제로 네이티브 의존성 원칙 유지).\n * 참조: rhwp (MIT) src/parser/crypto.rs + FIPS-197 (AES 표준)\n */\n\n// ── S-Box & 역 S-Box ──\n\nconst S_BOX = new Uint8Array([\n 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,\n 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,\n 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,\n 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,\n 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,\n 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,\n 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,\n 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,\n 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,\n 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,\n 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,\n 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,\n 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,\n 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,\n 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,\n 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16,\n])\n\nconst INV_S_BOX = new Uint8Array([\n 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,\n 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,\n 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,\n 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,\n 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,\n 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,\n 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,\n 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,\n 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,\n 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,\n 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,\n 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,\n 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,\n 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,\n 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,\n 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d,\n])\n\n// ── RCON (라운드 상수) ──\n\nconst RCON = new Uint8Array([0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36])\n\n// ── GF(2^8) 곱셈 ──\n\nfunction gmul(a: number, b: number): number {\n let p = 0\n for (let i = 0; i < 8; i++) {\n if (b & 1) p ^= a\n const hi = a & 0x80\n a = (a << 1) & 0xff\n if (hi) a ^= 0x1b\n b >>= 1\n }\n return p\n}\n\n// ── 키 확장 (AES-128: 4 words → 44 words) ──\n\nfunction expandKey(key: Uint8Array): Uint32Array {\n const w = new Uint32Array(44)\n\n // 첫 4 words: 원본 키\n for (let i = 0; i < 4; i++) {\n w[i] = (key[4 * i] << 24) | (key[4 * i + 1] << 16) | (key[4 * i + 2] << 8) | key[4 * i + 3]\n }\n\n for (let i = 4; i < 44; i++) {\n let temp = w[i - 1]\n if (i % 4 === 0) {\n // RotWord + SubWord + RCON\n temp = ((temp << 8) | (temp >>> 24)) >>> 0\n temp = (S_BOX[(temp >>> 24) & 0xff] << 24) |\n (S_BOX[(temp >>> 16) & 0xff] << 16) |\n (S_BOX[(temp >>> 8) & 0xff] << 8) |\n S_BOX[temp & 0xff]\n temp = (temp ^ (RCON[i / 4 - 1] << 24)) >>> 0\n }\n w[i] = (w[i - 4] ^ temp) >>> 0\n }\n\n return w\n}\n\n// ── AES-128 단일 블록 복호화 (16바이트) ──\n\nfunction decryptBlock(block: Uint8Array, roundKeys: Uint32Array): Uint8Array {\n // state를 4x4 column-major 배열로 로드\n const s = new Uint8Array(16)\n for (let i = 0; i < 16; i++) s[i] = block[i]\n\n // AddRoundKey (round 10)\n addRoundKey(s, roundKeys, 10)\n\n // Rounds 9 → 1\n for (let round = 9; round >= 1; round--) {\n invShiftRows(s)\n invSubBytes(s)\n addRoundKey(s, roundKeys, round)\n invMixColumns(s)\n }\n\n // Final round (round 0)\n invShiftRows(s)\n invSubBytes(s)\n addRoundKey(s, roundKeys, 0)\n\n return s\n}\n\nfunction addRoundKey(s: Uint8Array, w: Uint32Array, round: number): void {\n const base = round * 4\n for (let c = 0; c < 4; c++) {\n const k = w[base + c]\n s[c * 4] ^= (k >>> 24) & 0xff\n s[c * 4 + 1] ^= (k >>> 16) & 0xff\n s[c * 4 + 2] ^= (k >>> 8) & 0xff\n s[c * 4 + 3] ^= k & 0xff\n }\n}\n\nfunction invSubBytes(s: Uint8Array): void {\n for (let i = 0; i < 16; i++) s[i] = INV_S_BOX[s[i]]\n}\n\nfunction invShiftRows(s: Uint8Array): void {\n // Row 0: no shift\n // Row 1: shift right 1\n let t = s[13]; s[13] = s[9]; s[9] = s[5]; s[5] = s[1]; s[1] = t\n // Row 2: shift right 2\n t = s[2]; s[2] = s[10]; s[10] = t\n t = s[6]; s[6] = s[14]; s[14] = t\n // Row 3: shift right 3 (= left 1)\n t = s[3]; s[3] = s[7]; s[7] = s[11]; s[11] = s[15]; s[15] = t\n}\n\nfunction invMixColumns(s: Uint8Array): void {\n for (let c = 0; c < 4; c++) {\n const i = c * 4\n const a0 = s[i], a1 = s[i + 1], a2 = s[i + 2], a3 = s[i + 3]\n s[i] = gmul(a0, 0x0e) ^ gmul(a1, 0x0b) ^ gmul(a2, 0x0d) ^ gmul(a3, 0x09)\n s[i + 1] = gmul(a0, 0x09) ^ gmul(a1, 0x0e) ^ gmul(a2, 0x0b) ^ gmul(a3, 0x0d)\n s[i + 2] = gmul(a0, 0x0d) ^ gmul(a1, 0x09) ^ gmul(a2, 0x0e) ^ gmul(a3, 0x0b)\n s[i + 3] = gmul(a0, 0x0b) ^ gmul(a1, 0x0d) ^ gmul(a2, 0x09) ^ gmul(a3, 0x0e)\n }\n}\n\n// ── 공개 API ──\n\n/** AES-128 ECB 복호화. data 길이는 16의 배수여야 함. */\nexport function aes128EcbDecrypt(data: Uint8Array, key: Uint8Array): Uint8Array {\n if (key.length !== 16) throw new Error(\"AES-128 키는 16바이트여야 합니다\")\n if (data.length % 16 !== 0) throw new Error(\"AES ECB 입력은 16바이트의 배수여야 합니다\")\n\n const roundKeys = expandKey(key)\n const out = new Uint8Array(data.length)\n\n for (let offset = 0; offset < data.length; offset += 16) {\n const block = data.subarray(offset, offset + 16)\n const decrypted = decryptBlock(block, roundKeys)\n out.set(decrypted, offset)\n }\n\n return out\n}\n","/**\n * HWP 배포용(distribution) 문서 복호화.\n *\n * 배포용 HWP는 ViewText/Section{N} 스트림에 암호화된 본문을 저장.\n * 첫 레코드(HWPTAG_DISTRIBUTE_DOC_DATA)의 256바이트 payload에서 AES 키를 추출한 뒤\n * 나머지 데이터를 AES-128 ECB로 복호화.\n *\n * 알고리즘 참조: rhwp (MIT) src/parser/crypto.rs\n * 포맷 참조: HWP 5.0 바이너리 스펙 — 배포용 문서 구조\n */\n\nimport { aes128EcbDecrypt } from \"./aes.js\"\nimport { decompressStream } from \"./record.js\"\n\n// ── MSVC LCG (Linear Congruential Generator) ──\n\n/** MSVC CRT rand() 호환 LCG */\nclass MsvcLcg {\n private seed: number\n\n constructor(seed: number) {\n this.seed = seed >>> 0 // u32로 강제\n }\n\n /** 0 ~ 0x7FFF 범위 난수 반환 (MSVC rand() 호환) */\n rand(): number {\n // MSVC LCG: seed = seed * 214013 + 2531011\n // JS에서 32bit 정수 오버플로우를 정확히 재현하기 위해 Math.imul 사용\n this.seed = (Math.imul(this.seed, 214013) + 2531011) >>> 0\n return (this.seed >>> 16) & 0x7fff\n }\n}\n\n// ── 배포용 문서 256바이트 payload 복호화 ──\n\n/**\n * DISTRIBUTE_DOC_DATA 레코드의 256바이트 payload를 LCG+XOR로 복호화.\n *\n * 구조:\n * - bytes[0..4]: LCG seed (u32 LE)\n * - bytes[4..256]: XOR 암호화된 데이터\n *\n * XOR 규칙: LCG에서 키 바이트를 뽑고, n = (lcg.rand() & 0xF) + 1 바이트마다 키 교체\n */\nfunction decryptDistributePayload(payload: Uint8Array): Uint8Array {\n if (payload.length < 256) throw new Error(\"배포용 payload가 256바이트 미만입니다\")\n\n const seed = (payload[0] | (payload[1] << 8) | (payload[2] << 16) | (payload[3] << 24)) >>> 0\n const lcg = new MsvcLcg(seed)\n\n const result = new Uint8Array(payload.subarray(0, 256)) // 원본 복사\n\n // rhwp 호환: i=0부터 시작하여 n 카운터를 소비하되, i<4는 XOR 스킵 (seed 보존)\n // i=4부터 시작하면 LCG 시퀀스가 어긋남 — i=0~3에서도 n을 소비해야 정확함\n let i = 0\n let n = 0\n let key = 0\n\n while (i < 256) {\n if (n === 0) {\n key = lcg.rand() & 0xff\n n = (lcg.rand() & 0x0f) + 1\n }\n if (i >= 4) {\n result[i] ^= key\n }\n i++\n n--\n }\n\n return result\n}\n\n// ── AES 키 추출 ──\n\n/**\n * 복호화된 256바이트 payload에서 AES-128 키(16바이트) 추출.\n * offset = 4 + (decrypted[0] & 0x0F)\n */\nfunction extractAesKey(decryptedPayload: Uint8Array): Uint8Array {\n const offset = 4 + (decryptedPayload[0] & 0x0f)\n if (offset + 16 > decryptedPayload.length) {\n throw new Error(\"AES 키 추출 실패: 오프셋이 payload 범위를 초과합니다\")\n }\n return decryptedPayload.slice(offset, offset + 16)\n}\n\n// ── 레코드 헤더 파싱 ──\n\n/** HWP 레코드 헤더에서 tag_id와 size 추출 */\nfunction parseRecordHeader(data: Uint8Array, offset: number): { tagId: number; size: number; headerSize: number } {\n if (offset + 4 > data.length) throw new Error(\"레코드 헤더 파싱 실패: 데이터 부족\")\n\n const header = (data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)) >>> 0\n const tagId = header & 0x3ff\n let size = (header >>> 20) & 0xfff\n let headerSize = 4\n\n if (size === 0xfff) {\n if (offset + 8 > data.length) throw new Error(\"확장 레코드 크기 파싱 실패: 데이터 부족\")\n size = (data[offset + 4] | (data[offset + 5] << 8) | (data[offset + 6] << 16) | (data[offset + 7] << 24)) >>> 0\n headerSize = 8\n }\n\n return { tagId, size, headerSize }\n}\n\n// ── 공개 API ──\n\n/** HWPTAG_DISTRIBUTE_DOC_DATA 태그 ID (HWPTAG_BEGIN + 12 = 0x10 + 12 = 0x1C = 28) */\nconst TAG_DISTRIBUTE_DOC_DATA = 0x10 + 12 // = 28\n\n/**\n * ViewText 스트림을 복호화하여 일반 BodyText 레코드 데이터로 변환.\n *\n * @param viewTextRaw ViewText/Section{N} 스트림의 원본 바이트\n * @param compressed FileHeader의 compressed 플래그\n * @returns 복호화된 레코드 데이터 (readRecords()로 파싱 가능)\n */\nexport function decryptViewText(viewTextRaw: Buffer, compressed: boolean): Buffer {\n const data = new Uint8Array(viewTextRaw)\n\n // 1. 첫 레코드 파싱 (DISTRIBUTE_DOC_DATA)\n const rec = parseRecordHeader(data, 0)\n if (rec.tagId !== TAG_DISTRIBUTE_DOC_DATA) {\n throw new Error(`배포용 문서의 첫 레코드가 DISTRIBUTE_DOC_DATA(${TAG_DISTRIBUTE_DOC_DATA})가 아닙니다 (실제: ${rec.tagId})`)\n }\n\n const payloadStart = rec.headerSize\n const payloadEnd = payloadStart + rec.size\n if (payloadEnd > data.length || rec.size < 256) {\n throw new Error(\"배포용 payload가 유효하지 않습니다\")\n }\n\n // 2. 256바이트 payload 복호화 (LCG + XOR)\n const payload = data.subarray(payloadStart, payloadStart + 256)\n const decryptedPayload = decryptDistributePayload(payload)\n\n // 3. AES-128 키 추출\n const aesKey = extractAesKey(decryptedPayload)\n\n // 4. 나머지 데이터를 AES-128 ECB 복호화\n const encryptedStart = payloadEnd\n const encryptedData = data.subarray(encryptedStart)\n\n if (encryptedData.length === 0) {\n throw new Error(\"배포용 문서에 암호화된 본문 데이터가 없습니다\")\n }\n\n // AES ECB는 16바이트 블록 단위 — 패딩 처리\n const alignedLen = encryptedData.length - (encryptedData.length % 16)\n if (alignedLen === 0) {\n throw new Error(\"암호화된 데이터가 너무 짧습니다 (16바이트 미만)\")\n }\n\n const alignedData = encryptedData.subarray(0, alignedLen)\n const decrypted = aes128EcbDecrypt(alignedData, aesKey)\n\n // 5. 압축 해제 (compressed 플래그가 설정된 경우)\n if (compressed) {\n try {\n return decompressStream(Buffer.from(decrypted))\n } catch {\n // 압축이 아닐 수도 있음 — 그대로 반환\n return Buffer.from(decrypted)\n }\n }\n\n return Buffer.from(decrypted)\n}\n\n// 테스트용 내부 함수 export\nexport { MsvcLcg as _MsvcLcg, decryptDistributePayload as _decryptDistributePayload, extractAesKey as _extractAesKey }\n","const WORD_COMMANDS = new Map<string, string>([\n [\"alpha\", \"\\\\alpha\"],\n [\"beta\", \"\\\\beta\"],\n [\"gamma\", \"\\\\gamma\"],\n [\"delta\", \"\\\\delta\"],\n [\"epsilon\", \"\\\\epsilon\"],\n [\"theta\", \"\\\\theta\"],\n [\"lambda\", \"\\\\lambda\"],\n [\"mu\", \"\\\\mu\"],\n [\"pi\", \"\\\\pi\"],\n [\"sigma\", \"\\\\sigma\"],\n [\"tau\", \"\\\\tau\"],\n [\"phi\", \"\\\\phi\"],\n [\"omega\", \"\\\\omega\"],\n [\"sin\", \"\\\\sin\"],\n [\"cos\", \"\\\\cos\"],\n [\"tan\", \"\\\\tan\"],\n [\"sec\", \"\\\\sec\"],\n [\"csc\", \"\\\\csc\"],\n [\"cot\", \"\\\\cot\"],\n [\"log\", \"\\\\log\"],\n [\"ln\", \"\\\\ln\"],\n [\"lim\", \"\\\\lim\"],\n [\"inf\", \"\\\\infty\"],\n [\"sum\", \"\\\\sum\"],\n [\"smallsum\", \"\\\\sum\"],\n [\"prod\", \"\\\\prod\"],\n [\"int\", \"\\\\int\"],\n [\"oint\", \"\\\\oint\"],\n [\"rightarrow\", \"\\\\rightarrow\"],\n [\"leftarrow\", \"\\\\leftarrow\"],\n [\"partial\", \"\\\\partial\"],\n [\"nabla\", \"\\\\nabla\"],\n [\"angle\", \"\\\\angle\"],\n [\"triangle\", \"\\\\triangle\"],\n [\"vec\", \"\\\\vec\"],\n [\"bar\", \"\\\\overline\"],\n [\"dot\", \"\\\\dot\"],\n [\"hat\", \"\\\\hat\"],\n [\"left\", \"\\\\left\"],\n [\"right\", \"\\\\right\"],\n])\n\nconst SYMBOL_WORDS = new Map<string, string>([\n [\"times\", \"\\\\times\"],\n [\"divide\", \"\\\\div\"],\n [\"div\", \"\\\\div\"],\n [\"le\", \"\\\\leq\"],\n [\"ge\", \"\\\\geq\"],\n [\"geq\", \"\\\\geq\"],\n [\"deg\", \"^\\\\circ\"],\n [\"rarrow\", \"\\\\rightarrow\"],\n [\"larrow\", \"\\\\leftarrow\"],\n [\"lrarrow\", \"\\\\leftrightarrow\"],\n [\"in\", \"\\\\in\"],\n [\"notin\", \"\\\\notin\"],\n [\"emptyset\", \"\\\\emptyset\"],\n [\"subset\", \"\\\\subset\"],\n [\"nsubset\", \"\\\\nsubseteq\"],\n [\"cup\", \"\\\\cup\"],\n [\"cap\", \"\\\\cap\"],\n [\"smallinter\", \"\\\\cap\"],\n [\"sim\", \"\\\\sim\"],\n [\"circ\", \"\\\\circ\"],\n [\"bot\", \"\\\\perp\"],\n [\"dyad\", \"\\\\overleftrightarrow\"],\n [\"arch\", \"\\\\overset{\\\\frown}\"],\n])\n\nexport function hwpEquationToLatex(equation: string): string {\n return convertEquation(equation.replace(/\\0/g, \"\").trim(), 0)\n}\n\nfunction convertEquation(equation: string, depth: number): string {\n if (!equation || depth > 12) return equation\n\n let result = equation\n .replace(/\\s+/g, \" \")\n .replace(/`+/g, \"\\\\,\")\n .replace(/~+/g, \"\\\\,\")\n .trim()\n\n result = convertMatrixLike(result)\n result = convertRoots(result, depth)\n result = convertOver(result, depth)\n result = convertSqrt(result, depth)\n result = convertScripts(result)\n result = convertOperators(result)\n result = removeFontDirectives(result)\n result = convertWords(result)\n result = cleanupLatexSpacing(result)\n\n return result\n}\n\nfunction convertMatrixLike(input: string): string {\n return input\n .replace(/\\bmatrix\\s*\\{([^{}]*)\\}/gi, (_match, body: string) =>\n `\\\\begin{matrix} ${body.split(\"#\").map(part => part.trim()).join(\" & \")} \\\\end{matrix}`\n )\n .replace(/\\bcases\\s*\\{([^{}]*)\\}/gi, (_match, body: string) =>\n `\\\\begin{cases} ${body.split(\"#\").map(part => part.trim()).join(\" \\\\\\\\ \")} \\\\end{cases}`\n )\n}\n\nfunction convertRoots(input: string, depth: number): string {\n return input.replace(/(?<!\\\\)\\broot\\s+({[^{}]*}|\\S+)\\s+of\\s+({[^{}]*}|\\S+)/gi, (_match, degree: string, radicand: string) => {\n return `\\\\sqrt[${convertEquation(unwrapGroup(degree), depth + 1)}]{${convertEquation(unwrapGroup(radicand), depth + 1)}}`\n })\n}\n\nfunction convertSqrt(input: string, depth: number): string {\n return input.replace(/(?<!\\\\)\\bsqrt\\s*({[^{}]*}|\\S+)/gi, (_match, radicand: string) => {\n return `\\\\sqrt{${convertEquation(unwrapGroup(radicand), depth + 1)}}`\n })\n}\n\nfunction convertOver(input: string, depth: number): string {\n let result = input\n for (let guard = 0; guard < 50; guard++) {\n const over = findTopLevelWord(result, \"over\")\n if (over < 0) break\n\n const left = readLeftAtom(result, over)\n const right = readRightAtom(result, over + \"over\".length)\n if (!left || !right) break\n\n const numerator = convertEquation(unwrapGroup(left.atom), depth + 1)\n const denominator = convertEquation(unwrapGroup(right.atom), depth + 1)\n result =\n result.slice(0, left.start) +\n `\\\\frac{${numerator}}{${denominator}}` +\n result.slice(right.end)\n }\n return result\n}\n\nfunction convertScripts(input: string): string {\n return input\n .replace(/\\s*\\^\\s*/g, \"^\")\n .replace(/\\s*_\\s*/g, \"_\")\n .replace(/\\^(?!\\{)([^\\s{}_^]+)/g, \"^{$1}\")\n .replace(/_(?!\\{)([^\\s{}_^]+)/g, \"_{$1}\")\n}\n\nfunction convertOperators(input: string): string {\n return input\n .replace(/\\+-/g, \"\\\\pm\")\n .replace(/-\\+/g, \"\\\\mp\")\n .replace(/\\/\\//g, \"\\\\parallel\")\n .replace(/△/g, \"\\\\triangle \")\n .replace(/□/g, \"\\\\square \")\n .replace(/‧/g, \"\\\\cdot \")\n .replace(/!=/g, \"\\\\neq\")\n .replace(/<=/g, \"\\\\leq\")\n .replace(/>=/g, \"\\\\geq\")\n .replace(/==/g, \"\\\\equiv\")\n}\n\nfunction removeFontDirectives(input: string): string {\n return input.replace(/(?<!\\\\)\\b(?:rm|it)\\b\\s*/gi, \"\")\n}\n\nfunction convertWords(input: string): string {\n return input.replace(/(?<![\\\\A-Za-z0-9])([A-Za-z][A-Za-z0-9]*)(?![A-Za-z0-9])/g, word => {\n const exact = SYMBOL_WORDS.get(word)\n if (exact) return exact\n const lower = word.toLowerCase()\n return SYMBOL_WORDS.get(lower) ?? WORD_COMMANDS.get(lower) ?? word\n })\n}\n\nfunction cleanupLatexSpacing(input: string): string {\n return input\n .replace(/\\\\left\\s*\\{/g, \"\\\\left\\\\{\")\n .replace(/\\\\right\\s*\\}/g, \"\\\\right\\\\}\")\n .replace(/\\\\left\\s*([\\[\\]\\(\\)\\|])/g, \"\\\\left$1\")\n .replace(/\\\\right\\s*([\\[\\]\\(\\)\\|])/g, \"\\\\right$1\")\n .replace(/\\s*\\\\,\\s*/g, \"\\\\,\")\n .replace(/\\s+/g, \" \")\n .replace(/\\{\\s+/g, \"{\")\n .replace(/\\s+\\}/g, \"}\")\n .trim()\n}\n\nfunction findTopLevelWord(input: string, word: string): number {\n let curly = 0\n let paren = 0\n for (let i = 0; i <= input.length - word.length; i++) {\n const ch = input[i]\n if (ch === \"{\") curly++\n else if (ch === \"}\") curly = Math.max(0, curly - 1)\n else if (ch === \"(\") paren++\n else if (ch === \")\") paren = Math.max(0, paren - 1)\n\n if (curly !== 0 || paren !== 0) continue\n if (input.slice(i, i + word.length).toLowerCase() !== word) continue\n if (isWordChar(input[i - 1]) || isWordChar(input[i + word.length])) continue\n return i\n }\n return -1\n}\n\nfunction readLeftAtom(input: string, end: number): { start: number; atom: string } | null {\n let pos = end - 1\n while (pos >= 0 && /\\s/.test(input[pos])) pos--\n if (pos < 0) return null\n\n if (input[pos] === \"}\") {\n const start = findMatchingLeft(input, pos, \"{\", \"}\")\n if (start >= 0) return { start, atom: input.slice(start, pos + 1) }\n }\n if (input[pos] === \")\") {\n const start = findMatchingLeft(input, pos, \"(\", \")\")\n if (start >= 0) return { start, atom: input.slice(start, pos + 1) }\n }\n\n let start = pos\n while (start >= 0 && !/\\s/.test(input[start]) && !/[+\\-=<>]/.test(input[start])) start--\n return { start: start + 1, atom: input.slice(start + 1, pos + 1) }\n}\n\nfunction readRightAtom(input: string, start: number): { end: number; atom: string } | null {\n let pos = start\n while (pos < input.length && /\\s/.test(input[pos])) pos++\n if (pos >= input.length) return null\n\n if (input[pos] === \"{\") {\n const end = findMatchingRight(input, pos, \"{\", \"}\")\n if (end >= 0) return { end: end + 1, atom: input.slice(pos, end + 1) }\n }\n if (input[pos] === \"(\") {\n const end = findMatchingRight(input, pos, \"(\", \")\")\n if (end >= 0) return { end: end + 1, atom: input.slice(pos, end + 1) }\n }\n\n let end = pos\n while (end < input.length && !/\\s/.test(input[end]) && !/[+\\-=<>]/.test(input[end])) end++\n return { end, atom: input.slice(pos, end) }\n}\n\nfunction findMatchingLeft(input: string, closeIndex: number, open: string, close: string): number {\n let depth = 0\n for (let i = closeIndex; i >= 0; i--) {\n if (input[i] === close) depth++\n else if (input[i] === open) {\n depth--\n if (depth === 0) return i\n }\n }\n return -1\n}\n\nfunction findMatchingRight(input: string, openIndex: number, open: string, close: string): number {\n let depth = 0\n for (let i = openIndex; i < input.length; i++) {\n if (input[i] === open) depth++\n else if (input[i] === close) {\n depth--\n if (depth === 0) return i\n }\n }\n return -1\n}\n\nfunction unwrapGroup(input: string): string {\n const trimmed = input.trim()\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) return trimmed.slice(1, -1)\n return trimmed\n}\n\nfunction isWordChar(ch: string | undefined): boolean {\n return !!ch && /[A-Za-z0-9_]/.test(ch)\n}\n","/** HWP 5.x 바이너리 파서 — OLE2 컨테이너 → 섹션 → Markdown */\n\nimport {\n readRecords, decompressStream, parseFileHeader, extractTextWithControls, extractEquationText, parseDocInfo,\n TAG_PARA_HEADER, TAG_PARA_TEXT, TAG_CHAR_SHAPE, TAG_CTRL_HEADER, TAG_LIST_HEADER, TAG_TABLE,\n TAG_EQEDIT,\n FLAG_COMPRESSED, FLAG_ENCRYPTED, FLAG_DISTRIBUTION, FLAG_DRM,\n type HwpRecord, type HwpDocInfo, type HwpCharShape, type HwpParaShape,\n} from \"./record.js\"\nimport { decryptViewText } from \"./crypto.js\"\nimport { hwpEquationToLatex } from \"./equation.js\"\nimport { parseLenientCfb, type LenientCfbContainer } from \"./cfb-lenient.js\"\nimport { buildTable, blocksToMarkdown, flattenLayoutTables, MAX_COLS, MAX_ROWS } from \"../table/builder.js\"\nimport type { CellContext, IRBlock, IRTable, DocumentMetadata, InternalParseResult, ParseOptions, ParseWarning, OutlineItem, InlineStyle, ExtractedImage } from \"../types.js\"\nimport { HEADING_RATIO_H1, HEADING_RATIO_H2, HEADING_RATIO_H3 } from \"../types.js\"\nimport { KordocError, sanitizeHref } from \"../utils.js\"\nimport { parsePageRange } from \"../page-range.js\"\n\nimport { createRequire } from \"module\"\nconst require = createRequire(import.meta.url)\nconst CFB: CfbModule = require(\"cfb\")\n\ninterface CfbEntry { name?: string; content?: Buffer | Uint8Array }\ninterface CfbContainer { FileIndex?: CfbEntry[] }\ninterface CfbModule {\n parse(data: Buffer): CfbContainer\n find(cfb: CfbContainer, path: string): CfbEntry | null\n}\n\n/** 최대 섹션 수 — 비정상 파일에 의한 무한 루프 방지 */\nconst MAX_SECTIONS = 100\n/** 누적 압축 해제 최대 크기 (100MB) */\nconst MAX_TOTAL_DECOMPRESS = 100 * 1024 * 1024\n\nexport function parseHwp5Document(buffer: Buffer, options?: ParseOptions): InternalParseResult {\n // CFB 파싱: strict 먼저, 실패 시 lenient 폴백\n let cfb: CfbContainer | null = null\n let lenientCfb: LenientCfbContainer | null = null\n const warnings: ParseWarning[] = []\n\n try {\n cfb = CFB.parse(buffer)\n } catch {\n try {\n lenientCfb = parseLenientCfb(buffer)\n warnings.push({ message: \"손상된 CFB 컨테이너 — lenient 모드로 복구\", code: \"LENIENT_CFB_RECOVERY\" })\n } catch {\n throw new KordocError(\"CFB 컨테이너 파싱 실패 (strict 및 lenient 모두)\")\n }\n }\n\n // CFB 래퍼: strict/lenient 통합 인터페이스\n const findStream = (path: string): Buffer | null => {\n if (cfb) {\n const entry = CFB.find(cfb, path)\n return entry?.content ? Buffer.from(entry.content) : null\n }\n return lenientCfb!.findStream(path)\n }\n\n const headerData = findStream(\"/FileHeader\")\n if (!headerData) throw new KordocError(\"FileHeader 스트림 없음\")\n const header = parseFileHeader(headerData)\n if (header.signature !== \"HWP Document File\") throw new KordocError(\"HWP 시그니처 불일치\")\n if (header.flags & FLAG_ENCRYPTED) throw new KordocError(\"암호화된 HWP는 지원하지 않습니다\")\n if (header.flags & FLAG_DRM) throw new KordocError(\"DRM 보호된 HWP는 지원하지 않습니다\")\n const compressed = (header.flags & FLAG_COMPRESSED) !== 0\n const distribution = (header.flags & FLAG_DISTRIBUTION) !== 0\n\n const metadata: DocumentMetadata = {\n version: `${header.versionMajor}.x`,\n }\n if (cfb) extractHwp5Metadata(cfb, metadata)\n\n // DocInfo 파싱 (스타일 정보 추출)\n const docInfo = cfb\n ? parseDocInfoStream(cfb, compressed)\n : parseDocInfoFromStream(findStream(\"/DocInfo\"), compressed)\n\n const sections = distribution\n ? (cfb ? findViewTextSections(cfb, compressed) : findViewTextSectionsLenient(lenientCfb!, compressed))\n : (cfb ? findSections(cfb) : findSectionsLenient(lenientCfb!, compressed))\n if (sections.length === 0) throw new KordocError(\"섹션 스트림을 찾을 수 없습니다\")\n\n metadata.pageCount = sections.length\n\n // 페이지 범위 필터링 (섹션 단위 근사치)\n const pageFilter = options?.pages ? parsePageRange(options.pages, sections.length) : null\n const totalTarget = pageFilter ? pageFilter.size : sections.length\n\n const blocks: IRBlock[] = []\n const nestedTableCounter = { count: 0 }\n let totalDecompressed = 0\n let parsedSections = 0\n for (let si = 0; si < sections.length; si++) {\n if (pageFilter && !pageFilter.has(si + 1)) continue\n try {\n const sectionData = sections[si]\n // 배포용 문서는 findViewTextSections에서 이미 복호화+압축해제 완료\n const data = (!distribution && compressed) ? decompressStream(Buffer.from(sectionData)) : Buffer.from(sectionData)\n totalDecompressed += data.length\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\n const records = readRecords(data)\n const sectionBlocks = parseSection(records, docInfo, warnings, si + 1, nestedTableCounter)\n blocks.push(...sectionBlocks)\n parsedSections++\n options?.onProgress?.(parsedSections, totalTarget)\n } catch (secErr) {\n if (secErr instanceof KordocError) throw secErr\n warnings.push({ page: si + 1, message: `섹션 ${si + 1} 파싱 실패: ${secErr instanceof Error ? secErr.message : \"알 수 없는 오류\"}`, code: \"PARTIAL_PARSE\" })\n }\n }\n\n // BinData에서 이미지 추출\n const images = cfb\n ? extractHwp5Images(cfb, blocks, compressed, warnings)\n : extractHwp5ImagesLenient(lenientCfb!, blocks, compressed, warnings)\n\n // 레이아웃 테이블 해체 (heading 감지 전에 수행하여 해체된 텍스트도 heading 감지 대상)\n const flatBlocks = flattenLayoutTables(blocks)\n\n // 스타일 기반 헤딩 감지\n if (docInfo) {\n detectHwp5Headings(flatBlocks, docInfo)\n }\n\n // outline 구축\n const outline: OutlineItem[] = flatBlocks\n .filter(b => b.type === \"heading\" && b.level && b.text)\n .map(b => ({ level: b.level!, text: b.text!, pageNumber: b.pageNumber }))\n\n const markdown = blocksToMarkdown(flatBlocks)\n return { markdown, blocks: flatBlocks, metadata, outline: outline.length > 0 ? outline : undefined, warnings: warnings.length > 0 ? warnings : undefined, images: images.length > 0 ? images : undefined }\n}\n\n/** DocInfo 스트림 파싱 (best-effort) */\nfunction parseDocInfoStream(cfb: CfbContainer, compressed: boolean): HwpDocInfo | null {\n try {\n const entry = CFB.find(cfb, \"/DocInfo\")\n if (!entry?.content) return null\n const data = compressed ? decompressStream(Buffer.from(entry.content)) : Buffer.from(entry.content)\n const records = readRecords(data)\n return parseDocInfo(records)\n } catch {\n return null\n }\n}\n\n/** DocInfo — Buffer에서 직접 파싱 (lenient용) */\nfunction parseDocInfoFromStream(raw: Buffer | null, compressed: boolean): HwpDocInfo | null {\n if (!raw) return null\n try {\n const data = compressed ? decompressStream(raw) : raw\n return parseDocInfo(readRecords(data))\n } catch {\n return null\n }\n}\n\n/** 스타일 기반 헤딩 감지 — 큰 폰트 + 짧은 텍스트 → heading */\nfunction detectHwp5Headings(blocks: IRBlock[], docInfo: HwpDocInfo): void {\n // 기본 폰트 크기 결정 (본문 스타일 또는 가장 많이 사용되는 크기)\n let baseFontSize = 0\n\n // \"바탕글\", \"본문\" 등 본문 스타일 찾기\n for (const style of docInfo.styles) {\n const name = (style.nameKo || style.name).toLowerCase()\n if (name.includes(\"바탕\") || name.includes(\"본문\") || name === \"normal\" || name === \"body\") {\n const cs = docInfo.charShapes[style.charShapeId]\n // cs.fontSize는 0.1pt 단위 → pt로 변환 (블록의 style.fontSize와 동일 단위)\n if (cs?.fontSize > 0) { baseFontSize = cs.fontSize / 10; break }\n }\n }\n\n // 본문 스타일 못 찾으면 블록의 폰트 크기 중 최빈값 사용\n if (baseFontSize === 0) {\n const sizeFreq = new Map<number, number>()\n for (const b of blocks) {\n if (b.style?.fontSize) {\n sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + 1)\n }\n }\n let maxCount = 0\n for (const [size, count] of sizeFreq) {\n if (count > maxCount) { maxCount = count; baseFontSize = size }\n }\n }\n\n if (baseFontSize <= 0) return\n\n for (const block of blocks) {\n // 개요 수준(outlineLevel)으로 이미 heading이 된 블록은 스킵\n if (block.type === \"heading\") continue\n if (block.type !== \"paragraph\" || !block.text) continue\n const text = block.text.trim()\n if (text.length === 0 || text.length > 200) continue\n if (/^\\d+$/.test(text)) continue\n\n let level = 0\n\n // 폰트 크기 비율 기반 헤딩 감지 (스타일 정보가 있을 때만)\n if (block.style?.fontSize && baseFontSize > 0) {\n const ratio = block.style.fontSize / baseFontSize\n if (ratio >= HEADING_RATIO_H1) level = 1\n else if (ratio >= HEADING_RATIO_H2) level = 2\n else if (ratio >= HEADING_RATIO_H3) level = 3\n }\n\n // \"제N장/절/편\" 패턴 → H2, \"제N조\" 패턴 → H3 (스타일 유무 무관)\n if (/^제\\d+[장절편]\\s/.test(text) && text.length <= 50) {\n if (level === 0) level = 2\n } else if (/^제\\d+(조의?\\d*)\\s*[\\((]/.test(text) && text.length <= 80) {\n if (level === 0) level = 3\n }\n\n if (level > 0) {\n block.type = \"heading\"\n block.level = level\n }\n }\n}\n\n// ─── 메타데이터 추출 (best-effort) ───────────────────\n\n/**\n * OLE2 SummaryInformation 스트림에서 제목/작성자 추출.\n * HWP5는 \\005HwpSummaryInformation 또는 \\005SummaryInformation에 저장.\n * OLE2 Property Set 포맷의 간이 파싱 — 실패 시 조용히 무시.\n */\nfunction extractHwp5Metadata(cfb: CfbContainer, metadata: DocumentMetadata): void {\n try {\n // HWP 전용 SummaryInformation 먼저, 없으면 표준 OLE2\n const summaryEntry =\n CFB.find(cfb, \"/\\x05HwpSummaryInformation\") ||\n CFB.find(cfb, \"/\\x05SummaryInformation\")\n if (!summaryEntry?.content) return\n\n const data = Buffer.from(summaryEntry.content)\n if (data.length < 48) return\n\n // OLE2 Property Set Header: byte order(2) + version(2) + OS(4) + CLSID(16) + numSets(4) = 28\n // Then FMTID(16) + offset(4)\n const numSets = data.readUInt32LE(24)\n if (numSets === 0) return\n\n const setOffset = data.readUInt32LE(44)\n if (setOffset >= data.length - 8) return\n\n // Property Set: size(4) + numProperties(4) + [propertyId(4) + offset(4)] * N\n const numProps = data.readUInt32LE(setOffset + 4)\n if (numProps === 0 || numProps > 100) return\n\n for (let i = 0; i < numProps; i++) {\n const entryOffset = setOffset + 8 + i * 8\n if (entryOffset + 8 > data.length) break\n\n const propId = data.readUInt32LE(entryOffset)\n const propOffset = setOffset + data.readUInt32LE(entryOffset + 4)\n if (propOffset + 8 > data.length) continue\n\n // Property ID: 2=Title, 4=Author, 6=Subject/Description\n if (propId !== 2 && propId !== 4 && propId !== 6) continue\n\n const propType = data.readUInt32LE(propOffset)\n // Type 0x1E = VT_LPSTR (ANSI string)\n if (propType !== 0x1e) continue\n\n const strLen = data.readUInt32LE(propOffset + 4)\n if (strLen === 0 || strLen > 10000 || propOffset + 8 + strLen > data.length) continue\n\n const str = data.subarray(propOffset + 8, propOffset + 8 + strLen).toString(\"utf8\").replace(/\\0+$/, \"\").trim()\n if (!str) continue\n\n if (propId === 2) metadata.title = str\n else if (propId === 4) metadata.author = str\n else if (propId === 6) metadata.description = str\n }\n } catch {\n // best-effort — 실패 시 조용히 무시\n }\n}\n\n/** 메타데이터만 추출 (전체 파싱 없이) — MCP parse_metadata용 */\nexport function extractHwp5MetadataOnly(buffer: Buffer): DocumentMetadata {\n const cfb = CFB.parse(buffer)\n const headerEntry = CFB.find(cfb, \"/FileHeader\")\n if (!headerEntry?.content) throw new KordocError(\"FileHeader 스트림 없음\")\n const header = parseFileHeader(Buffer.from(headerEntry.content))\n if (header.signature !== \"HWP Document File\") throw new KordocError(\"HWP 시그니처 불일치\")\n\n const metadata: DocumentMetadata = {\n version: `${header.versionMajor}.x`,\n }\n extractHwp5Metadata(cfb, metadata)\n\n const sections = findSections(cfb)\n metadata.pageCount = sections.length\n\n return metadata\n}\n\n/** 배포용 문서: ViewText/Section{N} 스트림을 복호화하여 반환 */\nfunction findViewTextSections(cfb: CfbContainer, compressed: boolean): Buffer[] {\n const sections: Array<{ idx: number; content: Buffer }> = []\n\n for (let i = 0; i < MAX_SECTIONS; i++) {\n const entry = CFB.find(cfb, `/ViewText/Section${i}`)\n if (!entry?.content) break\n try {\n const decrypted = decryptViewText(Buffer.from(entry.content), compressed)\n sections.push({ idx: i, content: decrypted })\n } catch {\n // 복호화 실패 시 해당 섹션 스킵\n break\n }\n }\n\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\n}\n\nfunction findSections(cfb: CfbContainer): Buffer[] {\n const sections: Array<{ idx: number; content: Buffer }> = []\n\n for (let i = 0; i < MAX_SECTIONS; i++) {\n const entry = CFB.find(cfb, `/BodyText/Section${i}`)\n if (!entry?.content) break\n sections.push({ idx: i, content: Buffer.from(entry.content) })\n }\n\n if (sections.length === 0 && cfb.FileIndex) {\n for (const entry of cfb.FileIndex) {\n if (sections.length >= MAX_SECTIONS) break\n if (entry.name?.startsWith(\"Section\") && entry.content) {\n const idx = parseInt(entry.name.replace(\"Section\", \"\"), 10) || 0\n sections.push({ idx, content: Buffer.from(entry.content) })\n }\n }\n }\n\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\n}\n\n/** Lenient CFB: BodyText/Section{N} 탐색 — 누적 압축해제 크기 추적 */\nfunction findSectionsLenient(lcfb: LenientCfbContainer, compressed: boolean): Buffer[] {\n const sections: Array<{ idx: number; content: Buffer }> = []\n let totalDecompressed = 0\n for (let i = 0; i < MAX_SECTIONS; i++) {\n const raw = lcfb.findStream(`/BodyText/Section${i}`) ?? lcfb.findStream(`Section${i}`)\n if (!raw) break\n const content = compressed ? decompressStream(raw) : raw\n totalDecompressed += content.length\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\n sections.push({ idx: i, content })\n }\n if (sections.length === 0) {\n // fallback: 이름에 \"Section\" 포함된 스트림\n for (const e of lcfb.entries()) {\n if (sections.length >= MAX_SECTIONS) break\n if (e.name.startsWith(\"Section\")) {\n const idx = parseInt(e.name.replace(\"Section\", \"\"), 10) || 0\n const raw = lcfb.findStream(e.name)\n if (raw) {\n const content = compressed ? decompressStream(raw) : raw\n totalDecompressed += content.length\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\n sections.push({ idx, content })\n }\n }\n }\n }\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\n}\n\n/** Lenient CFB: ViewText/Section{N} 복호화 — 누적 크기 추적 */\nfunction findViewTextSectionsLenient(lcfb: LenientCfbContainer, compressed: boolean): Buffer[] {\n const sections: Array<{ idx: number; content: Buffer }> = []\n let totalDecompressed = 0\n for (let i = 0; i < MAX_SECTIONS; i++) {\n const raw = lcfb.findStream(`/ViewText/Section${i}`) ?? lcfb.findStream(`Section${i}`)\n if (!raw) break\n try {\n const content = decryptViewText(raw, compressed)\n totalDecompressed += content.length\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\n sections.push({ idx: i, content })\n } catch { break }\n }\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\n}\n\n// ─── BinData ���미지 추출 ─────��─────────────────��────\n\n/** SHAPE_COMPONENT 태그 — HWP5 스펙 */\nconst TAG_SHAPE_COMPONENT = 0x004a\nconst CTRL_ID_EQEDIT = \"deqe\"\n\n/** gso 제어 뒤의 하위 레코드에서 binDataId 추출 (best-effort) */\nfunction extractBinDataId(records: HwpRecord[], ctrlIdx: number): number {\n const ctrlLevel = records[ctrlIdx].level\n // CTRL_HEADER 이후의 하위 레코드들을 순회\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 50; j++) {\n const r = records[j]\n if (r.level <= ctrlLevel) break // 같은/상위 레벨이면 이 제어 블록 끝\n // SHAPE_COMPONENT에서 picture 타입이면 binDataId 추출\n // picture 데이터는 SHAPE_COMPONENT 뒤에 오는 하위 레코드에 있음\n // HWP5에서 그림 정보는 level이 높은 하위 레코드에 binDataId가 uint16LE로 저장\n if (r.data.length >= 2) {\n // 매직바이트로 이미지인지 확인하는 대신, SHAPE_COMPONENT 뒤의 하위 레코드에서 binDataId를 읽음\n // HWP5 picture 구조: CTRL_HEADER(gso) → LIST_HEADER → SHAPE_COMPONENT → [picture data record]\n // picture data record에서 offset 0부터 uint16LE = binDataId\n if (r.tagId > TAG_SHAPE_COMPONENT && r.level > ctrlLevel + 1 && r.data.length >= 4) {\n const possibleId = r.data.readUInt16LE(0)\n if (possibleId < 10000) return possibleId // 합리적 범위\n }\n }\n }\n return -1\n}\n\nfunction isEquationControlId(ctrlId: string): boolean {\n return ctrlId === CTRL_ID_EQEDIT || ctrlId === \"eqed\"\n}\n\nfunction formatEquationForMarkdown(equation: string): string {\n const normalized = hwpEquationToLatex(equation)\n if (!normalized) return \"\"\n return `$${normalized.replace(/\\$/g, \"\\\\$\")}$`\n}\n\nfunction extractEquationFromControl(records: HwpRecord[], ctrlIdx: number): string | null {\n const ctrlLevel = records[ctrlIdx].level\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 10; j++) {\n const r = records[j]\n if (r.level <= ctrlLevel) break\n if (r.tagId !== TAG_EQEDIT) continue\n const equation = extractEquationText(r.data)\n return equation ? formatEquationForMarkdown(equation) : null\n }\n return null\n}\n\nfunction renderTextWithEquations(textRecords: Buffer[], equations: string[]): string {\n const queue = [...equations]\n return textRecords\n .map(data => extractTextWithControls(data, ctrlId => {\n if (!isEquationControlId(ctrlId) || queue.length === 0) return null\n return queue.shift()\n }))\n .join(\"\")\n .replace(/\\$\\$/g, \"$ $\")\n}\n\n/** MIME 타입 매직바이트 판별 */\nfunction detectImageMime(data: Buffer | Uint8Array): string | null {\n if (data.length < 4) return null\n if (data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4e && data[3] === 0x47) return \"image/png\"\n if (data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff) return \"image/jpeg\"\n if (data[0] === 0x47 && data[1] === 0x49 && data[2] === 0x46) return \"image/gif\"\n if (data[0] === 0x42 && data[1] === 0x4d) return \"image/bmp\"\n if (data[0] === 0xd7 && data[1] === 0xcd && data[2] === 0xc6 && data[3] === 0x9a) return \"image/wmf\"\n if (data[0] === 0x01 && data[1] === 0x00 && data[2] === 0x00 && data[3] === 0x00) return \"image/emf\"\n return null\n}\n\n/** OLE2 BinData 스토리지에서 이미지 추출, blocks의 image 블록과 매핑 */\nfunction extractHwp5Images(\n cfb: CfbContainer,\n blocks: IRBlock[],\n compressed: boolean,\n warnings: ParseWarning[],\n): ExtractedImage[] {\n // BinData 스토리지의 모든 파일을 FileIndex 순회로 수집 (O(n), 기존 O(20000) CFB.find 제거)\n const binDataMap = new Map<number, { data: Buffer; name: string }>()\n const binDataRe = /\\/BinData\\/[Bb][Ii][Nn](\\d{4})$/\n if (cfb.FileIndex) {\n for (const entry of cfb.FileIndex) {\n if (!entry?.name || !entry.content) continue\n const match = entry.name.match(binDataRe)\n if (!match) continue\n const idx = parseInt(match[1], 10)\n let data = Buffer.from(entry.content)\n if (compressed) {\n try { data = decompressStream(data) } catch { /* 이미 비압축일 수 있음 */ }\n }\n binDataMap.set(idx, { data, name: entry.name })\n }\n }\n\n if (binDataMap.size === 0) return []\n\n const images: ExtractedImage[] = []\n let imageIndex = 0\n\n for (const block of blocks) {\n if (block.type !== \"image\" || !block.text) continue\n const binId = parseInt(block.text, 10)\n if (isNaN(binId)) continue\n\n const bin = binDataMap.get(binId)\n if (!bin) {\n warnings.push({ page: block.pageNumber, message: `BinData ${binId} 없음`, code: \"SKIPPED_IMAGE\" })\n block.type = \"paragraph\"\n block.text = `[이미지: BinData ${binId}]`\n continue\n }\n\n const mime = detectImageMime(bin.data)\n if (!mime) {\n warnings.push({ page: block.pageNumber, message: `BinData ${binId}: 알 수 없는 이미지 형식`, code: \"SKIPPED_IMAGE\" })\n block.type = \"paragraph\"\n block.text = `[이미지: ${bin.name}]`\n continue\n }\n\n imageIndex++\n const ext = mime.includes(\"jpeg\") ? \"jpg\" : mime.includes(\"png\") ? \"png\" : mime.includes(\"gif\") ? \"gif\" : mime.includes(\"bmp\") ? \"bmp\" : \"bin\"\n const filename = `image_${String(imageIndex).padStart(3, \"0\")}.${ext}`\n\n images.push({ filename, data: new Uint8Array(bin.data), mimeType: mime })\n block.text = filename\n block.imageData = { data: new Uint8Array(bin.data), mimeType: mime, filename: bin.name }\n }\n\n return images\n}\n\n/** Lenient CFB: BinData 이미지 추출 */\nfunction extractHwp5ImagesLenient(\n lcfb: LenientCfbContainer,\n blocks: IRBlock[],\n compressed: boolean,\n warnings: ParseWarning[],\n): ExtractedImage[] {\n // BinData 엔트리 수집\n const binDataMap = new Map<number, { data: Buffer; name: string }>()\n const binRe = /^BIN(\\d{4})/i\n for (const e of lcfb.entries()) {\n const match = e.name.match(binRe)\n if (!match) continue\n const idx = parseInt(match[1], 10)\n let raw = lcfb.findStream(e.name)\n if (!raw) continue\n if (compressed) {\n try { raw = decompressStream(raw) } catch { /* 이미 비압축일 수 있음 */ }\n }\n binDataMap.set(idx, { data: raw, name: e.name })\n }\n if (binDataMap.size === 0) return []\n\n const images: ExtractedImage[] = []\n let imageIndex = 0\n for (const block of blocks) {\n if (block.type !== \"image\" || !block.text) continue\n const binId = parseInt(block.text, 10)\n if (isNaN(binId)) continue\n const bin = binDataMap.get(binId)\n if (!bin) {\n warnings.push({ page: block.pageNumber, message: `BinData ${binId} ���음`, code: \"SKIPPED_IMAGE\" })\n block.type = \"paragraph\"; block.text = `[이미지: BinData ${binId}]`; continue\n }\n const mime = detectImageMime(bin.data)\n if (!mime) {\n warnings.push({ page: block.pageNumber, message: `BinData ${binId}: 알 수 없는 이미지 형식`, code: \"SKIPPED_IMAGE\" })\n block.type = \"paragraph\"; block.text = `[이미지: ${bin.name}]`; continue\n }\n imageIndex++\n const ext = mime.includes(\"jpeg\") ? \"jpg\" : mime.includes(\"png\") ? \"png\" : mime.includes(\"gif\") ? \"gif\" : mime.includes(\"bmp\") ? \"bmp\" : \"bin\"\n const filename = `image_${String(imageIndex).padStart(3, \"0\")}.${ext}`\n images.push({ filename, data: new Uint8Array(bin.data), mimeType: mime })\n block.text = filename\n block.imageData = { data: new Uint8Array(bin.data), mimeType: mime, filename: bin.name }\n }\n return images\n}\n\nfunction parseSection(records: HwpRecord[], docInfo: HwpDocInfo | null, warnings: ParseWarning[], sectionNum: number, counter?: { count: number }): IRBlock[] {\n const blocks: IRBlock[] = []\n let i = 0\n\n while (i < records.length) {\n const rec = records[i]\n\n if (rec.tagId === TAG_PARA_HEADER && rec.level === 0) {\n const { paragraph, tables, nextIdx, charShapeIds, paraShapeId } = parseParagraphWithTables(records, i, counter)\n if (paragraph) {\n const block: IRBlock = { type: \"paragraph\", text: paragraph, pageNumber: sectionNum }\n // CHAR_SHAPE 기반 스타일 정보 추가\n if (docInfo && charShapeIds.length > 0) {\n const style = resolveCharStyle(charShapeIds, docInfo)\n if (style) block.style = style\n }\n // PARA_SHAPE 개요 수준으로 heading 즉시 설정\n if (docInfo && paraShapeId >= 0 && paraShapeId < docInfo.paraShapes.length) {\n const ol = docInfo.paraShapes[paraShapeId].outlineLevel\n if (ol >= 1 && ol <= 6) {\n block.type = \"heading\"\n block.level = ol\n }\n }\n blocks.push(block)\n }\n for (const t of tables) blocks.push({ type: \"table\", table: t, pageNumber: sectionNum })\n i = nextIdx\n continue\n }\n\n if (rec.tagId === TAG_CTRL_HEADER && rec.level <= 1 && rec.data.length >= 4) {\n const ctrlId = rec.data.subarray(0, 4).toString(\"ascii\")\n if (ctrlId === \" lbt\" || ctrlId === \"tbl \") {\n const { table, nextIdx } = parseTableBlock(records, i, counter)\n if (table) blocks.push({ type: \"table\", table, pageNumber: sectionNum })\n i = nextIdx\n continue\n }\n // 그리기 객체(gso) — 이미지 또는 글상자\n if (ctrlId === \"gso \" || ctrlId === \" osg\") {\n const binId = extractBinDataId(records, i)\n if (binId >= 0) {\n blocks.push({ type: \"image\", text: String(binId), pageNumber: sectionNum })\n } else {\n // 이미지가 아니면 글상자(TextBox) 텍스트 추출 시도\n const boxText = extractTextBoxText(records, i)\n if (boxText) {\n blocks.push({ type: \"paragraph\", text: boxText, pageNumber: sectionNum })\n }\n // 텍스트도 없으면 조용히 스킵 (장식용 도형)\n }\n } else if (ctrlId === \" elo\" || ctrlId === \"ole \") {\n warnings.push({ page: sectionNum, message: `스킵된 제어 요소: ${ctrlId.trim()}`, code: \"SKIPPED_IMAGE\" })\n }\n // 각주/미주 — CTRL_HEADER 아래의 텍스트를 추출하여 footnoteText로 연결\n else if (ctrlId === \"fn \" || ctrlId === \" nf \" || ctrlId === \"en \" || ctrlId === \" ne \") {\n const noteText = extractNoteText(records, i)\n if (noteText && blocks.length > 0) {\n // 직전 paragraph 블록에 footnoteText 연결\n const lastBlock = blocks[blocks.length - 1]\n if (lastBlock.type === \"paragraph\") {\n lastBlock.footnoteText = lastBlock.footnoteText\n ? lastBlock.footnoteText + \"; \" + noteText\n : noteText\n }\n }\n }\n // 하이퍼링크 — CTRL_HEADER 데이터에서 URL 추출\n else if (ctrlId === \"%tok\" || ctrlId === \"klnk\") {\n const url = extractHyperlinkUrl(rec.data)\n if (url && blocks.length > 0) {\n const lastBlock = blocks[blocks.length - 1]\n if (lastBlock.type === \"paragraph\" && !lastBlock.href) {\n lastBlock.href = sanitizeHref(url) ?? undefined\n }\n }\n }\n }\n\n i++\n }\n\n return blocks\n}\n\n/** 각주/미주 CTRL_HEADER 아래의 본문 텍스트 추출 */\nfunction extractNoteText(records: HwpRecord[], ctrlIdx: number): string | null {\n const ctrlLevel = records[ctrlIdx].level\n const texts: string[] = []\n let textRecords: Buffer[] = []\n let equations: string[] = []\n\n const flushText = () => {\n const text = renderTextWithEquations(textRecords, equations).trim()\n if (text) texts.push(text)\n textRecords = []\n equations = []\n }\n\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 100; j++) {\n const r = records[j]\n if (r.level <= ctrlLevel) break // 상위 레벨 도달 → 이 컨트롤 블록 끝\n\n if (r.tagId === TAG_PARA_HEADER) {\n flushText()\n }\n\n if (r.tagId === TAG_PARA_TEXT) {\n textRecords.push(r.data)\n }\n\n if (r.tagId === TAG_CTRL_HEADER && r.data.length >= 4) {\n const ctrlId = r.data.subarray(0, 4).toString(\"ascii\")\n if (isEquationControlId(ctrlId)) {\n const equation = extractEquationFromControl(records, j)\n if (equation) equations.push(equation)\n }\n }\n }\n\n flushText()\n return texts.length > 0 ? texts.join(\" \") : null\n}\n\n/** 글상자(TextBox) 제어 요소 아래의 텍스트 추출 — extractNoteText와 동일 패턴 */\nfunction extractTextBoxText(records: HwpRecord[], ctrlIdx: number): string | null {\n const ctrlLevel = records[ctrlIdx].level\n const texts: string[] = []\n let textRecords: Buffer[] = []\n let equations: string[] = []\n\n const flushText = () => {\n const text = renderTextWithEquations(textRecords, equations).trim()\n if (text) texts.push(text)\n textRecords = []\n equations = []\n }\n\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 200; j++) {\n const r = records[j]\n if (r.level <= ctrlLevel) break\n\n if (r.tagId === TAG_PARA_HEADER) {\n flushText()\n }\n\n if (r.tagId === TAG_PARA_TEXT) {\n textRecords.push(r.data)\n }\n\n if (r.tagId === TAG_CTRL_HEADER && r.data.length >= 4) {\n const ctrlId = r.data.subarray(0, 4).toString(\"ascii\")\n if (isEquationControlId(ctrlId)) {\n const equation = extractEquationFromControl(records, j)\n if (equation) equations.push(equation)\n }\n }\n }\n\n flushText()\n return texts.length > 0 ? texts.join(\"\\n\") : null\n}\n\n/** 하이퍼링크 CTRL_HEADER에서 URL 추출 (best-effort) */\nfunction extractHyperlinkUrl(data: Buffer): string | null {\n // HWP5 하이퍼링크 CTRL_HEADER 구조:\n // ctrlId(4) + 기타 필드들... + URL 문자열 (UTF-16LE, length-prefixed)\n // 정확한 오프셋은 버전마다 다를 수 있으므로 URL 패턴 스캔으로 폴백\n try {\n // UTF-16LE에서 \"http\" 시그니처 스캔\n const httpSig = Buffer.from(\"http\", \"utf16le\") // \"h\\0t\\0t\\0p\\0\"\n const idx = data.indexOf(httpSig)\n if (idx >= 0) {\n // null terminator(0x0000 0x0000)까지 UTF-16LE로 읽기\n let end = idx\n while (end + 1 < data.length) {\n const ch = data.readUInt16LE(end)\n if (ch === 0) break\n end += 2\n }\n const url = data.subarray(idx, end).toString(\"utf16le\")\n // 기본 URL 검증\n if (/^https?:\\/\\/.+/.test(url) && url.length < 2000) {\n return url\n }\n }\n } catch { /* best-effort */ }\n return null\n}\n\n/** CHAR_SHAPE ID 배열에서 대표 스타일 결정 (최빈값) */\nfunction resolveCharStyle(charShapeIds: number[], docInfo: HwpDocInfo): InlineStyle | undefined {\n if (charShapeIds.length === 0 || docInfo.charShapes.length === 0) return undefined\n\n // 가장 많이 나타나는 charShapeId 사용\n const freq = new Map<number, number>()\n let maxCount = 0, dominantId = charShapeIds[0]\n for (const id of charShapeIds) {\n const count = (freq.get(id) || 0) + 1\n freq.set(id, count)\n if (count > maxCount) { maxCount = count; dominantId = id }\n }\n\n const cs = docInfo.charShapes[dominantId]\n if (!cs) return undefined\n\n const style: InlineStyle = {}\n if (cs.fontSize > 0) style.fontSize = cs.fontSize / 10 // 0.1pt → pt\n if (cs.attrFlags & 0x01) style.italic = true\n if (cs.attrFlags & 0x02) style.bold = true\n\n return (style.fontSize || style.bold || style.italic) ? style : undefined\n}\n\nfunction parseParagraphWithTables(records: HwpRecord[], startIdx: number, counter?: { count: number }) {\n const startLevel = records[startIdx].level\n const textRecords: Buffer[] = []\n const equations: string[] = []\n const tables: ReturnType<typeof buildTable>[] = []\n const charShapeIds: number[] = []\n\n // PARA_HEADER에서 paraShapeId 추출 (offset 8-9, u16)\n const paraHeaderData = records[startIdx].data\n const paraShapeId = paraHeaderData.length >= 10 ? paraHeaderData.readUInt16LE(8) : -1\n\n let i = startIdx + 1\n\n while (i < records.length) {\n const rec = records[i]\n if (rec.tagId === TAG_PARA_HEADER && rec.level <= startLevel) break\n\n if (rec.tagId === TAG_PARA_TEXT) {\n textRecords.push(rec.data)\n }\n\n // CHAR_SHAPE 레코드 — 문단 내 글자 모양 인덱스 배열\n if (rec.tagId === TAG_CHAR_SHAPE && rec.data.length >= 8) {\n // 구조: [position(u32) + charShapeId(u32)] * N\n for (let offset = 0; offset + 7 < rec.data.length; offset += 8) {\n charShapeIds.push(rec.data.readUInt32LE(offset + 4))\n }\n }\n\n if (rec.tagId === TAG_CTRL_HEADER && rec.data.length >= 4) {\n const ctrlId = rec.data.subarray(0, 4).toString(\"ascii\")\n if (isEquationControlId(ctrlId)) {\n const equation = extractEquationFromControl(records, i)\n if (equation) equations.push(equation)\n } else if (ctrlId === \" lbt\" || ctrlId === \"tbl \") {\n const { table, nextIdx } = parseTableBlock(records, i, counter)\n if (table) tables.push(table)\n i = nextIdx\n continue\n }\n }\n i++\n }\n\n const text = renderTextWithEquations(textRecords, equations)\n const trimmed = text.trim()\n return { paragraph: trimmed || null, tables, nextIdx: i, charShapeIds, paraShapeId }\n}\n\nfunction parseTableBlock(records: HwpRecord[], startIdx: number, counter?: { count: number }) {\n const tableLevel = records[startIdx].level\n let i = startIdx + 1\n let rows = 0, cols = 0\n const cells: CellContext[] = []\n\n while (i < records.length) {\n const rec = records[i]\n if (rec.tagId === TAG_PARA_HEADER && rec.level <= tableLevel) break\n if (rec.tagId === TAG_CTRL_HEADER && rec.level <= tableLevel) break\n\n if (rec.tagId === TAG_TABLE && rec.data.length >= 8) {\n rows = Math.min(rec.data.readUInt16LE(4), MAX_ROWS)\n cols = Math.min(rec.data.readUInt16LE(6), MAX_COLS)\n }\n\n if (rec.tagId === TAG_LIST_HEADER) {\n const { cell, nextIdx } = parseCellBlock(records, i, tableLevel, counter)\n if (cell) cells.push(cell)\n i = nextIdx\n continue\n }\n i++\n }\n\n if (rows === 0 || cols === 0 || cells.length === 0) return { table: null, nextIdx: i }\n\n // colAddr/rowAddr가 있으면 arrangeCells가 이미 완성된 그리드를 반환하므로\n // buildTable(2-pass) 없이 직접 IRTable 생성 — 이중 colSpan 확장 방지\n const hasAddr = cells.some(c => c.colAddr !== undefined && c.rowAddr !== undefined)\n if (hasAddr) {\n const cellRows = arrangeCells(rows, cols, cells)\n const irCells = cellRows.map(row => row.map(c => ({\n text: c.text.trim(),\n colSpan: c.colSpan,\n rowSpan: c.rowSpan,\n })))\n return { table: { rows, cols, cells: irCells, hasHeader: rows > 1 }, nextIdx: i }\n }\n\n const cellRows = arrangeCells(rows, cols, cells)\n return { table: buildTable(cellRows), nextIdx: i }\n}\n\nfunction parseCellBlock(records: HwpRecord[], startIdx: number, tableLevel: number, counter?: { count: number }) {\n const rec = records[startIdx]\n const cellLevel = rec.level\n const texts: string[] = []\n let textRecords: Buffer[] = []\n let equations: string[] = []\n\n const flushText = () => {\n const text = renderTextWithEquations(textRecords, equations).trim()\n if (text) texts.push(text)\n textRecords = []\n equations = []\n }\n\n // LIST_HEADER에서 셀 위치 및 병합 정보 추출\n // HWP5 셀 LIST_HEADER 구조:\n // paraCount(u16) + flags(u32) + width(u16) + colAddr(u16) + rowAddr(u16) + colSpan(u16) + rowSpan(u16)\n // offset: 0 2 6 8 10 12 14\n let colSpan = 1\n let rowSpan = 1\n let colAddr: number | undefined\n let rowAddr: number | undefined\n if (rec.data.length >= 16) {\n colAddr = rec.data.readUInt16LE(8)\n rowAddr = rec.data.readUInt16LE(10)\n const cs = rec.data.readUInt16LE(12)\n const rs = rec.data.readUInt16LE(14)\n if (cs > 0) colSpan = Math.min(cs, MAX_COLS)\n if (rs > 0) rowSpan = Math.min(rs, MAX_ROWS)\n }\n\n let i = startIdx + 1\n\n while (i < records.length) {\n const r = records[i]\n if (r.tagId === TAG_LIST_HEADER && r.level <= cellLevel) break\n if (r.level <= tableLevel && (r.tagId === TAG_PARA_HEADER || r.tagId === TAG_CTRL_HEADER)) break\n\n if (r.tagId === TAG_PARA_HEADER) {\n flushText()\n }\n\n if (r.tagId === TAG_PARA_TEXT) {\n textRecords.push(r.data)\n }\n\n // 셀 내부 중첩 테이블 감지 (HWP5에서는 내용 파싱 없이 마커만 표시)\n // 힌트 없음 — HWP5는 이 단계에서 중첩 테이블 내부를 파싱하지 않으므로 첫 행 추출 불가\n if (r.tagId === TAG_CTRL_HEADER && r.data.length >= 4) {\n const ctrlId = r.data.subarray(0, 4).toString(\"ascii\")\n if (isEquationControlId(ctrlId)) {\n const equation = extractEquationFromControl(records, i)\n if (equation) equations.push(equation)\n } else if (ctrlId === \" lbt\" || ctrlId === \"tbl \") {\n flushText()\n if (counter) {\n counter.count++\n texts.push(`[중첩 테이블 #${counter.count}]`)\n } else {\n texts.push(\"[중첩 테이블]\")\n }\n }\n }\n\n i++\n }\n\n flushText()\n return { cell: { text: texts.join(\"\\n\"), colSpan, rowSpan, colAddr, rowAddr } as CellContext, nextIdx: i }\n}\n\nfunction arrangeCells(rows: number, cols: number, cells: CellContext[]): CellContext[][] {\n const grid: (CellContext | null)[][] = Array.from({ length: rows }, () => Array(cols).fill(null))\n\n // colAddr/rowAddr가 있으면 직접 배치 (HWP5 병합 테이블 정확도 향상)\n const hasAddr = cells.some(c => c.colAddr !== undefined && c.rowAddr !== undefined)\n\n if (hasAddr) {\n for (const cell of cells) {\n const r = cell.rowAddr ?? 0\n const c = cell.colAddr ?? 0\n if (r >= rows || c >= cols) continue\n grid[r][c] = cell\n\n for (let dr = 0; dr < cell.rowSpan; dr++) {\n for (let dc = 0; dc < cell.colSpan; dc++) {\n if (dr === 0 && dc === 0) continue\n if (r + dr < rows && c + dc < cols)\n grid[r + dr][c + dc] = { text: \"\", colSpan: 1, rowSpan: 1 }\n }\n }\n }\n } else {\n // fallback: 순차 배치 (colAddr 없는 경우)\n let cellIdx = 0\n for (let r = 0; r < rows && cellIdx < cells.length; r++) {\n for (let c = 0; c < cols && cellIdx < cells.length; c++) {\n if (grid[r][c] !== null) continue\n const cell = cells[cellIdx++]\n grid[r][c] = cell\n\n for (let dr = 0; dr < cell.rowSpan; dr++) {\n for (let dc = 0; dc < cell.colSpan; dc++) {\n if (dr === 0 && dc === 0) continue\n if (r + dr < rows && c + dc < cols)\n grid[r + dr][c + dc] = { text: \"\", colSpan: 1, rowSpan: 1 }\n }\n }\n }\n }\n }\n\n return grid.map(row => row.map(c => c || { text: \"\", colSpan: 1, rowSpan: 1 }))\n}\n","/**\n * HWP 3.0 (한글 워드프로세서 3.x) 텍스트 추출 파서.\n *\n * 1996~2002년 한컴이 사용한 binary 포맷. CFB(OLE2) 컨테이너가 아닌 단일 binary stream.\n * 내부 구조 요약:\n * 30 byte signature\n * + 128 byte DocInfo (compressed/encrypted 플래그 + InfoBlock 길이)\n * + 1008 byte DocSummary (제목/저자/날짜)\n * + InfoBlock (가변 — 폰트/스타일 메타데이터)\n * + Body (compressed!=0 이면 raw deflate 압축)\n *\n * Body 는 paragraph 의 list. 각 paragraph 는 헤더 + LineInfos + (inline char shapes) + char stream.\n * char stream 은 hchar (u16 little-endian) 의 시퀀스로, 1..31 영역(13 제외) 은 제어 문자\n * (제어 문자별로 추가 byte 를 소비하고 일부는 nested paragraph list 가짐).\n *\n * 본 구현은 **텍스트 추출 전용** — 표/그림 레이아웃, 글자 속성, 캡션 위치 등은 모두 무시한다.\n * 표 셀과 그림 캡션, 머리말/꼬리말, 각주의 본문 텍스트는 재귀로 모아서 결과에 포함시킨다.\n *\n * 출처: rhwp/src/parser/hwp3/mod.rs (Apache-2.0). 알고리즘 1:1 포팅 + minimal 변형.\n */\n\nimport { inflateRawSync } from \"zlib\"\nimport type { DocumentMetadata, IRBlock, InternalParseResult, ParseOptions, ParseWarning } from \"../types.js\"\nimport { JOHAB_UNMAPPED, decodeJohab } from \"./johab.js\"\nimport { Reader } from \"./reader.js\"\nimport { readHeader } from \"./records.js\"\n\nconst PARA_HEADER_FIXED_SIZE = 43 // follow_prev(1) + char_count(2) + line_count(2) + include_cs(1) + flags(1) + sc_flags(4) + style_idx(1) + rep_char_shape(31)\nconst PARA_SHAPE_SIZE = 187 // ParaShape 구조 (rhwp records.rs Hwp3ParaShape::read 합산)\nconst LINE_INFO_SIZE = 14 // Hwp3LineInfo (u16 × 7)\nconst INLINE_CHAR_SHAPE_SIZE = 31 // Hwp3CharShape (rep_char_shape 와 동일)\n// 제어 문자별 ch 외 추가 read byte 수. (ch 는 이미 paragraph loop 가 read 한 후라 여기엔 미포함.)\n// 단위: byte. 동시에 char_count 에서 차지하는 hchar 도 다름 — 아래 EXTRA_HCHAR.\n//\n// rhwp/src/parser/hwp3/mod.rs ch 분기 그대로 옮긴 표.\n// 9 (Tab) : extra=0 byte, hchar=1\n// 18~21 (각종 번호) : extra=6 byte, hchar=4\n// 22 (메일머지) : extra=22 byte, hchar=12\n// 23 (글자겹침) : extra=8 byte, hchar=5\n// 24,25 (하이픈) : extra=4 byte, hchar=3\n// 26 (찾아보기) : extra=244 byte, hchar=123 (1 + 122 추가)\n// 28 (개요번호) : extra=62 byte, hchar=32 (1 + 31 추가)\n// 30 (묶음빈칸) : extra=2 byte, hchar=2\n// 31 (고정폭빈칸) : extra=2 byte, hchar=2\n// 7,8 (날짜) : extra=6 byte, hchar=4\n// default (10/11/12/15/16/17/27/29 등): 8 byte 헤더 + 종류별 추가\ntype CtrlSimple = { extraBytes: number; extraHchar: number; emit: string | null }\nconst SIMPLE_CTRL: ReadonlyMap<number, CtrlSimple> = new Map([\n [9, { extraBytes: 0, extraHchar: 0, emit: \"\\t\" }],\n [7, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\n [8, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\n [18, { extraBytes: 6, extraHchar: 3, emit: \" \" }], // AutoNumber → 공백 (HWP5 패턴)\n [19, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\n [20, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\n [21, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\n [22, { extraBytes: 22, extraHchar: 11, emit: \"\" }],\n [23, { extraBytes: 8, extraHchar: 4, emit: \"\" }],\n [24, { extraBytes: 4, extraHchar: 2, emit: \"-\" }],\n [25, { extraBytes: 4, extraHchar: 2, emit: \"-\" }],\n [26, { extraBytes: 244, extraHchar: 122, emit: \"\" }],\n [28, { extraBytes: 62, extraHchar: 31, emit: \"\" }],\n [30, { extraBytes: 2, extraHchar: 1, emit: \" \" }],\n [31, { extraBytes: 2, extraHchar: 1, emit: \" \" }],\n])\n\ninterface ParaContext {\n /** 누적된 paragraph text 의 array — 각 entry 가 한 paragraph */\n paragraphs: string[]\n warnings: ParseWarning[]\n}\n\nexport interface Hwp3ParseOptions extends ParseOptions {\n /** 표/그림 nested paragraph 본문도 출력 (기본 true). */\n includeNested?: boolean\n}\n\n/**\n * HWP3 buffer → InternalParseResult.\n * encrypted 본문은 복호화 못하고 ENCRYPTED 코드로 throw.\n */\nexport function parseHwp3Document(\n buffer: ArrayBuffer,\n _options?: Hwp3ParseOptions,\n): InternalParseResult {\n const headReader = new Reader(Buffer.from(buffer))\n const header = readHeader(headReader)\n\n if (header.encrypted !== 0) {\n const e: Error & { code?: string } = new Error(\"HWP3 본문이 암호로 보호되어 있어 추출할 수 없습니다.\")\n e.code = \"ENCRYPTED\"\n throw e\n }\n\n // InfoBlock skip — 폰트/스타일 메타데이터, 텍스트 추출엔 불필요.\n headReader.skip(header.infoBlockLength)\n\n // Body: compressed != 0 이면 raw deflate (zlib 헤더 없는 RFC 1951)\n const tail = headReader.readToEnd()\n let body: Buffer\n const warnings: ParseWarning[] = []\n if (header.compressed !== 0) {\n try {\n body = inflateRawSync(tail)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n throw new Error(`HWP3 압축 해제 실패: ${msg}`)\n }\n } else {\n body = tail\n }\n\n const bodyReader = new Reader(body)\n const ctx: ParaContext = { paragraphs: [], warnings }\n try {\n skipFontFacesAndStyles(bodyReader)\n parseParagraphList(bodyReader, ctx)\n } catch (err) {\n // 부분 파싱 실패 — 모은 만큼이라도 반환. truncated 경고 추가.\n warnings.push({\n code: \"PARTIAL_PARSE\",\n message: `HWP3 paragraph stream 도중 파싱 중단: ${err instanceof Error ? err.message : String(err)}`,\n })\n }\n\n const text = ctx.paragraphs.filter(p => p.length > 0).join(\"\\n\\n\")\n const blocks: IRBlock[] = ctx.paragraphs.map(p => ({ type: \"paragraph\", text: p }))\n\n const metadata: DocumentMetadata = {\n title: header.title || undefined,\n author: header.author || undefined,\n description: header.subject || undefined,\n createdAt: header.date || undefined,\n version: \"3.0\",\n }\n\n return {\n markdown: text,\n blocks,\n metadata,\n warnings: warnings.length ? warnings : undefined,\n }\n}\n\n/**\n * 본문 paragraph_list 진입 전 — 압축 해제된 body 의 앞쪽에는 font / style 메타데이터가 있다.\n * rhwp/src/parser/hwp3/mod.rs:1654~1700 흐름 그대로:\n * - 7개 언어별 font face: n_fonts(u16) + n_fonts × 40 byte name\n * - n_styles(u16) + n_styles × (20 byte name + 31 byte char_shape + 187 byte para_shape)\n */\nfunction skipFontFacesAndStyles(reader: Reader): void {\n const STYLE_RECORD_SIZE = 20 + 31 + 187 // = 238\n for (let lang = 0; lang < 7; lang++) {\n const n = reader.readU16()\n reader.skip(n * 40)\n }\n const nStyles = reader.readU16()\n reader.skip(nStyles * STYLE_RECORD_SIZE)\n}\n\n/** char_count==0 빈 paragraph 가 list 끝. */\nfunction parseParagraphList(reader: Reader, ctx: ParaContext): void {\n for (;;) {\n if (reader.eof()) return\n\n // ParaInfo 헤더 (가변 size). list 끝 sentinel(empty para)이 아니어도 stream sync 가\n // 어긋난 이전 paragraph 의 잔재로 비정상 헤더가 들어올 수 있다. char_count 가\n // 1 paragraph 한도(64K) 를 넘는다거나 lineCount 가 비정상적이면 list 종료로 간주.\n const followPrev = reader.readU8()\n const charCount = reader.readU16()\n if (charCount === 0) {\n // 빈 paragraph: 이미 3 byte 읽었으므로 40 byte 더 read 후 종료\n reader.skip(40)\n return\n }\n const lineCount = reader.readU16()\n // 방어: 한 paragraph 의 line 수가 4096 을 넘는 건 stream 어긋남으로 간주.\n if (charCount > 60000 || lineCount > 4096) {\n ctx.warnings.push({\n code: \"PARTIAL_PARSE\",\n message: `HWP3 비정상 paragraph 헤더 (char_count=${charCount}, line_count=${lineCount}) → 이후 stream 포기`,\n })\n return\n }\n const includeCharShape = reader.readU8()\n reader.skip(1) // flags\n reader.skip(4) // special_char_flags\n reader.skip(1) // style_index\n reader.skip(31) // rep_char_shape\n if (followPrev === 0) reader.skip(PARA_SHAPE_SIZE)\n\n // LineInfos\n reader.skip(lineCount * LINE_INFO_SIZE)\n\n // Inline char shapes — char_count 만큼 (flag u8, flag != 1 이면 charshape 31 byte)\n if (includeCharShape !== 0) {\n for (let i = 0; i < charCount; i++) {\n const flag = reader.readU8()\n if (flag !== 1) reader.skip(INLINE_CHAR_SHAPE_SIZE)\n }\n }\n\n // Char stream — paragraph 단위로 try/catch 해서 한 paragraph 가 깨져도 list 전체는\n // 살리되, sync 가 어긋난 후의 후속 paragraph 들도 비정상 헤더가 나올 가능성이 커서\n // 헤더 sanity check 로 방어한다.\n try {\n const text = parseCharStream(reader, charCount, ctx)\n ctx.paragraphs.push(text)\n } catch (err) {\n ctx.warnings.push({\n code: \"PARTIAL_PARSE\",\n message: `HWP3 paragraph #${ctx.paragraphs.length} char stream 파싱 실패: ${err instanceof Error ? err.message : String(err)}`,\n })\n return\n }\n }\n}\n\n/**\n * paragraph 본문 char_count 개의 hchar 를 처리해 텍스트 추출.\n * 제어 문자는 제어 byte 만큼 정확히 소비하고 일부 (10/11/15/16/17 등) 는\n * nested paragraph list 를 별도로 ctx 에 모은다.\n */\nfunction parseCharStream(reader: Reader, charCount: number, ctx: ParaContext): string {\n let out = \"\"\n let i = 0\n while (i < charCount) {\n const ch = reader.readU16()\n i += 1\n\n if (ch === 13) {\n out += \"\\n\"\n continue\n }\n if (ch === 0) {\n // 일부 패딩/오류 케이스 — 무시\n continue\n }\n if (ch >= 32) {\n // 일반 hchar (ASCII < 0x80 영역도 u16 으로 들어옴)\n const cp = decodeJohab(ch)\n if (cp !== JOHAB_UNMAPPED) out += String.fromCodePoint(cp)\n continue\n }\n\n // 1..31 (13 제외) 제어 문자\n const simple = SIMPLE_CTRL.get(ch)\n if (simple) {\n reader.skip(simple.extraBytes)\n i += simple.extraHchar\n if (simple.emit) out += simple.emit\n continue\n }\n\n // ch=10/11/12/14/15/16/17/27/29 등: 8 byte 추가 헤더 + 종류별 추가 처리\n // 8 byte = u32 header_val1 + u16 ch2 + 2 byte (hchar 정렬)\n const headerVal1 = reader.readU32() // size 또는 type-specific\n reader.readU16() // ch2 (sanity, ch와 같아야 함)\n i += 3 // 8 byte 헤더는 char_count 에서 4 hchar 차지 (1 이미 + 3)\n\n // 종류별 분기\n switch (ch) {\n case 10:\n // 표 / 글상자 / 수식 / 버튼: 84 byte info + cells + caption\n out += parseTableLike(reader, ctx)\n break\n case 11:\n // 그림: 348 byte info + n_ext byte\n parsePicture(reader, ctx)\n break\n case 12:\n // 선: 84 byte info\n reader.skip(84)\n break\n case 14:\n // 선 (alternate path) — rhwp mod.rs line 943: 84 byte info\n reader.skip(84)\n break\n case 15: {\n // 숨은 설명: 8 byte info + nested paragraph list\n reader.skip(8)\n parseParagraphList(reader, ctx)\n break\n }\n case 16: {\n // 머리말/꼬리말: 10 byte info + nested\n reader.skip(10)\n parseParagraphList(reader, ctx)\n break\n }\n case 17: {\n // 각주/미주: 14 byte info + nested\n reader.skip(14)\n parseParagraphList(reader, ctx)\n break\n }\n case 29:\n // 상호참조: header_val1 size raw skip (1MB 이상 비정상)\n if (headerVal1 < 1_000_000) reader.skip(headerVal1)\n break\n default:\n // ch=2/3/4/5/6/27 등: rhwp mod.rs:1011 의 \"알 수 없음\" 분기에서\n // header_val1 을 길이로 사용하지 않는다고 명시 (\"ch=3 실증: 헤더 직후가 정상 단락\n // 내용이므로 추가 skip 없음\"). 즉 8 byte 헤더만 소비하고 다음 char 로.\n // 경고는 첫 등장만 기록 — 본문에 페이지번호/필드코드가 많이 깔린 paragraph 가\n // 전형적인 케이스라 logging 폭주 방지.\n if (!ctx.warnings.some(w => w.code === \"UNSUPPORTED_ELEMENT\")) {\n ctx.warnings.push({\n code: \"UNSUPPORTED_ELEMENT\",\n message: `HWP3 부분 처리 제어 문자 ch=${ch} (이후 동일 코드 경고 생략)`,\n })\n }\n break\n }\n }\n return out.trim()\n}\n\n/** ch=10 표/글상자/수식/버튼 본문 텍스트 추출. */\nfunction parseTableLike(reader: Reader, ctx: ParaContext): string {\n // 84 byte info_buf\n const info = reader.readBytes(84)\n const cellCount = info.readUInt16LE(80) || 1\n // 방어: cellCount 가 비정상적으로 크면 stream 어긋남으로 간주, 추가 처리 포기.\n // 한 표에 cell 256 개 초과는 사실상 없음 (HWP3 spec 상 행/열 한계도 그 미만).\n if (cellCount > 256) {\n ctx.warnings.push({\n code: \"PARTIAL_PARSE\",\n message: `HWP3 표 cell_count=${cellCount} 비정상 — 표 본문 추출 포기`,\n })\n throw new Error(`HWP3 비정상 cell_count=${cellCount}`)\n }\n // 각 셀: 27 byte 정보 → 셀별 nested paragraph list (재귀)\n reader.skip(27 * cellCount)\n\n // 셀별 텍스트 collect — 셀 내부 paragraph 는 ctx 에 직접 push 되므로\n // 본 paragraph 의 \"표 자리\" 에는 placeholder 만 남기고 셀 텍스트는 ctx 안에서 별도 paragraph 로 보존.\n for (let i = 0; i < cellCount; i++) {\n parseParagraphList(reader, ctx)\n }\n // 캡션 paragraph list 1회\n parseParagraphList(reader, ctx)\n return \"\" // 표 자리에는 빈 문자열 (셀 텍스트는 이미 ctx.paragraphs 에 포함됨)\n}\n\n/** ch=11 그림 — info 348 byte + n_ext bytes (info[0..4] 가 n_ext). */\nfunction parsePicture(reader: Reader, _ctx: ParaContext): void {\n const info = reader.readBytes(348)\n const nExt = info.readUInt32LE(0)\n if (nExt > 0 && nExt < 100 * 1024 * 1024) reader.skip(nExt)\n}\n","// Auto-generated from rhwp/src/parser/hwp3/johab_map.rs — DO NOT EDIT.\n// Pairs of (johab-code, unicode-codepoint), sorted by key for binary search.\n// Total entries: 5893\n\nexport const JOHAB_SYMBOLS: ReadonlyArray<number> = Object.freeze([\n 0x8441,0x3000, 0x8442,0x3131, 0x8443,0x3132, 0x8444,0x3133, 0x8445,0x3134, 0x8446,0x3135, 0x8447,0x3136, 0x8448,0x3137,\n 0x8449,0x3139, 0x844A,0x313A, 0x844B,0x313B, 0x844C,0x313C, 0x844D,0x313D, 0x844E,0x313E, 0x844F,0x313F, 0x8450,0x3140,\n 0x8451,0x3141, 0x8453,0x3142, 0x8454,0x3144, 0x8455,0x3145, 0x8456,0x3146, 0x8457,0x3147, 0x8458,0x3148, 0x8459,0x314A,\n 0x845A,0x314B, 0x845B,0x314C, 0x845C,0x314D, 0x845D,0x314E, 0x8461,0x314F, 0x8481,0x3150, 0x84A1,0x3151, 0x84C1,0x3152,\n 0x84E1,0x3153, 0x8541,0x3154, 0x8561,0x3155, 0x8581,0x3156, 0x85A1,0x3157, 0x85C1,0x3158, 0x85E1,0x3159, 0x8641,0x315A,\n 0x8661,0x315B, 0x8681,0x315C, 0x86A1,0x315D, 0x86C1,0x315E, 0x86E1,0x315F, 0x8741,0x3160, 0x8761,0x3161, 0x8781,0x3162,\n 0x87A1,0x3163, 0x8841,0x3131, 0x8C41,0x3132, 0x9041,0x3134, 0x9441,0x3137, 0x9841,0x3138, 0x9C41,0x3139, 0xA041,0x3141,\n 0xA441,0x3142, 0xA841,0x3143, 0xAC41,0x3145, 0xB041,0x3146, 0xB441,0x3147, 0xB841,0x3148, 0xBC41,0x3149, 0xC041,0x314A,\n 0xC441,0x314B, 0xC841,0x314C, 0xCC41,0x314D, 0xD041,0x314E, 0xD931,0x3000, 0xD932,0x3001, 0xD933,0x3002, 0xD934,0x00B7,\n 0xD935,0x2025, 0xD936,0x2026, 0xD937,0x00A8, 0xD938,0x3003, 0xD939,0x00AD, 0xD93A,0x2015, 0xD93B,0x2225, 0xD93C,0xFF3C,\n 0xD93D,0x223C, 0xD93E,0x2018, 0xD93F,0x2019, 0xD940,0x201C, 0xD941,0x201D, 0xD942,0x3014, 0xD943,0x3015, 0xD944,0x3008,\n 0xD945,0x3009, 0xD946,0x300A, 0xD947,0x300B, 0xD948,0x300C, 0xD949,0x300D, 0xD94A,0x300E, 0xD94B,0x300F, 0xD94C,0x3010,\n 0xD94D,0x3011, 0xD94E,0x00B1, 0xD94F,0x00D7, 0xD950,0x00F7, 0xD951,0x2260, 0xD952,0x2264, 0xD953,0x2265, 0xD954,0x221E,\n 0xD955,0x2234, 0xD956,0x00B0, 0xD957,0x2032, 0xD958,0x2033, 0xD959,0x2103, 0xD95A,0x212B, 0xD95B,0xFFE0, 0xD95C,0xFFE1,\n 0xD95D,0xFFE5, 0xD95E,0x2642, 0xD95F,0x2640, 0xD960,0x2220, 0xD961,0x22A5, 0xD962,0x2312, 0xD963,0x2202, 0xD964,0x2207,\n 0xD965,0x2261, 0xD966,0x2252, 0xD967,0x00A7, 0xD968,0x203B, 0xD969,0x2606, 0xD96A,0x2605, 0xD96B,0x25CB, 0xD96C,0x25CF,\n 0xD96D,0x25CE, 0xD96E,0x25C7, 0xD96F,0x25C6, 0xD970,0x25A1, 0xD971,0x25A0, 0xD972,0x25B3, 0xD973,0x25B2, 0xD974,0x25BD,\n 0xD975,0x25BC, 0xD976,0x2192, 0xD977,0x2190, 0xD978,0x2191, 0xD979,0x2193, 0xD97A,0x2194, 0xD97B,0x3013, 0xD97C,0x226A,\n 0xD97D,0x226B, 0xD97E,0x221A, 0xD991,0x223D, 0xD992,0x221D, 0xD993,0x2235, 0xD994,0x222B, 0xD995,0x222C, 0xD996,0x2208,\n 0xD997,0x220B, 0xD998,0x2286, 0xD999,0x2287, 0xD99A,0x2282, 0xD99B,0x2283, 0xD99C,0x222A, 0xD99D,0x2229, 0xD99E,0x2227,\n 0xD99F,0x2228, 0xD9A0,0xFFE2, 0xD9A1,0x21D2, 0xD9A2,0x21D4, 0xD9A3,0x2200, 0xD9A4,0x2203, 0xD9A5,0x00B4, 0xD9A6,0xFF5E,\n 0xD9A7,0x02C7, 0xD9A8,0x02D8, 0xD9A9,0x02DD, 0xD9AA,0x02DA, 0xD9AB,0x02D9, 0xD9AC,0x00B8, 0xD9AD,0x02DB, 0xD9AE,0x00A1,\n 0xD9AF,0x00BF, 0xD9B0,0x02D0, 0xD9B1,0x222E, 0xD9B2,0x2211, 0xD9B3,0x220F, 0xD9B4,0x00A4, 0xD9B5,0x2109, 0xD9B6,0x2030,\n 0xD9B7,0x25C1, 0xD9B8,0x25C0, 0xD9B9,0x25B7, 0xD9BA,0x25B6, 0xD9BB,0x2664, 0xD9BC,0x2660, 0xD9BD,0x2661, 0xD9BE,0x2665,\n 0xD9BF,0x2667, 0xD9C0,0x2663, 0xD9C1,0x2299, 0xD9C2,0x25C8, 0xD9C3,0x25A3, 0xD9C4,0x25D0, 0xD9C5,0x25D1, 0xD9C6,0x2592,\n 0xD9C7,0x25A4, 0xD9C8,0x25A5, 0xD9C9,0x25A8, 0xD9CA,0x25A7, 0xD9CB,0x25A6, 0xD9CC,0x25A9, 0xD9CD,0x2668, 0xD9CE,0x260F,\n 0xD9CF,0x260E, 0xD9D0,0x261C, 0xD9D1,0x261E, 0xD9D2,0x00B6, 0xD9D3,0x2020, 0xD9D4,0x2021, 0xD9D5,0x2195, 0xD9D6,0x2197,\n 0xD9D7,0x2199, 0xD9D8,0x2196, 0xD9D9,0x2198, 0xD9DA,0x266D, 0xD9DB,0x2669, 0xD9DC,0x266A, 0xD9DD,0x266C, 0xD9DE,0x327F,\n 0xD9DF,0x321C, 0xD9E0,0x2116, 0xD9E1,0x33C7, 0xD9E2,0x2122, 0xD9E3,0x33C2, 0xD9E4,0x33D8, 0xD9E5,0x2121, 0xD9E6,0x20AC,\n 0xD9E7,0x00AE, 0xDA31,0xFF01, 0xDA32,0xFF02, 0xDA33,0xFF03, 0xDA34,0xFF04, 0xDA35,0xFF05, 0xDA36,0xFF06, 0xDA37,0xFF07,\n 0xDA38,0xFF08, 0xDA39,0xFF09, 0xDA3A,0xFF0A, 0xDA3B,0xFF0B, 0xDA3C,0xFF0C, 0xDA3D,0xFF0D, 0xDA3E,0xFF0E, 0xDA3F,0xFF0F,\n 0xDA40,0xFF10, 0xDA41,0xFF11, 0xDA42,0xFF12, 0xDA43,0xFF13, 0xDA44,0xFF14, 0xDA45,0xFF15, 0xDA46,0xFF16, 0xDA47,0xFF17,\n 0xDA48,0xFF18, 0xDA49,0xFF19, 0xDA4A,0xFF1A, 0xDA4B,0xFF1B, 0xDA4C,0xFF1C, 0xDA4D,0xFF1D, 0xDA4E,0xFF1E, 0xDA4F,0xFF1F,\n 0xDA50,0xFF20, 0xDA51,0xFF21, 0xDA52,0xFF22, 0xDA53,0xFF23, 0xDA54,0xFF24, 0xDA55,0xFF25, 0xDA56,0xFF26, 0xDA57,0xFF27,\n 0xDA58,0xFF28, 0xDA59,0xFF29, 0xDA5A,0xFF2A, 0xDA5B,0xFF2B, 0xDA5C,0xFF2C, 0xDA5D,0xFF2D, 0xDA5E,0xFF2E, 0xDA5F,0xFF2F,\n 0xDA60,0xFF30, 0xDA61,0xFF31, 0xDA62,0xFF32, 0xDA63,0xFF33, 0xDA64,0xFF34, 0xDA65,0xFF35, 0xDA66,0xFF36, 0xDA67,0xFF37,\n 0xDA68,0xFF38, 0xDA69,0xFF39, 0xDA6A,0xFF3A, 0xDA6B,0xFF3B, 0xDA6C,0xFFE6, 0xDA6D,0xFF3D, 0xDA6E,0xFF3E, 0xDA6F,0xFF3F,\n 0xDA70,0xFF40, 0xDA71,0xFF41, 0xDA72,0xFF42, 0xDA73,0xFF43, 0xDA74,0xFF44, 0xDA75,0xFF45, 0xDA76,0xFF46, 0xDA77,0xFF47,\n 0xDA78,0xFF48, 0xDA79,0xFF49, 0xDA7A,0xFF4A, 0xDA7B,0xFF4B, 0xDA7C,0xFF4C, 0xDA7D,0xFF4D, 0xDA7E,0xFF4E, 0xDA91,0xFF4F,\n 0xDA92,0xFF50, 0xDA93,0xFF51, 0xDA94,0xFF52, 0xDA95,0xFF53, 0xDA96,0xFF54, 0xDA97,0xFF55, 0xDA98,0xFF56, 0xDA99,0xFF57,\n 0xDA9A,0xFF58, 0xDA9B,0xFF59, 0xDA9C,0xFF5A, 0xDA9D,0xFF5B, 0xDA9E,0xFF5C, 0xDA9F,0xFF5D, 0xDAA0,0xFFE3, 0xDAD4,0x3164,\n 0xDAD5,0x3165, 0xDAD6,0x3166, 0xDAD7,0x3167, 0xDAD8,0x3168, 0xDAD9,0x3169, 0xDADA,0x316A, 0xDADB,0x316B, 0xDADC,0x316C,\n 0xDADD,0x316D, 0xDADE,0x316E, 0xDADF,0x316F, 0xDAE0,0x3170, 0xDAE1,0x3171, 0xDAE2,0x3172, 0xDAE3,0x3173, 0xDAE4,0x3174,\n 0xDAE5,0x3175, 0xDAE6,0x3176, 0xDAE7,0x3177, 0xDAE8,0x3178, 0xDAE9,0x3179, 0xDAEA,0x317A, 0xDAEB,0x317B, 0xDAEC,0x317C,\n 0xDAED,0x317D, 0xDAEE,0x317E, 0xDAEF,0x317F, 0xDAF0,0x3180, 0xDAF1,0x3181, 0xDAF2,0x3182, 0xDAF3,0x3183, 0xDAF4,0x3184,\n 0xDAF5,0x3185, 0xDAF6,0x3186, 0xDAF7,0x3187, 0xDAF8,0x3188, 0xDAF9,0x3189, 0xDAFA,0x318A, 0xDAFB,0x318B, 0xDAFC,0x318C,\n 0xDAFD,0x318D, 0xDAFE,0x318E, 0xDB31,0x2170, 0xDB32,0x2171, 0xDB33,0x2172, 0xDB34,0x2173, 0xDB35,0x2174, 0xDB36,0x2175,\n 0xDB37,0x2176, 0xDB38,0x2177, 0xDB39,0x2178, 0xDB3A,0x2179, 0xDB40,0x2160, 0xDB41,0x2161, 0xDB42,0x2162, 0xDB43,0x2163,\n 0xDB44,0x2164, 0xDB45,0x2165, 0xDB46,0x2166, 0xDB47,0x2167, 0xDB48,0x2168, 0xDB49,0x2169, 0xDB51,0x0391, 0xDB52,0x0392,\n 0xDB53,0x0393, 0xDB54,0x0394, 0xDB55,0x0395, 0xDB56,0x0396, 0xDB57,0x0397, 0xDB58,0x0398, 0xDB59,0x0399, 0xDB5A,0x039A,\n 0xDB5B,0x039B, 0xDB5C,0x039C, 0xDB5D,0x039D, 0xDB5E,0x039E, 0xDB5F,0x039F, 0xDB60,0x03A0, 0xDB61,0x03A1, 0xDB62,0x03A3,\n 0xDB63,0x03A4, 0xDB64,0x03A5, 0xDB65,0x03A6, 0xDB66,0x03A7, 0xDB67,0x03A8, 0xDB68,0x03A9, 0xDB71,0x03B1, 0xDB72,0x03B2,\n 0xDB73,0x03B3, 0xDB74,0x03B4, 0xDB75,0x03B5, 0xDB76,0x03B6, 0xDB77,0x03B7, 0xDB78,0x03B8, 0xDB79,0x03B9, 0xDB7A,0x03BA,\n 0xDB7B,0x03BB, 0xDB7C,0x03BC, 0xDB7D,0x03BD, 0xDB7E,0x03BE, 0xDB91,0x03BF, 0xDB92,0x03C0, 0xDB93,0x03C1, 0xDB94,0x03C3,\n 0xDB95,0x03C4, 0xDB96,0x03C5, 0xDB97,0x03C6, 0xDB98,0x03C7, 0xDB99,0x03C8, 0xDB9A,0x03C9, 0xDBA1,0x2500, 0xDBA2,0x2502,\n 0xDBA3,0x250C, 0xDBA4,0x2510, 0xDBA5,0x2518, 0xDBA6,0x2514, 0xDBA7,0x251C, 0xDBA8,0x252C, 0xDBA9,0x2524, 0xDBAA,0x2534,\n 0xDBAB,0x253C, 0xDBAC,0x2501, 0xDBAD,0x2503, 0xDBAE,0x250F, 0xDBAF,0x2513, 0xDBB0,0x251B, 0xDBB1,0x2517, 0xDBB2,0x2523,\n 0xDBB3,0x2533, 0xDBB4,0x252B, 0xDBB5,0x253B, 0xDBB6,0x254B, 0xDBB7,0x2520, 0xDBB8,0x252F, 0xDBB9,0x2528, 0xDBBA,0x2537,\n 0xDBBB,0x253F, 0xDBBC,0x251D, 0xDBBD,0x2530, 0xDBBE,0x2525, 0xDBBF,0x2538, 0xDBC0,0x2542, 0xDBC1,0x2512, 0xDBC2,0x2511,\n 0xDBC3,0x251A, 0xDBC4,0x2519, 0xDBC5,0x2516, 0xDBC6,0x2515, 0xDBC7,0x250E, 0xDBC8,0x250D, 0xDBC9,0x251E, 0xDBCA,0x251F,\n 0xDBCB,0x2521, 0xDBCC,0x2522, 0xDBCD,0x2526, 0xDBCE,0x2527, 0xDBCF,0x2529, 0xDBD0,0x252A, 0xDBD1,0x252D, 0xDBD2,0x252E,\n 0xDBD3,0x2531, 0xDBD4,0x2532, 0xDBD5,0x2535, 0xDBD6,0x2536, 0xDBD7,0x2539, 0xDBD8,0x253A, 0xDBD9,0x253D, 0xDBDA,0x253E,\n 0xDBDB,0x2540, 0xDBDC,0x2541, 0xDBDD,0x2543, 0xDBDE,0x2544, 0xDBDF,0x2545, 0xDBE0,0x2546, 0xDBE1,0x2547, 0xDBE2,0x2548,\n 0xDBE3,0x2549, 0xDBE4,0x254A, 0xDC31,0x3395, 0xDC32,0x3396, 0xDC33,0x3397, 0xDC34,0x2113, 0xDC35,0x3398, 0xDC36,0x33C4,\n 0xDC37,0x33A3, 0xDC38,0x33A4, 0xDC39,0x33A5, 0xDC3A,0x33A6, 0xDC3B,0x3399, 0xDC3C,0x339A, 0xDC3D,0x339B, 0xDC3E,0x339C,\n 0xDC3F,0x339D, 0xDC40,0x339E, 0xDC41,0x339F, 0xDC42,0x33A0, 0xDC43,0x33A1, 0xDC44,0x33A2, 0xDC45,0x33CA, 0xDC46,0x338D,\n 0xDC47,0x338E, 0xDC48,0x338F, 0xDC49,0x33CF, 0xDC4A,0x3388, 0xDC4B,0x3389, 0xDC4C,0x33C8, 0xDC4D,0x33A7, 0xDC4E,0x33A8,\n 0xDC4F,0x33B0, 0xDC50,0x33B1, 0xDC51,0x33B2, 0xDC52,0x33B3, 0xDC53,0x33B4, 0xDC54,0x33B5, 0xDC55,0x33B6, 0xDC56,0x33B7,\n 0xDC57,0x33B8, 0xDC58,0x33B9, 0xDC59,0x3380, 0xDC5A,0x3381, 0xDC5B,0x3382, 0xDC5C,0x3383, 0xDC5D,0x3384, 0xDC5E,0x33BA,\n 0xDC5F,0x33BB, 0xDC60,0x33BC, 0xDC61,0x33BD, 0xDC62,0x33BE, 0xDC63,0x33BF, 0xDC64,0x3390, 0xDC65,0x3391, 0xDC66,0x3392,\n 0xDC67,0x3393, 0xDC68,0x3394, 0xDC69,0x2126, 0xDC6A,0x33C0, 0xDC6B,0x33C1, 0xDC6C,0x338A, 0xDC6D,0x338B, 0xDC6E,0x338C,\n 0xDC6F,0x33D6, 0xDC70,0x33C5, 0xDC71,0x33AD, 0xDC72,0x33AE, 0xDC73,0x33AF, 0xDC74,0x33DB, 0xDC75,0x33A9, 0xDC76,0x33AA,\n 0xDC77,0x33AB, 0xDC78,0x33AC, 0xDC79,0x33DD, 0xDC7A,0x33D0, 0xDC7B,0x33D3, 0xDC7C,0x33C3, 0xDC7D,0x33C9, 0xDC7E,0x33DC,\n 0xDC91,0x33C6, 0xDCA1,0x00C6, 0xDCA2,0x00D0, 0xDCA3,0x00AA, 0xDCA4,0x0126, 0xDCA6,0x0132, 0xDCA8,0x013F, 0xDCA9,0x0141,\n 0xDCAA,0x00D8, 0xDCAB,0x0152, 0xDCAC,0x00BA, 0xDCAD,0x00DE, 0xDCAE,0x0166, 0xDCAF,0x014A, 0xDCB1,0x3260, 0xDCB2,0x3261,\n 0xDCB3,0x3262, 0xDCB4,0x3263, 0xDCB5,0x3264, 0xDCB6,0x3265, 0xDCB7,0x3266, 0xDCB8,0x3267, 0xDCB9,0x3268, 0xDCBA,0x3269,\n 0xDCBB,0x326A, 0xDCBC,0x326B, 0xDCBD,0x326C, 0xDCBE,0x326D, 0xDCBF,0x326E, 0xDCC0,0x326F, 0xDCC1,0x3270, 0xDCC2,0x3271,\n 0xDCC3,0x3272, 0xDCC4,0x3273, 0xDCC5,0x3274, 0xDCC6,0x3275, 0xDCC7,0x3276, 0xDCC8,0x3277, 0xDCC9,0x3278, 0xDCCA,0x3279,\n 0xDCCB,0x327A, 0xDCCC,0x327B, 0xDCCD,0x24D0, 0xDCCE,0x24D1, 0xDCCF,0x24D2, 0xDCD0,0x24D3, 0xDCD1,0x24D4, 0xDCD2,0x24D5,\n 0xDCD3,0x24D6, 0xDCD4,0x24D7, 0xDCD5,0x24D8, 0xDCD6,0x24D9, 0xDCD7,0x24DA, 0xDCD8,0x24DB, 0xDCD9,0x24DC, 0xDCDA,0x24DD,\n 0xDCDB,0x24DE, 0xDCDC,0x24DF, 0xDCDD,0x24E0, 0xDCDE,0x24E1, 0xDCDF,0x24E2, 0xDCE0,0x24E3, 0xDCE1,0x24E4, 0xDCE2,0x24E5,\n 0xDCE3,0x24E6, 0xDCE4,0x24E7, 0xDCE5,0x24E8, 0xDCE6,0x24E9, 0xDCE7,0x2460, 0xDCE8,0x2461, 0xDCE9,0x2462, 0xDCEA,0x2463,\n 0xDCEB,0x2464, 0xDCEC,0x2465, 0xDCED,0x2466, 0xDCEE,0x2467, 0xDCEF,0x2468, 0xDCF0,0x2469, 0xDCF1,0x246A, 0xDCF2,0x246B,\n 0xDCF3,0x246C, 0xDCF4,0x246D, 0xDCF5,0x246E, 0xDCF6,0x00BD, 0xDCF7,0x2153, 0xDCF8,0x2154, 0xDCF9,0x00BC, 0xDCFA,0x00BE,\n 0xDCFB,0x215B, 0xDCFC,0x215C, 0xDCFD,0x215D, 0xDCFE,0x215E, 0xDD31,0x00E6, 0xDD32,0x0111, 0xDD33,0x00F0, 0xDD34,0x0127,\n 0xDD35,0x0131, 0xDD36,0x0133, 0xDD37,0x0138, 0xDD38,0x0140, 0xDD39,0x0142, 0xDD3A,0x00F8, 0xDD3B,0x0153, 0xDD3C,0x00DF,\n 0xDD3D,0x00FE, 0xDD3E,0x0167, 0xDD3F,0x014B, 0xDD40,0x0149, 0xDD41,0x3200, 0xDD42,0x3201, 0xDD43,0x3202, 0xDD44,0x3203,\n 0xDD45,0x3204, 0xDD46,0x3205, 0xDD47,0x3206, 0xDD48,0x3207, 0xDD49,0x3208, 0xDD4A,0x3209, 0xDD4B,0x320A, 0xDD4C,0x320B,\n 0xDD4D,0x320C, 0xDD4E,0x320D, 0xDD4F,0x320E, 0xDD50,0x320F, 0xDD51,0x3210, 0xDD52,0x3211, 0xDD53,0x3212, 0xDD54,0x3213,\n 0xDD55,0x3214, 0xDD56,0x3215, 0xDD57,0x3216, 0xDD58,0x3217, 0xDD59,0x3218, 0xDD5A,0x3219, 0xDD5B,0x321A, 0xDD5C,0x321B,\n 0xDD5D,0x249C, 0xDD5E,0x249D, 0xDD5F,0x249E, 0xDD60,0x249F, 0xDD61,0x24A0, 0xDD62,0x24A1, 0xDD63,0x24A2, 0xDD64,0x24A3,\n 0xDD65,0x24A4, 0xDD66,0x24A5, 0xDD67,0x24A6, 0xDD68,0x24A7, 0xDD69,0x24A8, 0xDD6A,0x24A9, 0xDD6B,0x24AA, 0xDD6C,0x24AB,\n 0xDD6D,0x24AC, 0xDD6E,0x24AD, 0xDD6F,0x24AE, 0xDD70,0x24AF, 0xDD71,0x24B0, 0xDD72,0x24B1, 0xDD73,0x24B2, 0xDD74,0x24B3,\n 0xDD75,0x24B4, 0xDD76,0x24B5, 0xDD77,0x2474, 0xDD78,0x2475, 0xDD79,0x2476, 0xDD7A,0x2477, 0xDD7B,0x2478, 0xDD7C,0x2479,\n 0xDD7D,0x247A, 0xDD7E,0x247B, 0xDD91,0x247C, 0xDD92,0x247D, 0xDD93,0x247E, 0xDD94,0x247F, 0xDD95,0x2480, 0xDD96,0x2481,\n 0xDD97,0x2482, 0xDD98,0x00B9, 0xDD99,0x00B2, 0xDD9A,0x00B3, 0xDD9B,0x2074, 0xDD9C,0x207F, 0xDD9D,0x2081, 0xDD9E,0x2082,\n 0xDD9F,0x2083, 0xDDA0,0x2084, 0xDDA1,0x3041, 0xDDA2,0x3042, 0xDDA3,0x3043, 0xDDA4,0x3044, 0xDDA5,0x3045, 0xDDA6,0x3046,\n 0xDDA7,0x3047, 0xDDA8,0x3048, 0xDDA9,0x3049, 0xDDAA,0x304A, 0xDDAB,0x304B, 0xDDAC,0x304C, 0xDDAD,0x304D, 0xDDAE,0x304E,\n 0xDDAF,0x304F, 0xDDB0,0x3050, 0xDDB1,0x3051, 0xDDB2,0x3052, 0xDDB3,0x3053, 0xDDB4,0x3054, 0xDDB5,0x3055, 0xDDB6,0x3056,\n 0xDDB7,0x3057, 0xDDB8,0x3058, 0xDDB9,0x3059, 0xDDBA,0x305A, 0xDDBB,0x305B, 0xDDBC,0x305C, 0xDDBD,0x305D, 0xDDBE,0x305E,\n 0xDDBF,0x305F, 0xDDC0,0x3060, 0xDDC1,0x3061, 0xDDC2,0x3062, 0xDDC3,0x3063, 0xDDC4,0x3064, 0xDDC5,0x3065, 0xDDC6,0x3066,\n 0xDDC7,0x3067, 0xDDC8,0x3068, 0xDDC9,0x3069, 0xDDCA,0x306A, 0xDDCB,0x306B, 0xDDCC,0x306C, 0xDDCD,0x306D, 0xDDCE,0x306E,\n 0xDDCF,0x306F, 0xDDD0,0x3070, 0xDDD1,0x3071, 0xDDD2,0x3072, 0xDDD3,0x3073, 0xDDD4,0x3074, 0xDDD5,0x3075, 0xDDD6,0x3076,\n 0xDDD7,0x3077, 0xDDD8,0x3078, 0xDDD9,0x3079, 0xDDDA,0x307A, 0xDDDB,0x307B, 0xDDDC,0x307C, 0xDDDD,0x307D, 0xDDDE,0x307E,\n 0xDDDF,0x307F, 0xDDE0,0x3080, 0xDDE1,0x3081, 0xDDE2,0x3082, 0xDDE3,0x3083, 0xDDE4,0x3084, 0xDDE5,0x3085, 0xDDE6,0x3086,\n 0xDDE7,0x3087, 0xDDE8,0x3088, 0xDDE9,0x3089, 0xDDEA,0x308A, 0xDDEB,0x308B, 0xDDEC,0x308C, 0xDDED,0x308D, 0xDDEE,0x308E,\n 0xDDEF,0x308F, 0xDDF0,0x3090, 0xDDF1,0x3091, 0xDDF2,0x3092, 0xDDF3,0x3093, 0xDE31,0x30A1, 0xDE32,0x30A2, 0xDE33,0x30A3,\n 0xDE34,0x30A4, 0xDE35,0x30A5, 0xDE36,0x30A6, 0xDE37,0x30A7, 0xDE38,0x30A8, 0xDE39,0x30A9, 0xDE3A,0x30AA, 0xDE3B,0x30AB,\n 0xDE3C,0x30AC, 0xDE3D,0x30AD, 0xDE3E,0x30AE, 0xDE3F,0x30AF, 0xDE40,0x30B0, 0xDE41,0x30B1, 0xDE42,0x30B2, 0xDE43,0x30B3,\n 0xDE44,0x30B4, 0xDE45,0x30B5, 0xDE46,0x30B6, 0xDE47,0x30B7, 0xDE48,0x30B8, 0xDE49,0x30B9, 0xDE4A,0x30BA, 0xDE4B,0x30BB,\n 0xDE4C,0x30BC, 0xDE4D,0x30BD, 0xDE4E,0x30BE, 0xDE4F,0x30BF, 0xDE50,0x30C0, 0xDE51,0x30C1, 0xDE52,0x30C2, 0xDE53,0x30C3,\n 0xDE54,0x30C4, 0xDE55,0x30C5, 0xDE56,0x30C6, 0xDE57,0x30C7, 0xDE58,0x30C8, 0xDE59,0x30C9, 0xDE5A,0x30CA, 0xDE5B,0x30CB,\n 0xDE5C,0x30CC, 0xDE5D,0x30CD, 0xDE5E,0x30CE, 0xDE5F,0x30CF, 0xDE60,0x30D0, 0xDE61,0x30D1, 0xDE62,0x30D2, 0xDE63,0x30D3,\n 0xDE64,0x30D4, 0xDE65,0x30D5, 0xDE66,0x30D6, 0xDE67,0x30D7, 0xDE68,0x30D8, 0xDE69,0x30D9, 0xDE6A,0x30DA, 0xDE6B,0x30DB,\n 0xDE6C,0x30DC, 0xDE6D,0x30DD, 0xDE6E,0x30DE, 0xDE6F,0x30DF, 0xDE70,0x30E0, 0xDE71,0x30E1, 0xDE72,0x30E2, 0xDE73,0x30E3,\n 0xDE74,0x30E4, 0xDE75,0x30E5, 0xDE76,0x30E6, 0xDE77,0x30E7, 0xDE78,0x30E8, 0xDE79,0x30E9, 0xDE7A,0x30EA, 0xDE7B,0x30EB,\n 0xDE7C,0x30EC, 0xDE7D,0x30ED, 0xDE7E,0x30EE, 0xDE91,0x30EF, 0xDE92,0x30F0, 0xDE93,0x30F1, 0xDE94,0x30F2, 0xDE95,0x30F3,\n 0xDE96,0x30F4, 0xDE97,0x30F5, 0xDE98,0x30F6, 0xDEA1,0x0410, 0xDEA2,0x0411, 0xDEA3,0x0412, 0xDEA4,0x0413, 0xDEA5,0x0414,\n 0xDEA6,0x0415, 0xDEA7,0x0401, 0xDEA8,0x0416, 0xDEA9,0x0417, 0xDEAA,0x0418, 0xDEAB,0x0419, 0xDEAC,0x041A, 0xDEAD,0x041B,\n 0xDEAE,0x041C, 0xDEAF,0x041D, 0xDEB0,0x041E, 0xDEB1,0x041F, 0xDEB2,0x0420, 0xDEB3,0x0421, 0xDEB4,0x0422, 0xDEB5,0x0423,\n 0xDEB6,0x0424, 0xDEB7,0x0425, 0xDEB8,0x0426, 0xDEB9,0x0427, 0xDEBA,0x0428, 0xDEBB,0x0429, 0xDEBC,0x042A, 0xDEBD,0x042B,\n 0xDEBE,0x042C, 0xDEBF,0x042D, 0xDEC0,0x042E, 0xDEC1,0x042F, 0xDED1,0x0430, 0xDED2,0x0431, 0xDED3,0x0432, 0xDED4,0x0433,\n 0xDED5,0x0434, 0xDED6,0x0435, 0xDED7,0x0451, 0xDED8,0x0436, 0xDED9,0x0437, 0xDEDA,0x0438, 0xDEDB,0x0439, 0xDEDC,0x043A,\n 0xDEDD,0x043B, 0xDEDE,0x043C, 0xDEDF,0x043D, 0xDEE0,0x043E, 0xDEE1,0x043F, 0xDEE2,0x0440, 0xDEE3,0x0441, 0xDEE4,0x0442,\n 0xDEE5,0x0443, 0xDEE6,0x0444, 0xDEE7,0x0445, 0xDEE8,0x0446, 0xDEE9,0x0447, 0xDEEA,0x0448, 0xDEEB,0x0449, 0xDEEC,0x044A,\n 0xDEED,0x044B, 0xDEEE,0x044C, 0xDEEF,0x044D, 0xDEF0,0x044E, 0xDEF1,0x044F, 0xE031,0x4F3D, 0xE032,0x4F73, 0xE033,0x5047,\n 0xE034,0x50F9, 0xE035,0x52A0, 0xE036,0x53EF, 0xE037,0x5475, 0xE038,0x54E5, 0xE039,0x5609, 0xE03A,0x5AC1, 0xE03B,0x5BB6,\n 0xE03C,0x6687, 0xE03D,0x67B6, 0xE03E,0x67B7, 0xE03F,0x67EF, 0xE040,0x6B4C, 0xE041,0x73C2, 0xE042,0x75C2, 0xE043,0x7A3C,\n 0xE044,0x82DB, 0xE045,0x8304, 0xE046,0x8857, 0xE047,0x8888, 0xE048,0x8A36, 0xE049,0x8CC8, 0xE04A,0x8DCF, 0xE04B,0x8EFB,\n 0xE04C,0x8FE6, 0xE04D,0x99D5, 0xE04E,0x523B, 0xE04F,0x5374, 0xE050,0x5404, 0xE051,0x606A, 0xE052,0x6164, 0xE053,0x6BBC,\n 0xE054,0x73CF, 0xE055,0x811A, 0xE056,0x89BA, 0xE057,0x89D2, 0xE058,0x95A3, 0xE059,0x4F83, 0xE05A,0x520A, 0xE05B,0x58BE,\n 0xE05C,0x5978, 0xE05D,0x59E6, 0xE05E,0x5E72, 0xE05F,0x5E79, 0xE060,0x61C7, 0xE061,0x63C0, 0xE062,0x6746, 0xE063,0x67EC,\n 0xE064,0x687F, 0xE065,0x6F97, 0xE066,0x764E, 0xE067,0x770B, 0xE068,0x78F5, 0xE069,0x7A08, 0xE06A,0x7AFF, 0xE06B,0x7C21,\n 0xE06C,0x809D, 0xE06D,0x826E, 0xE06E,0x8271, 0xE06F,0x8AEB, 0xE070,0x9593, 0xE071,0x4E6B, 0xE072,0x559D, 0xE073,0x66F7,\n 0xE074,0x6E34, 0xE075,0x78A3, 0xE076,0x7AED, 0xE077,0x845B, 0xE078,0x8910, 0xE079,0x874E, 0xE07A,0x97A8, 0xE07B,0x52D8,\n 0xE07C,0x574E, 0xE07D,0x582A, 0xE07E,0x5D4C, 0xE091,0x611F, 0xE092,0x61BE, 0xE093,0x6221, 0xE094,0x6562, 0xE095,0x67D1,\n 0xE096,0x6A44, 0xE097,0x6E1B, 0xE098,0x7518, 0xE099,0x75B3, 0xE09A,0x76E3, 0xE09B,0x77B0, 0xE09C,0x7D3A, 0xE09D,0x90AF,\n 0xE09E,0x9451, 0xE09F,0x9452, 0xE0A0,0x9F95, 0xE0A1,0x5323, 0xE0A2,0x5CAC, 0xE0A3,0x7532, 0xE0A4,0x80DB, 0xE0A5,0x9240,\n 0xE0A6,0x9598, 0xE0A7,0x525B, 0xE0A8,0x5808, 0xE0A9,0x59DC, 0xE0AA,0x5CA1, 0xE0AB,0x5D17, 0xE0AC,0x5EB7, 0xE0AD,0x5F3A,\n 0xE0AE,0x5F4A, 0xE0AF,0x6177, 0xE0B0,0x6C5F, 0xE0B1,0x757A, 0xE0B2,0x7586, 0xE0B3,0x7CE0, 0xE0B4,0x7D73, 0xE0B5,0x7DB1,\n 0xE0B6,0x7F8C, 0xE0B7,0x8154, 0xE0B8,0x8221, 0xE0B9,0x8591, 0xE0BA,0x8941, 0xE0BB,0x8B1B, 0xE0BC,0x92FC, 0xE0BD,0x964D,\n 0xE0BE,0x9C47, 0xE0BF,0x4ECB, 0xE0C0,0x4EF7, 0xE0C1,0x500B, 0xE0C2,0x51F1, 0xE0C3,0x584F, 0xE0C4,0x6137, 0xE0C5,0x613E,\n 0xE0C6,0x6168, 0xE0C7,0x6539, 0xE0C8,0x69EA, 0xE0C9,0x6F11, 0xE0CA,0x75A5, 0xE0CB,0x7686, 0xE0CC,0x76D6, 0xE0CD,0x7B87,\n 0xE0CE,0x82A5, 0xE0CF,0x84CB, 0xE0D0,0xF900, 0xE0D1,0x93A7, 0xE0D2,0x958B, 0xE0D3,0x5580, 0xE0D4,0x5BA2, 0xE0D5,0x5751,\n 0xE0D6,0xF901, 0xE0D7,0x7CB3, 0xE0D8,0x7FB9, 0xE0D9,0x91B5, 0xE0DA,0x5028, 0xE0DB,0x53BB, 0xE0DC,0x5C45, 0xE0DD,0x5DE8,\n 0xE0DE,0x62D2, 0xE0DF,0x636E, 0xE0E0,0x64DA, 0xE0E1,0x64E7, 0xE0E2,0x6E20, 0xE0E3,0x70AC, 0xE0E4,0x795B, 0xE0E5,0x8DDD,\n 0xE0E6,0x8E1E, 0xE0E7,0xF902, 0xE0E8,0x907D, 0xE0E9,0x9245, 0xE0EA,0x92F8, 0xE0EB,0x4E7E, 0xE0EC,0x4EF6, 0xE0ED,0x5065,\n 0xE0EE,0x5DFE, 0xE0EF,0x5EFA, 0xE0F0,0x6106, 0xE0F1,0x6957, 0xE0F2,0x8171, 0xE0F3,0x8654, 0xE0F4,0x8E47, 0xE0F5,0x9375,\n 0xE0F6,0x9A2B, 0xE0F7,0x4E5E, 0xE0F8,0x5091, 0xE0F9,0x6770, 0xE0FA,0x6840, 0xE0FB,0x5109, 0xE0FC,0x528D, 0xE0FD,0x5292,\n 0xE0FE,0x6AA2, 0xE131,0x77BC, 0xE132,0x9210, 0xE133,0x9ED4, 0xE134,0x52AB, 0xE135,0x602F, 0xE136,0x8FF2, 0xE137,0x5048,\n 0xE138,0x61A9, 0xE139,0x63ED, 0xE13A,0x64CA, 0xE13B,0x683C, 0xE13C,0x6A84, 0xE13D,0x6FC0, 0xE13E,0x8188, 0xE13F,0x89A1,\n 0xE140,0x9694, 0xE141,0x5805, 0xE142,0x727D, 0xE143,0x72AC, 0xE144,0x7504, 0xE145,0x7D79, 0xE146,0x7E6D, 0xE147,0x80A9,\n 0xE148,0x898B, 0xE149,0x8B74, 0xE14A,0x9063, 0xE14B,0x9D51, 0xE14C,0x6289, 0xE14D,0x6C7A, 0xE14E,0x6F54, 0xE14F,0x7D50,\n 0xE150,0x7F3A, 0xE151,0x8A23, 0xE152,0x517C, 0xE153,0x614A, 0xE154,0x7B9D, 0xE155,0x8B19, 0xE156,0x9257, 0xE157,0x938C,\n 0xE158,0x4EAC, 0xE159,0x4FD3, 0xE15A,0x501E, 0xE15B,0x50BE, 0xE15C,0x5106, 0xE15D,0x52C1, 0xE15E,0x52CD, 0xE15F,0x537F,\n 0xE160,0x5770, 0xE161,0x5883, 0xE162,0x5E9A, 0xE163,0x5F91, 0xE164,0x6176, 0xE165,0x61AC, 0xE166,0x64CE, 0xE167,0x656C,\n 0xE168,0x666F, 0xE169,0x66BB, 0xE16A,0x66F4, 0xE16B,0x6897, 0xE16C,0x6D87, 0xE16D,0x7085, 0xE16E,0x70F1, 0xE16F,0x749F,\n 0xE170,0x74A5, 0xE171,0x74CA, 0xE172,0x75D9, 0xE173,0x786C, 0xE174,0x78EC, 0xE175,0x7ADF, 0xE176,0x7AF6, 0xE177,0x7D45,\n 0xE178,0x7D93, 0xE179,0x8015, 0xE17A,0x803F, 0xE17B,0x811B, 0xE17C,0x8396, 0xE17D,0x8B66, 0xE17E,0x8F15, 0xE191,0x9015,\n 0xE192,0x93E1, 0xE193,0x9803, 0xE194,0x9838, 0xE195,0x9A5A, 0xE196,0x9BE8, 0xE197,0x4FC2, 0xE198,0x5553, 0xE199,0x583A,\n 0xE19A,0x5951, 0xE19B,0x5B63, 0xE19C,0x5C46, 0xE19D,0x60B8, 0xE19E,0x6212, 0xE19F,0x6842, 0xE1A0,0x68B0, 0xE1A1,0x68E8,\n 0xE1A2,0x6EAA, 0xE1A3,0x754C, 0xE1A4,0x7678, 0xE1A5,0x78CE, 0xE1A6,0x7A3D, 0xE1A7,0x7CFB, 0xE1A8,0x7E6B, 0xE1A9,0x7E7C,\n 0xE1AA,0x8A08, 0xE1AB,0x8AA1, 0xE1AC,0x8C3F, 0xE1AD,0x968E, 0xE1AE,0x9DC4, 0xE1AF,0x53E4, 0xE1B0,0x53E9, 0xE1B1,0x544A,\n 0xE1B2,0x5471, 0xE1B3,0x56FA, 0xE1B4,0x59D1, 0xE1B5,0x5B64, 0xE1B6,0x5C3B, 0xE1B7,0x5EAB, 0xE1B8,0x62F7, 0xE1B9,0x6537,\n 0xE1BA,0x6545, 0xE1BB,0x6572, 0xE1BC,0x66A0, 0xE1BD,0x67AF, 0xE1BE,0x69C1, 0xE1BF,0x6CBD, 0xE1C0,0x75FC, 0xE1C1,0x7690,\n 0xE1C2,0x777E, 0xE1C3,0x7A3F, 0xE1C4,0x7F94, 0xE1C5,0x8003, 0xE1C6,0x80A1, 0xE1C7,0x818F, 0xE1C8,0x82E6, 0xE1C9,0x82FD,\n 0xE1CA,0x83F0, 0xE1CB,0x85C1, 0xE1CC,0x8831, 0xE1CD,0x88B4, 0xE1CE,0x8AA5, 0xE1CF,0xF903, 0xE1D0,0x8F9C, 0xE1D1,0x932E,\n 0xE1D2,0x96C7, 0xE1D3,0x9867, 0xE1D4,0x9AD8, 0xE1D5,0x9F13, 0xE1D6,0x54ED, 0xE1D7,0x659B, 0xE1D8,0x66F2, 0xE1D9,0x688F,\n 0xE1DA,0x7A40, 0xE1DB,0x8C37, 0xE1DC,0x9D60, 0xE1DD,0x56F0, 0xE1DE,0x5764, 0xE1DF,0x5D11, 0xE1E0,0x6606, 0xE1E1,0x68B1,\n 0xE1E2,0x68CD, 0xE1E3,0x6EFE, 0xE1E4,0x7428, 0xE1E5,0x889E, 0xE1E6,0x9BE4, 0xE1E7,0x6C68, 0xE1E8,0xF904, 0xE1E9,0x9AA8,\n 0xE1EA,0x4F9B, 0xE1EB,0x516C, 0xE1EC,0x5171, 0xE1ED,0x529F, 0xE1EE,0x5B54, 0xE1EF,0x5DE5, 0xE1F0,0x6050, 0xE1F1,0x606D,\n 0xE1F2,0x62F1, 0xE1F3,0x63A7, 0xE1F4,0x653B, 0xE1F5,0x73D9, 0xE1F6,0x7A7A, 0xE1F7,0x86A3, 0xE1F8,0x8CA2, 0xE1F9,0x978F,\n 0xE1FA,0x4E32, 0xE1FB,0x5BE1, 0xE1FC,0x6208, 0xE1FD,0x679C, 0xE1FE,0x74DC, 0xE231,0x79D1, 0xE232,0x83D3, 0xE233,0x8A87,\n 0xE234,0x8AB2, 0xE235,0x8DE8, 0xE236,0x904E, 0xE237,0x934B, 0xE238,0x9846, 0xE239,0x5ED3, 0xE23A,0x69E8, 0xE23B,0x85FF,\n 0xE23C,0x90ED, 0xE23D,0xF905, 0xE23E,0x51A0, 0xE23F,0x5B98, 0xE240,0x5BEC, 0xE241,0x6163, 0xE242,0x68FA, 0xE243,0x6B3E,\n 0xE244,0x704C, 0xE245,0x742F, 0xE246,0x74D8, 0xE247,0x7BA1, 0xE248,0x7F50, 0xE249,0x83C5, 0xE24A,0x89C0, 0xE24B,0x8CAB,\n 0xE24C,0x95DC, 0xE24D,0x9928, 0xE24E,0x522E, 0xE24F,0x605D, 0xE250,0x62EC, 0xE251,0x9002, 0xE252,0x4F8A, 0xE253,0x5149,\n 0xE254,0x5321, 0xE255,0x58D9, 0xE256,0x5EE3, 0xE257,0x66E0, 0xE258,0x6D38, 0xE259,0x709A, 0xE25A,0x72C2, 0xE25B,0x73D6,\n 0xE25C,0x7B50, 0xE25D,0x80F1, 0xE25E,0x945B, 0xE25F,0x5366, 0xE260,0x639B, 0xE261,0x7F6B, 0xE262,0x4E56, 0xE263,0x5080,\n 0xE264,0x584A, 0xE265,0x58DE, 0xE266,0x602A, 0xE267,0x6127, 0xE268,0x62D0, 0xE269,0x69D0, 0xE26A,0x9B41, 0xE26B,0x5B8F,\n 0xE26C,0x7D18, 0xE26D,0x80B1, 0xE26E,0x8F5F, 0xE26F,0x4EA4, 0xE270,0x50D1, 0xE271,0x54AC, 0xE272,0x55AC, 0xE273,0x5B0C,\n 0xE274,0x5DA0, 0xE275,0x5DE7, 0xE276,0x652A, 0xE277,0x654E, 0xE278,0x6821, 0xE279,0x6A4B, 0xE27A,0x72E1, 0xE27B,0x768E,\n 0xE27C,0x77EF, 0xE27D,0x7D5E, 0xE27E,0x7FF9, 0xE291,0x81A0, 0xE292,0x854E, 0xE293,0x86DF, 0xE294,0x8F03, 0xE295,0x8F4E,\n 0xE296,0x90CA, 0xE297,0x9903, 0xE298,0x9A55, 0xE299,0x9BAB, 0xE29A,0x4E18, 0xE29B,0x4E45, 0xE29C,0x4E5D, 0xE29D,0x4EC7,\n 0xE29E,0x4FF1, 0xE29F,0x5177, 0xE2A0,0x52FE, 0xE2A1,0x5340, 0xE2A2,0x53E3, 0xE2A3,0x53E5, 0xE2A4,0x548E, 0xE2A5,0x5614,\n 0xE2A6,0x5775, 0xE2A7,0x57A2, 0xE2A8,0x5BC7, 0xE2A9,0x5D87, 0xE2AA,0x5ED0, 0xE2AB,0x61FC, 0xE2AC,0x62D8, 0xE2AD,0x6551,\n 0xE2AE,0x67B8, 0xE2AF,0x67E9, 0xE2B0,0x69CB, 0xE2B1,0x6B50, 0xE2B2,0x6BC6, 0xE2B3,0x6BEC, 0xE2B4,0x6C42, 0xE2B5,0x6E9D,\n 0xE2B6,0x7078, 0xE2B7,0x72D7, 0xE2B8,0x7396, 0xE2B9,0x7403, 0xE2BA,0x77BF, 0xE2BB,0x77E9, 0xE2BC,0x7A76, 0xE2BD,0x7D7F,\n 0xE2BE,0x8009, 0xE2BF,0x81FC, 0xE2C0,0x8205, 0xE2C1,0x820A, 0xE2C2,0x82DF, 0xE2C3,0x8862, 0xE2C4,0x8B33, 0xE2C5,0x8CFC,\n 0xE2C6,0x8EC0, 0xE2C7,0x9011, 0xE2C8,0x90B1, 0xE2C9,0x9264, 0xE2CA,0x92B6, 0xE2CB,0x99D2, 0xE2CC,0x9A45, 0xE2CD,0x9CE9,\n 0xE2CE,0x9DD7, 0xE2CF,0x9F9C, 0xE2D0,0x570B, 0xE2D1,0x5C40, 0xE2D2,0x83CA, 0xE2D3,0x97A0, 0xE2D4,0x97AB, 0xE2D5,0x9EB4,\n 0xE2D6,0x541B, 0xE2D7,0x7A98, 0xE2D8,0x7FA4, 0xE2D9,0x88D9, 0xE2DA,0x8ECD, 0xE2DB,0x90E1, 0xE2DC,0x5800, 0xE2DD,0x5C48,\n 0xE2DE,0x6398, 0xE2DF,0x7A9F, 0xE2E0,0x5BAE, 0xE2E1,0x5F13, 0xE2E2,0x7A79, 0xE2E3,0x7AAE, 0xE2E4,0x828E, 0xE2E5,0x8EAC,\n 0xE2E6,0x5026, 0xE2E7,0x5238, 0xE2E8,0x52F8, 0xE2E9,0x5377, 0xE2EA,0x5708, 0xE2EB,0x62F3, 0xE2EC,0x6372, 0xE2ED,0x6B0A,\n 0xE2EE,0x6DC3, 0xE2EF,0x7737, 0xE2F0,0x53A5, 0xE2F1,0x7357, 0xE2F2,0x8568, 0xE2F3,0x8E76, 0xE2F4,0x95D5, 0xE2F5,0x673A,\n 0xE2F6,0x6AC3, 0xE2F7,0x6F70, 0xE2F8,0x8A6D, 0xE2F9,0x8ECC, 0xE2FA,0x994B, 0xE2FB,0xF906, 0xE2FC,0x6677, 0xE2FD,0x6B78,\n 0xE2FE,0x8CB4, 0xE331,0x9B3C, 0xE332,0xF907, 0xE333,0x53EB, 0xE334,0x572D, 0xE335,0x594E, 0xE336,0x63C6, 0xE337,0x69FB,\n 0xE338,0x73EA, 0xE339,0x7845, 0xE33A,0x7ABA, 0xE33B,0x7AC5, 0xE33C,0x7CFE, 0xE33D,0x8475, 0xE33E,0x898F, 0xE33F,0x8D73,\n 0xE340,0x9035, 0xE341,0x95A8, 0xE342,0x52FB, 0xE343,0x5747, 0xE344,0x7547, 0xE345,0x7B60, 0xE346,0x83CC, 0xE347,0x921E,\n 0xE348,0xF908, 0xE349,0x6A58, 0xE34A,0x514B, 0xE34B,0x524B, 0xE34C,0x5287, 0xE34D,0x621F, 0xE34E,0x68D8, 0xE34F,0x6975,\n 0xE350,0x9699, 0xE351,0x50C5, 0xE352,0x52A4, 0xE353,0x52E4, 0xE354,0x61C3, 0xE355,0x65A4, 0xE356,0x6839, 0xE357,0x69FF,\n 0xE358,0x747E, 0xE359,0x7B4B, 0xE35A,0x82B9, 0xE35B,0x83EB, 0xE35C,0x89B2, 0xE35D,0x8B39, 0xE35E,0x8FD1, 0xE35F,0x9949,\n 0xE360,0xF909, 0xE361,0x4ECA, 0xE362,0x5997, 0xE363,0x64D2, 0xE364,0x6611, 0xE365,0x6A8E, 0xE366,0x7434, 0xE367,0x7981,\n 0xE368,0x79BD, 0xE369,0x82A9, 0xE36A,0x887E, 0xE36B,0x887F, 0xE36C,0x895F, 0xE36D,0xF90A, 0xE36E,0x9326, 0xE36F,0x4F0B,\n 0xE370,0x53CA, 0xE371,0x6025, 0xE372,0x6271, 0xE373,0x6C72, 0xE374,0x7D1A, 0xE375,0x7D66, 0xE376,0x4E98, 0xE377,0x5162,\n 0xE378,0x77DC, 0xE379,0x80AF, 0xE37A,0x4F01, 0xE37B,0x4F0E, 0xE37C,0x5176, 0xE37D,0x5180, 0xE37E,0x55DC, 0xE391,0x5668,\n 0xE392,0x573B, 0xE393,0x57FA, 0xE394,0x57FC, 0xE395,0x5914, 0xE396,0x5947, 0xE397,0x5993, 0xE398,0x5BC4, 0xE399,0x5C90,\n 0xE39A,0x5D0E, 0xE39B,0x5DF1, 0xE39C,0x5E7E, 0xE39D,0x5FCC, 0xE39E,0x6280, 0xE39F,0x65D7, 0xE3A0,0x65E3, 0xE3A1,0x671E,\n 0xE3A2,0x671F, 0xE3A3,0x675E, 0xE3A4,0x68CB, 0xE3A5,0x68C4, 0xE3A6,0x6A5F, 0xE3A7,0x6B3A, 0xE3A8,0x6C23, 0xE3A9,0x6C7D,\n 0xE3AA,0x6C82, 0xE3AB,0x6DC7, 0xE3AC,0x7398, 0xE3AD,0x7426, 0xE3AE,0x742A, 0xE3AF,0x7482, 0xE3B0,0x74A3, 0xE3B1,0x7578,\n 0xE3B2,0x757F, 0xE3B3,0x7881, 0xE3B4,0x78EF, 0xE3B5,0x7941, 0xE3B6,0x7947, 0xE3B7,0x7948, 0xE3B8,0x797A, 0xE3B9,0x7B95,\n 0xE3BA,0x7D00, 0xE3BB,0x7DBA, 0xE3BC,0x7F88, 0xE3BD,0x8006, 0xE3BE,0x802D, 0xE3BF,0x808C, 0xE3C0,0x8A18, 0xE3C1,0x8B4F,\n 0xE3C2,0x8C48, 0xE3C3,0x8D77, 0xE3C4,0x9321, 0xE3C5,0x9324, 0xE3C6,0x98E2, 0xE3C7,0x9951, 0xE3C8,0x9A0E, 0xE3C9,0x9A0F,\n 0xE3CA,0x9A65, 0xE3CB,0x9E92, 0xE3CC,0x7DCA, 0xE3CD,0x4F76, 0xE3CE,0x5409, 0xE3CF,0x62EE, 0xE3D0,0x6854, 0xE3D1,0x91D1,\n 0xE3D2,0x55AB, 0xE3D3,0x513A, 0xE3D4,0xF90B, 0xE3D5,0xF90C, 0xE3D6,0x5A1C, 0xE3D7,0x61E6, 0xE3D8,0xF90D, 0xE3D9,0x62CF,\n 0xE3DA,0x62FF, 0xE3DB,0xF90E, 0xE3DC,0xF90F, 0xE3DD,0xF910, 0xE3DE,0xF911, 0xE3DF,0xF912, 0xE3E0,0xF913, 0xE3E1,0x90A3,\n 0xE3E2,0xF914, 0xE3E3,0xF915, 0xE3E4,0xF916, 0xE3E5,0xF917, 0xE3E6,0xF918, 0xE3E7,0x8AFE, 0xE3E8,0xF919, 0xE3E9,0xF91A,\n 0xE3EA,0xF91B, 0xE3EB,0xF91C, 0xE3EC,0x6696, 0xE3ED,0xF91D, 0xE3EE,0x7156, 0xE3EF,0xF91E, 0xE3F0,0xF91F, 0xE3F1,0x96E3,\n 0xE3F2,0xF920, 0xE3F3,0x634F, 0xE3F4,0x637A, 0xE3F5,0x5357, 0xE3F6,0xF921, 0xE3F7,0x678F, 0xE3F8,0x6960, 0xE3F9,0x6E73,\n 0xE3FA,0xF922, 0xE3FB,0x7537, 0xE3FC,0xF923, 0xE3FD,0xF924, 0xE3FE,0xF925, 0xE431,0x7D0D, 0xE432,0xF926, 0xE433,0xF927,\n 0xE434,0x8872, 0xE435,0x56CA, 0xE436,0x5A18, 0xE437,0xF928, 0xE438,0xF929, 0xE439,0xF92A, 0xE43A,0xF92B, 0xE43B,0xF92C,\n 0xE43C,0x4E43, 0xE43D,0xF92D, 0xE43E,0x5167, 0xE43F,0x5948, 0xE440,0x67F0, 0xE441,0x8010, 0xE442,0xF92E, 0xE443,0x5973,\n 0xE444,0x5E74, 0xE445,0x649A, 0xE446,0x79CA, 0xE447,0x5FF5, 0xE448,0x606C, 0xE449,0x62C8, 0xE44A,0x637B, 0xE44B,0x5BE7,\n 0xE44C,0x5BD7, 0xE44D,0x52AA, 0xE44E,0xF92F, 0xE44F,0x5974, 0xE450,0x5F29, 0xE451,0x6012, 0xE452,0xF930, 0xE453,0xF931,\n 0xE454,0xF932, 0xE455,0x7459, 0xE456,0xF933, 0xE457,0xF934, 0xE458,0xF935, 0xE459,0xF936, 0xE45A,0xF937, 0xE45B,0xF938,\n 0xE45C,0x99D1, 0xE45D,0xF939, 0xE45E,0xF93A, 0xE45F,0xF93B, 0xE460,0xF93C, 0xE461,0xF93D, 0xE462,0xF93E, 0xE463,0xF93F,\n 0xE464,0xF940, 0xE465,0xF941, 0xE466,0xF942, 0xE467,0xF943, 0xE468,0x6FC3, 0xE469,0xF944, 0xE46A,0xF945, 0xE46B,0x81BF,\n 0xE46C,0x8FB2, 0xE46D,0x60F1, 0xE46E,0xF946, 0xE46F,0xF947, 0xE470,0x8166, 0xE471,0xF948, 0xE472,0xF949, 0xE473,0x5C3F,\n 0xE474,0xF94A, 0xE475,0xF94B, 0xE476,0xF94C, 0xE477,0xF94D, 0xE478,0xF94E, 0xE479,0xF94F, 0xE47A,0xF950, 0xE47B,0xF951,\n 0xE47C,0x5AE9, 0xE47D,0x8A25, 0xE47E,0x677B, 0xE491,0x7D10, 0xE492,0xF952, 0xE493,0xF953, 0xE494,0xF954, 0xE495,0xF955,\n 0xE496,0xF956, 0xE497,0xF957, 0xE498,0x80FD, 0xE499,0xF958, 0xE49A,0xF959, 0xE49B,0x5C3C, 0xE49C,0x6CE5, 0xE49D,0x533F,\n 0xE49E,0x6EBA, 0xE49F,0x591A, 0xE4A0,0x8336, 0xE4A1,0x4E39, 0xE4A2,0x4EB6, 0xE4A3,0x4F46, 0xE4A4,0x55AE, 0xE4A5,0x5718,\n 0xE4A6,0x58C7, 0xE4A7,0x5F56, 0xE4A8,0x65B7, 0xE4A9,0x65E6, 0xE4AA,0x6A80, 0xE4AB,0x6BB5, 0xE4AC,0x6E4D, 0xE4AD,0x77ED,\n 0xE4AE,0x7AEF, 0xE4AF,0x7C1E, 0xE4B0,0x7DDE, 0xE4B1,0x86CB, 0xE4B2,0x8892, 0xE4B3,0x9132, 0xE4B4,0x935B, 0xE4B5,0x64BB,\n 0xE4B6,0x6FBE, 0xE4B7,0x737A, 0xE4B8,0x75B8, 0xE4B9,0x9054, 0xE4BA,0x5556, 0xE4BB,0x574D, 0xE4BC,0x61BA, 0xE4BD,0x64D4,\n 0xE4BE,0x66C7, 0xE4BF,0x6DE1, 0xE4C0,0x6E5B, 0xE4C1,0x6F6D, 0xE4C2,0x6FB9, 0xE4C3,0x75F0, 0xE4C4,0x8043, 0xE4C5,0x81BD,\n 0xE4C6,0x8541, 0xE4C7,0x8983, 0xE4C8,0x8AC7, 0xE4C9,0x8B5A, 0xE4CA,0x931F, 0xE4CB,0x6C93, 0xE4CC,0x7553, 0xE4CD,0x7B54,\n 0xE4CE,0x8E0F, 0xE4CF,0x905D, 0xE4D0,0x5510, 0xE4D1,0x5802, 0xE4D2,0x5858, 0xE4D3,0x5E62, 0xE4D4,0x6207, 0xE4D5,0x649E,\n 0xE4D6,0x68E0, 0xE4D7,0x7576, 0xE4D8,0x7CD6, 0xE4D9,0x87B3, 0xE4DA,0x9EE8, 0xE4DB,0x4EE3, 0xE4DC,0x5788, 0xE4DD,0x576E,\n 0xE4DE,0x5927, 0xE4DF,0x5C0D, 0xE4E0,0x5CB1, 0xE4E1,0x5E36, 0xE4E2,0x5F85, 0xE4E3,0x6234, 0xE4E4,0x64E1, 0xE4E5,0x73B3,\n 0xE4E6,0x81FA, 0xE4E7,0x888B, 0xE4E8,0x8CB8, 0xE4E9,0x968A, 0xE4EA,0x9EDB, 0xE4EB,0x5B85, 0xE4EC,0x5FB7, 0xE4ED,0x60B3,\n 0xE4EE,0x5012, 0xE4EF,0x5200, 0xE4F0,0x5230, 0xE4F1,0x5716, 0xE4F2,0x5835, 0xE4F3,0x5857, 0xE4F4,0x5C0E, 0xE4F5,0x5C60,\n 0xE4F6,0x5CF6, 0xE4F7,0x5D8B, 0xE4F8,0x5EA6, 0xE4F9,0x5F92, 0xE4FA,0x60BC, 0xE4FB,0x6311, 0xE4FC,0x6389, 0xE4FD,0x6417,\n 0xE4FE,0x6843, 0xE531,0x68F9, 0xE532,0x6AC2, 0xE533,0x6DD8, 0xE534,0x6E21, 0xE535,0x6ED4, 0xE536,0x6FE4, 0xE537,0x71FE,\n 0xE538,0x76DC, 0xE539,0x7779, 0xE53A,0x79B1, 0xE53B,0x7A3B, 0xE53C,0x8404, 0xE53D,0x89A9, 0xE53E,0x8CED, 0xE53F,0x8DF3,\n 0xE540,0x8E48, 0xE541,0x9003, 0xE542,0x9014, 0xE543,0x9053, 0xE544,0x90FD, 0xE545,0x934D, 0xE546,0x9676, 0xE547,0x97DC,\n 0xE548,0x6BD2, 0xE549,0x7006, 0xE54A,0x7258, 0xE54B,0x72A2, 0xE54C,0x7368, 0xE54D,0x7763, 0xE54E,0x79BF, 0xE54F,0x7BE4,\n 0xE550,0x7E9B, 0xE551,0x8B80, 0xE552,0x58A9, 0xE553,0x60C7, 0xE554,0x6566, 0xE555,0x65FD, 0xE556,0x66BE, 0xE557,0x6C8C,\n 0xE558,0x711E, 0xE559,0x71C9, 0xE55A,0x8C5A, 0xE55B,0x9813, 0xE55C,0x4E6D, 0xE55D,0x7A81, 0xE55E,0x4EDD, 0xE55F,0x51AC,\n 0xE560,0x51CD, 0xE561,0x52D5, 0xE562,0x540C, 0xE563,0x61A7, 0xE564,0x6771, 0xE565,0x6850, 0xE566,0x68DF, 0xE567,0x6D1E,\n 0xE568,0x6F7C, 0xE569,0x75BC, 0xE56A,0x77B3, 0xE56B,0x7AE5, 0xE56C,0x80F4, 0xE56D,0x8463, 0xE56E,0x9285, 0xE56F,0x515C,\n 0xE570,0x6597, 0xE571,0x675C, 0xE572,0x6793, 0xE573,0x75D8, 0xE574,0x7AC7, 0xE575,0x8373, 0xE576,0xF95A, 0xE577,0x8C46,\n 0xE578,0x9017, 0xE579,0x982D, 0xE57A,0x5C6F, 0xE57B,0x81C0, 0xE57C,0x829A, 0xE57D,0x9041, 0xE57E,0x906F, 0xE591,0x920D,\n 0xE592,0x5F97, 0xE593,0x5D9D, 0xE594,0x6A59, 0xE595,0x71C8, 0xE596,0x767B, 0xE597,0x7B49, 0xE598,0x85E4, 0xE599,0x8B04,\n 0xE59A,0x9127, 0xE59B,0x9A30, 0xE59C,0x5587, 0xE59D,0x61F6, 0xE59E,0xF95B, 0xE59F,0x7669, 0xE5A0,0x7F85, 0xE5A1,0x863F,\n 0xE5A2,0x87BA, 0xE5A3,0x88F8, 0xE5A4,0x908F, 0xE5A5,0xF95C, 0xE5A6,0x6D1B, 0xE5A7,0x70D9, 0xE5A8,0x73DE, 0xE5A9,0x7D61,\n 0xE5AA,0x843D, 0xE5AB,0xF95D, 0xE5AC,0x916A, 0xE5AD,0x99F1, 0xE5AE,0xF95E, 0xE5AF,0x4E82, 0xE5B0,0x5375, 0xE5B1,0x6B04,\n 0xE5B2,0x6B12, 0xE5B3,0x703E, 0xE5B4,0x721B, 0xE5B5,0x862D, 0xE5B6,0x9E1E, 0xE5B7,0x524C, 0xE5B8,0x8FA3, 0xE5B9,0x5D50,\n 0xE5BA,0x64E5, 0xE5BB,0x652C, 0xE5BC,0x6B16, 0xE5BD,0x6FEB, 0xE5BE,0x7C43, 0xE5BF,0x7E9C, 0xE5C0,0x85CD, 0xE5C1,0x8964,\n 0xE5C2,0x89BD, 0xE5C3,0x62C9, 0xE5C4,0x81D8, 0xE5C5,0x881F, 0xE5C6,0x5ECA, 0xE5C7,0x6717, 0xE5C8,0x6D6A, 0xE5C9,0x72FC,\n 0xE5CA,0x7405, 0xE5CB,0x746F, 0xE5CC,0x8782, 0xE5CD,0x90DE, 0xE5CE,0x4F86, 0xE5CF,0x5D0D, 0xE5D0,0x5FA0, 0xE5D1,0x840A,\n 0xE5D2,0x51B7, 0xE5D3,0x63A0, 0xE5D4,0x7565, 0xE5D5,0x4EAE, 0xE5D6,0x5006, 0xE5D7,0x5169, 0xE5D8,0x51C9, 0xE5D9,0x6881,\n 0xE5DA,0x6A11, 0xE5DB,0x7CAE, 0xE5DC,0x7CB1, 0xE5DD,0x7CE7, 0xE5DE,0x826F, 0xE5DF,0x8AD2, 0xE5E0,0x8F1B, 0xE5E1,0x91CF,\n 0xE5E2,0x4FB6, 0xE5E3,0x5137, 0xE5E4,0x52F5, 0xE5E5,0x5442, 0xE5E6,0x5EEC, 0xE5E7,0x616E, 0xE5E8,0x623E, 0xE5E9,0x65C5,\n 0xE5EA,0x6ADA, 0xE5EB,0x6FFE, 0xE5EC,0x792A, 0xE5ED,0x85DC, 0xE5EE,0x8823, 0xE5EF,0x95AD, 0xE5F0,0x9A62, 0xE5F1,0x9A6A,\n 0xE5F2,0x9E97, 0xE5F3,0x9ECE, 0xE5F4,0x529B, 0xE5F5,0x66C6, 0xE5F6,0x6B77, 0xE5F7,0x701D, 0xE5F8,0x792B, 0xE5F9,0x8F62,\n 0xE5FA,0x9742, 0xE5FB,0x6190, 0xE5FC,0x6200, 0xE5FD,0x6523, 0xE5FE,0x6F23, 0xE631,0x7149, 0xE632,0x7489, 0xE633,0x7DF4,\n 0xE634,0x806F, 0xE635,0x84EE, 0xE636,0x8F26, 0xE637,0x9023, 0xE638,0x934A, 0xE639,0x51BD, 0xE63A,0x5217, 0xE63B,0x52A3,\n 0xE63C,0x6D0C, 0xE63D,0x70C8, 0xE63E,0x88C2, 0xE63F,0x5EC9, 0xE640,0x6582, 0xE641,0x6BAE, 0xE642,0x6FC2, 0xE643,0x7C3E,\n 0xE644,0x7375, 0xE645,0x4EE4, 0xE646,0x4F36, 0xE647,0x56F9, 0xE648,0xF95F, 0xE649,0x5CBA, 0xE64A,0x5DBA, 0xE64B,0x601C,\n 0xE64C,0x73B2, 0xE64D,0x7B2D, 0xE64E,0x7F9A, 0xE64F,0x7FCE, 0xE650,0x8046, 0xE651,0x901E, 0xE652,0x9234, 0xE653,0x96F6,\n 0xE654,0x9748, 0xE655,0x9818, 0xE656,0x9F61, 0xE657,0x4F8B, 0xE658,0x6FA7, 0xE659,0x79AE, 0xE65A,0x91B4, 0xE65B,0x96B7,\n 0xE65C,0x52DE, 0xE65D,0xF960, 0xE65E,0x6488, 0xE65F,0x64C4, 0xE660,0x6AD3, 0xE661,0x6F5E, 0xE662,0x7018, 0xE663,0x7210,\n 0xE664,0x76E7, 0xE665,0x8001, 0xE666,0x8606, 0xE667,0x865C, 0xE668,0x8DEF, 0xE669,0x8F05, 0xE66A,0x9732, 0xE66B,0x9B6F,\n 0xE66C,0x9DFA, 0xE66D,0x9E75, 0xE66E,0x788C, 0xE66F,0x797F, 0xE670,0x7DA0, 0xE671,0x83C9, 0xE672,0x9304, 0xE673,0x9E7F,\n 0xE674,0x9E93, 0xE675,0x8AD6, 0xE676,0x58DF, 0xE677,0x5F04, 0xE678,0x6727, 0xE679,0x7027, 0xE67A,0x74CF, 0xE67B,0x7C60,\n 0xE67C,0x807E, 0xE67D,0x5121, 0xE67E,0x7028, 0xE691,0x7262, 0xE692,0x78CA, 0xE693,0x8CC2, 0xE694,0x8CDA, 0xE695,0x8CF4,\n 0xE696,0x96F7, 0xE697,0x4E86, 0xE698,0x50DA, 0xE699,0x5BEE, 0xE69A,0x5ED6, 0xE69B,0x6599, 0xE69C,0x71CE, 0xE69D,0x7642,\n 0xE69E,0x77AD, 0xE69F,0x804A, 0xE6A0,0x84FC, 0xE6A1,0x907C, 0xE6A2,0x9B27, 0xE6A3,0x9F8D, 0xE6A4,0x58D8, 0xE6A5,0x5A41,\n 0xE6A6,0x5C62, 0xE6A7,0x6A13, 0xE6A8,0x6DDA, 0xE6A9,0x6F0F, 0xE6AA,0x763B, 0xE6AB,0x7D2F, 0xE6AC,0x7E37, 0xE6AD,0x851E,\n 0xE6AE,0x8938, 0xE6AF,0x93E4, 0xE6B0,0x964B, 0xE6B1,0x5289, 0xE6B2,0x65D2, 0xE6B3,0x67F3, 0xE6B4,0x69B4, 0xE6B5,0x6D41,\n 0xE6B6,0x6E9C, 0xE6B7,0x700F, 0xE6B8,0x7409, 0xE6B9,0x7460, 0xE6BA,0x7559, 0xE6BB,0x7624, 0xE6BC,0x786B, 0xE6BD,0x8B2C,\n 0xE6BE,0x985E, 0xE6BF,0x516D, 0xE6C0,0x622E, 0xE6C1,0x9678, 0xE6C2,0x4F96, 0xE6C3,0x502B, 0xE6C4,0x5D19, 0xE6C5,0x6DEA,\n 0xE6C6,0x7DB8, 0xE6C7,0x8F2A, 0xE6C8,0x5F8B, 0xE6C9,0x6144, 0xE6CA,0x6817, 0xE6CB,0xF961, 0xE6CC,0x9686, 0xE6CD,0x52D2,\n 0xE6CE,0x808B, 0xE6CF,0x51DC, 0xE6D0,0x51CC, 0xE6D1,0x695E, 0xE6D2,0x7A1C, 0xE6D3,0x7DBE, 0xE6D4,0x83F1, 0xE6D5,0x9675,\n 0xE6D6,0x4FDA, 0xE6D7,0x5229, 0xE6D8,0x5398, 0xE6D9,0x540F, 0xE6DA,0x550E, 0xE6DB,0x5C65, 0xE6DC,0x60A7, 0xE6DD,0x674E,\n 0xE6DE,0x68A8, 0xE6DF,0x6D6C, 0xE6E0,0x7281, 0xE6E1,0x72F8, 0xE6E2,0x7406, 0xE6E3,0x7483, 0xE6E4,0xF962, 0xE6E5,0x75E2,\n 0xE6E6,0x7C6C, 0xE6E7,0x7F79, 0xE6E8,0x7FB8, 0xE6E9,0x8389, 0xE6EA,0x88CF, 0xE6EB,0x88E1, 0xE6EC,0x91CC, 0xE6ED,0x91D0,\n 0xE6EE,0x96E2, 0xE6EF,0x9BC9, 0xE6F0,0x541D, 0xE6F1,0x6F7E, 0xE6F2,0x71D0, 0xE6F3,0x7498, 0xE6F4,0x85FA, 0xE6F5,0x8EAA,\n 0xE6F6,0x96A3, 0xE6F7,0x9C57, 0xE6F8,0x9E9F, 0xE6F9,0x6797, 0xE6FA,0x6DCB, 0xE6FB,0x7433, 0xE6FC,0x81E8, 0xE6FD,0x9716,\n 0xE6FE,0x782C, 0xE731,0x7ACB, 0xE732,0x7B20, 0xE733,0x7C92, 0xE734,0x6469, 0xE735,0x746A, 0xE736,0x75F2, 0xE737,0x78BC,\n 0xE738,0x78E8, 0xE739,0x99AC, 0xE73A,0x9B54, 0xE73B,0x9EBB, 0xE73C,0x5BDE, 0xE73D,0x5E55, 0xE73E,0x6F20, 0xE73F,0x819C,\n 0xE740,0x83AB, 0xE741,0x9088, 0xE742,0x4E07, 0xE743,0x534D, 0xE744,0x5A29, 0xE745,0x5DD2, 0xE746,0x5F4E, 0xE747,0x6162,\n 0xE748,0x633D, 0xE749,0x6669, 0xE74A,0x66FC, 0xE74B,0x6EFF, 0xE74C,0x6F2B, 0xE74D,0x7063, 0xE74E,0x779E, 0xE74F,0x842C,\n 0xE750,0x8513, 0xE751,0x883B, 0xE752,0x8F13, 0xE753,0x9945, 0xE754,0x9C3B, 0xE755,0x551C, 0xE756,0x62B9, 0xE757,0x672B,\n 0xE758,0x6CAB, 0xE759,0x8309, 0xE75A,0x896A, 0xE75B,0x977A, 0xE75C,0x4EA1, 0xE75D,0x5984, 0xE75E,0x5FD8, 0xE75F,0x5FD9,\n 0xE760,0x671B, 0xE761,0x7DB2, 0xE762,0x7F54, 0xE763,0x8292, 0xE764,0x832B, 0xE765,0x83BD, 0xE766,0x8F1E, 0xE767,0x9099,\n 0xE768,0x57CB, 0xE769,0x59B9, 0xE76A,0x5A92, 0xE76B,0x5BD0, 0xE76C,0x6627, 0xE76D,0x679A, 0xE76E,0x6885, 0xE76F,0x6BCF,\n 0xE770,0x7164, 0xE771,0x7F75, 0xE772,0x8CB7, 0xE773,0x8CE3, 0xE774,0x9081, 0xE775,0x9B45, 0xE776,0x8108, 0xE777,0x8C8A,\n 0xE778,0x964C, 0xE779,0x9A40, 0xE77A,0x9EA5, 0xE77B,0x5B5F, 0xE77C,0x6C13, 0xE77D,0x731B, 0xE77E,0x76F2, 0xE791,0x76DF,\n 0xE792,0x840C, 0xE793,0x51AA, 0xE794,0x8993, 0xE795,0x514D, 0xE796,0x5195, 0xE797,0x52C9, 0xE798,0x68C9, 0xE799,0x6C94,\n 0xE79A,0x7704, 0xE79B,0x7720, 0xE79C,0x7DBF, 0xE79D,0x7DEC, 0xE79E,0x9762, 0xE79F,0x9EB5, 0xE7A0,0x6EC5, 0xE7A1,0x8511,\n 0xE7A2,0x51A5, 0xE7A3,0x540D, 0xE7A4,0x547D, 0xE7A5,0x660E, 0xE7A6,0x669D, 0xE7A7,0x6927, 0xE7A8,0x6E9F, 0xE7A9,0x76BF,\n 0xE7AA,0x7791, 0xE7AB,0x8317, 0xE7AC,0x84C2, 0xE7AD,0x879F, 0xE7AE,0x9169, 0xE7AF,0x9298, 0xE7B0,0x9CF4, 0xE7B1,0x8882,\n 0xE7B2,0x4FAE, 0xE7B3,0x5192, 0xE7B4,0x52DF, 0xE7B5,0x59C6, 0xE7B6,0x5E3D, 0xE7B7,0x6155, 0xE7B8,0x6478, 0xE7B9,0x6479,\n 0xE7BA,0x66AE, 0xE7BB,0x67D0, 0xE7BC,0x6A21, 0xE7BD,0x6BCD, 0xE7BE,0x6BDB, 0xE7BF,0x725F, 0xE7C0,0x7261, 0xE7C1,0x7441,\n 0xE7C2,0x7738, 0xE7C3,0x77DB, 0xE7C4,0x8017, 0xE7C5,0x82BC, 0xE7C6,0x8305, 0xE7C7,0x8B00, 0xE7C8,0x8B28, 0xE7C9,0x8C8C,\n 0xE7CA,0x6728, 0xE7CB,0x6C90, 0xE7CC,0x7267, 0xE7CD,0x76EE, 0xE7CE,0x7766, 0xE7CF,0x7A46, 0xE7D0,0x9DA9, 0xE7D1,0x6B7F,\n 0xE7D2,0x6C92, 0xE7D3,0x5922, 0xE7D4,0x6726, 0xE7D5,0x8499, 0xE7D6,0x536F, 0xE7D7,0x5893, 0xE7D8,0x5999, 0xE7D9,0x5EDF,\n 0xE7DA,0x63CF, 0xE7DB,0x6634, 0xE7DC,0x6773, 0xE7DD,0x6E3A, 0xE7DE,0x732B, 0xE7DF,0x7AD7, 0xE7E0,0x82D7, 0xE7E1,0x9328,\n 0xE7E2,0x52D9, 0xE7E3,0x5DEB, 0xE7E4,0x61AE, 0xE7E5,0x61CB, 0xE7E6,0x620A, 0xE7E7,0x62C7, 0xE7E8,0x64AB, 0xE7E9,0x65E0,\n 0xE7EA,0x6959, 0xE7EB,0x6B66, 0xE7EC,0x6BCB, 0xE7ED,0x7121, 0xE7EE,0x73F7, 0xE7EF,0x755D, 0xE7F0,0x7E46, 0xE7F1,0x821E,\n 0xE7F2,0x8302, 0xE7F3,0x856A, 0xE7F4,0x8AA3, 0xE7F5,0x8CBF, 0xE7F6,0x9727, 0xE7F7,0x9D61, 0xE7F8,0x58A8, 0xE7F9,0x9ED8,\n 0xE7FA,0x5011, 0xE7FB,0x520E, 0xE7FC,0x543B, 0xE7FD,0x554F, 0xE7FE,0x6587, 0xE831,0x6C76, 0xE832,0x7D0A, 0xE833,0x7D0B,\n 0xE834,0x805E, 0xE835,0x868A, 0xE836,0x9580, 0xE837,0x96EF, 0xE838,0x52FF, 0xE839,0x6C95, 0xE83A,0x7269, 0xE83B,0x5473,\n 0xE83C,0x5A9A, 0xE83D,0x5C3E, 0xE83E,0x5D4B, 0xE83F,0x5F4C, 0xE840,0x5FAE, 0xE841,0x672A, 0xE842,0x68B6, 0xE843,0x6963,\n 0xE844,0x6E3C, 0xE845,0x6E44, 0xE846,0x7709, 0xE847,0x7C73, 0xE848,0x7F8E, 0xE849,0x8587, 0xE84A,0x8B0E, 0xE84B,0x8FF7,\n 0xE84C,0x9761, 0xE84D,0x9EF4, 0xE84E,0x5CB7, 0xE84F,0x60B6, 0xE850,0x610D, 0xE851,0x61AB, 0xE852,0x654F, 0xE853,0x65FB,\n 0xE854,0x65FC, 0xE855,0x6C11, 0xE856,0x6CEF, 0xE857,0x739F, 0xE858,0x73C9, 0xE859,0x7DE1, 0xE85A,0x9594, 0xE85B,0x5BC6,\n 0xE85C,0x871C, 0xE85D,0x8B10, 0xE85E,0x525D, 0xE85F,0x535A, 0xE860,0x62CD, 0xE861,0x640F, 0xE862,0x64B2, 0xE863,0x6734,\n 0xE864,0x6A38, 0xE865,0x6CCA, 0xE866,0x73C0, 0xE867,0x749E, 0xE868,0x7B94, 0xE869,0x7C95, 0xE86A,0x7E1B, 0xE86B,0x818A,\n 0xE86C,0x8236, 0xE86D,0x8584, 0xE86E,0x8FEB, 0xE86F,0x96F9, 0xE870,0x99C1, 0xE871,0x4F34, 0xE872,0x534A, 0xE873,0x53CD,\n 0xE874,0x53DB, 0xE875,0x62CC, 0xE876,0x642C, 0xE877,0x6500, 0xE878,0x6591, 0xE879,0x69C3, 0xE87A,0x6CEE, 0xE87B,0x6F58,\n 0xE87C,0x73ED, 0xE87D,0x7554, 0xE87E,0x7622, 0xE891,0x76E4, 0xE892,0x76FC, 0xE893,0x78D0, 0xE894,0x78FB, 0xE895,0x792C,\n 0xE896,0x7D46, 0xE897,0x822C, 0xE898,0x87E0, 0xE899,0x8FD4, 0xE89A,0x9812, 0xE89B,0x98EF, 0xE89C,0x52C3, 0xE89D,0x62D4,\n 0xE89E,0x64A5, 0xE89F,0x6E24, 0xE8A0,0x6F51, 0xE8A1,0x767C, 0xE8A2,0x8DCB, 0xE8A3,0x91B1, 0xE8A4,0x9262, 0xE8A5,0x9AEE,\n 0xE8A6,0x9B43, 0xE8A7,0x5023, 0xE8A8,0x508D, 0xE8A9,0x574A, 0xE8AA,0x59A8, 0xE8AB,0x5C28, 0xE8AC,0x5E47, 0xE8AD,0x5F77,\n 0xE8AE,0x623F, 0xE8AF,0x653E, 0xE8B0,0x65B9, 0xE8B1,0x65C1, 0xE8B2,0x6609, 0xE8B3,0x678B, 0xE8B4,0x699C, 0xE8B5,0x6EC2,\n 0xE8B6,0x78C5, 0xE8B7,0x7D21, 0xE8B8,0x80AA, 0xE8B9,0x8180, 0xE8BA,0x822B, 0xE8BB,0x82B3, 0xE8BC,0x84A1, 0xE8BD,0x868C,\n 0xE8BE,0x8A2A, 0xE8BF,0x8B17, 0xE8C0,0x90A6, 0xE8C1,0x9632, 0xE8C2,0x9F90, 0xE8C3,0x500D, 0xE8C4,0x4FF3, 0xE8C5,0xF963,\n 0xE8C6,0x57F9, 0xE8C7,0x5F98, 0xE8C8,0x62DC, 0xE8C9,0x6392, 0xE8CA,0x676F, 0xE8CB,0x6E43, 0xE8CC,0x7119, 0xE8CD,0x76C3,\n 0xE8CE,0x80CC, 0xE8CF,0x80DA, 0xE8D0,0x88F4, 0xE8D1,0x88F5, 0xE8D2,0x8919, 0xE8D3,0x8CE0, 0xE8D4,0x8F29, 0xE8D5,0x914D,\n 0xE8D6,0x966A, 0xE8D7,0x4F2F, 0xE8D8,0x4F70, 0xE8D9,0x5E1B, 0xE8DA,0x67CF, 0xE8DB,0x6822, 0xE8DC,0x767D, 0xE8DD,0x767E,\n 0xE8DE,0x9B44, 0xE8DF,0x5E61, 0xE8E0,0x6A0A, 0xE8E1,0x7169, 0xE8E2,0x71D4, 0xE8E3,0x756A, 0xE8E4,0xF964, 0xE8E5,0x7E41,\n 0xE8E6,0x8543, 0xE8E7,0x85E9, 0xE8E8,0x98DC, 0xE8E9,0x4F10, 0xE8EA,0x7B4F, 0xE8EB,0x7F70, 0xE8EC,0x95A5, 0xE8ED,0x51E1,\n 0xE8EE,0x5E06, 0xE8EF,0x68B5, 0xE8F0,0x6C3E, 0xE8F1,0x6C4E, 0xE8F2,0x6CDB, 0xE8F3,0x72AF, 0xE8F4,0x7BC4, 0xE8F5,0x8303,\n 0xE8F6,0x6CD5, 0xE8F7,0x743A, 0xE8F8,0x50FB, 0xE8F9,0x5288, 0xE8FA,0x58C1, 0xE8FB,0x64D8, 0xE8FC,0x6A97, 0xE8FD,0x74A7,\n 0xE8FE,0x7656, 0xE931,0x78A7, 0xE932,0x8617, 0xE933,0x95E2, 0xE934,0x9739, 0xE935,0xF965, 0xE936,0x535E, 0xE937,0x5F01,\n 0xE938,0x8B8A, 0xE939,0x8FA8, 0xE93A,0x8FAF, 0xE93B,0x908A, 0xE93C,0x5225, 0xE93D,0x77A5, 0xE93E,0x9C49, 0xE93F,0x9F08,\n 0xE940,0x4E19, 0xE941,0x5002, 0xE942,0x5175, 0xE943,0x5C5B, 0xE944,0x5E77, 0xE945,0x661E, 0xE946,0x663A, 0xE947,0x67C4,\n 0xE948,0x68C5, 0xE949,0x70B3, 0xE94A,0x7501, 0xE94B,0x75C5, 0xE94C,0x79C9, 0xE94D,0x7ADD, 0xE94E,0x8F27, 0xE94F,0x9920,\n 0xE950,0x9A08, 0xE951,0x4FDD, 0xE952,0x5821, 0xE953,0x5831, 0xE954,0x5BF6, 0xE955,0x666E, 0xE956,0x6B65, 0xE957,0x6D11,\n 0xE958,0x6E7A, 0xE959,0x6F7D, 0xE95A,0x73E4, 0xE95B,0x752B, 0xE95C,0x83E9, 0xE95D,0x88DC, 0xE95E,0x8913, 0xE95F,0x8B5C,\n 0xE960,0x8F14, 0xE961,0x4F0F, 0xE962,0x50D5, 0xE963,0x5310, 0xE964,0x535C, 0xE965,0x5B93, 0xE966,0x5FA9, 0xE967,0x670D,\n 0xE968,0x798F, 0xE969,0x8179, 0xE96A,0x832F, 0xE96B,0x8514, 0xE96C,0x8907, 0xE96D,0x8986, 0xE96E,0x8F39, 0xE96F,0x8F3B,\n 0xE970,0x99A5, 0xE971,0x9C12, 0xE972,0x672C, 0xE973,0x4E76, 0xE974,0x4FF8, 0xE975,0x5949, 0xE976,0x5C01, 0xE977,0x5CEF,\n 0xE978,0x5CF0, 0xE979,0x6367, 0xE97A,0x68D2, 0xE97B,0x70FD, 0xE97C,0x71A2, 0xE97D,0x742B, 0xE97E,0x7E2B, 0xE991,0x84EC,\n 0xE992,0x8702, 0xE993,0x9022, 0xE994,0x92D2, 0xE995,0x9CF3, 0xE996,0x4E0D, 0xE997,0x4ED8, 0xE998,0x4FEF, 0xE999,0x5085,\n 0xE99A,0x5256, 0xE99B,0x526F, 0xE99C,0x5426, 0xE99D,0x5490, 0xE99E,0x57E0, 0xE99F,0x592B, 0xE9A0,0x5A66, 0xE9A1,0x5B5A,\n 0xE9A2,0x5B75, 0xE9A3,0x5BCC, 0xE9A4,0x5E9C, 0xE9A5,0xF966, 0xE9A6,0x6276, 0xE9A7,0x6577, 0xE9A8,0x65A7, 0xE9A9,0x6D6E,\n 0xE9AA,0x6EA5, 0xE9AB,0x7236, 0xE9AC,0x7B26, 0xE9AD,0x7C3F, 0xE9AE,0x7F36, 0xE9AF,0x8150, 0xE9B0,0x8151, 0xE9B1,0x819A,\n 0xE9B2,0x8240, 0xE9B3,0x8299, 0xE9B4,0x83A9, 0xE9B5,0x8A03, 0xE9B6,0x8CA0, 0xE9B7,0x8CE6, 0xE9B8,0x8CFB, 0xE9B9,0x8D74,\n 0xE9BA,0x8DBA, 0xE9BB,0x90E8, 0xE9BC,0x91DC, 0xE9BD,0x961C, 0xE9BE,0x9644, 0xE9BF,0x99D9, 0xE9C0,0x9CE7, 0xE9C1,0x5317,\n 0xE9C2,0x5206, 0xE9C3,0x5429, 0xE9C4,0x5674, 0xE9C5,0x58B3, 0xE9C6,0x5954, 0xE9C7,0x596E, 0xE9C8,0x5FFF, 0xE9C9,0x61A4,\n 0xE9CA,0x626E, 0xE9CB,0x6610, 0xE9CC,0x6C7E, 0xE9CD,0x711A, 0xE9CE,0x76C6, 0xE9CF,0x7C89, 0xE9D0,0x7CDE, 0xE9D1,0x7D1B,\n 0xE9D2,0x82AC, 0xE9D3,0x8CC1, 0xE9D4,0x96F0, 0xE9D5,0xF967, 0xE9D6,0x4F5B, 0xE9D7,0x5F17, 0xE9D8,0x5F7F, 0xE9D9,0x62C2,\n 0xE9DA,0x5D29, 0xE9DB,0x670B, 0xE9DC,0x68DA, 0xE9DD,0x787C, 0xE9DE,0x7E43, 0xE9DF,0x9D6C, 0xE9E0,0x4E15, 0xE9E1,0x5099,\n 0xE9E2,0x5315, 0xE9E3,0x532A, 0xE9E4,0x5351, 0xE9E5,0x5983, 0xE9E6,0x5A62, 0xE9E7,0x5E87, 0xE9E8,0x60B2, 0xE9E9,0x618A,\n 0xE9EA,0x6249, 0xE9EB,0x6279, 0xE9EC,0x6590, 0xE9ED,0x6787, 0xE9EE,0x69A7, 0xE9EF,0x6BD4, 0xE9F0,0x6BD6, 0xE9F1,0x6BD7,\n 0xE9F2,0x6BD8, 0xE9F3,0x6CB8, 0xE9F4,0xF968, 0xE9F5,0x7435, 0xE9F6,0x75FA, 0xE9F7,0x7812, 0xE9F8,0x7891, 0xE9F9,0x79D5,\n 0xE9FA,0x79D8, 0xE9FB,0x7C83, 0xE9FC,0x7DCB, 0xE9FD,0x7FE1, 0xE9FE,0x80A5, 0xEA31,0x813E, 0xEA32,0x81C2, 0xEA33,0x83F2,\n 0xEA34,0x871A, 0xEA35,0x88E8, 0xEA36,0x8AB9, 0xEA37,0x8B6C, 0xEA38,0x8CBB, 0xEA39,0x9119, 0xEA3A,0x975E, 0xEA3B,0x98DB,\n 0xEA3C,0x9F3B, 0xEA3D,0x56AC, 0xEA3E,0x5B2A, 0xEA3F,0x5F6C, 0xEA40,0x658C, 0xEA41,0x6AB3, 0xEA42,0x6BAF, 0xEA43,0x6D5C,\n 0xEA44,0x6FF1, 0xEA45,0x7015, 0xEA46,0x725D, 0xEA47,0x73AD, 0xEA48,0x8CA7, 0xEA49,0x8CD3, 0xEA4A,0x983B, 0xEA4B,0x6191,\n 0xEA4C,0x6C37, 0xEA4D,0x8058, 0xEA4E,0x9A01, 0xEA4F,0x4E4D, 0xEA50,0x4E8B, 0xEA51,0x4E9B, 0xEA52,0x4ED5, 0xEA53,0x4F3A,\n 0xEA54,0x4F3C, 0xEA55,0x4F7F, 0xEA56,0x4FDF, 0xEA57,0x50FF, 0xEA58,0x53F2, 0xEA59,0x53F8, 0xEA5A,0x5506, 0xEA5B,0x55E3,\n 0xEA5C,0x56DB, 0xEA5D,0x58EB, 0xEA5E,0x5962, 0xEA5F,0x5A11, 0xEA60,0x5BEB, 0xEA61,0x5BFA, 0xEA62,0x5C04, 0xEA63,0x5DF3,\n 0xEA64,0x5E2B, 0xEA65,0x5F99, 0xEA66,0x601D, 0xEA67,0x6368, 0xEA68,0x659C, 0xEA69,0x65AF, 0xEA6A,0x67F6, 0xEA6B,0x67FB,\n 0xEA6C,0x68AD, 0xEA6D,0x6B7B, 0xEA6E,0x6C99, 0xEA6F,0x6CD7, 0xEA70,0x6E23, 0xEA71,0x7009, 0xEA72,0x7345, 0xEA73,0x7802,\n 0xEA74,0x793E, 0xEA75,0x7940, 0xEA76,0x7960, 0xEA77,0x79C1, 0xEA78,0x7BE9, 0xEA79,0x7D17, 0xEA7A,0x7D72, 0xEA7B,0x8086,\n 0xEA7C,0x820D, 0xEA7D,0x838E, 0xEA7E,0x84D1, 0xEA91,0x86C7, 0xEA92,0x88DF, 0xEA93,0x8A50, 0xEA94,0x8A5E, 0xEA95,0x8B1D,\n 0xEA96,0x8CDC, 0xEA97,0x8D66, 0xEA98,0x8FAD, 0xEA99,0x90AA, 0xEA9A,0x98FC, 0xEA9B,0x99DF, 0xEA9C,0x9E9D, 0xEA9D,0x524A,\n 0xEA9E,0xF969, 0xEA9F,0x6714, 0xEAA0,0xF96A, 0xEAA1,0x5098, 0xEAA2,0x522A, 0xEAA3,0x5C71, 0xEAA4,0x6563, 0xEAA5,0x6C55,\n 0xEAA6,0x73CA, 0xEAA7,0x7523, 0xEAA8,0x759D, 0xEAA9,0x7B97, 0xEAAA,0x849C, 0xEAAB,0x9178, 0xEAAC,0x9730, 0xEAAD,0x4E77,\n 0xEAAE,0x6492, 0xEAAF,0x6BBA, 0xEAB0,0x715E, 0xEAB1,0x85A9, 0xEAB2,0x4E09, 0xEAB3,0xF96B, 0xEAB4,0x6749, 0xEAB5,0x68EE,\n 0xEAB6,0x6E17, 0xEAB7,0x829F, 0xEAB8,0x8518, 0xEAB9,0x886B, 0xEABA,0x63F7, 0xEABB,0x6F81, 0xEABC,0x9212, 0xEABD,0x98AF,\n 0xEABE,0x4E0A, 0xEABF,0x50B7, 0xEAC0,0x50CF, 0xEAC1,0x511F, 0xEAC2,0x5546, 0xEAC3,0x55AA, 0xEAC4,0x5617, 0xEAC5,0x5B40,\n 0xEAC6,0x5C19, 0xEAC7,0x5CE0, 0xEAC8,0x5E38, 0xEAC9,0x5E8A, 0xEACA,0x5EA0, 0xEACB,0x5EC2, 0xEACC,0x60F3, 0xEACD,0x6851,\n 0xEACE,0x6A61, 0xEACF,0x6E58, 0xEAD0,0x723D, 0xEAD1,0x7240, 0xEAD2,0x72C0, 0xEAD3,0x76F8, 0xEAD4,0x7965, 0xEAD5,0x7BB1,\n 0xEAD6,0x7FD4, 0xEAD7,0x88F3, 0xEAD8,0x89F4, 0xEAD9,0x8A73, 0xEADA,0x8C61, 0xEADB,0x8CDE, 0xEADC,0x971C, 0xEADD,0x585E,\n 0xEADE,0x74BD, 0xEADF,0x8CFD, 0xEAE0,0x55C7, 0xEAE1,0xF96C, 0xEAE2,0x7A61, 0xEAE3,0x7D22, 0xEAE4,0x8272, 0xEAE5,0x7272,\n 0xEAE6,0x751F, 0xEAE7,0x7525, 0xEAE8,0xF96D, 0xEAE9,0x7B19, 0xEAEA,0x5885, 0xEAEB,0x58FB, 0xEAEC,0x5DBC, 0xEAED,0x5E8F,\n 0xEAEE,0x5EB6, 0xEAEF,0x5F90, 0xEAF0,0x6055, 0xEAF1,0x6292, 0xEAF2,0x637F, 0xEAF3,0x654D, 0xEAF4,0x6691, 0xEAF5,0x66D9,\n 0xEAF6,0x66F8, 0xEAF7,0x6816, 0xEAF8,0x68F2, 0xEAF9,0x7280, 0xEAFA,0x745E, 0xEAFB,0x7B6E, 0xEAFC,0x7D6E, 0xEAFD,0x7DD6,\n 0xEAFE,0x7F72, 0xEB31,0x80E5, 0xEB32,0x8212, 0xEB33,0x85AF, 0xEB34,0x897F, 0xEB35,0x8A93, 0xEB36,0x901D, 0xEB37,0x92E4,\n 0xEB38,0x9ECD, 0xEB39,0x9F20, 0xEB3A,0x5915, 0xEB3B,0x596D, 0xEB3C,0x5E2D, 0xEB3D,0x60DC, 0xEB3E,0x6614, 0xEB3F,0x6673,\n 0xEB40,0x6790, 0xEB41,0x6C50, 0xEB42,0x6DC5, 0xEB43,0x6F5F, 0xEB44,0x77F3, 0xEB45,0x78A9, 0xEB46,0x84C6, 0xEB47,0x91CB,\n 0xEB48,0x932B, 0xEB49,0x4ED9, 0xEB4A,0x50CA, 0xEB4B,0x5148, 0xEB4C,0x5584, 0xEB4D,0x5B0B, 0xEB4E,0x5BA3, 0xEB4F,0x6247,\n 0xEB50,0x657E, 0xEB51,0x65CB, 0xEB52,0x6E32, 0xEB53,0x717D, 0xEB54,0x7401, 0xEB55,0x7444, 0xEB56,0x7487, 0xEB57,0x74BF,\n 0xEB58,0x766C, 0xEB59,0x79AA, 0xEB5A,0x7DDA, 0xEB5B,0x7E55, 0xEB5C,0x7FA8, 0xEB5D,0x817A, 0xEB5E,0x81B3, 0xEB5F,0x8239,\n 0xEB60,0x861A, 0xEB61,0x87EC, 0xEB62,0x8A75, 0xEB63,0x8DE3, 0xEB64,0x9078, 0xEB65,0x9291, 0xEB66,0x9425, 0xEB67,0x994D,\n 0xEB68,0x9BAE, 0xEB69,0x5368, 0xEB6A,0x5C51, 0xEB6B,0x6954, 0xEB6C,0x6CC4, 0xEB6D,0x6D29, 0xEB6E,0x6E2B, 0xEB6F,0x820C,\n 0xEB70,0x859B, 0xEB71,0x893B, 0xEB72,0x8A2D, 0xEB73,0x8AAA, 0xEB74,0x96EA, 0xEB75,0x9F67, 0xEB76,0x5261, 0xEB77,0x66B9,\n 0xEB78,0x6BB2, 0xEB79,0x7E96, 0xEB7A,0x87FE, 0xEB7B,0x8D0D, 0xEB7C,0x9583, 0xEB7D,0x965D, 0xEB7E,0x651D, 0xEB91,0x6D89,\n 0xEB92,0x71EE, 0xEB93,0xF96E, 0xEB94,0x57CE, 0xEB95,0x59D3, 0xEB96,0x5BAC, 0xEB97,0x6027, 0xEB98,0x60FA, 0xEB99,0x6210,\n 0xEB9A,0x661F, 0xEB9B,0x665F, 0xEB9C,0x7329, 0xEB9D,0x73F9, 0xEB9E,0x76DB, 0xEB9F,0x7701, 0xEBA0,0x7B6C, 0xEBA1,0x8056,\n 0xEBA2,0x8072, 0xEBA3,0x8165, 0xEBA4,0x8AA0, 0xEBA5,0x9192, 0xEBA6,0x4E16, 0xEBA7,0x52E2, 0xEBA8,0x6B72, 0xEBA9,0x6D17,\n 0xEBAA,0x7A05, 0xEBAB,0x7B39, 0xEBAC,0x7D30, 0xEBAD,0xF96F, 0xEBAE,0x8CB0, 0xEBAF,0x53EC, 0xEBB0,0x562F, 0xEBB1,0x5851,\n 0xEBB2,0x5BB5, 0xEBB3,0x5C0F, 0xEBB4,0x5C11, 0xEBB5,0x5DE2, 0xEBB6,0x6240, 0xEBB7,0x6383, 0xEBB8,0x6414, 0xEBB9,0x662D,\n 0xEBBA,0x68B3, 0xEBBB,0x6CBC, 0xEBBC,0x6D88, 0xEBBD,0x6EAF, 0xEBBE,0x701F, 0xEBBF,0x70A4, 0xEBC0,0x71D2, 0xEBC1,0x7526,\n 0xEBC2,0x758F, 0xEBC3,0x758E, 0xEBC4,0x7619, 0xEBC5,0x7B11, 0xEBC6,0x7BE0, 0xEBC7,0x7C2B, 0xEBC8,0x7D20, 0xEBC9,0x7D39,\n 0xEBCA,0x852C, 0xEBCB,0x856D, 0xEBCC,0x8607, 0xEBCD,0x8A34, 0xEBCE,0x900D, 0xEBCF,0x9061, 0xEBD0,0x90B5, 0xEBD1,0x92B7,\n 0xEBD2,0x97F6, 0xEBD3,0x9A37, 0xEBD4,0x4FD7, 0xEBD5,0x5C6C, 0xEBD6,0x675F, 0xEBD7,0x6D91, 0xEBD8,0x7C9F, 0xEBD9,0x7E8C,\n 0xEBDA,0x8B16, 0xEBDB,0x8D16, 0xEBDC,0x901F, 0xEBDD,0x5B6B, 0xEBDE,0x5DFD, 0xEBDF,0x640D, 0xEBE0,0x84C0, 0xEBE1,0x905C,\n 0xEBE2,0x98E1, 0xEBE3,0x7387, 0xEBE4,0x5B8B, 0xEBE5,0x609A, 0xEBE6,0x677E, 0xEBE7,0x6DDE, 0xEBE8,0x8A1F, 0xEBE9,0x8AA6,\n 0xEBEA,0x9001, 0xEBEB,0x980C, 0xEBEC,0x5237, 0xEBED,0xF970, 0xEBEE,0x7051, 0xEBEF,0x788E, 0xEBF0,0x9396, 0xEBF1,0x8870,\n 0xEBF2,0x91D7, 0xEBF3,0x4FEE, 0xEBF4,0x53D7, 0xEBF5,0x55FD, 0xEBF6,0x56DA, 0xEBF7,0x5782, 0xEBF8,0x58FD, 0xEBF9,0x5AC2,\n 0xEBFA,0x5B88, 0xEBFB,0x5CAB, 0xEBFC,0x5CC0, 0xEBFD,0x5E25, 0xEBFE,0x6101, 0xEC31,0x620D, 0xEC32,0x624B, 0xEC33,0x6388,\n 0xEC34,0x641C, 0xEC35,0x6536, 0xEC36,0x6578, 0xEC37,0x6A39, 0xEC38,0x6B8A, 0xEC39,0x6C34, 0xEC3A,0x6D19, 0xEC3B,0x6F31,\n 0xEC3C,0x71E7, 0xEC3D,0x72E9, 0xEC3E,0x7378, 0xEC3F,0x7407, 0xEC40,0x74B2, 0xEC41,0x7626, 0xEC42,0x7761, 0xEC43,0x79C0,\n 0xEC44,0x7A57, 0xEC45,0x7AEA, 0xEC46,0x7CB9, 0xEC47,0x7D8F, 0xEC48,0x7DAC, 0xEC49,0x7E61, 0xEC4A,0x7F9E, 0xEC4B,0x8129,\n 0xEC4C,0x8331, 0xEC4D,0x8490, 0xEC4E,0x84DA, 0xEC4F,0x85EA, 0xEC50,0x8896, 0xEC51,0x8AB0, 0xEC52,0x8B90, 0xEC53,0x8F38,\n 0xEC54,0x9042, 0xEC55,0x9083, 0xEC56,0x916C, 0xEC57,0x9296, 0xEC58,0x92B9, 0xEC59,0x968B, 0xEC5A,0x96A7, 0xEC5B,0x96A8,\n 0xEC5C,0x96D6, 0xEC5D,0x9700, 0xEC5E,0x9808, 0xEC5F,0x9996, 0xEC60,0x9AD3, 0xEC61,0x9B1A, 0xEC62,0x53D4, 0xEC63,0x587E,\n 0xEC64,0x5919, 0xEC65,0x5B70, 0xEC66,0x5BBF, 0xEC67,0x6DD1, 0xEC68,0x6F5A, 0xEC69,0x719F, 0xEC6A,0x7421, 0xEC6B,0x74B9,\n 0xEC6C,0x8085, 0xEC6D,0x83FD, 0xEC6E,0x5DE1, 0xEC6F,0x5F87, 0xEC70,0x5FAA, 0xEC71,0x6042, 0xEC72,0x65EC, 0xEC73,0x6812,\n 0xEC74,0x696F, 0xEC75,0x6A53, 0xEC76,0x6B89, 0xEC77,0x6D35, 0xEC78,0x6DF3, 0xEC79,0x73E3, 0xEC7A,0x76FE, 0xEC7B,0x77AC,\n 0xEC7C,0x7B4D, 0xEC7D,0x7D14, 0xEC7E,0x8123, 0xEC91,0x821C, 0xEC92,0x8340, 0xEC93,0x84F4, 0xEC94,0x8563, 0xEC95,0x8A62,\n 0xEC96,0x8AC4, 0xEC97,0x9187, 0xEC98,0x931E, 0xEC99,0x9806, 0xEC9A,0x99B4, 0xEC9B,0x620C, 0xEC9C,0x8853, 0xEC9D,0x8FF0,\n 0xEC9E,0x9265, 0xEC9F,0x5D07, 0xECA0,0x5D27, 0xECA1,0x5D69, 0xECA2,0x745F, 0xECA3,0x819D, 0xECA4,0x8768, 0xECA5,0x6FD5,\n 0xECA6,0x62FE, 0xECA7,0x7FD2, 0xECA8,0x8936, 0xECA9,0x8972, 0xECAA,0x4E1E, 0xECAB,0x4E58, 0xECAC,0x50E7, 0xECAD,0x52DD,\n 0xECAE,0x5347, 0xECAF,0x627F, 0xECB0,0x6607, 0xECB1,0x7E69, 0xECB2,0x8805, 0xECB3,0x965E, 0xECB4,0x4F8D, 0xECB5,0x5319,\n 0xECB6,0x5636, 0xECB7,0x59CB, 0xECB8,0x5AA4, 0xECB9,0x5C38, 0xECBA,0x5C4E, 0xECBB,0x5C4D, 0xECBC,0x5E02, 0xECBD,0x5F11,\n 0xECBE,0x6043, 0xECBF,0x65BD, 0xECC0,0x662F, 0xECC1,0x6642, 0xECC2,0x67BE, 0xECC3,0x67F4, 0xECC4,0x731C, 0xECC5,0x77E2,\n 0xECC6,0x793A, 0xECC7,0x7FC5, 0xECC8,0x8494, 0xECC9,0x84CD, 0xECCA,0x8996, 0xECCB,0x8A66, 0xECCC,0x8A69, 0xECCD,0x8AE1,\n 0xECCE,0x8C55, 0xECCF,0x8C7A, 0xECD0,0x57F4, 0xECD1,0x5BD4, 0xECD2,0x5F0F, 0xECD3,0x606F, 0xECD4,0x62ED, 0xECD5,0x690D,\n 0xECD6,0x6B96, 0xECD7,0x6E5C, 0xECD8,0x7184, 0xECD9,0x7BD2, 0xECDA,0x8755, 0xECDB,0x8B58, 0xECDC,0x8EFE, 0xECDD,0x98DF,\n 0xECDE,0x98FE, 0xECDF,0x4F38, 0xECE0,0x4F81, 0xECE1,0x4FE1, 0xECE2,0x547B, 0xECE3,0x5A20, 0xECE4,0x5BB8, 0xECE5,0x613C,\n 0xECE6,0x65B0, 0xECE7,0x6668, 0xECE8,0x71FC, 0xECE9,0x7533, 0xECEA,0x795E, 0xECEB,0x7D33, 0xECEC,0x814E, 0xECED,0x81E3,\n 0xECEE,0x8398, 0xECEF,0x85AA, 0xECF0,0x85CE, 0xECF1,0x8703, 0xECF2,0x8A0A, 0xECF3,0x8EAB, 0xECF4,0x8F9B, 0xECF5,0xF971,\n 0xECF6,0x8FC5, 0xECF7,0x5931, 0xECF8,0x5BA4, 0xECF9,0x5BE6, 0xECFA,0x6089, 0xECFB,0x5BE9, 0xECFC,0x5C0B, 0xECFD,0x5FC3,\n 0xECFE,0x6C81, 0xED31,0xF972, 0xED32,0x6DF1, 0xED33,0x700B, 0xED34,0x751A, 0xED35,0x82AF, 0xED36,0x8AF6, 0xED37,0x4EC0,\n 0xED38,0x5341, 0xED39,0xF973, 0xED3A,0x96D9, 0xED3B,0x6C0F, 0xED3C,0x4E9E, 0xED3D,0x4FC4, 0xED3E,0x5152, 0xED3F,0x555E,\n 0xED40,0x5A25, 0xED41,0x5CE8, 0xED42,0x6211, 0xED43,0x7259, 0xED44,0x82BD, 0xED45,0x83AA, 0xED46,0x86FE, 0xED47,0x8859,\n 0xED48,0x8A1D, 0xED49,0x963F, 0xED4A,0x96C5, 0xED4B,0x9913, 0xED4C,0x9D09, 0xED4D,0x9D5D, 0xED4E,0x580A, 0xED4F,0x5CB3,\n 0xED50,0x5DBD, 0xED51,0x5E44, 0xED52,0x60E1, 0xED53,0x6115, 0xED54,0x63E1, 0xED55,0x6A02, 0xED56,0x6E25, 0xED57,0x9102,\n 0xED58,0x9354, 0xED59,0x984E, 0xED5A,0x9C10, 0xED5B,0x9F77, 0xED5C,0x5B89, 0xED5D,0x5CB8, 0xED5E,0x6309, 0xED5F,0x664F,\n 0xED60,0x6848, 0xED61,0x773C, 0xED62,0x96C1, 0xED63,0x978D, 0xED64,0x9854, 0xED65,0x9B9F, 0xED66,0x65A1, 0xED67,0x8B01,\n 0xED68,0x8ECB, 0xED69,0x95BC, 0xED6A,0x5535, 0xED6B,0x5CA9, 0xED6C,0x5DD6, 0xED6D,0x5EB5, 0xED6E,0x6697, 0xED6F,0x764C,\n 0xED70,0x83F4, 0xED71,0x95C7, 0xED72,0x58D3, 0xED73,0x62BC, 0xED74,0x72CE, 0xED75,0x9D28, 0xED76,0x4EF0, 0xED77,0x592E,\n 0xED78,0x600F, 0xED79,0x663B, 0xED7A,0x6B83, 0xED7B,0x79E7, 0xED7C,0x9D26, 0xED7D,0x5393, 0xED7E,0x54C0, 0xED91,0x57C3,\n 0xED92,0x5D16, 0xED93,0x611B, 0xED94,0x66D6, 0xED95,0x6DAF, 0xED96,0x788D, 0xED97,0x827E, 0xED98,0x9698, 0xED99,0x9744,\n 0xED9A,0x5384, 0xED9B,0x627C, 0xED9C,0x6396, 0xED9D,0x6DB2, 0xED9E,0x7E0A, 0xED9F,0x814B, 0xEDA0,0x984D, 0xEDA1,0x6AFB,\n 0xEDA2,0x7F4C, 0xEDA3,0x9DAF, 0xEDA4,0x9E1A, 0xEDA5,0x4E5F, 0xEDA6,0x503B, 0xEDA7,0x51B6, 0xEDA8,0x591C, 0xEDA9,0x60F9,\n 0xEDAA,0x63F6, 0xEDAB,0x6930, 0xEDAC,0x723A, 0xEDAD,0x8036, 0xEDAE,0xF974, 0xEDAF,0x91CE, 0xEDB0,0x5F31, 0xEDB1,0xF975,\n 0xEDB2,0xF976, 0xEDB3,0x7D04, 0xEDB4,0x82E5, 0xEDB5,0x846F, 0xEDB6,0x84BB, 0xEDB7,0x85E5, 0xEDB8,0x8E8D, 0xEDB9,0xF977,\n 0xEDBA,0x4F6F, 0xEDBB,0xF978, 0xEDBC,0xF979, 0xEDBD,0x58E4, 0xEDBE,0x5B43, 0xEDBF,0x6059, 0xEDC0,0x63DA, 0xEDC1,0x6518,\n 0xEDC2,0x656D, 0xEDC3,0x6698, 0xEDC4,0xF97A, 0xEDC5,0x694A, 0xEDC6,0x6A23, 0xEDC7,0x6D0B, 0xEDC8,0x7001, 0xEDC9,0x716C,\n 0xEDCA,0x75D2, 0xEDCB,0x760D, 0xEDCC,0x79B3, 0xEDCD,0x7A70, 0xEDCE,0xF97B, 0xEDCF,0x7F8A, 0xEDD0,0xF97C, 0xEDD1,0x8944,\n 0xEDD2,0xF97D, 0xEDD3,0x8B93, 0xEDD4,0x91C0, 0xEDD5,0x967D, 0xEDD6,0xF97E, 0xEDD7,0x990A, 0xEDD8,0x5704, 0xEDD9,0x5FA1,\n 0xEDDA,0x65BC, 0xEDDB,0x6F01, 0xEDDC,0x7600, 0xEDDD,0x79A6, 0xEDDE,0x8A9E, 0xEDDF,0x99AD, 0xEDE0,0x9B5A, 0xEDE1,0x9F6C,\n 0xEDE2,0x5104, 0xEDE3,0x61B6, 0xEDE4,0x6291, 0xEDE5,0x6A8D, 0xEDE6,0x81C6, 0xEDE7,0x5043, 0xEDE8,0x5830, 0xEDE9,0x5F66,\n 0xEDEA,0x7109, 0xEDEB,0x8A00, 0xEDEC,0x8AFA, 0xEDED,0x5B7C, 0xEDEE,0x8616, 0xEDEF,0x4FFA, 0xEDF0,0x513C, 0xEDF1,0x56B4,\n 0xEDF2,0x5944, 0xEDF3,0x63A9, 0xEDF4,0x6DF9, 0xEDF5,0x5DAA, 0xEDF6,0x696D, 0xEDF7,0x5186, 0xEDF8,0x4E88, 0xEDF9,0x4F59,\n 0xEDFA,0xF97F, 0xEDFB,0xF980, 0xEDFC,0xF981, 0xEDFD,0x5982, 0xEDFE,0xF982, 0xEE31,0xF983, 0xEE32,0x6B5F, 0xEE33,0x6C5D,\n 0xEE34,0xF984, 0xEE35,0x74B5, 0xEE36,0x7916, 0xEE37,0xF985, 0xEE38,0x8207, 0xEE39,0x8245, 0xEE3A,0x8339, 0xEE3B,0x8F3F,\n 0xEE3C,0x8F5D, 0xEE3D,0xF986, 0xEE3E,0x9918, 0xEE3F,0xF987, 0xEE40,0xF988, 0xEE41,0xF989, 0xEE42,0x4EA6, 0xEE43,0xF98A,\n 0xEE44,0x57DF, 0xEE45,0x5F79, 0xEE46,0x6613, 0xEE47,0xF98B, 0xEE48,0xF98C, 0xEE49,0x75AB, 0xEE4A,0x7E79, 0xEE4B,0x8B6F,\n 0xEE4C,0xF98D, 0xEE4D,0x9006, 0xEE4E,0x9A5B, 0xEE4F,0x56A5, 0xEE50,0x5827, 0xEE51,0x59F8, 0xEE52,0x5A1F, 0xEE53,0x5BB4,\n 0xEE54,0xF98E, 0xEE55,0x5EF6, 0xEE56,0xF98F, 0xEE57,0xF990, 0xEE58,0x6350, 0xEE59,0x633B, 0xEE5A,0xF991, 0xEE5B,0x693D,\n 0xEE5C,0x6C87, 0xEE5D,0x6CBF, 0xEE5E,0x6D8E, 0xEE5F,0x6D93, 0xEE60,0x6DF5, 0xEE61,0x6F14, 0xEE62,0xF992, 0xEE63,0x70DF,\n 0xEE64,0x7136, 0xEE65,0x7159, 0xEE66,0xF993, 0xEE67,0x71C3, 0xEE68,0x71D5, 0xEE69,0xF994, 0xEE6A,0x784F, 0xEE6B,0x786F,\n 0xEE6C,0xF995, 0xEE6D,0x7B75, 0xEE6E,0x7DE3, 0xEE6F,0xF996, 0xEE70,0x7E2F, 0xEE71,0xF997, 0xEE72,0x884D, 0xEE73,0x8EDF,\n 0xEE74,0xF998, 0xEE75,0xF999, 0xEE76,0xF99A, 0xEE77,0x925B, 0xEE78,0xF99B, 0xEE79,0x9CF6, 0xEE7A,0xF99C, 0xEE7B,0xF99D,\n 0xEE7C,0xF99E, 0xEE7D,0x6085, 0xEE7E,0x6D85, 0xEE91,0xF99F, 0xEE92,0x71B1, 0xEE93,0xF9A0, 0xEE94,0xF9A1, 0xEE95,0x95B1,\n 0xEE96,0x53AD, 0xEE97,0xF9A2, 0xEE98,0xF9A3, 0xEE99,0xF9A4, 0xEE9A,0x67D3, 0xEE9B,0xF9A5, 0xEE9C,0x708E, 0xEE9D,0x7130,\n 0xEE9E,0x7430, 0xEE9F,0x8276, 0xEEA0,0x82D2, 0xEEA1,0xF9A6, 0xEEA2,0x95BB, 0xEEA3,0x9AE5, 0xEEA4,0x9E7D, 0xEEA5,0x66C4,\n 0xEEA6,0xF9A7, 0xEEA7,0x71C1, 0xEEA8,0x8449, 0xEEA9,0xF9A8, 0xEEAA,0xF9A9, 0xEEAB,0x584B, 0xEEAC,0xF9AA, 0xEEAD,0xF9AB,\n 0xEEAE,0x5DB8, 0xEEAF,0x5F71, 0xEEB0,0xF9AC, 0xEEB1,0x6620, 0xEEB2,0x668E, 0xEEB3,0x6979, 0xEEB4,0x69AE, 0xEEB5,0x6C38,\n 0xEEB6,0x6CF3, 0xEEB7,0x6E36, 0xEEB8,0x6F41, 0xEEB9,0x6FDA, 0xEEBA,0x701B, 0xEEBB,0x702F, 0xEEBC,0x7150, 0xEEBD,0x71DF,\n 0xEEBE,0x7370, 0xEEBF,0xF9AD, 0xEEC0,0x745B, 0xEEC1,0xF9AE, 0xEEC2,0x74D4, 0xEEC3,0x76C8, 0xEEC4,0x7A4E, 0xEEC5,0x7E93,\n 0xEEC6,0xF9AF, 0xEEC7,0xF9B0, 0xEEC8,0x82F1, 0xEEC9,0x8A60, 0xEECA,0x8FCE, 0xEECB,0xF9B1, 0xEECC,0x9348, 0xEECD,0xF9B2,\n 0xEECE,0x9719, 0xEECF,0xF9B3, 0xEED0,0xF9B4, 0xEED1,0x4E42, 0xEED2,0x502A, 0xEED3,0xF9B5, 0xEED4,0x5208, 0xEED5,0x53E1,\n 0xEED6,0x66F3, 0xEED7,0x6C6D, 0xEED8,0x6FCA, 0xEED9,0x730A, 0xEEDA,0x777F, 0xEEDB,0x7A62, 0xEEDC,0x82AE, 0xEEDD,0x85DD,\n 0xEEDE,0x8602, 0xEEDF,0xF9B6, 0xEEE0,0x88D4, 0xEEE1,0x8A63, 0xEEE2,0x8B7D, 0xEEE3,0x8C6B, 0xEEE4,0xF9B7, 0xEEE5,0x92B3,\n 0xEEE6,0xF9B8, 0xEEE7,0x9713, 0xEEE8,0x9810, 0xEEE9,0x4E94, 0xEEEA,0x4F0D, 0xEEEB,0x4FC9, 0xEEEC,0x50B2, 0xEEED,0x5348,\n 0xEEEE,0x543E, 0xEEEF,0x5433, 0xEEF0,0x55DA, 0xEEF1,0x5862, 0xEEF2,0x58BA, 0xEEF3,0x5967, 0xEEF4,0x5A1B, 0xEEF5,0x5BE4,\n 0xEEF6,0x609F, 0xEEF7,0xF9B9, 0xEEF8,0x61CA, 0xEEF9,0x6556, 0xEEFA,0x65FF, 0xEEFB,0x6664, 0xEEFC,0x68A7, 0xEEFD,0x6C5A,\n 0xEEFE,0x6FB3, 0xEF31,0x70CF, 0xEF32,0x71AC, 0xEF33,0x7352, 0xEF34,0x7B7D, 0xEF35,0x8708, 0xEF36,0x8AA4, 0xEF37,0x9C32,\n 0xEF38,0x9F07, 0xEF39,0x5C4B, 0xEF3A,0x6C83, 0xEF3B,0x7344, 0xEF3C,0x7389, 0xEF3D,0x923A, 0xEF3E,0x6EAB, 0xEF3F,0x7465,\n 0xEF40,0x761F, 0xEF41,0x7A69, 0xEF42,0x7E15, 0xEF43,0x860A, 0xEF44,0x5140, 0xEF45,0x58C5, 0xEF46,0x64C1, 0xEF47,0x74EE,\n 0xEF48,0x7515, 0xEF49,0x7670, 0xEF4A,0x7FC1, 0xEF4B,0x9095, 0xEF4C,0x96CD, 0xEF4D,0x9954, 0xEF4E,0x6E26, 0xEF4F,0x74E6,\n 0xEF50,0x7AA9, 0xEF51,0x7AAA, 0xEF52,0x81E5, 0xEF53,0x86D9, 0xEF54,0x8778, 0xEF55,0x8A1B, 0xEF56,0x5A49, 0xEF57,0x5B8C,\n 0xEF58,0x5B9B, 0xEF59,0x68A1, 0xEF5A,0x6900, 0xEF5B,0x6D63, 0xEF5C,0x73A9, 0xEF5D,0x7413, 0xEF5E,0x742C, 0xEF5F,0x7897,\n 0xEF60,0x7DE9, 0xEF61,0x7FEB, 0xEF62,0x8118, 0xEF63,0x8155, 0xEF64,0x839E, 0xEF65,0x8C4C, 0xEF66,0x962E, 0xEF67,0x9811,\n 0xEF68,0x66F0, 0xEF69,0x5F80, 0xEF6A,0x65FA, 0xEF6B,0x6789, 0xEF6C,0x6C6A, 0xEF6D,0x738B, 0xEF6E,0x502D, 0xEF6F,0x5A03,\n 0xEF70,0x6B6A, 0xEF71,0x77EE, 0xEF72,0x5916, 0xEF73,0x5D6C, 0xEF74,0x5DCD, 0xEF75,0x7325, 0xEF76,0x754F, 0xEF77,0xF9BA,\n 0xEF78,0xF9BB, 0xEF79,0x50E5, 0xEF7A,0x51F9, 0xEF7B,0x582F, 0xEF7C,0x592D, 0xEF7D,0x5996, 0xEF7E,0x59DA, 0xEF91,0x5BE5,\n 0xEF92,0xF9BC, 0xEF93,0xF9BD, 0xEF94,0x5DA2, 0xEF95,0x62D7, 0xEF96,0x6416, 0xEF97,0x6493, 0xEF98,0x64FE, 0xEF99,0xF9BE,\n 0xEF9A,0x66DC, 0xEF9B,0xF9BF, 0xEF9C,0x6A48, 0xEF9D,0xF9C0, 0xEF9E,0x71FF, 0xEF9F,0x7464, 0xEFA0,0xF9C1, 0xEFA1,0x7A88,\n 0xEFA2,0x7AAF, 0xEFA3,0x7E47, 0xEFA4,0x7E5E, 0xEFA5,0x8000, 0xEFA6,0x8170, 0xEFA7,0xF9C2, 0xEFA8,0x87EF, 0xEFA9,0x8981,\n 0xEFAA,0x8B20, 0xEFAB,0x9059, 0xEFAC,0xF9C3, 0xEFAD,0x9080, 0xEFAE,0x9952, 0xEFAF,0x617E, 0xEFB0,0x6B32, 0xEFB1,0x6D74,\n 0xEFB2,0x7E1F, 0xEFB3,0x8925, 0xEFB4,0x8FB1, 0xEFB5,0x4FD1, 0xEFB6,0x50AD, 0xEFB7,0x5197, 0xEFB8,0x52C7, 0xEFB9,0x57C7,\n 0xEFBA,0x5889, 0xEFBB,0x5BB9, 0xEFBC,0x5EB8, 0xEFBD,0x6142, 0xEFBE,0x6995, 0xEFBF,0x6D8C, 0xEFC0,0x6E67, 0xEFC1,0x6EB6,\n 0xEFC2,0x7194, 0xEFC3,0x7462, 0xEFC4,0x7528, 0xEFC5,0x752C, 0xEFC6,0x8073, 0xEFC7,0x8338, 0xEFC8,0x84C9, 0xEFC9,0x8E0A,\n 0xEFCA,0x9394, 0xEFCB,0x93DE, 0xEFCC,0xF9C4, 0xEFCD,0x4E8E, 0xEFCE,0x4F51, 0xEFCF,0x5076, 0xEFD0,0x512A, 0xEFD1,0x53C8,\n 0xEFD2,0x53CB, 0xEFD3,0x53F3, 0xEFD4,0x5B87, 0xEFD5,0x5BD3, 0xEFD6,0x5C24, 0xEFD7,0x611A, 0xEFD8,0x6182, 0xEFD9,0x65F4,\n 0xEFDA,0x725B, 0xEFDB,0x7397, 0xEFDC,0x7440, 0xEFDD,0x76C2, 0xEFDE,0x7950, 0xEFDF,0x7991, 0xEFE0,0x79B9, 0xEFE1,0x7D06,\n 0xEFE2,0x7FBD, 0xEFE3,0x828B, 0xEFE4,0x85D5, 0xEFE5,0x865E, 0xEFE6,0x8FC2, 0xEFE7,0x9047, 0xEFE8,0x90F5, 0xEFE9,0x91EA,\n 0xEFEA,0x9685, 0xEFEB,0x96E8, 0xEFEC,0x96E9, 0xEFED,0x52D6, 0xEFEE,0x5F67, 0xEFEF,0x65ED, 0xEFF0,0x6631, 0xEFF1,0x682F,\n 0xEFF2,0x715C, 0xEFF3,0x7A36, 0xEFF4,0x90C1, 0xEFF5,0x980A, 0xEFF6,0x4E91, 0xEFF7,0xF9C5, 0xEFF8,0x6A52, 0xEFF9,0x6B9E,\n 0xEFFA,0x6F90, 0xEFFB,0x7189, 0xEFFC,0x8018, 0xEFFD,0x82B8, 0xEFFE,0x8553, 0xF031,0x904B, 0xF032,0x9695, 0xF033,0x96F2,\n 0xF034,0x97FB, 0xF035,0x851A, 0xF036,0x9B31, 0xF037,0x4E90, 0xF038,0x718A, 0xF039,0x96C4, 0xF03A,0x5143, 0xF03B,0x539F,\n 0xF03C,0x54E1, 0xF03D,0x5713, 0xF03E,0x5712, 0xF03F,0x57A3, 0xF040,0x5A9B, 0xF041,0x5AC4, 0xF042,0x5BC3, 0xF043,0x6028,\n 0xF044,0x613F, 0xF045,0x63F4, 0xF046,0x6C85, 0xF047,0x6D39, 0xF048,0x6E72, 0xF049,0x6E90, 0xF04A,0x7230, 0xF04B,0x733F,\n 0xF04C,0x7457, 0xF04D,0x82D1, 0xF04E,0x8881, 0xF04F,0x8F45, 0xF050,0x9060, 0xF051,0xF9C6, 0xF052,0x9662, 0xF053,0x9858,\n 0xF054,0x9D1B, 0xF055,0x6708, 0xF056,0x8D8A, 0xF057,0x925E, 0xF058,0x4F4D, 0xF059,0x5049, 0xF05A,0x50DE, 0xF05B,0x5371,\n 0xF05C,0x570D, 0xF05D,0x59D4, 0xF05E,0x5A01, 0xF05F,0x5C09, 0xF060,0x6170, 0xF061,0x6690, 0xF062,0x6E2D, 0xF063,0x7232,\n 0xF064,0x744B, 0xF065,0x7DEF, 0xF066,0x80C3, 0xF067,0x840E, 0xF068,0x8466, 0xF069,0x853F, 0xF06A,0x875F, 0xF06B,0x885B,\n 0xF06C,0x8918, 0xF06D,0x8B02, 0xF06E,0x9055, 0xF06F,0x97CB, 0xF070,0x9B4F, 0xF071,0x4E73, 0xF072,0x4F91, 0xF073,0x5112,\n 0xF074,0x516A, 0xF075,0xF9C7, 0xF076,0x552F, 0xF077,0x55A9, 0xF078,0x5B7A, 0xF079,0x5BA5, 0xF07A,0x5E7C, 0xF07B,0x5E7D,\n 0xF07C,0x5EBE, 0xF07D,0x60A0, 0xF07E,0x60DF, 0xF091,0x6108, 0xF092,0x6109, 0xF093,0x63C4, 0xF094,0x6538, 0xF095,0x6709,\n 0xF096,0xF9C8, 0xF097,0x67D4, 0xF098,0x67DA, 0xF099,0xF9C9, 0xF09A,0x6961, 0xF09B,0x6962, 0xF09C,0x6CB9, 0xF09D,0x6D27,\n 0xF09E,0xF9CA, 0xF09F,0x6E38, 0xF0A0,0xF9CB, 0xF0A1,0x6FE1, 0xF0A2,0x7336, 0xF0A3,0x7337, 0xF0A4,0xF9CC, 0xF0A5,0x745C,\n 0xF0A6,0x7531, 0xF0A7,0xF9CD, 0xF0A8,0x7652, 0xF0A9,0xF9CE, 0xF0AA,0xF9CF, 0xF0AB,0x7DAD, 0xF0AC,0x81FE, 0xF0AD,0x8438,\n 0xF0AE,0x88D5, 0xF0AF,0x8A98, 0xF0B0,0x8ADB, 0xF0B1,0x8AED, 0xF0B2,0x8E30, 0xF0B3,0x8E42, 0xF0B4,0x904A, 0xF0B5,0x903E,\n 0xF0B6,0x907A, 0xF0B7,0x9149, 0xF0B8,0x91C9, 0xF0B9,0x936E, 0xF0BA,0xF9D0, 0xF0BB,0xF9D1, 0xF0BC,0x5809, 0xF0BD,0xF9D2,\n 0xF0BE,0x6BD3, 0xF0BF,0x8089, 0xF0C0,0x80B2, 0xF0C1,0xF9D3, 0xF0C2,0xF9D4, 0xF0C3,0x5141, 0xF0C4,0x596B, 0xF0C5,0x5C39,\n 0xF0C6,0xF9D5, 0xF0C7,0xF9D6, 0xF0C8,0x6F64, 0xF0C9,0x73A7, 0xF0CA,0x80E4, 0xF0CB,0x8D07, 0xF0CC,0xF9D7, 0xF0CD,0x9217,\n 0xF0CE,0x958F, 0xF0CF,0xF9D8, 0xF0D0,0xF9D9, 0xF0D1,0xF9DA, 0xF0D2,0xF9DB, 0xF0D3,0x807F, 0xF0D4,0x620E, 0xF0D5,0x701C,\n 0xF0D6,0x7D68, 0xF0D7,0x878D, 0xF0D8,0xF9DC, 0xF0D9,0x57A0, 0xF0DA,0x6069, 0xF0DB,0x6147, 0xF0DC,0x6BB7, 0xF0DD,0x8ABE,\n 0xF0DE,0x9280, 0xF0DF,0x96B1, 0xF0E0,0x4E59, 0xF0E1,0x541F, 0xF0E2,0x6DEB, 0xF0E3,0x852D, 0xF0E4,0x9670, 0xF0E5,0x97F3,\n 0xF0E6,0x98EE, 0xF0E7,0x63D6, 0xF0E8,0x6CE3, 0xF0E9,0x9091, 0xF0EA,0x51DD, 0xF0EB,0x61C9, 0xF0EC,0x81BA, 0xF0ED,0x9DF9,\n 0xF0EE,0x4F9D, 0xF0EF,0x501A, 0xF0F0,0x5100, 0xF0F1,0x5B9C, 0xF0F2,0x610F, 0xF0F3,0x61FF, 0xF0F4,0x64EC, 0xF0F5,0x6905,\n 0xF0F6,0x6BC5, 0xF0F7,0x7591, 0xF0F8,0x77E3, 0xF0F9,0x7FA9, 0xF0FA,0x8264, 0xF0FB,0x858F, 0xF0FC,0x87FB, 0xF0FD,0x8863,\n 0xF0FE,0x8ABC, 0xF131,0x8B70, 0xF132,0x91AB, 0xF133,0x4E8C, 0xF134,0x4EE5, 0xF135,0x4F0A, 0xF136,0xF9DD, 0xF137,0xF9DE,\n 0xF138,0x5937, 0xF139,0x59E8, 0xF13A,0xF9DF, 0xF13B,0x5DF2, 0xF13C,0x5F1B, 0xF13D,0x5F5B, 0xF13E,0x6021, 0xF13F,0xF9E0,\n 0xF140,0xF9E1, 0xF141,0xF9E2, 0xF142,0xF9E3, 0xF143,0x723E, 0xF144,0x73E5, 0xF145,0xF9E4, 0xF146,0x7570, 0xF147,0x75CD,\n 0xF148,0xF9E5, 0xF149,0x79FB, 0xF14A,0xF9E6, 0xF14B,0x800C, 0xF14C,0x8033, 0xF14D,0x8084, 0xF14E,0x82E1, 0xF14F,0x8351,\n 0xF150,0xF9E7, 0xF151,0xF9E8, 0xF152,0x8CBD, 0xF153,0x8CB3, 0xF154,0x9087, 0xF155,0xF9E9, 0xF156,0xF9EA, 0xF157,0x98F4,\n 0xF158,0x990C, 0xF159,0xF9EB, 0xF15A,0xF9EC, 0xF15B,0x7037, 0xF15C,0x76CA, 0xF15D,0x7FCA, 0xF15E,0x7FCC, 0xF15F,0x7FFC,\n 0xF160,0x8B1A, 0xF161,0x4EBA, 0xF162,0x4EC1, 0xF163,0x5203, 0xF164,0x5370, 0xF165,0xF9ED, 0xF166,0x54BD, 0xF167,0x56E0,\n 0xF168,0x59FB, 0xF169,0x5BC5, 0xF16A,0x5F15, 0xF16B,0x5FCD, 0xF16C,0x6E6E, 0xF16D,0xF9EE, 0xF16E,0xF9EF, 0xF16F,0x7D6A,\n 0xF170,0x8335, 0xF171,0xF9F0, 0xF172,0x8693, 0xF173,0x8A8D, 0xF174,0xF9F1, 0xF175,0x976D, 0xF176,0x9777, 0xF177,0xF9F2,\n 0xF178,0xF9F3, 0xF179,0x4E00, 0xF17A,0x4F5A, 0xF17B,0x4F7E, 0xF17C,0x58F9, 0xF17D,0x65E5, 0xF17E,0x6EA2, 0xF191,0x9038,\n 0xF192,0x93B0, 0xF193,0x99B9, 0xF194,0x4EFB, 0xF195,0x58EC, 0xF196,0x598A, 0xF197,0x59D9, 0xF198,0x6041, 0xF199,0xF9F4,\n 0xF19A,0xF9F5, 0xF19B,0x7A14, 0xF19C,0xF9F6, 0xF19D,0x834F, 0xF19E,0x8CC3, 0xF19F,0x5165, 0xF1A0,0x5344, 0xF1A1,0xF9F7,\n 0xF1A2,0xF9F8, 0xF1A3,0xF9F9, 0xF1A4,0x4ECD, 0xF1A5,0x5269, 0xF1A6,0x5B55, 0xF1A7,0x82BF, 0xF1A8,0x4ED4, 0xF1A9,0x523A,\n 0xF1AA,0x54A8, 0xF1AB,0x59C9, 0xF1AC,0x59FF, 0xF1AD,0x5B50, 0xF1AE,0x5B57, 0xF1AF,0x5B5C, 0xF1B0,0x6063, 0xF1B1,0x6148,\n 0xF1B2,0x6ECB, 0xF1B3,0x7099, 0xF1B4,0x716E, 0xF1B5,0x7386, 0xF1B6,0x74F7, 0xF1B7,0x75B5, 0xF1B8,0x78C1, 0xF1B9,0x7D2B,\n 0xF1BA,0x8005, 0xF1BB,0x81EA, 0xF1BC,0x8328, 0xF1BD,0x8517, 0xF1BE,0x85C9, 0xF1BF,0x8AEE, 0xF1C0,0x8CC7, 0xF1C1,0x96CC,\n 0xF1C2,0x4F5C, 0xF1C3,0x52FA, 0xF1C4,0x56BC, 0xF1C5,0x65AB, 0xF1C6,0x6628, 0xF1C7,0x707C, 0xF1C8,0x70B8, 0xF1C9,0x7235,\n 0xF1CA,0x7DBD, 0xF1CB,0x828D, 0xF1CC,0x914C, 0xF1CD,0x96C0, 0xF1CE,0x9D72, 0xF1CF,0x5B71, 0xF1D0,0x68E7, 0xF1D1,0x6B98,\n 0xF1D2,0x6F7A, 0xF1D3,0x76DE, 0xF1D4,0x5C91, 0xF1D5,0x66AB, 0xF1D6,0x6F5B, 0xF1D7,0x7BB4, 0xF1D8,0x7C2A, 0xF1D9,0x8836,\n 0xF1DA,0x96DC, 0xF1DB,0x4E08, 0xF1DC,0x4ED7, 0xF1DD,0x5320, 0xF1DE,0x5834, 0xF1DF,0x58BB, 0xF1E0,0x58EF, 0xF1E1,0x596C,\n 0xF1E2,0x5C07, 0xF1E3,0x5E33, 0xF1E4,0x5E84, 0xF1E5,0x5F35, 0xF1E6,0x638C, 0xF1E7,0x66B2, 0xF1E8,0x6756, 0xF1E9,0x6A1F,\n 0xF1EA,0x6AA3, 0xF1EB,0x6B0C, 0xF1EC,0x6F3F, 0xF1ED,0x7246, 0xF1EE,0xF9FA, 0xF1EF,0x7350, 0xF1F0,0x748B, 0xF1F1,0x7AE0,\n 0xF1F2,0x7CA7, 0xF1F3,0x8178, 0xF1F4,0x81DF, 0xF1F5,0x81E7, 0xF1F6,0x838A, 0xF1F7,0x846C, 0xF1F8,0x8523, 0xF1F9,0x8594,\n 0xF1FA,0x85CF, 0xF1FB,0x88DD, 0xF1FC,0x8D13, 0xF1FD,0x91AC, 0xF1FE,0x9577, 0xF231,0x969C, 0xF232,0x518D, 0xF233,0x54C9,\n 0xF234,0x5728, 0xF235,0x5BB0, 0xF236,0x624D, 0xF237,0x6750, 0xF238,0x683D, 0xF239,0x6893, 0xF23A,0x6E3D, 0xF23B,0x6ED3,\n 0xF23C,0x707D, 0xF23D,0x7E21, 0xF23E,0x88C1, 0xF23F,0x8CA1, 0xF240,0x8F09, 0xF241,0x9F4B, 0xF242,0x9F4E, 0xF243,0x722D,\n 0xF244,0x7B8F, 0xF245,0x8ACD, 0xF246,0x931A, 0xF247,0x4F47, 0xF248,0x4F4E, 0xF249,0x5132, 0xF24A,0x5480, 0xF24B,0x59D0,\n 0xF24C,0x5E95, 0xF24D,0x62B5, 0xF24E,0x6775, 0xF24F,0x696E, 0xF250,0x6A17, 0xF251,0x6CAE, 0xF252,0x6E1A, 0xF253,0x72D9,\n 0xF254,0x732A, 0xF255,0x75BD, 0xF256,0x7BB8, 0xF257,0x7D35, 0xF258,0x82E7, 0xF259,0x83F9, 0xF25A,0x8457, 0xF25B,0x85F7,\n 0xF25C,0x8A5B, 0xF25D,0x8CAF, 0xF25E,0x8E87, 0xF25F,0x9019, 0xF260,0x90B8, 0xF261,0x96CE, 0xF262,0x9F5F, 0xF263,0x52E3,\n 0xF264,0x540A, 0xF265,0x5AE1, 0xF266,0x5BC2, 0xF267,0x6458, 0xF268,0x6575, 0xF269,0x6EF4, 0xF26A,0x72C4, 0xF26B,0xF9FB,\n 0xF26C,0x7684, 0xF26D,0x7A4D, 0xF26E,0x7B1B, 0xF26F,0x7C4D, 0xF270,0x7E3E, 0xF271,0x7FDF, 0xF272,0x837B, 0xF273,0x8B2B,\n 0xF274,0x8CCA, 0xF275,0x8D64, 0xF276,0x8DE1, 0xF277,0x8E5F, 0xF278,0x8FEA, 0xF279,0x8FF9, 0xF27A,0x9069, 0xF27B,0x93D1,\n 0xF27C,0x4F43, 0xF27D,0x4F7A, 0xF27E,0x50B3, 0xF291,0x5168, 0xF292,0x5178, 0xF293,0x524D, 0xF294,0x526A, 0xF295,0x5861,\n 0xF296,0x587C, 0xF297,0x5960, 0xF298,0x5C08, 0xF299,0x5C55, 0xF29A,0x5EDB, 0xF29B,0x609B, 0xF29C,0x6230, 0xF29D,0x6813,\n 0xF29E,0x6BBF, 0xF29F,0x6C08, 0xF2A0,0x6FB1, 0xF2A1,0x714E, 0xF2A2,0x7420, 0xF2A3,0x7530, 0xF2A4,0x7538, 0xF2A5,0x7551,\n 0xF2A6,0x7672, 0xF2A7,0x7B4C, 0xF2A8,0x7B8B, 0xF2A9,0x7BAD, 0xF2AA,0x7BC6, 0xF2AB,0x7E8F, 0xF2AC,0x8A6E, 0xF2AD,0x8F3E,\n 0xF2AE,0x8F49, 0xF2AF,0x923F, 0xF2B0,0x9293, 0xF2B1,0x9322, 0xF2B2,0x942B, 0xF2B3,0x96FB, 0xF2B4,0x985A, 0xF2B5,0x986B,\n 0xF2B6,0x991E, 0xF2B7,0x5207, 0xF2B8,0x622A, 0xF2B9,0x6298, 0xF2BA,0x6D59, 0xF2BB,0x7664, 0xF2BC,0x7ACA, 0xF2BD,0x7BC0,\n 0xF2BE,0x7D76, 0xF2BF,0x5360, 0xF2C0,0x5CBE, 0xF2C1,0x5E97, 0xF2C2,0x6F38, 0xF2C3,0x70B9, 0xF2C4,0x7C98, 0xF2C5,0x9711,\n 0xF2C6,0x9B8E, 0xF2C7,0x9EDE, 0xF2C8,0x63A5, 0xF2C9,0x647A, 0xF2CA,0x8776, 0xF2CB,0x4E01, 0xF2CC,0x4E95, 0xF2CD,0x4EAD,\n 0xF2CE,0x505C, 0xF2CF,0x5075, 0xF2D0,0x5448, 0xF2D1,0x59C3, 0xF2D2,0x5B9A, 0xF2D3,0x5E40, 0xF2D4,0x5EAD, 0xF2D5,0x5EF7,\n 0xF2D6,0x5F81, 0xF2D7,0x60C5, 0xF2D8,0x633A, 0xF2D9,0x653F, 0xF2DA,0x6574, 0xF2DB,0x65CC, 0xF2DC,0x6676, 0xF2DD,0x6678,\n 0xF2DE,0x67FE, 0xF2DF,0x6968, 0xF2E0,0x6A89, 0xF2E1,0x6B63, 0xF2E2,0x6C40, 0xF2E3,0x6DC0, 0xF2E4,0x6DE8, 0xF2E5,0x6E1F,\n 0xF2E6,0x6E5E, 0xF2E7,0x701E, 0xF2E8,0x70A1, 0xF2E9,0x738E, 0xF2EA,0x73FD, 0xF2EB,0x753A, 0xF2EC,0x775B, 0xF2ED,0x7887,\n 0xF2EE,0x798E, 0xF2EF,0x7A0B, 0xF2F0,0x7A7D, 0xF2F1,0x7CBE, 0xF2F2,0x7D8E, 0xF2F3,0x8247, 0xF2F4,0x8A02, 0xF2F5,0x8AEA,\n 0xF2F6,0x8C9E, 0xF2F7,0x912D, 0xF2F8,0x914A, 0xF2F9,0x91D8, 0xF2FA,0x9266, 0xF2FB,0x92CC, 0xF2FC,0x9320, 0xF2FD,0x9706,\n 0xF2FE,0x9756, 0xF331,0x975C, 0xF332,0x9802, 0xF333,0x9F0E, 0xF334,0x5236, 0xF335,0x5291, 0xF336,0x557C, 0xF337,0x5824,\n 0xF338,0x5E1D, 0xF339,0x5F1F, 0xF33A,0x608C, 0xF33B,0x63D0, 0xF33C,0x68AF, 0xF33D,0x6FDF, 0xF33E,0x796D, 0xF33F,0x7B2C,\n 0xF340,0x81CD, 0xF341,0x85BA, 0xF342,0x88FD, 0xF343,0x8AF8, 0xF344,0x8E44, 0xF345,0x918D, 0xF346,0x9664, 0xF347,0x969B,\n 0xF348,0x973D, 0xF349,0x984C, 0xF34A,0x9F4A, 0xF34B,0x4FCE, 0xF34C,0x5146, 0xF34D,0x51CB, 0xF34E,0x52A9, 0xF34F,0x5632,\n 0xF350,0x5F14, 0xF351,0x5F6B, 0xF352,0x63AA, 0xF353,0x64CD, 0xF354,0x65E9, 0xF355,0x6641, 0xF356,0x66FA, 0xF357,0x66F9,\n 0xF358,0x671D, 0xF359,0x689D, 0xF35A,0x68D7, 0xF35B,0x69FD, 0xF35C,0x6F15, 0xF35D,0x6F6E, 0xF35E,0x7167, 0xF35F,0x71E5,\n 0xF360,0x722A, 0xF361,0x74AA, 0xF362,0x773A, 0xF363,0x7956, 0xF364,0x795A, 0xF365,0x79DF, 0xF366,0x7A20, 0xF367,0x7A95,\n 0xF368,0x7C97, 0xF369,0x7CDF, 0xF36A,0x7D44, 0xF36B,0x7E70, 0xF36C,0x8087, 0xF36D,0x85FB, 0xF36E,0x86A4, 0xF36F,0x8A54,\n 0xF370,0x8ABF, 0xF371,0x8D99, 0xF372,0x8E81, 0xF373,0x9020, 0xF374,0x906D, 0xF375,0x91E3, 0xF376,0x963B, 0xF377,0x96D5,\n 0xF378,0x9CE5, 0xF379,0x65CF, 0xF37A,0x7C07, 0xF37B,0x8DB3, 0xF37C,0x93C3, 0xF37D,0x5B58, 0xF37E,0x5C0A, 0xF391,0x5352,\n 0xF392,0x62D9, 0xF393,0x731D, 0xF394,0x5027, 0xF395,0x5B97, 0xF396,0x5F9E, 0xF397,0x60B0, 0xF398,0x616B, 0xF399,0x68D5,\n 0xF39A,0x6DD9, 0xF39B,0x742E, 0xF39C,0x7A2E, 0xF39D,0x7D42, 0xF39E,0x7D9C, 0xF39F,0x7E31, 0xF3A0,0x816B, 0xF3A1,0x8E2A,\n 0xF3A2,0x8E35, 0xF3A3,0x937E, 0xF3A4,0x9418, 0xF3A5,0x4F50, 0xF3A6,0x5750, 0xF3A7,0x5DE6, 0xF3A8,0x5EA7, 0xF3A9,0x632B,\n 0xF3AA,0x7F6A, 0xF3AB,0x4E3B, 0xF3AC,0x4F4F, 0xF3AD,0x4F8F, 0xF3AE,0x505A, 0xF3AF,0x59DD, 0xF3B0,0x80C4, 0xF3B1,0x546A,\n 0xF3B2,0x5468, 0xF3B3,0x55FE, 0xF3B4,0x594F, 0xF3B5,0x5B99, 0xF3B6,0x5DDE, 0xF3B7,0x5EDA, 0xF3B8,0x665D, 0xF3B9,0x6731,\n 0xF3BA,0x67F1, 0xF3BB,0x682A, 0xF3BC,0x6CE8, 0xF3BD,0x6D32, 0xF3BE,0x6E4A, 0xF3BF,0x6F8D, 0xF3C0,0x70B7, 0xF3C1,0x73E0,\n 0xF3C2,0x7587, 0xF3C3,0x7C4C, 0xF3C4,0x7D02, 0xF3C5,0x7D2C, 0xF3C6,0x7DA2, 0xF3C7,0x821F, 0xF3C8,0x86DB, 0xF3C9,0x8A3B,\n 0xF3CA,0x8A85, 0xF3CB,0x8D70, 0xF3CC,0x8E8A, 0xF3CD,0x8F33, 0xF3CE,0x9031, 0xF3CF,0x914E, 0xF3D0,0x9152, 0xF3D1,0x9444,\n 0xF3D2,0x99D0, 0xF3D3,0x7AF9, 0xF3D4,0x7CA5, 0xF3D5,0x4FCA, 0xF3D6,0x5101, 0xF3D7,0x51C6, 0xF3D8,0x57C8, 0xF3D9,0x5BEF,\n 0xF3DA,0x5CFB, 0xF3DB,0x6659, 0xF3DC,0x6A3D, 0xF3DD,0x6D5A, 0xF3DE,0x6E96, 0xF3DF,0x6FEC, 0xF3E0,0x710C, 0xF3E1,0x756F,\n 0xF3E2,0x7AE3, 0xF3E3,0x8822, 0xF3E4,0x9021, 0xF3E5,0x9075, 0xF3E6,0x96CB, 0xF3E7,0x99FF, 0xF3E8,0x8301, 0xF3E9,0x4E2D,\n 0xF3EA,0x4EF2, 0xF3EB,0x8846, 0xF3EC,0x91CD, 0xF3ED,0x537D, 0xF3EE,0x6ADB, 0xF3EF,0x696B, 0xF3F0,0x6C41, 0xF3F1,0x847A,\n 0xF3F2,0x589E, 0xF3F3,0x618E, 0xF3F4,0x66FE, 0xF3F5,0x62EF, 0xF3F6,0x70DD, 0xF3F7,0x7511, 0xF3F8,0x75C7, 0xF3F9,0x7E52,\n 0xF3FA,0x84B8, 0xF3FB,0x8B49, 0xF3FC,0x8D08, 0xF3FD,0x4E4B, 0xF3FE,0x53EA, 0xF431,0x54AB, 0xF432,0x5730, 0xF433,0x5740,\n 0xF434,0x5FD7, 0xF435,0x6301, 0xF436,0x6307, 0xF437,0x646F, 0xF438,0x652F, 0xF439,0x65E8, 0xF43A,0x667A, 0xF43B,0x679D,\n 0xF43C,0x67B3, 0xF43D,0x6B62, 0xF43E,0x6C60, 0xF43F,0x6C9A, 0xF440,0x6F2C, 0xF441,0x77E5, 0xF442,0x7825, 0xF443,0x7949,\n 0xF444,0x7957, 0xF445,0x7D19, 0xF446,0x80A2, 0xF447,0x8102, 0xF448,0x81F3, 0xF449,0x829D, 0xF44A,0x82B7, 0xF44B,0x8718,\n 0xF44C,0x8A8C, 0xF44D,0xF9FC, 0xF44E,0x8D04, 0xF44F,0x8DBE, 0xF450,0x9072, 0xF451,0x76F4, 0xF452,0x7A19, 0xF453,0x7A37,\n 0xF454,0x7E54, 0xF455,0x8077, 0xF456,0x5507, 0xF457,0x55D4, 0xF458,0x5875, 0xF459,0x632F, 0xF45A,0x6422, 0xF45B,0x6649,\n 0xF45C,0x664B, 0xF45D,0x686D, 0xF45E,0x699B, 0xF45F,0x6B84, 0xF460,0x6D25, 0xF461,0x6EB1, 0xF462,0x73CD, 0xF463,0x7468,\n 0xF464,0x74A1, 0xF465,0x755B, 0xF466,0x75B9, 0xF467,0x76E1, 0xF468,0x771E, 0xF469,0x778B, 0xF46A,0x79E6, 0xF46B,0x7E09,\n 0xF46C,0x7E1D, 0xF46D,0x81FB, 0xF46E,0x852F, 0xF46F,0x8897, 0xF470,0x8A3A, 0xF471,0x8CD1, 0xF472,0x8EEB, 0xF473,0x8FB0,\n 0xF474,0x9032, 0xF475,0x93AD, 0xF476,0x9663, 0xF477,0x9673, 0xF478,0x9707, 0xF479,0x4F84, 0xF47A,0x53F1, 0xF47B,0x59EA,\n 0xF47C,0x5AC9, 0xF47D,0x5E19, 0xF47E,0x684E, 0xF491,0x74C6, 0xF492,0x75BE, 0xF493,0x79E9, 0xF494,0x7A92, 0xF495,0x81A3,\n 0xF496,0x86ED, 0xF497,0x8CEA, 0xF498,0x8DCC, 0xF499,0x8FED, 0xF49A,0x659F, 0xF49B,0x6715, 0xF49C,0xF9FD, 0xF49D,0x57F7,\n 0xF49E,0x6F57, 0xF49F,0x7DDD, 0xF4A0,0x8F2F, 0xF4A1,0x93F6, 0xF4A2,0x96C6, 0xF4A3,0x5FB5, 0xF4A4,0x61F2, 0xF4A5,0x6F84,\n 0xF4A6,0x4E14, 0xF4A7,0x4F98, 0xF4A8,0x501F, 0xF4A9,0x53C9, 0xF4AA,0x55DF, 0xF4AB,0x5D6F, 0xF4AC,0x5DEE, 0xF4AD,0x6B21,\n 0xF4AE,0x6B64, 0xF4AF,0x78CB, 0xF4B0,0x7B9A, 0xF4B1,0xF9FE, 0xF4B2,0x8E49, 0xF4B3,0x8ECA, 0xF4B4,0x906E, 0xF4B5,0x6349,\n 0xF4B6,0x643E, 0xF4B7,0x7740, 0xF4B8,0x7A84, 0xF4B9,0x932F, 0xF4BA,0x947F, 0xF4BB,0x9F6A, 0xF4BC,0x64B0, 0xF4BD,0x6FAF,\n 0xF4BE,0x71E6, 0xF4BF,0x74A8, 0xF4C0,0x74DA, 0xF4C1,0x7AC4, 0xF4C2,0x7C12, 0xF4C3,0x7E82, 0xF4C4,0x7CB2, 0xF4C5,0x7E98,\n 0xF4C6,0x8B9A, 0xF4C7,0x8D0A, 0xF4C8,0x947D, 0xF4C9,0x9910, 0xF4CA,0x994C, 0xF4CB,0x5239, 0xF4CC,0x5BDF, 0xF4CD,0x64E6,\n 0xF4CE,0x672D, 0xF4CF,0x7D2E, 0xF4D0,0x50ED, 0xF4D1,0x53C3, 0xF4D2,0x5879, 0xF4D3,0x6158, 0xF4D4,0x6159, 0xF4D5,0x61FA,\n 0xF4D6,0x65AC, 0xF4D7,0x7AD9, 0xF4D8,0x8B92, 0xF4D9,0x8B96, 0xF4DA,0x5009, 0xF4DB,0x5021, 0xF4DC,0x5275, 0xF4DD,0x5531,\n 0xF4DE,0x5A3C, 0xF4DF,0x5EE0, 0xF4E0,0x5F70, 0xF4E1,0x6134, 0xF4E2,0x655E, 0xF4E3,0x660C, 0xF4E4,0x6636, 0xF4E5,0x66A2,\n 0xF4E6,0x69CD, 0xF4E7,0x6EC4, 0xF4E8,0x6F32, 0xF4E9,0x7316, 0xF4EA,0x7621, 0xF4EB,0x7A93, 0xF4EC,0x8139, 0xF4ED,0x8259,\n 0xF4EE,0x83D6, 0xF4EF,0x84BC, 0xF4F0,0x50B5, 0xF4F1,0x57F0, 0xF4F2,0x5BC0, 0xF4F3,0x5BE8, 0xF4F4,0x5F69, 0xF4F5,0x63A1,\n 0xF4F6,0x7826, 0xF4F7,0x7DB5, 0xF4F8,0x83DC, 0xF4F9,0x8521, 0xF4FA,0x91C7, 0xF4FB,0x91F5, 0xF4FC,0x518A, 0xF4FD,0x67F5,\n 0xF4FE,0x7B56, 0xF531,0x8CAC, 0xF532,0x51C4, 0xF533,0x59BB, 0xF534,0x60BD, 0xF535,0x8655, 0xF536,0x501C, 0xF537,0xF9FF,\n 0xF538,0x5254, 0xF539,0x5C3A, 0xF53A,0x617D, 0xF53B,0x621A, 0xF53C,0x62D3, 0xF53D,0x64F2, 0xF53E,0x65A5, 0xF53F,0x6ECC,\n 0xF540,0x7620, 0xF541,0x810A, 0xF542,0x8E60, 0xF543,0x965F, 0xF544,0x96BB, 0xF545,0x4EDF, 0xF546,0x5343, 0xF547,0x5598,\n 0xF548,0x5929, 0xF549,0x5DDD, 0xF54A,0x64C5, 0xF54B,0x6CC9, 0xF54C,0x6DFA, 0xF54D,0x7394, 0xF54E,0x7A7F, 0xF54F,0x821B,\n 0xF550,0x85A6, 0xF551,0x8CE4, 0xF552,0x8E10, 0xF553,0x9077, 0xF554,0x91E7, 0xF555,0x95E1, 0xF556,0x9621, 0xF557,0x97C6,\n 0xF558,0x51F8, 0xF559,0x54F2, 0xF55A,0x5586, 0xF55B,0x5FB9, 0xF55C,0x64A4, 0xF55D,0x6F88, 0xF55E,0x7DB4, 0xF55F,0x8F1F,\n 0xF560,0x8F4D, 0xF561,0x9435, 0xF562,0x50C9, 0xF563,0x5C16, 0xF564,0x6CBE, 0xF565,0x6DFB, 0xF566,0x751B, 0xF567,0x77BB,\n 0xF568,0x7C3D, 0xF569,0x7C64, 0xF56A,0x8A79, 0xF56B,0x8AC2, 0xF56C,0x581E, 0xF56D,0x59BE, 0xF56E,0x5E16, 0xF56F,0x6377,\n 0xF570,0x7252, 0xF571,0x758A, 0xF572,0x776B, 0xF573,0x8ADC, 0xF574,0x8CBC, 0xF575,0x8F12, 0xF576,0x5EF3, 0xF577,0x6674,\n 0xF578,0x6DF8, 0xF579,0x807D, 0xF57A,0x83C1, 0xF57B,0x8ACB, 0xF57C,0x9751, 0xF57D,0x9BD6, 0xF57E,0xFA00, 0xF591,0x5243,\n 0xF592,0x66FF, 0xF593,0x6D95, 0xF594,0x6EEF, 0xF595,0x7DE0, 0xF596,0x8AE6, 0xF597,0x902E, 0xF598,0x905E, 0xF599,0x9AD4,\n 0xF59A,0x521D, 0xF59B,0x527F, 0xF59C,0x54E8, 0xF59D,0x6194, 0xF59E,0x6284, 0xF59F,0x62DB, 0xF5A0,0x68A2, 0xF5A1,0x6912,\n 0xF5A2,0x695A, 0xF5A3,0x6A35, 0xF5A4,0x7092, 0xF5A5,0x7126, 0xF5A6,0x785D, 0xF5A7,0x7901, 0xF5A8,0x790E, 0xF5A9,0x79D2,\n 0xF5AA,0x7A0D, 0xF5AB,0x8096, 0xF5AC,0x8278, 0xF5AD,0x82D5, 0xF5AE,0x8349, 0xF5AF,0x8549, 0xF5B0,0x8C82, 0xF5B1,0x8D85,\n 0xF5B2,0x9162, 0xF5B3,0x918B, 0xF5B4,0x91AE, 0xF5B5,0x4FC3, 0xF5B6,0x56D1, 0xF5B7,0x71ED, 0xF5B8,0x77D7, 0xF5B9,0x8700,\n 0xF5BA,0x89F8, 0xF5BB,0x5BF8, 0xF5BC,0x5FD6, 0xF5BD,0x6751, 0xF5BE,0x90A8, 0xF5BF,0x53E2, 0xF5C0,0x585A, 0xF5C1,0x5BF5,\n 0xF5C2,0x60A4, 0xF5C3,0x6181, 0xF5C4,0x6460, 0xF5C5,0x7E3D, 0xF5C6,0x8070, 0xF5C7,0x8525, 0xF5C8,0x9283, 0xF5C9,0x64AE,\n 0xF5CA,0x50AC, 0xF5CB,0x5D14, 0xF5CC,0x6700, 0xF5CD,0x589C, 0xF5CE,0x62BD, 0xF5CF,0x63A8, 0xF5D0,0x690E, 0xF5D1,0x6978,\n 0xF5D2,0x6A1E, 0xF5D3,0x6E6B, 0xF5D4,0x76BA, 0xF5D5,0x79CB, 0xF5D6,0x82BB, 0xF5D7,0x8429, 0xF5D8,0x8ACF, 0xF5D9,0x8DA8,\n 0xF5DA,0x8FFD, 0xF5DB,0x9112, 0xF5DC,0x914B, 0xF5DD,0x919C, 0xF5DE,0x9310, 0xF5DF,0x9318, 0xF5E0,0x939A, 0xF5E1,0x96DB,\n 0xF5E2,0x9A36, 0xF5E3,0x9C0D, 0xF5E4,0x4E11, 0xF5E5,0x755C, 0xF5E6,0x795D, 0xF5E7,0x7AFA, 0xF5E8,0x7B51, 0xF5E9,0x7BC9,\n 0xF5EA,0x7E2E, 0xF5EB,0x84C4, 0xF5EC,0x8E59, 0xF5ED,0x8E74, 0xF5EE,0x8EF8, 0xF5EF,0x9010, 0xF5F0,0x6625, 0xF5F1,0x693F,\n 0xF5F2,0x7443, 0xF5F3,0x51FA, 0xF5F4,0x672E, 0xF5F5,0x9EDC, 0xF5F6,0x5145, 0xF5F7,0x5FE0, 0xF5F8,0x6C96, 0xF5F9,0x87F2,\n 0xF5FA,0x885D, 0xF5FB,0x8877, 0xF5FC,0x60B4, 0xF5FD,0x81B5, 0xF5FE,0x8403, 0xF631,0x8D05, 0xF632,0x53D6, 0xF633,0x5439,\n 0xF634,0x5634, 0xF635,0x5A36, 0xF636,0x5C31, 0xF637,0x708A, 0xF638,0x7FE0, 0xF639,0x805A, 0xF63A,0x8106, 0xF63B,0x81ED,\n 0xF63C,0x8DA3, 0xF63D,0x9189, 0xF63E,0x9A5F, 0xF63F,0x9DF2, 0xF640,0x5074, 0xF641,0x4EC4, 0xF642,0x53A0, 0xF643,0x60FB,\n 0xF644,0x6E2C, 0xF645,0x5C64, 0xF646,0x4F88, 0xF647,0x5024, 0xF648,0x55E4, 0xF649,0x5CD9, 0xF64A,0x5E5F, 0xF64B,0x6065,\n 0xF64C,0x6894, 0xF64D,0x6CBB, 0xF64E,0x6DC4, 0xF64F,0x71BE, 0xF650,0x75D4, 0xF651,0x75F4, 0xF652,0x7661, 0xF653,0x7A1A,\n 0xF654,0x7A49, 0xF655,0x7DC7, 0xF656,0x7DFB, 0xF657,0x7F6E, 0xF658,0x81F4, 0xF659,0x86A9, 0xF65A,0x8F1C, 0xF65B,0x96C9,\n 0xF65C,0x99B3, 0xF65D,0x9F52, 0xF65E,0x5247, 0xF65F,0x52C5, 0xF660,0x98ED, 0xF661,0x89AA, 0xF662,0x4E03, 0xF663,0x67D2,\n 0xF664,0x6F06, 0xF665,0x4FB5, 0xF666,0x5BE2, 0xF667,0x6795, 0xF668,0x6C88, 0xF669,0x6D78, 0xF66A,0x741B, 0xF66B,0x7827,\n 0xF66C,0x91DD, 0xF66D,0x937C, 0xF66E,0x87C4, 0xF66F,0x79E4, 0xF670,0x7A31, 0xF671,0x5FEB, 0xF672,0x4ED6, 0xF673,0x54A4,\n 0xF674,0x553E, 0xF675,0x58AE, 0xF676,0x59A5, 0xF677,0x60F0, 0xF678,0x6253, 0xF679,0x62D6, 0xF67A,0x6736, 0xF67B,0x6955,\n 0xF67C,0x8235, 0xF67D,0x9640, 0xF67E,0x99B1, 0xF691,0x99DD, 0xF692,0x502C, 0xF693,0x5353, 0xF694,0x5544, 0xF695,0x577C,\n 0xF696,0xFA01, 0xF697,0x6258, 0xF698,0xFA02, 0xF699,0x64E2, 0xF69A,0x666B, 0xF69B,0x67DD, 0xF69C,0x6FC1, 0xF69D,0x6FEF,\n 0xF69E,0x7422, 0xF69F,0x7438, 0xF6A0,0x8A17, 0xF6A1,0x9438, 0xF6A2,0x5451, 0xF6A3,0x5606, 0xF6A4,0x5766, 0xF6A5,0x5F48,\n 0xF6A6,0x619A, 0xF6A7,0x6B4E, 0xF6A8,0x7058, 0xF6A9,0x70AD, 0xF6AA,0x7DBB, 0xF6AB,0x8A95, 0xF6AC,0x596A, 0xF6AD,0x812B,\n 0xF6AE,0x63A2, 0xF6AF,0x7708, 0xF6B0,0x803D, 0xF6B1,0x8CAA, 0xF6B2,0x5854, 0xF6B3,0x642D, 0xF6B4,0x69BB, 0xF6B5,0x5B95,\n 0xF6B6,0x5E11, 0xF6B7,0x6E6F, 0xF6B8,0xFA03, 0xF6B9,0x8569, 0xF6BA,0x514C, 0xF6BB,0x53F0, 0xF6BC,0x592A, 0xF6BD,0x6020,\n 0xF6BE,0x614B, 0xF6BF,0x6B86, 0xF6C0,0x6C70, 0xF6C1,0x6CF0, 0xF6C2,0x7B1E, 0xF6C3,0x80CE, 0xF6C4,0x82D4, 0xF6C5,0x8DC6,\n 0xF6C6,0x90B0, 0xF6C7,0x98B1, 0xF6C8,0xFA04, 0xF6C9,0x64C7, 0xF6CA,0x6FA4, 0xF6CB,0x6491, 0xF6CC,0x6504, 0xF6CD,0x514E,\n 0xF6CE,0x5410, 0xF6CF,0x571F, 0xF6D0,0x8A0E, 0xF6D1,0x615F, 0xF6D2,0x6876, 0xF6D3,0xFA05, 0xF6D4,0x75DB, 0xF6D5,0x7B52,\n 0xF6D6,0x7D71, 0xF6D7,0x901A, 0xF6D8,0x5806, 0xF6D9,0x69CC, 0xF6DA,0x817F, 0xF6DB,0x892A, 0xF6DC,0x9000, 0xF6DD,0x9839,\n 0xF6DE,0x5078, 0xF6DF,0x5957, 0xF6E0,0x59AC, 0xF6E1,0x6295, 0xF6E2,0x900F, 0xF6E3,0x9B2A, 0xF6E4,0x615D, 0xF6E5,0x7279,\n 0xF6E6,0x95D6, 0xF6E7,0x5761, 0xF6E8,0x5A46, 0xF6E9,0x5DF4, 0xF6EA,0x628A, 0xF6EB,0x64AD, 0xF6EC,0x64FA, 0xF6ED,0x6777,\n 0xF6EE,0x6CE2, 0xF6EF,0x6D3E, 0xF6F0,0x722C, 0xF6F1,0x7436, 0xF6F2,0x7834, 0xF6F3,0x7F77, 0xF6F4,0x82AD, 0xF6F5,0x8DDB,\n 0xF6F6,0x9817, 0xF6F7,0x5224, 0xF6F8,0x5742, 0xF6F9,0x677F, 0xF6FA,0x7248, 0xF6FB,0x74E3, 0xF6FC,0x8CA9, 0xF6FD,0x8FA6,\n 0xF6FE,0x9211, 0xF731,0x962A, 0xF732,0x516B, 0xF733,0x53ED, 0xF734,0x634C, 0xF735,0x4F69, 0xF736,0x5504, 0xF737,0x6096,\n 0xF738,0x6557, 0xF739,0x6C9B, 0xF73A,0x6D7F, 0xF73B,0x724C, 0xF73C,0x72FD, 0xF73D,0x7A17, 0xF73E,0x8987, 0xF73F,0x8C9D,\n 0xF740,0x5F6D, 0xF741,0x6F8E, 0xF742,0x70F9, 0xF743,0x81A8, 0xF744,0x610E, 0xF745,0x4FBF, 0xF746,0x504F, 0xF747,0x6241,\n 0xF748,0x7247, 0xF749,0x7BC7, 0xF74A,0x7DE8, 0xF74B,0x7FE9, 0xF74C,0x904D, 0xF74D,0x97AD, 0xF74E,0x9A19, 0xF74F,0x8CB6,\n 0xF750,0x576A, 0xF751,0x5E73, 0xF752,0x67B0, 0xF753,0x840D, 0xF754,0x8A55, 0xF755,0x5420, 0xF756,0x5B16, 0xF757,0x5E63,\n 0xF758,0x5EE2, 0xF759,0x5F0A, 0xF75A,0x6583, 0xF75B,0x80BA, 0xF75C,0x853D, 0xF75D,0x9589, 0xF75E,0x965B, 0xF75F,0x4F48,\n 0xF760,0x5305, 0xF761,0x530D, 0xF762,0x530F, 0xF763,0x5486, 0xF764,0x54FA, 0xF765,0x5703, 0xF766,0x5E03, 0xF767,0x6016,\n 0xF768,0x629B, 0xF769,0x62B1, 0xF76A,0x6355, 0xF76B,0xFA06, 0xF76C,0x6CE1, 0xF76D,0x6D66, 0xF76E,0x75B1, 0xF76F,0x7832,\n 0xF770,0x80DE, 0xF771,0x812F, 0xF772,0x82DE, 0xF773,0x8461, 0xF774,0x84B2, 0xF775,0x888D, 0xF776,0x8912, 0xF777,0x900B,\n 0xF778,0x92EA, 0xF779,0x98FD, 0xF77A,0x9B91, 0xF77B,0x5E45, 0xF77C,0x66B4, 0xF77D,0x66DD, 0xF77E,0x7011, 0xF791,0x7206,\n 0xF792,0xFA07, 0xF793,0x4FF5, 0xF794,0x527D, 0xF795,0x5F6A, 0xF796,0x6153, 0xF797,0x6753, 0xF798,0x6A19, 0xF799,0x6F02,\n 0xF79A,0x74E2, 0xF79B,0x7968, 0xF79C,0x8868, 0xF79D,0x8C79, 0xF79E,0x98C7, 0xF79F,0x98C4, 0xF7A0,0x9A43, 0xF7A1,0x54C1,\n 0xF7A2,0x7A1F, 0xF7A3,0x6953, 0xF7A4,0x8AF7, 0xF7A5,0x8C4A, 0xF7A6,0x98A8, 0xF7A7,0x99AE, 0xF7A8,0x5F7C, 0xF7A9,0x62AB,\n 0xF7AA,0x75B2, 0xF7AB,0x76AE, 0xF7AC,0x88AB, 0xF7AD,0x907F, 0xF7AE,0x9642, 0xF7AF,0x5339, 0xF7B0,0x5F3C, 0xF7B1,0x5FC5,\n 0xF7B2,0x6CCC, 0xF7B3,0x73CC, 0xF7B4,0x7562, 0xF7B5,0x758B, 0xF7B6,0x7B46, 0xF7B7,0x82FE, 0xF7B8,0x999D, 0xF7B9,0x4E4F,\n 0xF7BA,0x903C, 0xF7BB,0x4E0B, 0xF7BC,0x4F55, 0xF7BD,0x53A6, 0xF7BE,0x590F, 0xF7BF,0x5EC8, 0xF7C0,0x6630, 0xF7C1,0x6CB3,\n 0xF7C2,0x7455, 0xF7C3,0x8377, 0xF7C4,0x8766, 0xF7C5,0x8CC0, 0xF7C6,0x9050, 0xF7C7,0x971E, 0xF7C8,0x9C15, 0xF7C9,0x58D1,\n 0xF7CA,0x5B78, 0xF7CB,0x8650, 0xF7CC,0x8B14, 0xF7CD,0x9DB4, 0xF7CE,0x5BD2, 0xF7CF,0x6068, 0xF7D0,0x608D, 0xF7D1,0x65F1,\n 0xF7D2,0x6C57, 0xF7D3,0x6F22, 0xF7D4,0x6FA3, 0xF7D5,0x701A, 0xF7D6,0x7F55, 0xF7D7,0x7FF0, 0xF7D8,0x9591, 0xF7D9,0x9592,\n 0xF7DA,0x9650, 0xF7DB,0x97D3, 0xF7DC,0x5272, 0xF7DD,0x8F44, 0xF7DE,0x51FD, 0xF7DF,0x542B, 0xF7E0,0x54B8, 0xF7E1,0x5563,\n 0xF7E2,0x558A, 0xF7E3,0x6ABB, 0xF7E4,0x6DB5, 0xF7E5,0x7DD8, 0xF7E6,0x8266, 0xF7E7,0x929C, 0xF7E8,0x9677, 0xF7E9,0x9E79,\n 0xF7EA,0x5408, 0xF7EB,0x54C8, 0xF7EC,0x76D2, 0xF7ED,0x86E4, 0xF7EE,0x95A4, 0xF7EF,0x95D4, 0xF7F0,0x965C, 0xF7F1,0x4EA2,\n 0xF7F2,0x4F09, 0xF7F3,0x59EE, 0xF7F4,0x5AE6, 0xF7F5,0x5DF7, 0xF7F6,0x6052, 0xF7F7,0x6297, 0xF7F8,0x676D, 0xF7F9,0x6841,\n 0xF7FA,0x6C86, 0xF7FB,0x6E2F, 0xF7FC,0x7F38, 0xF7FD,0x809B, 0xF7FE,0x822A, 0xF831,0xFA08, 0xF832,0xFA09, 0xF833,0x9805,\n 0xF834,0x4EA5, 0xF835,0x5055, 0xF836,0x54B3, 0xF837,0x5793, 0xF838,0x595A, 0xF839,0x5B69, 0xF83A,0x5BB3, 0xF83B,0x61C8,\n 0xF83C,0x6977, 0xF83D,0x6D77, 0xF83E,0x7023, 0xF83F,0x87F9, 0xF840,0x89E3, 0xF841,0x8A72, 0xF842,0x8AE7, 0xF843,0x9082,\n 0xF844,0x99ED, 0xF845,0x9AB8, 0xF846,0x52BE, 0xF847,0x6838, 0xF848,0x5016, 0xF849,0x5E78, 0xF84A,0x674F, 0xF84B,0x8347,\n 0xF84C,0x884C, 0xF84D,0x4EAB, 0xF84E,0x5411, 0xF84F,0x56AE, 0xF850,0x73E6, 0xF851,0x9115, 0xF852,0x97FF, 0xF853,0x9909,\n 0xF854,0x9957, 0xF855,0x9999, 0xF856,0x5653, 0xF857,0x589F, 0xF858,0x865B, 0xF859,0x8A31, 0xF85A,0x61B2, 0xF85B,0x6AF6,\n 0xF85C,0x737B, 0xF85D,0x8ED2, 0xF85E,0x6B47, 0xF85F,0x96AA, 0xF860,0x9A57, 0xF861,0x5955, 0xF862,0x7200, 0xF863,0x8D6B,\n 0xF864,0x9769, 0xF865,0x4FD4, 0xF866,0x5CF4, 0xF867,0x5F26, 0xF868,0x61F8, 0xF869,0x665B, 0xF86A,0x6CEB, 0xF86B,0x70AB,\n 0xF86C,0x7384, 0xF86D,0x73B9, 0xF86E,0x73FE, 0xF86F,0x7729, 0xF870,0x774D, 0xF871,0x7D43, 0xF872,0x7D62, 0xF873,0x7E23,\n 0xF874,0x8237, 0xF875,0x8852, 0xF876,0xFA0A, 0xF877,0x8CE2, 0xF878,0x9249, 0xF879,0x986F, 0xF87A,0x5B51, 0xF87B,0x7A74,\n 0xF87C,0x8840, 0xF87D,0x9801, 0xF87E,0x5ACC, 0xF891,0x4FE0, 0xF892,0x5354, 0xF893,0x593E, 0xF894,0x5CFD, 0xF895,0x633E,\n 0xF896,0x6D79, 0xF897,0x72F9, 0xF898,0x8105, 0xF899,0x8107, 0xF89A,0x83A2, 0xF89B,0x92CF, 0xF89C,0x9830, 0xF89D,0x4EA8,\n 0xF89E,0x5144, 0xF89F,0x5211, 0xF8A0,0x578B, 0xF8A1,0x5F62, 0xF8A2,0x6CC2, 0xF8A3,0x6ECE, 0xF8A4,0x7005, 0xF8A5,0x7050,\n 0xF8A6,0x70AF, 0xF8A7,0x7192, 0xF8A8,0x73E9, 0xF8A9,0x7469, 0xF8AA,0x834A, 0xF8AB,0x87A2, 0xF8AC,0x8861, 0xF8AD,0x9008,\n 0xF8AE,0x90A2, 0xF8AF,0x93A3, 0xF8B0,0x99A8, 0xF8B1,0x516E, 0xF8B2,0x5F57, 0xF8B3,0x60E0, 0xF8B4,0x6167, 0xF8B5,0x66B3,\n 0xF8B6,0x8559, 0xF8B7,0x8E4A, 0xF8B8,0x91AF, 0xF8B9,0x978B, 0xF8BA,0x4E4E, 0xF8BB,0x4E92, 0xF8BC,0x547C, 0xF8BD,0x58D5,\n 0xF8BE,0x58FA, 0xF8BF,0x597D, 0xF8C0,0x5CB5, 0xF8C1,0x5F27, 0xF8C2,0x6236, 0xF8C3,0x6248, 0xF8C4,0x660A, 0xF8C5,0x6667,\n 0xF8C6,0x6BEB, 0xF8C7,0x6D69, 0xF8C8,0x6DCF, 0xF8C9,0x6E56, 0xF8CA,0x6EF8, 0xF8CB,0x6F94, 0xF8CC,0x6FE0, 0xF8CD,0x6FE9,\n 0xF8CE,0x705D, 0xF8CF,0x72D0, 0xF8D0,0x7425, 0xF8D1,0x745A, 0xF8D2,0x74E0, 0xF8D3,0x7693, 0xF8D4,0x795C, 0xF8D5,0x7CCA,\n 0xF8D6,0x7E1E, 0xF8D7,0x80E1, 0xF8D8,0x82A6, 0xF8D9,0x846B, 0xF8DA,0x84BF, 0xF8DB,0x864E, 0xF8DC,0x865F, 0xF8DD,0x8774,\n 0xF8DE,0x8B77, 0xF8DF,0x8C6A, 0xF8E0,0x93AC, 0xF8E1,0x9800, 0xF8E2,0x9865, 0xF8E3,0x60D1, 0xF8E4,0x6216, 0xF8E5,0x9177,\n 0xF8E6,0x5A5A, 0xF8E7,0x660F, 0xF8E8,0x6DF7, 0xF8E9,0x6E3E, 0xF8EA,0x743F, 0xF8EB,0x9B42, 0xF8EC,0x5FFD, 0xF8ED,0x60DA,\n 0xF8EE,0x7B0F, 0xF8EF,0x54C4, 0xF8F0,0x5F18, 0xF8F1,0x6C5E, 0xF8F2,0x6CD3, 0xF8F3,0x6D2A, 0xF8F4,0x70D8, 0xF8F5,0x7D05,\n 0xF8F6,0x8679, 0xF8F7,0x8A0C, 0xF8F8,0x9D3B, 0xF8F9,0x5316, 0xF8FA,0x548C, 0xF8FB,0x5B05, 0xF8FC,0x6A3A, 0xF8FD,0x706B,\n 0xF8FE,0x7575, 0xF931,0x798D, 0xF932,0x79BE, 0xF933,0x82B1, 0xF934,0x83EF, 0xF935,0x8A71, 0xF936,0x8B41, 0xF937,0x8CA8,\n 0xF938,0x9774, 0xF939,0xFA0B, 0xF93A,0x64F4, 0xF93B,0x652B, 0xF93C,0x78BA, 0xF93D,0x78BB, 0xF93E,0x7A6B, 0xF93F,0x4E38,\n 0xF940,0x559A, 0xF941,0x5950, 0xF942,0x5BA6, 0xF943,0x5E7B, 0xF944,0x60A3, 0xF945,0x63DB, 0xF946,0x6B61, 0xF947,0x6665,\n 0xF948,0x6853, 0xF949,0x6E19, 0xF94A,0x7165, 0xF94B,0x74B0, 0xF94C,0x7D08, 0xF94D,0x9084, 0xF94E,0x9A69, 0xF94F,0x9C25,\n 0xF950,0x6D3B, 0xF951,0x6ED1, 0xF952,0x733E, 0xF953,0x8C41, 0xF954,0x95CA, 0xF955,0x51F0, 0xF956,0x5E4C, 0xF957,0x5FA8,\n 0xF958,0x604D, 0xF959,0x60F6, 0xF95A,0x6130, 0xF95B,0x614C, 0xF95C,0x6643, 0xF95D,0x6644, 0xF95E,0x69A5, 0xF95F,0x6CC1,\n 0xF960,0x6E5F, 0xF961,0x6EC9, 0xF962,0x6F62, 0xF963,0x714C, 0xF964,0x749C, 0xF965,0x7687, 0xF966,0x7BC1, 0xF967,0x7C27,\n 0xF968,0x8352, 0xF969,0x8757, 0xF96A,0x9051, 0xF96B,0x968D, 0xF96C,0x9EC3, 0xF96D,0x532F, 0xF96E,0x56DE, 0xF96F,0x5EFB,\n 0xF970,0x5F8A, 0xF971,0x6062, 0xF972,0x6094, 0xF973,0x61F7, 0xF974,0x6666, 0xF975,0x6703, 0xF976,0x6A9C, 0xF977,0x6DEE,\n 0xF978,0x6FAE, 0xF979,0x7070, 0xF97A,0x736A, 0xF97B,0x7E6A, 0xF97C,0x81BE, 0xF97D,0x8334, 0xF97E,0x86D4, 0xF991,0x8AA8,\n 0xF992,0x8CC4, 0xF993,0x5283, 0xF994,0x7372, 0xF995,0x5B96, 0xF996,0x6A6B, 0xF997,0x9404, 0xF998,0x54EE, 0xF999,0x5686,\n 0xF99A,0x5B5D, 0xF99B,0x6548, 0xF99C,0x6585, 0xF99D,0x66C9, 0xF99E,0x689F, 0xF99F,0x6D8D, 0xF9A0,0x6DC6, 0xF9A1,0x723B,\n 0xF9A2,0x80B4, 0xF9A3,0x9175, 0xF9A4,0x9A4D, 0xF9A5,0x4FAF, 0xF9A6,0x5019, 0xF9A7,0x539A, 0xF9A8,0x540E, 0xF9A9,0x543C,\n 0xF9AA,0x5589, 0xF9AB,0x55C5, 0xF9AC,0x5E3F, 0xF9AD,0x5F8C, 0xF9AE,0x673D, 0xF9AF,0x7166, 0xF9B0,0x73DD, 0xF9B1,0x9005,\n 0xF9B2,0x52DB, 0xF9B3,0x52F3, 0xF9B4,0x5864, 0xF9B5,0x58CE, 0xF9B6,0x7104, 0xF9B7,0x718F, 0xF9B8,0x71FB, 0xF9B9,0x85B0,\n 0xF9BA,0x8A13, 0xF9BB,0x6688, 0xF9BC,0x85A8, 0xF9BD,0x55A7, 0xF9BE,0x6684, 0xF9BF,0x714A, 0xF9C0,0x8431, 0xF9C1,0x5349,\n 0xF9C2,0x5599, 0xF9C3,0x6BC1, 0xF9C4,0x5F59, 0xF9C5,0x5FBD, 0xF9C6,0x63EE, 0xF9C7,0x6689, 0xF9C8,0x7147, 0xF9C9,0x8AF1,\n 0xF9CA,0x8F1D, 0xF9CB,0x9EBE, 0xF9CC,0x4F11, 0xF9CD,0x643A, 0xF9CE,0x70CB, 0xF9CF,0x7566, 0xF9D0,0x8667, 0xF9D1,0x6064,\n 0xF9D2,0x8B4E, 0xF9D3,0x9DF8, 0xF9D4,0x5147, 0xF9D5,0x51F6, 0xF9D6,0x5308, 0xF9D7,0x6D36, 0xF9D8,0x80F8, 0xF9D9,0x9ED1,\n 0xF9DA,0x6615, 0xF9DB,0x6B23, 0xF9DC,0x7098, 0xF9DD,0x75D5, 0xF9DE,0x5403, 0xF9DF,0x5C79, 0xF9E0,0x7D07, 0xF9E1,0x8A16,\n 0xF9E2,0x6B20, 0xF9E3,0x6B3D, 0xF9E4,0x6B46, 0xF9E5,0x5438, 0xF9E6,0x6070, 0xF9E7,0x6D3D, 0xF9E8,0x7FD5, 0xF9E9,0x8208,\n 0xF9EA,0x50D6, 0xF9EB,0x51DE, 0xF9EC,0x559C, 0xF9ED,0x566B, 0xF9EE,0x56CD, 0xF9EF,0x59EC, 0xF9F0,0x5B09, 0xF9F1,0x5E0C,\n 0xF9F2,0x6199, 0xF9F3,0x6198, 0xF9F4,0x6231, 0xF9F5,0x665E, 0xF9F6,0x66E6, 0xF9F7,0x7199, 0xF9F8,0x71B9, 0xF9F9,0x71BA,\n 0xF9FA,0x72A7, 0xF9FB,0x79A7, 0xF9FC,0x7A00, 0xF9FD,0x7FB2, 0xF9FE,0x8A70,\n])\n","/**\n * HWP 3.0 상용 조합형 → 유니코드 디코더.\n *\n * 한국어 한글은 cho/jung/jong 비트 분해로 0xAC00 한글 음절 영역에 직접 매핑되고,\n * 한자/기호 등 그 외 영역은 johab-symbols.ts 의 lookup table 로 처리한다.\n * 매핑되지 않는 코드는 '?' 로 fallback 한다.\n *\n * 출처: rhwp/src/parser/hwp3/johab.rs (Apache-2.0). 알고리즘 동일.\n */\n\nimport { JOHAB_SYMBOLS } from \"./johab-symbols.js\"\n\n// 인덱스 → 자모 위치. -1 은 invalid (KS X 1001 johab 정의).\nconst CHO_MAP: ReadonlyArray<number> = Object.freeze([\n -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n])\nconst JUNG_MAP: ReadonlyArray<number> = Object.freeze([\n -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, 5, 6, 7, 8, 9, 10, -1, -1, 11, 12, 13, 14,\n 15, 16, -1, -1, 17, 18, 19, 20, -1, -1,\n])\nconst JONG_MAP: ReadonlyArray<number> = Object.freeze([\n -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19,\n 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,\n])\n\n/** JOHAB_SYMBOLS flat array (key,val,key,val…) 에서 key 이진 탐색. */\nfunction lookupSymbol(ch: number): number | null {\n let lo = 0\n let hi = JOHAB_SYMBOLS.length / 2 - 1\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1\n const k = JOHAB_SYMBOLS[mid * 2]\n if (k === ch) return JOHAB_SYMBOLS[mid * 2 + 1]\n if (k < ch) lo = mid + 1\n else hi = mid - 1\n }\n return null\n}\n\n/** 매핑 실패를 명확히 알리기 위한 sentinel. 호출자가 string 에 추가하지 않도록 skip. */\nexport const JOHAB_UNMAPPED = -1\n\n/**\n * HWP3 hchar (u16) → 유니코드 코드포인트. 매핑 실패 시 JOHAB_UNMAPPED.\n *\n * 매핑 실패 케이스를 '?' 로 fallback 시키면 검색 인덱스에 noise 가 누적된다 (특히\n * 메타 컨트롤이 가득한 paragraph 가 ??? 시퀀스를 생산). 호출자가 unmapped 를\n * 식별해서 silently skip 할 수 있도록 sentinel 을 반환한다.\n */\nexport function decodeJohab(ch: number): number {\n // ASCII 영역 — 1바이트 직접 사용\n if (ch < 0x80) return ch\n\n // 조합형 한글 (상위 비트 1): cho 5b | jung 5b | jong 5b\n if (ch >= 0x8000) {\n const choIdx = (ch >> 10) & 0x1f\n const jungIdx = (ch >> 5) & 0x1f\n const jongIdx = ch & 0x1f\n\n const cho = CHO_MAP[choIdx]\n const jung = JUNG_MAP[jungIdx]\n let jong = JONG_MAP[jongIdx]\n\n if (cho !== -1 && jung !== -1) {\n if (jong === -1) jong = 0\n // 0xAC00 + (cho * 21 * 28) + (jung * 28) + jong\n return 0xac00 + cho * 588 + jung * 28 + jong\n }\n\n // 한자/기호: lookup table\n const hit = lookupSymbol(ch)\n if (hit !== null) return hit\n }\n\n return JOHAB_UNMAPPED\n}\n\n/**\n * HWP3 hchar stream (u16 LE 순서) 를 string 으로 디코딩.\n *\n * DocSummary 의 56 hchar (112 byte) 영역에 사용. 본문 char stream 과 같은 단위인데\n * 그 영역은 ASCII 도 high byte 0 으로 padding 되어 있다 (\"C\\x00r\\x00...\"). byte 단위\n * 디코딩으로 처리하면 NUL 에서 break 되어 첫 글자만 남으므로, hchar 단위 LE u16 로\n * 읽고 그 값이 0 이면 종료한다.\n */\nexport function decodeHcharString(bytes: Uint8Array): string {\n let out = \"\"\n let i = 0\n while (i + 1 < bytes.length) {\n const ch = bytes[i] | (bytes[i + 1] << 8) // LE u16\n if (ch === 0) break\n const cp = decodeJohab(ch)\n if (cp !== JOHAB_UNMAPPED) out += String.fromCodePoint(cp)\n i += 2\n }\n return out\n}\n\n/**\n * HWP3 byte sequence (1바이트 ASCII < 0x80, 2바이트 johab >= 0x80) 를 string 으로 디코딩.\n * NUL byte 만나면 종료. link_print_file/description 같은 짧은 byte string 영역에 사용.\n */\nexport function decodeHwp3String(bytes: Uint8Array): string {\n let out = \"\"\n let i = 0\n while (i < bytes.length) {\n const b1 = bytes[i]\n if (b1 === 0) break\n if (b1 < 0x80) {\n out += String.fromCharCode(b1)\n i += 1\n } else if (i + 1 < bytes.length) {\n const ch = (b1 << 8) | bytes[i + 1]\n const cp = decodeJohab(ch)\n if (cp !== JOHAB_UNMAPPED) out += String.fromCodePoint(cp)\n i += 2\n } else {\n i += 1\n }\n }\n return out\n}\n","/**\n * HWP3 binary stream reader.\n * Buffer 기반 cursor 로 little-endian primitive 를 순차 read 한다.\n * 부족한 데이터에선 InsufficientData 를 throw 해서 상위 try/catch 가 partial-parse 모드로 전환할 수 있게 한다.\n */\n\nexport class InsufficientDataError extends Error {\n constructor(public requested: number, public available: number) {\n super(`HWP3: insufficient data (need ${requested}, have ${available})`)\n this.name = \"InsufficientDataError\"\n }\n}\n\nexport class Reader {\n private pos: number\n\n constructor(private readonly buf: Buffer, start = 0) {\n this.pos = start\n }\n\n position(): number {\n return this.pos\n }\n\n remaining(): number {\n return this.buf.length - this.pos\n }\n\n eof(): boolean {\n return this.pos >= this.buf.length\n }\n\n skip(n: number): void {\n this.ensure(n)\n this.pos += n\n }\n\n private ensure(n: number) {\n if (this.pos + n > this.buf.length) {\n throw new InsufficientDataError(n, this.buf.length - this.pos)\n }\n }\n\n readU8(): number {\n this.ensure(1)\n const v = this.buf[this.pos]\n this.pos += 1\n return v\n }\n\n readU16(): number {\n this.ensure(2)\n const v = this.buf.readUInt16LE(this.pos)\n this.pos += 2\n return v\n }\n\n readU32(): number {\n this.ensure(4)\n const v = this.buf.readUInt32LE(this.pos)\n this.pos += 4\n return v\n }\n\n readBytes(n: number): Buffer {\n this.ensure(n)\n const slice = this.buf.subarray(this.pos, this.pos + n)\n this.pos += n\n return slice\n }\n\n /** 남은 모든 바이트를 새 Buffer 로 반환 (커서를 끝으로 이동). */\n readToEnd(): Buffer {\n const slice = this.buf.subarray(this.pos)\n this.pos = this.buf.length\n return slice\n }\n}\n","/**\n * HWP3 fixed-size record definitions.\n *\n * 모두 little-endian. 구조는 rhwp/src/parser/hwp3/records.rs 와 1:1 대응.\n * 텍스트 추출에 필요한 필드만 명시적으로 노출하고, 레이아웃 전용 필드 (margins,\n * tab stops 등) 는 단순 skip 한다.\n */\n\nimport { Reader } from \"./reader.js\"\nimport { decodeHcharString } from \"./johab.js\"\n\n// HWP3 file signature: \"HWP Document File V3.00 \" (24 bytes) + 6-byte tail (\\x1A\\x01\\x02\\x03\\x04\\x05)\n// 총 30 byte. 일부 실제 파일은 첫 30 byte 이내에 NUL pad 가 끼어있는 경우가 있어\n// 앞 23 byte 의 ASCII signature 만 strict 비교하고 나머지 7 byte 는 advisory.\nexport const SIGNATURE_PREFIX = Buffer.from(\"HWP Document File V3.00\", \"ascii\")\nexport const SIGNATURE_LEN = 30\n\n/** rhwp 와 같은 고정 byte size. cursor 가 정확히 이 만큼 advance 한다. */\nexport const DOC_INFO_SIZE = 128\nexport const DOC_SUMMARY_SIZE = 9 * 112 // 9 fields × 112 bytes (56 hchar each)\n\nexport interface Hwp3Header {\n /** DocInfo의 압축 플래그 (0이 아니면 InfoBlock 이후 raw deflate 압축). */\n compressed: number\n /** DocInfo 의 encrypted 플래그 (0 이 아니면 본문 암호화 → 복호화 못함). */\n encrypted: number\n /** InfoBlock 길이 (DocSummary 뒤 가변 길이 metadata). */\n infoBlockLength: number\n /** DocSummary 에서 추출한 메타데이터. */\n title: string\n subject: string\n author: string\n date: string\n}\n\n/**\n * 헤더 파싱: 30 byte signature + 128 byte DocInfo + 1008 byte DocSummary.\n * 호출 시 reader 위치는 0 이어야 하고, 반환 후엔 InfoBlock 시작점.\n */\nexport function readHeader(reader: Reader): Hwp3Header {\n // signature 30 byte — strict prefix check\n const sig = reader.readBytes(SIGNATURE_LEN)\n if (!sig.subarray(0, SIGNATURE_PREFIX.length).equals(SIGNATURE_PREFIX)) {\n throw new Error(\"HWP3: invalid file signature\")\n }\n\n // DocInfo 128 byte — 텍스트 추출에 필요한 3개 필드 외엔 skip.\n // 절대 offset 기준 (DocInfo 시작점 = docInfoStart):\n // encrypted : offset 96..97 (u16) — 0 이 아니면 본문 암호 보호\n // compressed : offset 124 (u8) — 0 이 아니면 InfoBlock 이후 raw deflate\n // info_block_length : offset 126..127 (u16) — 가변 InfoBlock 길이\n const docInfoStart = reader.position()\n reader.skip(96)\n const encrypted = reader.readU16() // 96..97\n reader.skip(124 - 98) // → 124\n const compressed = reader.readU8() // 124\n reader.skip(1) // sub_revision (125)\n const infoBlockLength = reader.readU16() // 126..127\n // DocInfo 끝까지 정확히 advance — sanity\n if (reader.position() !== docInfoStart + DOC_INFO_SIZE) {\n throw new Error(\n `HWP3: DocInfo size mismatch (got ${reader.position() - docInfoStart}, expected ${DOC_INFO_SIZE})`,\n )\n }\n\n // DocSummary 1008 byte — title/subject/author/date 만 추출, 나머지 (keywords, etc) skip.\n // DocSummary 의 string 은 56 hchar × 2 byte 로 구성 — byte 단위가 아닌 u16 hchar 단위로\n // 디코딩해야 ASCII 문자가 high byte 0 padding 으로 인해 잘리지 않는다.\n const summaryStart = reader.position()\n const title = decodeHcharString(reader.readBytes(112))\n const subject = decodeHcharString(reader.readBytes(112))\n const author = decodeHcharString(reader.readBytes(112))\n const date = decodeHcharString(reader.readBytes(112))\n // 나머지 (keywords ×2 + etc ×3 = 5 × 112 = 560 byte) skip\n reader.skip(5 * 112)\n if (reader.position() !== summaryStart + DOC_SUMMARY_SIZE) {\n throw new Error(\"HWP3: DocSummary size mismatch\")\n }\n\n return { compressed, encrypted, infoBlockLength, title, subject, author, date }\n}\n","/**\n * HWP 5.x 배포용 문서 \"상위 버전\" 경고 플레이스홀더 감지.\n *\n * 배포용(열람 제한) HWP 파일은 본문을 암호화하고, 복호화 실패 시 한컴에서 삽입한\n * 고정 경고 문자열이 노출된다. 이 문자열이 파싱 결과의 대부분을 차지하면 COM API\n * fallback으로 전환해야 한다.\n *\n * 이슈 #25 참고.\n */\n\n// 배포용 HWP의 고정 경고 문구 (버전·지역에 따라 미세 차이 가능 → 핵심 키만 매칭)\nconst SENTINEL_PATTERNS: RegExp[] = [\n /상위\\s*버전의\\s*배포용\\s*문서/,\n /최신\\s*버전의\\s*한글.*뷰어/,\n /문서를\\s*읽으려면/,\n]\n\n/**\n * 본문이 배포용 플레이스홀더로만 채워졌는지 판정.\n *\n * 기준:\n * - 패턴이 한 번 이상 매치\n * - 패턴을 제거한 나머지 의미 있는 텍스트가 매우 짧음 (공백·개행 제외 120자 미만)\n *\n * → 정상 본문이 섞여 있으면 false (COM fallback 불필요)\n */\nexport function isDistributionSentinel(markdown: string): boolean {\n if (!markdown) return false\n const hit = SENTINEL_PATTERNS.some(p => p.test(markdown))\n if (!hit) return false\n\n // 경고 문구 라인 제거 후 실질 내용이 짧은지\n const stripped = markdown\n .split(/\\r?\\n/)\n .filter(line => !SENTINEL_PATTERNS.some(p => p.test(line)))\n .join(\"\")\n .replace(/\\s+/g, \"\")\n\n return stripped.length < 120\n}\n","/**\n * XLSX (Office Open XML Spreadsheet) 파서\n *\n * ZIP + XML 구조를 jszip + xmldom으로 파싱하여 IRBlock[]로 변환.\n * 각 시트 → heading(시트명) + table(데이터) 블록.\n */\n\nimport JSZip from \"jszip\"\nimport { DOMParser } from \"@xmldom/xmldom\"\nimport type {\n IRBlock, IRTable, IRCell, CellContext, DocumentMetadata, InternalParseResult,\n ParseOptions, ParseWarning, ExtractedImage,\n} from \"../types.js\"\nimport { KordocError, precheckZipSize, stripDtd } from \"../utils.js\"\nimport { buildTable, blocksToMarkdown } from \"../table/builder.js\"\n\n// ─── 상수 ────────────────────────────────────────────\n\nconst MAX_SHEETS = 100\n/** ZIP 압축 해제 누적 최대 크기 (100MB) — ZIP bomb 방지 */\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\nconst MAX_ROWS = 10000\nconst MAX_COLS = 200\n\n// ─── 숫자값 정리 ──────────────────────────────────────\n\n/** 부동소수점 아티팩트 정리 (132.30000000000001 → 132.3) */\nfunction cleanNumericValue(raw: string): string {\n if (!/^-?\\d+\\.\\d+$/.test(raw)) return raw\n const num = parseFloat(raw)\n if (!isFinite(num)) return raw\n // toPrecision(15)로 IEEE 754 오차 제거 후 불필요한 후행 0 제거\n const cleaned = parseFloat(num.toPrecision(15)).toString()\n return cleaned\n}\n\n// ─── 셀 참조 파싱 ──────────────────────────────────────\n\n/** \"A1\" → { col: 0, row: 0 }, \"AB123\" → { col: 27, row: 122 } */\nfunction parseCellRef(ref: string): { col: number; row: number } | null {\n const m = ref.match(/^([A-Z]+)(\\d+)$/)\n if (!m) return null\n let col = 0\n for (const ch of m[1]) col = col * 26 + (ch.charCodeAt(0) - 64)\n return { col: col - 1, row: parseInt(m[2], 10) - 1 }\n}\n\n/** \"A1:C3\" → { startCol, startRow, endCol, endRow } */\nfunction parseMergeRef(ref: string): { startCol: number; startRow: number; endCol: number; endRow: number } | null {\n const parts = ref.split(\":\")\n if (parts.length !== 2) return null\n const start = parseCellRef(parts[0])\n const end = parseCellRef(parts[1])\n if (!start || !end) return null\n return { startCol: start.col, startRow: start.row, endCol: end.col, endRow: end.row }\n}\n\n// ─── XML 헬퍼 ──────────────────────────────────────────\n\nfunction getElements(parent: Element, tagName: string): Element[] {\n const nodes = parent.getElementsByTagName(tagName)\n const result: Element[] = []\n for (let i = 0; i < nodes.length; i++) result.push(nodes[i] as Element)\n return result\n}\n\nfunction getTextContent(el: Element): string {\n return el.textContent?.trim() ?? \"\"\n}\n\nfunction parseXml(text: string): Document {\n return new DOMParser().parseFromString(stripDtd(text), \"text/xml\")\n}\n\n// ─── 공유 문자열 파싱 ──────────────────────────────────\n\nfunction parseSharedStrings(xml: string): string[] {\n const doc = parseXml(xml)\n const strings: string[] = []\n const siList = getElements(doc.documentElement, \"si\")\n for (const si of siList) {\n // <si><t>text</t></si> 또는 <si><r><t>text</t></r>...</si>\n const tElements = getElements(si, \"t\")\n strings.push(tElements.map(t => t.textContent ?? \"\").join(\"\"))\n }\n return strings\n}\n\n// ─── 시트 목록 파싱 ─────────────────────────────────────\n\ninterface SheetInfo {\n name: string\n sheetId: string\n rId: string\n}\n\nfunction parseWorkbook(xml: string): SheetInfo[] {\n const doc = parseXml(xml)\n const sheets: SheetInfo[] = []\n const sheetElements = getElements(doc.documentElement, \"sheet\")\n for (const el of sheetElements) {\n sheets.push({\n name: el.getAttribute(\"name\") ?? `Sheet${sheets.length + 1}`,\n sheetId: el.getAttribute(\"sheetId\") ?? \"\",\n rId: el.getAttribute(\"r:id\") ?? \"\",\n })\n }\n return sheets\n}\n\n/** workbook.xml.rels 파싱 → rId → target 매핑 */\nfunction parseRels(xml: string): Map<string, string> {\n const doc = parseXml(xml)\n const map = new Map<string, string>()\n const rels = getElements(doc.documentElement, \"Relationship\")\n for (const rel of rels) {\n const id = rel.getAttribute(\"Id\")\n const target = rel.getAttribute(\"Target\")\n if (id && target) map.set(id, target)\n }\n return map\n}\n\n// ─── 워크시트 파싱 ──────────────────────────────────────\n\ninterface MergeInfo {\n startCol: number\n startRow: number\n endCol: number\n endRow: number\n}\n\nfunction parseWorksheet(\n xml: string,\n sharedStrings: string[],\n): { grid: string[][]; merges: MergeInfo[]; maxRow: number; maxCol: number } {\n const doc = parseXml(xml)\n const grid: string[][] = []\n let maxRow = 0\n let maxCol = 0\n\n // 데이터 행 파싱\n const rows = getElements(doc.documentElement, \"row\")\n for (const rowEl of rows) {\n const rowNum = parseInt(rowEl.getAttribute(\"r\") ?? \"0\", 10) - 1\n if (rowNum < 0 || rowNum >= MAX_ROWS) continue\n\n const cells = getElements(rowEl, \"c\")\n for (const cellEl of cells) {\n const ref = cellEl.getAttribute(\"r\")\n if (!ref) continue\n const pos = parseCellRef(ref)\n if (!pos || pos.col >= MAX_COLS) continue\n\n // 값 추출\n const type = cellEl.getAttribute(\"t\")\n const vElements = getElements(cellEl, \"v\")\n const fElements = getElements(cellEl, \"f\")\n let value = \"\"\n\n if (vElements.length > 0) {\n const raw = getTextContent(vElements[0])\n if (type === \"s\") {\n // shared string\n const idx = parseInt(raw, 10)\n value = sharedStrings[idx] ?? \"\"\n } else if (type === \"b\") {\n value = raw === \"1\" ? \"TRUE\" : \"FALSE\"\n } else {\n // 숫자값 부동소수점 아티팩트 정리 (9895607.8000000007 → 9895607.8)\n value = cleanNumericValue(raw)\n }\n } else if (type === \"inlineStr\") {\n // <is><t>text</t></is>\n const isEl = getElements(cellEl, \"is\")\n if (isEl.length > 0) {\n const tElements = getElements(isEl[0], \"t\")\n value = tElements.map(t => t.textContent ?? \"\").join(\"\")\n }\n }\n\n // 수식이 있고 값이 없으면 수식 표시\n if (!value && fElements.length > 0) {\n value = `=${getTextContent(fElements[0])}`\n }\n\n // 그리드 확장\n while (grid.length <= pos.row) grid.push([])\n while (grid[pos.row].length <= pos.col) grid[pos.row].push(\"\")\n grid[pos.row][pos.col] = value\n\n if (pos.row > maxRow) maxRow = pos.row\n if (pos.col > maxCol) maxCol = pos.col\n }\n }\n\n // 병합 셀 파싱\n const merges: MergeInfo[] = []\n const mergeCellElements = getElements(doc.documentElement, \"mergeCell\")\n for (const el of mergeCellElements) {\n const ref = el.getAttribute(\"ref\")\n if (!ref) continue\n const m = parseMergeRef(ref)\n if (m) merges.push(m)\n }\n\n return { grid, merges, maxRow, maxCol }\n}\n\n// ─── 시트 → IRBlock[] 변환 ────────────────────────────\n\nfunction sheetToBlocks(\n sheetName: string,\n grid: string[][],\n merges: MergeInfo[],\n maxRow: number,\n maxCol: number,\n sheetIndex: number,\n): IRBlock[] {\n const blocks: IRBlock[] = []\n\n // 시트명 = heading\n if (sheetName) {\n blocks.push({\n type: \"heading\",\n text: sheetName,\n level: 2,\n pageNumber: sheetIndex + 1,\n })\n }\n\n // 빈 시트\n if (maxRow < 0 || maxCol < 0 || grid.length === 0) return blocks\n\n // 병합 맵: \"row,col\" → { colSpan, rowSpan }\n const mergeMap = new Map<string, { colSpan: number; rowSpan: number }>()\n const mergeSkip = new Set<string>()\n for (const m of merges) {\n const colSpan = m.endCol - m.startCol + 1\n const rowSpan = m.endRow - m.startRow + 1\n mergeMap.set(`${m.startRow},${m.startCol}`, { colSpan, rowSpan })\n for (let r = m.startRow; r <= m.endRow; r++) {\n for (let c = m.startCol; c <= m.endCol; c++) {\n if (r !== m.startRow || c !== m.startCol) {\n mergeSkip.add(`${r},${c}`)\n }\n }\n }\n }\n\n // 유효 행 범위 감지 (앞뒤 빈 행 제거)\n let firstRow = -1\n let lastRow = -1\n for (let r = 0; r <= maxRow; r++) {\n const row = grid[r]\n if (row && row.some(cell => cell !== \"\")) {\n if (firstRow === -1) firstRow = r\n lastRow = r\n }\n }\n if (firstRow === -1) return blocks\n\n // CellContext[][] → buildTable로 IRTable 생성 (2-pass 알고리즘 재사용)\n const cellRows: CellContext[][] = []\n\n for (let r = firstRow; r <= lastRow; r++) {\n const row: CellContext[] = []\n for (let c = 0; c <= maxCol; c++) {\n const key = `${r},${c}`\n if (mergeSkip.has(key)) continue\n\n const text = (grid[r] && grid[r][c]) ?? \"\"\n const merge = mergeMap.get(key)\n row.push({\n text,\n colSpan: merge?.colSpan ?? 1,\n rowSpan: merge?.rowSpan ?? 1,\n })\n }\n cellRows.push(row)\n }\n\n if (cellRows.length > 0) {\n const table = buildTable(cellRows)\n if (table.rows > 0) {\n blocks.push({ type: \"table\", table, pageNumber: sheetIndex + 1 })\n }\n }\n\n return blocks\n}\n\n// ─── 메인 파서 ─────────────────────────────────────────\n\nexport async function parseXlsxDocument(\n buffer: ArrayBuffer,\n options?: ParseOptions,\n): Promise<InternalParseResult> {\n // ZIP bomb 사전 검사\n precheckZipSize(buffer, MAX_DECOMPRESS_SIZE)\n\n const zip = await JSZip.loadAsync(buffer)\n const warnings: ParseWarning[] = []\n\n // XLSX 구조 검증\n const workbookFile = zip.file(\"xl/workbook.xml\")\n if (!workbookFile) {\n throw new KordocError(\"유효하지 않은 XLSX 파일: xl/workbook.xml이 없습니다\")\n }\n\n // 1. 공유 문자열 로드\n let sharedStrings: string[] = []\n const ssFile = zip.file(\"xl/sharedStrings.xml\")\n if (ssFile) {\n sharedStrings = parseSharedStrings(await ssFile.async(\"text\"))\n }\n\n // 2. 시트 목록 로드\n const sheets = parseWorkbook(await workbookFile.async(\"text\"))\n if (sheets.length === 0) {\n throw new KordocError(\"XLSX 파일에 시트가 없습니다\")\n }\n\n // 3. 관계 매핑 (rId → 파일 경로)\n let relsMap = new Map<string, string>()\n const relsFile = zip.file(\"xl/_rels/workbook.xml.rels\")\n if (relsFile) {\n relsMap = parseRels(await relsFile.async(\"text\"))\n }\n\n // 4. 페이지 필터\n let pageFilter: Set<number> | null = null\n if (options?.pages) {\n const { parsePageRange } = await import(\"../page-range.js\")\n pageFilter = parsePageRange(options.pages, sheets.length)\n }\n\n // 5. 각 시트 파싱\n const blocks: IRBlock[] = []\n const processedSheets = Math.min(sheets.length, MAX_SHEETS)\n\n for (let i = 0; i < processedSheets; i++) {\n if (pageFilter && !pageFilter.has(i + 1)) continue\n\n const sheet = sheets[i]\n options?.onProgress?.(i + 1, processedSheets)\n\n // 시트 파일 경로 결정\n let sheetPath = relsMap.get(sheet.rId)\n if (sheetPath) {\n // 상대 경로 → 절대 경로\n if (!sheetPath.startsWith(\"xl/\") && !sheetPath.startsWith(\"/\")) {\n sheetPath = `xl/${sheetPath}`\n } else if (sheetPath.startsWith(\"/\")) {\n sheetPath = sheetPath.slice(1)\n }\n } else {\n sheetPath = `xl/worksheets/sheet${i + 1}.xml`\n }\n\n const sheetFile = zip.file(sheetPath)\n if (!sheetFile) {\n warnings.push({\n page: i + 1,\n message: `시트 \"${sheet.name}\" 파일을 찾을 수 없습니다: ${sheetPath}`,\n code: \"PARTIAL_PARSE\",\n })\n continue\n }\n\n try {\n const sheetXml = await sheetFile.async(\"text\")\n const { grid, merges, maxRow, maxCol } = parseWorksheet(sheetXml, sharedStrings)\n const sheetBlocks = sheetToBlocks(sheet.name, grid, merges, maxRow, maxCol, i)\n blocks.push(...sheetBlocks)\n } catch (err) {\n warnings.push({\n page: i + 1,\n message: `시트 \"${sheet.name}\" 파싱 실패: ${err instanceof Error ? err.message : \"알 수 없는 오류\"}`,\n code: \"PARTIAL_PARSE\",\n })\n }\n }\n\n // 6. 메타데이터 추출\n const metadata: DocumentMetadata = {\n pageCount: processedSheets,\n }\n const coreFile = zip.file(\"docProps/core.xml\")\n if (coreFile) {\n try {\n const coreXml = await coreFile.async(\"text\")\n const doc = parseXml(coreXml)\n const getFirst = (tag: string) => {\n const els = doc.getElementsByTagName(tag)\n return els.length > 0 ? (els[0].textContent ?? \"\").trim() : undefined\n }\n metadata.title = getFirst(\"dc:title\") || getFirst(\"dcterms:title\")\n metadata.author = getFirst(\"dc:creator\")\n metadata.description = getFirst(\"dc:description\")\n const created = getFirst(\"dcterms:created\")\n if (created) metadata.createdAt = created\n const modified = getFirst(\"dcterms:modified\")\n if (modified) metadata.modifiedAt = modified\n } catch { /* 메타데이터 실패는 무시 */ }\n }\n\n const markdown = blocksToMarkdown(blocks)\n\n return { markdown, blocks, metadata, warnings: warnings.length > 0 ? warnings : undefined }\n}\n","/**\n * BIFF8 (Excel 97-2003) 레코드 리더.\n *\n * Workbook 스트림(OLE2 → cfb-lenient로 추출)에서 4바이트 헤더(opcode u16 + length u16)\n * 기반 레코드를 순차 읽어들인다. 길이가 8224를 초과하는 데이터는 직후 CONTINUE\n * 레코드로 분할되며, 본 모듈은 호출자가 원할 때 자동 결합 옵션을 제공한다.\n *\n * 참조: docs/biff8-spec.md §2~§3, [MS-XLS] §2.4\n */\n\n// ─── Opcode 상수 ─────────────────────────────────────\n\nexport const OP_BOF = 0x0809\nexport const OP_EOF = 0x000a\nexport const OP_CONTINUE = 0x003c\n\n// Globals 서브스트림\nexport const OP_BOUNDSHEET8 = 0x0085\nexport const OP_SST = 0x00fc\nexport const OP_EXTSST = 0x00ff\nexport const OP_CODEPAGE = 0x0042\nexport const OP_DATE1904 = 0x0022\nexport const OP_FILEPASS = 0x002f\n\n// Worksheet 서브스트림 — 셀\nexport const OP_NUMBER = 0x0203\nexport const OP_RK = 0x027e\nexport const OP_MULRK = 0x00bd\nexport const OP_LABELSST = 0x00fd\nexport const OP_LABEL = 0x0204\nexport const OP_FORMULA = 0x0006\nexport const OP_STRING = 0x0207\nexport const OP_BOOLERR = 0x0205\nexport const OP_BLANK = 0x0201\nexport const OP_MULBLANK = 0x00be\nexport const OP_MERGECELLS = 0x00e5\nexport const OP_ROW = 0x0208\n\n// BOF dt 필드 값\nexport const DT_GLOBALS = 0x0005\nexport const DT_WORKSHEET = 0x0010\nexport const DT_CHART = 0x0020\nexport const DT_MACRO = 0x0040\n\n// ─── 타입 ──────────────────────────────────────────\n\nexport interface BiffRecord {\n opcode: number\n /** 본 레코드의 데이터 (CONTINUE 결합 안 한 raw) */\n data: Buffer\n /** Workbook 스트림 내 절대 오프셋 (헤더 시작 위치) — BoundSheet8 lbPlyPos 매칭용 */\n offset: number\n}\n\n// ─── 리더 ──────────────────────────────────────────\n\n/** 비정상 파일에 의한 메모리 폭주 방지 */\nconst MAX_RECORDS = 1_000_000\n\n/**\n * Workbook 스트림 전체에서 BIFF 레코드를 순차 읽는다.\n * CONTINUE 결합은 호출자 책임 (SST 디코딩 시점에서 처리).\n */\nexport function readRecords(stream: Buffer): BiffRecord[] {\n const out: BiffRecord[] = []\n let offset = 0\n\n while (offset + 4 <= stream.length && out.length < MAX_RECORDS) {\n const recOffset = offset\n const opcode = stream.readUInt16LE(offset)\n const length = stream.readUInt16LE(offset + 2)\n offset += 4\n\n if (offset + length > stream.length) {\n // 잘린 레코드 — lenient: 부분 데이터로 끊고 종료\n const data = stream.subarray(offset, stream.length)\n out.push({ opcode, data, offset: recOffset })\n break\n }\n\n const data = stream.subarray(offset, offset + length)\n out.push({ opcode, data, offset: recOffset })\n offset += length\n }\n\n return out\n}\n\n/**\n * 특정 레코드부터 직후 연속된 CONTINUE 레코드 데이터를 결합.\n * SST처럼 8224바이트를 초과해 분할되는 레코드 처리용.\n *\n * 반환: { combined: Buffer, segments: number[] }\n * - combined: 결합된 데이터\n * - segments: 각 CONTINUE 경계의 결합 후 오프셋 (디코딩 시 flags 재해석에 사용)\n */\nexport function combineWithContinue(\n records: BiffRecord[],\n startIndex: number,\n): { combined: Buffer; segments: number[]; nextIndex: number } {\n const first = records[startIndex]\n const chunks: Buffer[] = [first.data]\n const segments: number[] = [first.data.length] // 첫 CONTINUE 경계\n let i = startIndex + 1\n let total = first.data.length\n\n while (i < records.length && records[i].opcode === OP_CONTINUE) {\n chunks.push(records[i].data)\n total += records[i].data.length\n segments.push(total)\n i++\n }\n\n return {\n combined: Buffer.concat(chunks),\n segments,\n nextIndex: i,\n }\n}\n\n// ─── BOF 헬퍼 ──────────────────────────────────────\n\nexport interface BofInfo {\n vers: number\n /** 서브스트림 타입 (DT_*) */\n dt: number\n}\n\nexport function decodeBof(data: Buffer): BofInfo | null {\n if (data.length < 4) return null\n return {\n vers: data.readUInt16LE(0),\n dt: data.readUInt16LE(2),\n }\n}\n\n// ─── RK / MulRk 디코더 ─────────────────────────────\n\n/**\n * RK 32bit 압축 숫자 디코딩.\n *\n * 비트 0 (fDiv100): 1이면 결과를 100으로 나눔\n * 비트 1 (fInt): 1이면 정수, 0이면 double\n * 비트 2~31: 30비트 값\n *\n * 정수: 30비트 부호확장.\n * double: 30비트를 double의 상위 30비트(63..34)에 배치, 하위 34비트는 0.\n */\nexport function decodeRk(rk: number): number {\n const fDiv100 = (rk & 0x01) !== 0\n const fInt = (rk & 0x02) !== 0\n const val30 = rk >> 2 // signed 31-bit shift, 그러나 30bit 부호확장 별도 처리\n\n let num: number\n if (fInt) {\n // 30bit signed → 부호확장\n num = val30 // JS의 >> 2는 산술시프트라 부호 유지됨\n } else {\n // double 복원: 30bit가 double의 상위 30bit (63..34)\n // 하위 34bit는 0. JS bitwise는 32bit이므로 BigInt 사용.\n const high32 = (rk & 0xfffffffc) >>> 0 // 상위 30bit + 하위 2bit(0)\n // double 비트 패턴: high32 << 32 | 0\n const buf = Buffer.alloc(8)\n buf.writeUInt32LE(0, 0)\n buf.writeUInt32LE(high32, 4)\n num = buf.readDoubleLE(0)\n }\n\n return fDiv100 ? num / 100 : num\n}\n\nexport interface MulRkCell {\n col: number\n ixfe: number\n value: number\n}\n\n/**\n * MulRk 레코드 디코딩.\n * data 구조: [row u16][colFirst u16][rkrec_0]...[rkrec_n][colLast u16]\n * rkrec = [ixfe u16][rk u32] = 6바이트\n *\n * 반환: { row, cells: [{col, ixfe, value}, ...] }\n */\nexport function decodeMulRk(data: Buffer): { row: number; cells: MulRkCell[] } | null {\n if (data.length < 6) return null\n const row = data.readUInt16LE(0)\n const colFirst = data.readUInt16LE(2)\n const colLast = data.readUInt16LE(data.length - 2)\n const count = colLast - colFirst + 1\n if (count <= 0) return { row, cells: [] }\n\n const cells: MulRkCell[] = []\n let off = 4\n for (let i = 0; i < count && off + 6 <= data.length - 2; i++) {\n const ixfe = data.readUInt16LE(off)\n const rk = data.readUInt32LE(off + 2)\n cells.push({ col: colFirst + i, ixfe, value: decodeRk(rk) })\n off += 6\n }\n\n return { row, cells }\n}\n\n// ─── 일반 셀 헤더 (row, col, ixfe) ────────────────\n\nexport interface CellHeader {\n row: number\n col: number\n ixfe: number\n}\n\nexport function readCellHeader(data: Buffer): CellHeader | null {\n if (data.length < 6) return null\n return {\n row: data.readUInt16LE(0),\n col: data.readUInt16LE(2),\n ixfe: data.readUInt16LE(4),\n }\n}\n","/**\n * XLS 문자열 인코딩 디코더.\n *\n * BIFF8의 문자열은 다음 인코딩 중 하나:\n * - UTF-16LE (fHighByte=1)\n * - Compressed Unicode (fHighByte=0): 1바이트/문자, 상위 바이트는 0\n * - 구형 Label 레코드: CodePage 의존 (보통 CP949 또는 CP1200)\n *\n * 한국 공문서 .xls 우선 순위: UTF-16LE → Compressed → CP949\n *\n * 참조: docs/biff8-spec.md §3.3, §5\n */\n\n/**\n * UTF-16LE 디코딩 (Buffer.toString('utf16le')는 LE 가정으로 안전).\n */\nexport function decodeUtf16Le(buf: Buffer): string {\n return buf.toString(\"utf16le\")\n}\n\n/**\n * Compressed Unicode 디코딩.\n * 1바이트당 1문자, 각 바이트가 UTF-16 코드 포인트의 하위 바이트(상위 바이트=0).\n * 즉 ISO-8859-1 (Latin-1)과 동일.\n */\nexport function decodeCompressed(buf: Buffer): string {\n // Buffer.toString('latin1') == ISO-8859-1\n return buf.toString(\"latin1\")\n}\n\n/**\n * CP949 (EUC-KR 확장) 디코딩.\n * Node.js TextDecoder가 ICU 빌드일 때만 'euc-kr' 지원.\n * 미지원 환경에서는 latin1 폴백 (한글 깨짐, 영숫자만 보존).\n */\nexport function decodeCp949(buf: Buffer): string {\n try {\n // Node 18+ ICU 빌드: 'euc-kr', 'cp949' 모두 지원\n return new TextDecoder(\"euc-kr\", { fatal: false }).decode(buf)\n } catch {\n return buf.toString(\"latin1\")\n }\n}\n\n/**\n * 코드페이지 번호로 디코딩 (CodePage 레코드 0x0042 값).\n * 1200 = UTF-16LE\n * 949 = CP949\n * 1252 = Windows-1252\n * 기타 = latin1 폴백\n */\nexport function decodeByCodePage(buf: Buffer, codePage: number): string {\n if (codePage === 1200) return decodeUtf16Le(buf)\n if (codePage === 949) return decodeCp949(buf)\n if (codePage === 1252 || codePage === 65001) {\n try {\n return new TextDecoder(codePage === 65001 ? \"utf-8\" : \"windows-1252\", {\n fatal: false,\n }).decode(buf)\n } catch {\n return buf.toString(\"latin1\")\n }\n }\n return buf.toString(\"latin1\")\n}\n","/**\n * BIFF8 Shared String Table 디코더.\n *\n * SST 레코드(0x00FC)는 데이터가 8224B를 초과하면 직후 CONTINUE(0x003C) 레코드로 분할됨.\n * 단순히 데이터를 이어붙이는 게 아니라, **각 CONTINUE 경계의 첫 바이트는 새 flags\n * 바이트로 재해석**해야 한다 (MS-XLS §2.4.265 ~ §2.4.272).\n *\n * 본 모듈은 SST + 후속 CONTINUE를 통합 버퍼로 만든 후, segments 경계를 활용해\n * XLUnicodeRichExtendedString을 순차 디코딩한다.\n *\n * 참조: docs/biff8-spec.md §3.3\n */\n\nimport { decodeCompressed, decodeUtf16Le } from \"./encoding.js\"\nimport { combineWithContinue, type BiffRecord, OP_SST } from \"./record.js\"\n\ninterface ParseStringResult {\n text: string\n consumed: number\n}\n\n/**\n * 단일 XLUnicodeRichExtendedString 디코딩.\n *\n * 구조 (가변):\n * cch u16 문자 수\n * flags u8 bit 0 fHighByte (1=UTF-16LE, 0=compressed)\n * bit 2 fExtSt\n * bit 3 fRichSt\n * [cRun u16] rich text run 수 (fRichSt=1일 때만)\n * [cbExtRst u32] 확장 데이터 길이 (fExtSt=1일 때만)\n * rgb 가변 문자 데이터 (compressed: cch바이트, uncompressed: 2*cch바이트)\n * [richRuns 4*cRun] (fRichSt=1)\n * [extRst cbExtRst] (fExtSt=1)\n *\n * **CONTINUE 경계 처리**: 본 함수는 segments 정보를 받아 문자 데이터(rgb)가 경계를\n * 가로지르면 경계 직후 1바이트(새 flags)를 스킵하고 인코딩이 바뀌면 재해석한다.\n */\nfunction parseString(\n buf: Buffer,\n offset: number,\n segments: number[],\n): ParseStringResult | null {\n if (offset + 3 > buf.length) return null\n\n const cch = buf.readUInt16LE(offset)\n let flags = buf.readUInt8(offset + 2)\n let off = offset + 3\n\n let highByte = (flags & 0x01) !== 0\n const extSt = (flags & 0x04) !== 0\n const richSt = (flags & 0x08) !== 0\n\n let cRun = 0\n let cbExtRst = 0\n if (richSt) {\n if (off + 2 > buf.length) return null\n cRun = buf.readUInt16LE(off)\n off += 2\n }\n if (extSt) {\n if (off + 4 > buf.length) return null\n cbExtRst = buf.readUInt32LE(off)\n off += 4\n }\n\n // 문자 데이터 읽기 — CONTINUE 경계마다 새 flags 재해석\n // segments는 결합 버퍼 기준 경계 오프셋들. 첫 segment는 SST의 끝, 그 다음부터 CONTINUE 경계.\n const charBytes: Buffer[] = []\n let charsRead = 0\n\n while (charsRead < cch) {\n // 다음 경계 찾기\n const nextBoundary = segments.find(s => s > off) ?? buf.length\n\n const remainChars = cch - charsRead\n const bytesPerChar = highByte ? 2 : 1\n const bytesAvail = nextBoundary - off\n const charsInThisRun = Math.min(remainChars, Math.floor(bytesAvail / bytesPerChar))\n const bytesToRead = charsInThisRun * bytesPerChar\n\n if (bytesToRead > 0) {\n const slice = buf.subarray(off, off + bytesToRead)\n // highByte=0 (compressed) 처리: utf16le 통일을 위해 0x00 패딩 후 합칠 수도 있으나\n // 디코딩은 latin1로 따로 처리 후 string concat이 명확.\n charBytes.push(highByte ? slice : padToUtf16(slice))\n off += bytesToRead\n charsRead += charsInThisRun\n }\n\n if (charsRead < cch) {\n // 경계 진입 — 새 flags 1바이트\n if (off >= buf.length) return null\n flags = buf.readUInt8(off)\n highByte = (flags & 0x01) !== 0\n off += 1\n }\n }\n\n // 모든 charBytes는 utf16le로 통일된 상태 → 합쳐서 디코딩\n const text = decodeUtf16Le(Buffer.concat(charBytes))\n\n // rich runs 스킵\n if (richSt) off += 4 * cRun\n // extRst 스킵\n if (extSt) off += cbExtRst\n\n // 안전장치: 경계 넘침 방지\n if (off > buf.length) off = buf.length\n\n return { text, consumed: off - offset }\n}\n\n/** compressed (1바이트/문자) → utf16le (2바이트/문자) 패딩. */\nfunction padToUtf16(compressed: Buffer): Buffer {\n const out = Buffer.alloc(compressed.length * 2)\n for (let i = 0; i < compressed.length; i++) {\n out[i * 2] = compressed[i]\n out[i * 2 + 1] = 0\n }\n return out\n}\n\n/**\n * 레코드 배열에서 SST를 찾아 디코딩한다.\n * SST가 없으면 빈 배열 반환.\n */\nexport function decodeSST(records: BiffRecord[]): string[] {\n const sstIndex = records.findIndex(r => r.opcode === OP_SST)\n if (sstIndex < 0) return []\n\n const { combined, segments } = combineWithContinue(records, sstIndex)\n if (combined.length < 8) return []\n\n // const cstTotal = combined.readUInt32LE(0) // 참조 횟수 (사용 안 함)\n const cstUnique = combined.readUInt32LE(4)\n\n const strings: string[] = []\n let off = 8\n for (let i = 0; i < cstUnique && off < combined.length; i++) {\n const r = parseString(combined, off, segments)\n if (!r) break\n strings.push(r.text)\n off += r.consumed\n }\n\n return strings\n}\n\n// _ unused export silencer\nvoid decodeCompressed\n","/**\n * BIFF8 Worksheet 서브스트림의 셀 레코드 → RawCell 변환.\n *\n * 처리 대상: Number, RK, MulRk, LabelSst, BoolErr, Formula(+String), Label, Blank, MulBlank, MergeCells\n * 무시: Row 메타, GUTS, Header/Footer, Window 등\n *\n * 참조: docs/biff8-spec.md §3.4, §3.5\n */\n\nimport {\n OP_NUMBER,\n OP_RK,\n OP_MULRK,\n OP_LABELSST,\n OP_LABEL,\n OP_FORMULA,\n OP_STRING,\n OP_BOOLERR,\n OP_BLANK,\n OP_MULBLANK,\n OP_MERGECELLS,\n OP_BOF,\n OP_EOF,\n decodeMulRk,\n decodeRk,\n readCellHeader,\n type BiffRecord,\n} from \"./record.js\"\nimport { decodeUtf16Le } from \"./encoding.js\"\n\nexport type CellValue = string | number | boolean | null\n\nexport interface RawCell {\n row: number\n col: number\n value: CellValue\n}\n\nexport interface MergeRange {\n r1: number\n c1: number\n r2: number\n c2: number\n}\n\nexport interface RawSheet {\n /** 시트 시작 BOF의 절대 오프셋 */\n bofOffset: number\n cells: RawCell[]\n merges: MergeRange[]\n}\n\n/** BIFF8 표준 에러 코드 → 표시 문자열 */\nfunction errorCodeToText(code: number): string {\n switch (code) {\n case 0x00:\n return \"#NULL!\"\n case 0x07:\n return \"#DIV/0!\"\n case 0x0f:\n return \"#VALUE!\"\n case 0x17:\n return \"#REF!\"\n case 0x1d:\n return \"#NAME?\"\n case 0x24:\n return \"#NUM!\"\n case 0x2a:\n return \"#N/A\"\n default:\n return `#ERR${code}`\n }\n}\n\n/**\n * BIFF8 Label 레코드의 단순 문자열 디코딩.\n * 구조: row(2) col(2) ixfe(2) cch(2) flags(1) rgb(...)\n * - flags bit 0: 1=UTF-16LE, 0=compressed\n */\nfunction decodeLabelString(data: Buffer): string {\n if (data.length < 9) return \"\"\n const cch = data.readUInt16LE(6)\n const flags = data.readUInt8(8)\n const highByte = (flags & 0x01) !== 0\n const start = 9\n\n if (highByte) {\n const end = Math.min(start + cch * 2, data.length)\n return decodeUtf16Le(data.subarray(start, end))\n } else {\n const end = Math.min(start + cch, data.length)\n // compressed → utf16 패딩 후 디코딩\n const slice = data.subarray(start, end)\n const padded = Buffer.alloc(slice.length * 2)\n for (let i = 0; i < slice.length; i++) padded[i * 2] = slice[i]\n return decodeUtf16Le(padded)\n }\n}\n\n/**\n * Formula 레코드의 결과값 디코딩.\n * val 8바이트:\n * val[6..8] == 0xFFFF 이고:\n * val[0]=0x00: 결과가 문자열 → 직후 String 레코드 참조\n * val[0]=0x01: boolean → val[2] (0/1)\n * val[0]=0x02: error → val[2]\n * val[0]=0x03: empty\n * 그 외: double로 해석\n *\n * 반환:\n * - 문자열 결과 신호: { kind: 'stringRef' }\n * - 그 외: { kind: 'value', value: ... }\n */\ntype FormulaResult =\n | { kind: \"stringRef\" }\n | { kind: \"value\"; value: CellValue }\n\nfunction decodeFormulaResult(val: Buffer): FormulaResult {\n if (val.length < 8) return { kind: \"value\", value: null }\n const tail = val.readUInt16LE(6)\n if (tail === 0xffff) {\n const code = val.readUInt8(0)\n if (code === 0x00) return { kind: \"stringRef\" }\n if (code === 0x01) return { kind: \"value\", value: val.readUInt8(2) === 1 }\n if (code === 0x02) return { kind: \"value\", value: errorCodeToText(val.readUInt8(2)) }\n return { kind: \"value\", value: null } // empty\n }\n return { kind: \"value\", value: val.readDoubleLE(0) }\n}\n\n/**\n * Formula 직후의 String 레코드에서 결과 문자열 디코딩.\n * 구조: cch(2) flags(1) rgb(...)\n */\nfunction decodeFormulaStringRecord(data: Buffer): string {\n if (data.length < 3) return \"\"\n const cch = data.readUInt16LE(0)\n const flags = data.readUInt8(2)\n const highByte = (flags & 0x01) !== 0\n const start = 3\n\n if (highByte) {\n const end = Math.min(start + cch * 2, data.length)\n return decodeUtf16Le(data.subarray(start, end))\n } else {\n const end = Math.min(start + cch, data.length)\n const slice = data.subarray(start, end)\n const padded = Buffer.alloc(slice.length * 2)\n for (let i = 0; i < slice.length; i++) padded[i * 2] = slice[i]\n return decodeUtf16Le(padded)\n }\n}\n\n/**\n * 단일 Worksheet 서브스트림 (BOF~EOF) 의 셀 레코드 추출.\n * @param records 전체 레코드 배열\n * @param bofIndex 본 시트 BOF의 records 인덱스\n * @param sst 디코딩된 SST\n * @returns RawSheet — 다음 시트로 넘어갈 수 있는 endIndex 포함\n */\nexport function extractSheetCells(\n records: BiffRecord[],\n bofIndex: number,\n sst: string[],\n): { sheet: RawSheet; endIndex: number } {\n const cells: RawCell[] = []\n const merges: MergeRange[] = []\n const bofOffset = records[bofIndex].offset\n\n let i = bofIndex + 1\n while (i < records.length) {\n const rec = records[i]\n if (rec.opcode === OP_EOF) {\n i++\n break\n }\n if (rec.opcode === OP_BOF) {\n // 새 서브스트림 시작 — 안전장치\n break\n }\n\n switch (rec.opcode) {\n case OP_NUMBER: {\n const h = readCellHeader(rec.data)\n if (h && rec.data.length >= 14) {\n cells.push({ row: h.row, col: h.col, value: rec.data.readDoubleLE(6) })\n }\n break\n }\n case OP_RK: {\n const h = readCellHeader(rec.data)\n if (h && rec.data.length >= 10) {\n cells.push({ row: h.row, col: h.col, value: decodeRk(rec.data.readInt32LE(6)) })\n }\n break\n }\n case OP_MULRK: {\n const m = decodeMulRk(rec.data)\n if (m) {\n for (const c of m.cells) {\n cells.push({ row: m.row, col: c.col, value: c.value })\n }\n }\n break\n }\n case OP_LABELSST: {\n const h = readCellHeader(rec.data)\n if (h && rec.data.length >= 10) {\n const isst = rec.data.readUInt32LE(6)\n cells.push({ row: h.row, col: h.col, value: sst[isst] ?? \"\" })\n }\n break\n }\n case OP_LABEL: {\n const h = readCellHeader(rec.data)\n if (h) {\n cells.push({ row: h.row, col: h.col, value: decodeLabelString(rec.data) })\n }\n break\n }\n case OP_FORMULA: {\n const h = readCellHeader(rec.data)\n if (h && rec.data.length >= 14) {\n const result = decodeFormulaResult(rec.data.subarray(6, 14))\n if (result.kind === \"stringRef\") {\n // 직후 String 레코드 찾기\n const next = records[i + 1]\n if (next && next.opcode === OP_STRING) {\n cells.push({\n row: h.row,\n col: h.col,\n value: decodeFormulaStringRecord(next.data),\n })\n i++ // String 레코드 건너뛰기\n } else {\n cells.push({ row: h.row, col: h.col, value: \"\" })\n }\n } else {\n cells.push({ row: h.row, col: h.col, value: result.value })\n }\n }\n break\n }\n case OP_BOOLERR: {\n const h = readCellHeader(rec.data)\n if (h && rec.data.length >= 8) {\n const v = rec.data.readUInt8(6)\n const isErr = rec.data.readUInt8(7) === 1\n if (isErr) {\n cells.push({ row: h.row, col: h.col, value: errorCodeToText(v) })\n } else {\n cells.push({ row: h.row, col: h.col, value: v === 1 })\n }\n }\n break\n }\n case OP_BLANK:\n case OP_MULBLANK: {\n // 빈 셀은 결과 그리드에서 자연 처리됨 — 명시적 추가 안 함\n break\n }\n case OP_MERGECELLS: {\n // [cmcs u16][Ref8U[cmcs] (각 8바이트: rwFirst rwLast colFirst colLast)]\n if (rec.data.length >= 2) {\n const cmcs = rec.data.readUInt16LE(0)\n let off = 2\n for (let k = 0; k < cmcs && off + 8 <= rec.data.length; k++) {\n const r1 = rec.data.readUInt16LE(off)\n const r2 = rec.data.readUInt16LE(off + 2)\n const c1 = rec.data.readUInt16LE(off + 4)\n const c2 = rec.data.readUInt16LE(off + 6)\n merges.push({ r1, c1, r2, c2 })\n off += 8\n }\n }\n break\n }\n default:\n // 무시 (Row, Window, GUTS, etc)\n break\n }\n\n i++\n }\n\n return {\n sheet: { bofOffset, cells, merges },\n endIndex: i,\n }\n}\n","/**\n * XLS (BIFF8) 파서 — Workbook 스트림 → IRBlock[].\n *\n * 흐름:\n * 1. cfb-lenient로 OLE2 컨테이너 → \"Workbook\" 스트림 추출\n * 2. readRecords로 BIFF 레코드 시퀀스 파싱\n * 3. Globals 서브스트림: BoundSheet8 수집 + SST 디코딩\n * 4. 각 시트 BOF 인덱스 찾기 → extractSheetCells\n * 5. RawSheet → heading + IRTable 블록 변환\n *\n * 참조: docs/biff8-spec.md\n */\n\nimport type {\n IRBlock,\n CellContext,\n DocumentMetadata,\n InternalParseResult,\n ParseOptions,\n ParseWarning,\n} from \"../types.js\"\nimport { KordocError } from \"../utils.js\"\nimport { buildTable, blocksToMarkdown } from \"../table/builder.js\"\nimport { parseLenientCfb } from \"../hwp5/cfb-lenient.js\"\nimport {\n readRecords,\n decodeBof,\n OP_BOF,\n OP_EOF,\n OP_BOUNDSHEET8,\n OP_FILEPASS,\n OP_CODEPAGE,\n DT_GLOBALS,\n DT_WORKSHEET,\n type BiffRecord,\n} from \"./record.js\"\nimport { decodeSST } from \"./sst.js\"\nimport { extractSheetCells, type RawSheet, type CellValue } from \"./cell.js\"\nimport { decodeUtf16Le } from \"./encoding.js\"\n\n// ─── 상수 ─────────────────────────────────────────\n\nconst MAX_SHEETS = 100\nconst MAX_ROWS = 100_000\nconst MAX_COLS = 1_000\n\n// ─── BoundSheet8 ─────────────────────────────────\n\ninterface BoundSheet {\n name: string\n /** Workbook 스트림 절대 오프셋 — 본 시트 BOF 위치 */\n lbPlyPos: number\n /** 0=Worksheet, 1=Chart, 2=Macro */\n dt: number\n}\n\n/**\n * BoundSheet8 레코드 디코딩.\n * 구조: lbPlyPos(4) hsState(1) dt(1) stName(ShortXLUnicodeString)\n * ShortXLUnicodeString: cch(1) flags(1) chars(...)\n * flags bit 0: 1=UTF-16LE, 0=compressed\n */\nfunction decodeBoundSheet(data: Buffer): BoundSheet | null {\n if (data.length < 8) return null\n const lbPlyPos = data.readUInt32LE(0)\n const dt = data.readUInt8(5)\n const cch = data.readUInt8(6)\n const flags = data.readUInt8(7)\n const highByte = (flags & 0x01) !== 0\n const start = 8\n\n let name: string\n if (highByte) {\n const end = Math.min(start + cch * 2, data.length)\n name = decodeUtf16Le(data.subarray(start, end))\n } else {\n const end = Math.min(start + cch, data.length)\n const slice = data.subarray(start, end)\n const padded = Buffer.alloc(slice.length * 2)\n for (let i = 0; i < slice.length; i++) padded[i * 2] = slice[i]\n name = decodeUtf16Le(padded)\n }\n\n return { name, lbPlyPos, dt }\n}\n\n// ─── Globals 처리 ────────────────────────────────\n\ninterface GlobalsResult {\n sheets: BoundSheet[]\n sst: string[]\n codePage: number\n encrypted: boolean\n /** Globals 서브스트림이 끝난 records 인덱스 */\n endIndex: number\n}\n\nfunction processGlobals(records: BiffRecord[]): GlobalsResult {\n const sheets: BoundSheet[] = []\n let codePage = 1200\n let encrypted = false\n\n // 첫 BOF는 records[0]이어야 함\n const firstBof = records[0]\n if (!firstBof || firstBof.opcode !== OP_BOF) {\n throw new KordocError(\"XLS: 첫 레코드가 BOF가 아님\")\n }\n const bof = decodeBof(firstBof.data)\n if (!bof || bof.dt !== DT_GLOBALS) {\n throw new KordocError(\"XLS: Globals 서브스트림 BOF 누락\")\n }\n\n let i = 1\n while (i < records.length) {\n const r = records[i]\n if (r.opcode === OP_EOF) {\n i++\n break\n }\n if (r.opcode === OP_BOUNDSHEET8) {\n const bs = decodeBoundSheet(r.data)\n if (bs) sheets.push(bs)\n } else if (r.opcode === OP_CODEPAGE && r.data.length >= 2) {\n codePage = r.data.readUInt16LE(0)\n } else if (r.opcode === OP_FILEPASS) {\n encrypted = true\n }\n i++\n }\n\n // SST는 Globals 내부 어딘가 — 전체 records 검색하되 첫 EOF 이전만\n const globalsRecords = records.slice(0, i)\n const sst = decodeSST(globalsRecords)\n\n return { sheets, sst, codePage, encrypted, endIndex: i }\n}\n\n// ─── 시트 BOF 인덱스 찾기 ─────────────────────────\n\nfunction findSheetBofIndex(records: BiffRecord[], lbPlyPos: number): number {\n // 정확한 매칭 우선\n const exact = records.findIndex(\n r => r.opcode === OP_BOF && r.offset === lbPlyPos,\n )\n if (exact >= 0) return exact\n\n // 못 찾으면 가장 가까운 BOF (관용)\n const bofIndices = records\n .map((r, idx) => (r.opcode === OP_BOF ? idx : -1))\n .filter(idx => idx >= 0)\n if (bofIndices.length === 0) return -1\n // 첫 BOF는 Globals → 두 번째부터 시트\n return bofIndices.length > 1 ? bofIndices[1] : -1\n}\n\n// ─── RawSheet → IRBlock[] ────────────────────────\n\nfunction cellValueToText(v: CellValue): string {\n if (v === null || v === undefined) return \"\"\n if (typeof v === \"number\") {\n // 부동소수점 아티팩트 정리\n if (Number.isInteger(v)) return v.toString()\n const cleaned = parseFloat(v.toPrecision(15)).toString()\n return cleaned\n }\n if (typeof v === \"boolean\") return v ? \"TRUE\" : \"FALSE\"\n return v\n}\n\nfunction sheetToBlocks(\n sheetName: string,\n sheet: RawSheet,\n sheetIndex: number,\n): IRBlock[] {\n const blocks: IRBlock[] = []\n\n if (sheetName) {\n blocks.push({\n type: \"heading\",\n text: sheetName,\n level: 2,\n pageNumber: sheetIndex + 1,\n })\n }\n\n if (sheet.cells.length === 0) return blocks\n\n // 그리드 크기 계산\n let maxRow = -1\n let maxCol = -1\n for (const c of sheet.cells) {\n if (c.row > maxRow) maxRow = c.row\n if (c.col > maxCol) maxCol = c.col\n }\n for (const m of sheet.merges) {\n if (m.r2 > maxRow) maxRow = m.r2\n if (m.c2 > maxCol) maxCol = m.c2\n }\n if (maxRow < 0 || maxCol < 0) return blocks\n\n // DOS 방어\n if (maxRow >= MAX_ROWS || maxCol >= MAX_COLS) {\n maxRow = Math.min(maxRow, MAX_ROWS - 1)\n maxCol = Math.min(maxCol, MAX_COLS - 1)\n }\n\n // 그리드 채우기\n const grid: string[][] = Array.from({ length: maxRow + 1 }, () =>\n Array(maxCol + 1).fill(\"\"),\n )\n for (const c of sheet.cells) {\n if (c.row > maxRow || c.col > maxCol) continue\n grid[c.row][c.col] = cellValueToText(c.value)\n }\n\n // 병합 맵\n const mergeMap = new Map<string, { colSpan: number; rowSpan: number }>()\n const mergeSkip = new Set<string>()\n for (const m of sheet.merges) {\n const r1 = Math.min(m.r1, maxRow)\n const c1 = Math.min(m.c1, maxCol)\n const r2 = Math.min(m.r2, maxRow)\n const c2 = Math.min(m.c2, maxCol)\n mergeMap.set(`${r1},${c1}`, { colSpan: c2 - c1 + 1, rowSpan: r2 - r1 + 1 })\n for (let r = r1; r <= r2; r++) {\n for (let c = c1; c <= c2; c++) {\n if (r !== r1 || c !== c1) mergeSkip.add(`${r},${c}`)\n }\n }\n }\n\n // 유효 행 트리밍\n let firstRow = -1\n let lastRow = -1\n for (let r = 0; r <= maxRow; r++) {\n if (grid[r].some(v => v !== \"\")) {\n if (firstRow === -1) firstRow = r\n lastRow = r\n }\n }\n if (firstRow === -1) return blocks\n\n // CellContext[][] 빌드\n const cellRows: CellContext[][] = []\n for (let r = firstRow; r <= lastRow; r++) {\n const row: CellContext[] = []\n for (let c = 0; c <= maxCol; c++) {\n const key = `${r},${c}`\n if (mergeSkip.has(key)) continue\n const merge = mergeMap.get(key)\n row.push({\n text: grid[r][c],\n colSpan: merge?.colSpan ?? 1,\n rowSpan: merge?.rowSpan ?? 1,\n })\n }\n cellRows.push(row)\n }\n\n if (cellRows.length > 0) {\n const table = buildTable(cellRows)\n if (table.rows > 0) {\n blocks.push({ type: \"table\", table, pageNumber: sheetIndex + 1 })\n }\n }\n\n return blocks\n}\n\n// ─── 메인 ─────────────────────────────────────────\n\nexport async function parseXlsDocument(\n buffer: ArrayBuffer,\n options?: ParseOptions,\n): Promise<InternalParseResult> {\n const buf = Buffer.from(buffer)\n\n // 1. OLE2 컨테이너 → Workbook 스트림\n let cfb\n try {\n cfb = parseLenientCfb(buf)\n } catch (e) {\n throw new KordocError(\n `XLS: OLE2 시그니처 검증 실패 — ${e instanceof Error ? e.message : \"알 수 없는 오류\"}`,\n )\n }\n\n const wb = cfb.findStream(\"/Workbook\") ?? cfb.findStream(\"/Book\")\n if (!wb) {\n throw new KordocError(\"XLS: Workbook 스트림이 없음 (BIFF5 또는 비표준 파일)\")\n }\n\n // 2. BIFF 레코드 시퀀스\n const records = readRecords(wb)\n if (records.length === 0) {\n throw new KordocError(\"XLS: 시그니처 레코드가 없음 (Workbook 스트림 손상)\")\n }\n\n // 3. BIFF 버전 체크\n const firstBof = decodeBof(records[0].data)\n if (firstBof && firstBof.vers !== 0x0600) {\n throw new KordocError(\n `XLS: BIFF8(0x0600)만 지원 — 본 파일은 0x${firstBof.vers.toString(16)}`,\n )\n }\n\n // 4. Globals 처리\n const globals = processGlobals(records)\n const warnings: ParseWarning[] = []\n\n if (globals.encrypted) {\n return {\n markdown: \"\",\n blocks: [],\n metadata: { pageCount: globals.sheets.length },\n warnings: [\n {\n message: \"XLS 파일이 암호화되어 있어 파싱할 수 없습니다\",\n code: \"PARTIAL_PARSE\",\n },\n ],\n }\n }\n\n // 5. 페이지/시트 필터\n const totalSheets = Math.min(globals.sheets.length, MAX_SHEETS)\n let pageFilter: Set<number> | null = null\n if (options?.pages) {\n const { parsePageRange } = await import(\"../page-range.js\")\n pageFilter = parsePageRange(options.pages, totalSheets)\n }\n\n // 6. 각 시트 처리\n const allBlocks: IRBlock[] = []\n for (let i = 0; i < totalSheets; i++) {\n if (pageFilter && !pageFilter.has(i + 1)) continue\n const meta = globals.sheets[i]\n // BoundSheet8.dt: 0=Worksheet, 1=Macro, 2=Chart — 워크시트만 처리\n if (meta.dt !== 0) continue\n\n options?.onProgress?.(i + 1, totalSheets)\n\n const bofIdx = findSheetBofIndex(records, meta.lbPlyPos)\n if (bofIdx < 0) {\n warnings.push({\n page: i + 1,\n message: `시트 \"${meta.name}\" BOF를 찾을 수 없음 (lbPlyPos=${meta.lbPlyPos})`,\n code: \"PARTIAL_PARSE\",\n })\n continue\n }\n\n // 시트 BOF 검증\n const sheetBof = decodeBof(records[bofIdx].data)\n if (sheetBof && sheetBof.dt !== DT_WORKSHEET) {\n // 차트/매크로 등은 스킵\n continue\n }\n\n try {\n const { sheet } = extractSheetCells(records, bofIdx, globals.sst)\n const blocks = sheetToBlocks(meta.name, sheet, i)\n allBlocks.push(...blocks)\n } catch (e) {\n warnings.push({\n page: i + 1,\n message: `시트 \"${meta.name}\" 파싱 실패: ${e instanceof Error ? e.message : \"알 수 없는 오류\"}`,\n code: \"PARTIAL_PARSE\",\n })\n }\n }\n\n // 7. 메타데이터\n const metadata: DocumentMetadata = {\n pageCount: totalSheets,\n }\n\n return {\n markdown: blocksToMarkdown(allBlocks),\n blocks: allBlocks,\n metadata,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n","/**\n * DOCX (Office Open XML Document) 파서\n *\n * ZIP + XML 구조를 jszip + xmldom으로 파싱하여 IRBlock[]로 변환.\n * w:p → paragraph/heading, w:tbl → table, w:drawing → image.\n */\n\nimport JSZip from \"jszip\"\nimport { DOMParser } from \"@xmldom/xmldom\"\nimport type {\n IRBlock, IRTable, IRCell, DocumentMetadata, InternalParseResult,\n ParseOptions, ParseWarning, ExtractedImage, InlineStyle,\n} from \"../types.js\"\nimport { KordocError, precheckZipSize, stripDtd } from \"../utils.js\"\nimport { blocksToMarkdown } from \"../table/builder.js\"\nimport { ommlElementToLatex, isDisplayMath } from \"./equation.js\"\n\n/** ZIP 압축 해제 누적 최대 크기 (100MB) — ZIP bomb 방지 */\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\n\n// ─── XML 헬퍼 ──────────────────────────────────────────\n\n/** 네임스페이스 무시 태그 검색 — DOCX는 네임스페이스가 많음 */\nfunction getChildElements(parent: Element | Document, localName: string): Element[] {\n const result: Element[] = []\n const children = parent.childNodes\n for (let i = 0; i < children.length; i++) {\n const node = children[i]\n if (node.nodeType === 1) {\n const el = node as Element\n if (el.localName === localName || el.tagName?.endsWith(`:${localName}`)) {\n result.push(el)\n }\n }\n }\n return result\n}\n\n/** 재귀적으로 localName 매칭 — getElementsByTagName 대안 */\nfunction findElements(parent: Element | Document, localName: string): Element[] {\n const result: Element[] = []\n const walk = (node: Element | Document) => {\n const children = node.childNodes\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (child.nodeType === 1) {\n const el = child as Element\n if (el.localName === localName || el.tagName?.endsWith(`:${localName}`)) {\n result.push(el)\n }\n walk(el)\n }\n }\n }\n walk(parent)\n return result\n}\n\nfunction getAttr(el: Element, localName: string): string | null {\n // w:val, r:id 등 네임스페이스 포함 속성\n const attrs = el.attributes\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs[i]\n if (attr.localName === localName || attr.name === localName) return attr.value\n }\n return null\n}\n\nfunction parseXml(text: string): Document {\n return new DOMParser().parseFromString(stripDtd(text), \"text/xml\")\n}\n\n// ─── 스타일 파싱 ────────────────────────────────────────\n\ninterface StyleInfo {\n name: string\n basedOn?: string\n outlineLevel?: number\n}\n\nfunction parseStyles(xml: string): Map<string, StyleInfo> {\n const doc = parseXml(xml)\n const styles = new Map<string, StyleInfo>()\n const styleElements = findElements(doc, \"style\")\n\n for (const el of styleElements) {\n const styleId = getAttr(el, \"styleId\")\n if (!styleId) continue\n\n const nameEls = getChildElements(el, \"name\")\n const name = nameEls.length > 0 ? (getAttr(nameEls[0], \"val\") ?? \"\") : \"\"\n const basedOnEls = getChildElements(el, \"basedOn\")\n const basedOn = basedOnEls.length > 0 ? (getAttr(basedOnEls[0], \"val\") ?? undefined) : undefined\n\n // outlineLevel으로 heading 감지\n const pPrEls = getChildElements(el, \"pPr\")\n let outlineLevel: number | undefined\n if (pPrEls.length > 0) {\n const outlineEls = getChildElements(pPrEls[0], \"outlineLvl\")\n if (outlineEls.length > 0) {\n const val = getAttr(outlineEls[0], \"val\")\n if (val !== null) outlineLevel = parseInt(val, 10)\n }\n }\n\n // Heading 패턴 매칭\n if (outlineLevel === undefined) {\n const headingMatch = name.match(/^(?:heading|Heading)\\s*(\\d+)$/i)\n if (headingMatch) outlineLevel = parseInt(headingMatch[1], 10) - 1\n }\n\n styles.set(styleId, { name, basedOn, outlineLevel })\n }\n return styles\n}\n\n// ─── 번호 매기기 파싱 ──────────────────────────────────\n\ninterface NumberingInfo {\n numFmt: string // \"decimal\", \"bullet\", etc.\n level: number\n}\n\nfunction parseNumbering(xml: string): Map<string, Map<number, NumberingInfo>> {\n const doc = parseXml(xml)\n const abstractNums = new Map<string, Map<number, NumberingInfo>>()\n\n // abstractNum 파싱\n const abstractElements = findElements(doc, \"abstractNum\")\n for (const el of abstractElements) {\n const abstractNumId = getAttr(el, \"abstractNumId\")\n if (!abstractNumId) continue\n const levels = new Map<number, NumberingInfo>()\n const lvlElements = getChildElements(el, \"lvl\")\n for (const lvl of lvlElements) {\n const ilvl = parseInt(getAttr(lvl, \"ilvl\") ?? \"0\", 10)\n const numFmtEls = getChildElements(lvl, \"numFmt\")\n const numFmt = numFmtEls.length > 0 ? (getAttr(numFmtEls[0], \"val\") ?? \"bullet\") : \"bullet\"\n levels.set(ilvl, { numFmt, level: ilvl })\n }\n abstractNums.set(abstractNumId, levels)\n }\n\n // num → abstractNum 매핑\n const nums = new Map<string, Map<number, NumberingInfo>>()\n const numElements = findElements(doc, \"num\")\n for (const el of numElements) {\n const numId = getAttr(el, \"numId\")\n if (!numId) continue\n const abstractRefs = getChildElements(el, \"abstractNumId\")\n if (abstractRefs.length > 0) {\n const ref = getAttr(abstractRefs[0], \"val\")\n if (ref && abstractNums.has(ref)) {\n nums.set(numId, abstractNums.get(ref)!)\n }\n }\n }\n return nums\n}\n\n// ─── 관계 파싱 ─────────────────────────────────────────\n\nfunction parseRels(xml: string): Map<string, string> {\n const doc = parseXml(xml)\n const map = new Map<string, string>()\n const rels = findElements(doc, \"Relationship\")\n for (const rel of rels) {\n const id = getAttr(rel, \"Id\")\n const target = getAttr(rel, \"Target\")\n if (id && target) map.set(id, target)\n }\n return map\n}\n\n// ─── 각주 파싱 ─────────────────────────────────────────\n\nfunction parseFootnotes(xml: string): Map<string, string> {\n const doc = parseXml(xml)\n const notes = new Map<string, string>()\n const fnElements = findElements(doc, \"footnote\")\n for (const fn of fnElements) {\n const id = getAttr(fn, \"id\")\n if (!id || id === \"0\" || id === \"-1\") continue // 0=separator, -1=continuation\n const texts: string[] = []\n const pElements = findElements(fn, \"p\")\n for (const p of pElements) {\n const runs = findElements(p, \"r\")\n for (const r of runs) {\n const tElements = getChildElements(r, \"t\")\n for (const t of tElements) texts.push(t.textContent ?? \"\")\n }\n }\n notes.set(id, texts.join(\"\").trim())\n }\n return notes\n}\n\n// ─── OMML 수집 ────────────────────────────────────────\n\n/**\n * paragraph 내부의 최상위 OMML 엘리먼트(`<m:oMath>` / `<m:oMathPara>`) 수집.\n * `<m:oMathPara>` 안의 중첩 `<m:oMath>` 는 중복 제외.\n */\nfunction collectOmmlRoots(p: Element): Element[] {\n const out: Element[] = []\n const walk = (node: Element) => {\n const children = node.childNodes\n if (!children) return\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (child.nodeType !== 1) continue\n const el = child as Element\n const tag = el.localName || el.tagName?.replace(/^[^:]+:/, \"\") || \"\"\n if (tag === \"oMath\" || tag === \"oMathPara\") {\n out.push(el)\n // 내부는 재귀하지 않음 (oMathPara 안의 oMath 중복 방지)\n } else {\n walk(el)\n }\n }\n }\n walk(p)\n return out\n}\n\n// ─── Run 텍스트 추출 ──────────────────────────────────\n\ninterface RunResult {\n text: string\n bold: boolean\n italic: boolean\n}\n\nfunction extractRun(r: Element): RunResult {\n const tElements = getChildElements(r, \"t\")\n const text = tElements.map(t => t.textContent ?? \"\").join(\"\")\n\n let bold = false\n let italic = false\n const rPrEls = getChildElements(r, \"rPr\")\n if (rPrEls.length > 0) {\n bold = getChildElements(rPrEls[0], \"b\").length > 0\n italic = getChildElements(rPrEls[0], \"i\").length > 0\n }\n\n return { text, bold, italic }\n}\n\n// ─── 단락 파싱 ─────────────────────────────────────────\n\nfunction parseParagraph(\n p: Element,\n styles: Map<string, StyleInfo>,\n numbering: Map<string, Map<number, NumberingInfo>>,\n footnotes: Map<string, string>,\n rels: Map<string, string>,\n): IRBlock | null {\n // 스타일 확인\n const pPrEls = getChildElements(p, \"pPr\")\n let styleId = \"\"\n let numId = \"\"\n let ilvl = 0\n\n if (pPrEls.length > 0) {\n const pStyleEls = getChildElements(pPrEls[0], \"pStyle\")\n if (pStyleEls.length > 0) styleId = getAttr(pStyleEls[0], \"val\") ?? \"\"\n\n const numPrEls = getChildElements(pPrEls[0], \"numPr\")\n if (numPrEls.length > 0) {\n const numIdEls = getChildElements(numPrEls[0], \"numId\")\n const ilvlEls = getChildElements(numPrEls[0], \"ilvl\")\n numId = numIdEls.length > 0 ? (getAttr(numIdEls[0], \"val\") ?? \"\") : \"\"\n ilvl = ilvlEls.length > 0 ? parseInt(getAttr(ilvlEls[0], \"val\") ?? \"0\", 10) : 0\n }\n }\n\n // 텍스트 수집\n const parts: string[] = []\n let hasBold = false\n let hasItalic = false\n let href: string | undefined\n let footnoteText: string | undefined\n\n // 하이퍼링크 처리\n const hyperlinks = getChildElements(p, \"hyperlink\")\n const hyperlinkTexts = new Set<string>()\n\n for (const hl of hyperlinks) {\n const rId = getAttr(hl, \"id\")\n const hlText: string[] = []\n const runs = findElements(hl, \"r\")\n for (const r of runs) {\n const result = extractRun(r)\n hlText.push(result.text)\n }\n const text = hlText.join(\"\")\n if (text) {\n hyperlinkTexts.add(text)\n if (rId && rels.has(rId)) {\n href = rels.get(rId)\n parts.push(text)\n } else {\n parts.push(text)\n }\n }\n }\n\n // 일반 run 처리\n const runs = getChildElements(p, \"r\")\n for (const r of runs) {\n // 하이퍼링크 내부 run은 이미 처리됨 — 부모가 hyperlink이면 스킵\n if (r.parentNode && (r.parentNode as Element).localName === \"hyperlink\") continue\n\n const result = extractRun(r)\n if (result.bold) hasBold = true\n if (result.italic) hasItalic = true\n\n // 각주 참조 확인\n const fnRefEls = getChildElements(r, \"footnoteReference\")\n if (fnRefEls.length > 0) {\n const fnId = getAttr(fnRefEls[0], \"id\")\n if (fnId && footnotes.has(fnId)) {\n footnoteText = footnotes.get(fnId)\n }\n }\n\n if (result.text) parts.push(result.text)\n }\n\n // OMML 수식 — <m:oMath> / <m:oMathPara> 를 LaTeX 로 변환해 덧붙임.\n // 인라인 수식은 `$...$`, display 는 `$$...$$`. 순서는 run 뒤로 몰리지만\n // 대부분 한 단락 내 수식/텍스트가 분리돼 있어 실용상 무해.\n for (const om of collectOmmlRoots(p)) {\n const latex = ommlElementToLatex(om)\n if (!latex) continue\n if (isDisplayMath(om)) parts.push(\" $$\" + latex + \"$$ \")\n else parts.push(\" $\" + latex + \"$ \")\n }\n\n const text = parts.join(\"\").replace(/[ \\t]{2,}/g, \" \").trim()\n if (!text) return null\n\n // Heading 판별\n const style = styles.get(styleId)\n if (style?.outlineLevel !== undefined && style.outlineLevel >= 0 && style.outlineLevel <= 5) {\n return {\n type: \"heading\",\n text,\n level: style.outlineLevel + 1,\n }\n }\n\n // 리스트 판별\n if (numId && numId !== \"0\") {\n const numDef = numbering.get(numId)\n const levelInfo = numDef?.get(ilvl)\n const listType = levelInfo?.numFmt === \"bullet\" ? \"unordered\" : \"ordered\"\n return { type: \"list\", text, listType }\n }\n\n // 일반 단락\n const block: IRBlock = { type: \"paragraph\", text }\n if (hasBold || hasItalic) {\n block.style = { bold: hasBold || undefined, italic: hasItalic || undefined }\n }\n if (href) block.href = href\n if (footnoteText) block.footnoteText = footnoteText\n return block\n}\n\n// ─── 테이블 파싱 ────────────────────────────────────────\n\nfunction parseTable(\n tbl: Element,\n styles: Map<string, StyleInfo>,\n numbering: Map<string, Map<number, NumberingInfo>>,\n footnotes: Map<string, string>,\n rels: Map<string, string>,\n): IRBlock | null {\n const trElements = getChildElements(tbl, \"tr\")\n if (trElements.length === 0) return null\n\n const rows: IRCell[][] = []\n let maxCols = 0\n\n for (const tr of trElements) {\n const tcElements = getChildElements(tr, \"tc\")\n const row: IRCell[] = []\n\n for (const tc of tcElements) {\n // 셀 속성\n let colSpan = 1\n let rowSpan = 1\n const tcPrEls = getChildElements(tc, \"tcPr\")\n if (tcPrEls.length > 0) {\n const gridSpanEls = getChildElements(tcPrEls[0], \"gridSpan\")\n if (gridSpanEls.length > 0) {\n colSpan = parseInt(getAttr(gridSpanEls[0], \"val\") ?? \"1\", 10)\n }\n const vMergeEls = getChildElements(tcPrEls[0], \"vMerge\")\n if (vMergeEls.length > 0) {\n const val = getAttr(vMergeEls[0], \"val\")\n if (val !== \"restart\" && val !== null) {\n // 병합 계속 셀 — 스킵 마커\n row.push({ text: \"\", colSpan, rowSpan: 0 })\n continue\n }\n }\n }\n\n // 셀 텍스트\n const cellTexts: string[] = []\n const pElements = getChildElements(tc, \"p\")\n for (const p of pElements) {\n const block = parseParagraph(p, styles, numbering, footnotes, rels)\n if (block?.text) cellTexts.push(block.text)\n }\n\n row.push({ text: cellTexts.join(\"\\n\"), colSpan, rowSpan })\n }\n rows.push(row)\n if (row.length > maxCols) maxCols = row.length\n }\n\n // vMerge rowSpan 후처리: restart에서 아래로 연속되는 rowSpan=0 카운트\n for (let c = 0; c < maxCols; c++) {\n for (let r = 0; r < rows.length; r++) {\n const cell = rows[r][c]\n if (!cell || cell.rowSpan === 0) continue\n let span = 1\n for (let nr = r + 1; nr < rows.length; nr++) {\n if (rows[nr][c]?.rowSpan === 0) span++\n else break\n }\n cell.rowSpan = span\n }\n }\n\n // rowSpan=0인 placeholder 제거\n const cleanRows: IRCell[][] = []\n for (const row of rows) {\n const clean = row.filter(cell => cell.rowSpan !== 0)\n cleanRows.push(clean)\n }\n\n // 빈 테이블 체크\n if (cleanRows.length === 0) return null\n\n // 컬럼 수 재계산\n let cols = 0\n for (const row of cleanRows) {\n let c = 0\n for (const cell of row) c += cell.colSpan\n if (c > cols) cols = c\n }\n\n const table: IRTable = {\n rows: cleanRows.length,\n cols,\n cells: cleanRows,\n hasHeader: cleanRows.length > 1,\n }\n return { type: \"table\", table }\n}\n\n// ─── 이미지 추출 ────────────────────────────────────────\n\nasync function extractImages(\n zip: JSZip,\n rels: Map<string, string>,\n doc: Document,\n): Promise<{ blocks: IRBlock[]; images: ExtractedImage[] }> {\n const blocks: IRBlock[] = []\n const images: ExtractedImage[] = []\n\n const drawingElements = findElements(doc.documentElement, \"drawing\")\n let imgIdx = 0\n\n for (const drawing of drawingElements) {\n // a:blip → r:embed\n const blips = findElements(drawing, \"blip\")\n for (const blip of blips) {\n const embedId = getAttr(blip, \"embed\")\n if (!embedId) continue\n const target = rels.get(embedId)\n if (!target) continue\n\n const imgPath = target.startsWith(\"/\") ? target.slice(1)\n : target.startsWith(\"word/\") ? target\n : `word/${target}`\n\n const imgFile = zip.file(imgPath)\n if (!imgFile) continue\n\n try {\n const data = await imgFile.async(\"uint8array\")\n imgIdx++\n const ext = imgPath.split(\".\").pop()?.toLowerCase() ?? \"png\"\n const mimeMap: Record<string, string> = {\n png: \"image/png\", jpg: \"image/jpeg\", jpeg: \"image/jpeg\",\n gif: \"image/gif\", bmp: \"image/bmp\", wmf: \"image/wmf\", emf: \"image/emf\",\n }\n const filename = `image_${String(imgIdx).padStart(3, \"0\")}.${ext}`\n images.push({ filename, data, mimeType: mimeMap[ext] ?? \"image/png\" })\n blocks.push({ type: \"image\", text: filename })\n } catch { /* 이미지 실패 무시 */ }\n }\n }\n return { blocks, images }\n}\n\n// ─── 메인 파서 ─────────────────────────────────────────\n\nexport async function parseDocxDocument(\n buffer: ArrayBuffer,\n options?: ParseOptions,\n): Promise<InternalParseResult> {\n // ZIP bomb 사전 검사\n precheckZipSize(buffer, MAX_DECOMPRESS_SIZE)\n\n const zip = await JSZip.loadAsync(buffer)\n const warnings: ParseWarning[] = []\n\n // DOCX 구조 검증\n const docFile = zip.file(\"word/document.xml\")\n if (!docFile) {\n throw new KordocError(\"유효하지 않은 DOCX 파일: word/document.xml이 없습니다\")\n }\n\n // 1. 관계 로드\n let rels = new Map<string, string>()\n const relsFile = zip.file(\"word/_rels/document.xml.rels\")\n if (relsFile) {\n rels = parseRels(await relsFile.async(\"text\"))\n }\n\n // 2. 스타일 로드\n let styles = new Map<string, StyleInfo>()\n const stylesFile = zip.file(\"word/styles.xml\")\n if (stylesFile) {\n try {\n styles = parseStyles(await stylesFile.async(\"text\"))\n } catch { /* 스타일 실패 무시 */ }\n }\n\n // 3. 번호 매기기 로드\n let numbering = new Map<string, Map<number, NumberingInfo>>()\n const numFile = zip.file(\"word/numbering.xml\")\n if (numFile) {\n try {\n numbering = parseNumbering(await numFile.async(\"text\"))\n } catch { /* 번호 매기기 실패 무시 */ }\n }\n\n // 4. 각주 로드\n let footnotes = new Map<string, string>()\n const fnFile = zip.file(\"word/footnotes.xml\")\n if (fnFile) {\n try {\n footnotes = parseFootnotes(await fnFile.async(\"text\"))\n } catch { /* 각주 실패 무시 */ }\n }\n\n // 5. 본문 파싱\n const docXml = await docFile.async(\"text\")\n const doc = parseXml(docXml)\n const body = findElements(doc, \"body\")\n if (body.length === 0) {\n throw new KordocError(\"DOCX 본문(w:body)을 찾을 수 없습니다\")\n }\n\n const blocks: IRBlock[] = []\n const bodyEl = body[0]\n const children = bodyEl.childNodes\n\n for (let i = 0; i < children.length; i++) {\n const node = children[i]\n if (node.nodeType !== 1) continue\n const el = node as Element\n const localName = el.localName ?? el.tagName?.split(\":\").pop()\n\n if (localName === \"p\") {\n const block = parseParagraph(el, styles, numbering, footnotes, rels)\n if (block) blocks.push(block)\n } else if (localName === \"tbl\") {\n const block = parseTable(el, styles, numbering, footnotes, rels)\n if (block) blocks.push(block)\n }\n }\n\n // 6. 이미지 추출\n const { blocks: imgBlocks, images } = await extractImages(zip, rels, doc)\n // 이미지 블록은 본문에 이미 포함되어야 하지만, 누락된 것 추가\n // (drawing이 paragraph 내에 있으므로 대부분 이미 포함됨)\n\n // 7. 메타데이터\n const metadata: DocumentMetadata = {}\n const coreFile = zip.file(\"docProps/core.xml\")\n if (coreFile) {\n try {\n const coreXml = await coreFile.async(\"text\")\n const coreDoc = parseXml(coreXml)\n const getFirst = (tag: string) => {\n const els = coreDoc.getElementsByTagName(tag)\n return els.length > 0 ? (els[0].textContent ?? \"\").trim() : undefined\n }\n metadata.title = getFirst(\"dc:title\") || getFirst(\"dcterms:title\")\n metadata.author = getFirst(\"dc:creator\")\n metadata.description = getFirst(\"dc:description\")\n const created = getFirst(\"dcterms:created\")\n if (created) metadata.createdAt = created\n const modified = getFirst(\"dcterms:modified\")\n if (modified) metadata.modifiedAt = modified\n } catch { /* 메타데이터 실패 무시 */ }\n }\n\n // 8. 아웃라인\n const outline = blocks\n .filter(b => b.type === \"heading\")\n .map(b => ({ level: b.level ?? 2, text: b.text ?? \"\" }))\n\n const markdown = blocksToMarkdown(blocks)\n\n return {\n markdown,\n blocks,\n metadata,\n outline: outline.length > 0 ? outline : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n images: images.length > 0 ? images : undefined,\n }\n}\n","/**\n * DOCX OMML (Office Math ML) → LaTeX\n *\n * OMML 루트 엘리먼트(`<m:oMath>`, `<m:oMathPara>`) 를 재귀적으로 훑어 LaTeX\n * 문자열을 생성한다. `<m:r>/<m:t>` 텍스트, 분수/근호/첨자/행렬/괄호/함수\n * /적분 등 실무에서 가장 흔한 OMML 18종 태그를 지원.\n *\n * 레퍼런스:\n * - Microsoft OMML2MML.xsl (Office 공식 XSLT 매핑)\n * - Pandoc texmath (Text.TeXMath.Readers.OMML)\n * 매핑 테이블은 CLAUDE plan `.claude/plans/auto-update-and-math.md` 참조.\n *\n * Entry points:\n * - ommlElementToLatex(el) — 하나의 <m:oMath> 또는 <m:oMathPara> 엘리먼트를\n * LaTeX 로 변환 (delim 은 호출자가 씌움).\n * - isOmmlRoot(el) — 엘리먼트가 OMML 최상위인지 판별.\n */\n\n/** localName 비교 — 네임스페이스 prefix 제거 */\nfunction lname(el: Element): string {\n return el.localName || el.tagName?.replace(/^[^:]+:/, \"\") || \"\"\n}\n\n/** 자식 중 localName 매칭 엘리먼트들 (직계만) */\nfunction kids(parent: Element, name: string): Element[] {\n const out: Element[] = []\n const nodes = parent.childNodes\n if (!nodes) return out\n for (let i = 0; i < nodes.length; i++) {\n const n = nodes[i]\n if (n.nodeType !== 1) continue\n const el = n as Element\n if (lname(el) === name) out.push(el)\n }\n return out\n}\n\n/** 직계 자식 첫 매칭 또는 null */\nfunction firstKid(parent: Element, name: string): Element | null {\n const list = kids(parent, name)\n return list[0] ?? null\n}\n\n/** 자식 엘리먼트 순회 (직계만, Element only) */\nfunction eachChild(parent: Element): Element[] {\n const out: Element[] = []\n const nodes = parent.childNodes\n if (!nodes) return out\n for (let i = 0; i < nodes.length; i++) {\n if (nodes[i].nodeType === 1) out.push(nodes[i] as Element)\n }\n return out\n}\n\n/** <m:r> 내부 <m:t> 텍스트 집계. 특수 연산자에 백슬래시 매핑. */\nfunction runToLatex(r: Element): string {\n let out = \"\"\n for (const t of kids(r, \"t\")) out += t.textContent ?? \"\"\n return out\n}\n\n/** 함수 이름(sin/cos/log/ln/exp/tan/…) → `\\sin` 식 매핑 */\nconst FUNC_NAMES = new Set([\n \"sin\", \"cos\", \"tan\", \"cot\", \"sec\", \"csc\",\n \"sinh\", \"cosh\", \"tanh\", \"coth\",\n \"arcsin\", \"arccos\", \"arctan\",\n \"log\", \"ln\", \"lg\", \"exp\",\n \"det\", \"dim\", \"gcd\", \"inf\", \"sup\", \"lim\", \"max\", \"min\",\n \"Pr\", \"arg\",\n])\n\n/** acc/char → LaTeX accent */\nconst ACCENT_MAP: Record<string, string> = {\n \"̂\": \"\\\\hat\", // U+0302 COMBINING CIRCUMFLEX\n \"̃\": \"\\\\tilde\", // U+0303\n \"̄\": \"\\\\bar\", // U+0304\n \"̇\": \"\\\\dot\", // U+0307\n \"̈\": \"\\\\ddot\", // U+0308\n \"́\": \"\\\\acute\", // U+0301\n \"̀\": \"\\\\grave\", // U+0300\n \"̆\": \"\\\\breve\", // U+0306\n \"̌\": \"\\\\check\", // U+030C\n \"⃗\": \"\\\\vec\", // U+20D7 COMBINING RIGHT ARROW ABOVE\n \"→\": \"\\\\vec\",\n}\n\n/** n-ary 연산자 (m:nary) chr → LaTeX */\nconst NARY_MAP: Record<string, string> = {\n \"∑\": \"\\\\sum\",\n \"∏\": \"\\\\prod\",\n \"∐\": \"\\\\coprod\",\n \"∫\": \"\\\\int\",\n \"∬\": \"\\\\iint\",\n \"∭\": \"\\\\iiint\",\n \"∮\": \"\\\\oint\",\n \"∯\": \"\\\\oiint\",\n \"∰\": \"\\\\oiiint\",\n \"⋃\": \"\\\\bigcup\",\n \"⋂\": \"\\\\bigcap\",\n \"⨁\": \"\\\\bigoplus\",\n \"⨂\": \"\\\\bigotimes\",\n \"⨀\": \"\\\\bigodot\",\n}\n\n/** 괄호 문자 → LaTeX (좌/우) */\nfunction mapDelim(ch: string, isLeft: boolean): string {\n const l: Record<string, string> = {\n \"(\": \"(\", \"[\": \"[\", \"{\": \"\\\\{\", \"⟨\": \"\\\\langle\",\n \"|\": \"|\", \"‖\": \"\\\\|\", \"⌊\": \"\\\\lfloor\", \"⌈\": \"\\\\lceil\",\n \"\": \".\",\n }\n const r: Record<string, string> = {\n \")\": \")\", \"]\": \"]\", \"}\": \"\\\\}\", \"⟩\": \"\\\\rangle\",\n \"|\": \"|\", \"‖\": \"\\\\|\", \"⌋\": \"\\\\rfloor\", \"⌉\": \"\\\\rceil\",\n \"\": \".\",\n }\n const map = isLeft ? l : r\n return map[ch] ?? ch\n}\n\n/** 내용이 단일 문자거나 단순 원자면 `{}` 없이, 아니면 감싸서 반환 */\nfunction grp(body: string): string {\n const s = body.trim()\n if (s.length === 0) return \"{}\"\n // 이미 `{...}` 로 감싸진 경우 그대로\n if (s.startsWith(\"{\") && s.endsWith(\"}\")) return s\n return \"{\" + s + \"}\"\n}\n\n/** 엘리먼트 리스트를 연결한 LaTeX 문자열로 변환 */\nfunction childrenToLatex(parent: Element): string {\n let out = \"\"\n for (const ch of eachChild(parent)) {\n out += nodeToLatex(ch)\n }\n return out\n}\n\n/** 노드(Element) 하나 → LaTeX */\nfunction nodeToLatex(el: Element): string {\n const tag = lname(el)\n switch (tag) {\n case \"r\": return runToLatex(el)\n\n case \"e\": // generic container (인자로 쓰임) — 자식 연결\n case \"num\":\n case \"den\":\n case \"sub\":\n case \"sup\":\n case \"deg\":\n case \"lim\":\n case \"fName\":\n return childrenToLatex(el)\n\n // 분수\n case \"f\": {\n const n = firstKid(el, \"num\")\n const d = firstKid(el, \"den\")\n const num = n ? childrenToLatex(n) : \"\"\n const den = d ? childrenToLatex(d) : \"\"\n return \"\\\\frac\" + grp(num) + grp(den)\n }\n\n // 첨자\n case \"sSup\": {\n const e = firstKid(el, \"e\")\n const sup = firstKid(el, \"sup\")\n return grp(e ? childrenToLatex(e) : \"\") + \"^\" + grp(sup ? childrenToLatex(sup) : \"\")\n }\n case \"sSub\": {\n const e = firstKid(el, \"e\")\n const sub = firstKid(el, \"sub\")\n return grp(e ? childrenToLatex(e) : \"\") + \"_\" + grp(sub ? childrenToLatex(sub) : \"\")\n }\n case \"sSubSup\": {\n const e = firstKid(el, \"e\")\n const sub = firstKid(el, \"sub\")\n const sup = firstKid(el, \"sup\")\n return grp(e ? childrenToLatex(e) : \"\") +\n \"_\" + grp(sub ? childrenToLatex(sub) : \"\") +\n \"^\" + grp(sup ? childrenToLatex(sup) : \"\")\n }\n case \"sPre\": {\n // pre-superscript/subscript\n const sub = firstKid(el, \"sub\")\n const sup = firstKid(el, \"sup\")\n const e = firstKid(el, \"e\")\n const preSub = sub ? grp(childrenToLatex(sub)) : \"{}\"\n const preSup = sup ? grp(childrenToLatex(sup)) : \"{}\"\n const body = e ? childrenToLatex(e) : \"\"\n return \"{}_\" + preSub + \"^\" + preSup + grp(body)\n }\n\n // 근호\n case \"rad\": {\n const deg = firstKid(el, \"deg\")\n const e = firstKid(el, \"e\")\n const body = e ? childrenToLatex(e) : \"\"\n // degHide 속성이 있으면 degree 생략\n const radPr = firstKid(el, \"radPr\")\n let hide = false\n if (radPr) {\n const degHide = firstKid(radPr, \"degHide\")\n if (degHide) {\n const val = degHide.getAttribute(\"m:val\") ?? degHide.getAttribute(\"val\")\n hide = val === \"1\" || val === \"on\" || val === \"true\"\n }\n }\n const degStr = (!hide && deg) ? childrenToLatex(deg).trim() : \"\"\n return degStr ? \"\\\\sqrt[\" + degStr + \"]\" + grp(body) : \"\\\\sqrt\" + grp(body)\n }\n\n // n-ary 연산자 (sum, prod, int, …)\n case \"nary\": {\n const naryPr = firstKid(el, \"naryPr\")\n let op = \"\\\\int\"\n let subHide = false\n let supHide = false\n let limLoc = \"\"\n if (naryPr) {\n const chr = firstKid(naryPr, \"chr\")\n if (chr) {\n const v = chr.getAttribute(\"m:val\") ?? chr.getAttribute(\"val\") ?? \"\"\n if (v && NARY_MAP[v]) op = NARY_MAP[v]\n else if (v) op = v\n } else {\n // chr 생략 시 기본값은 integral (OMML 스펙)\n op = \"\\\\int\"\n }\n const sh = firstKid(naryPr, \"subHide\")\n const ph = firstKid(naryPr, \"supHide\")\n if (sh) subHide = (sh.getAttribute(\"m:val\") ?? sh.getAttribute(\"val\")) !== \"0\"\n if (ph) supHide = (ph.getAttribute(\"m:val\") ?? ph.getAttribute(\"val\")) !== \"0\"\n const ll = firstKid(naryPr, \"limLoc\")\n if (ll) limLoc = ll.getAttribute(\"m:val\") ?? ll.getAttribute(\"val\") ?? \"\"\n }\n const sub = firstKid(el, \"sub\")\n const sup = firstKid(el, \"sup\")\n const e = firstKid(el, \"e\")\n const subStr = (!subHide && sub) ? childrenToLatex(sub) : \"\"\n const supStr = (!supHide && sup) ? childrenToLatex(sup) : \"\"\n const body = e ? childrenToLatex(e) : \"\"\n\n let head = op\n if (limLoc === \"undOvr\") {\n // limit 위치를 연산자 아래/위 (sum/prod 기본)\n if (subStr) head += \"_\" + grp(subStr)\n if (supStr) head += \"^\" + grp(supStr)\n } else {\n if (subStr) head += \"_\" + grp(subStr)\n if (supStr) head += \"^\" + grp(supStr)\n }\n return head + \" \" + body\n }\n\n // 괄호 (delimiter)\n case \"d\": {\n const dPr = firstKid(el, \"dPr\")\n let beg = \"(\"\n let end = \")\"\n let sep = \",\"\n if (dPr) {\n const begChr = firstKid(dPr, \"begChr\")\n const endChr = firstKid(dPr, \"endChr\")\n const sepChr = firstKid(dPr, \"sepChr\")\n if (begChr) beg = begChr.getAttribute(\"m:val\") ?? begChr.getAttribute(\"val\") ?? beg\n if (endChr) end = endChr.getAttribute(\"m:val\") ?? endChr.getAttribute(\"val\") ?? end\n if (sepChr) sep = sepChr.getAttribute(\"m:val\") ?? sepChr.getAttribute(\"val\") ?? sep\n }\n const items = kids(el, \"e\").map(childrenToLatex)\n const body = items.join(sep)\n return \"\\\\left\" + mapDelim(beg, true) + body + \"\\\\right\" + mapDelim(end, false)\n }\n\n // 행렬\n case \"m\": {\n const rows: string[] = []\n for (const mr of kids(el, \"mr\")) {\n const cells = kids(mr, \"e\").map(childrenToLatex)\n rows.push(cells.join(\" & \"))\n }\n return \"\\\\begin{matrix}\" + rows.join(\" \\\\\\\\ \") + \"\\\\end{matrix}\"\n }\n\n // 상자/박스 (acc 와 유사하지만 bar 가 아닌 box)\n case \"box\":\n return childrenToLatex(el)\n\n // 함수 적용 (sin, cos, log …)\n case \"func\": {\n const fn = firstKid(el, \"fName\")\n const e = firstKid(el, \"e\")\n const fnStr = fn ? childrenToLatex(fn).trim() : \"\"\n const body = e ? childrenToLatex(e) : \"\"\n const fnLatex = FUNC_NAMES.has(fnStr) ? \"\\\\\" + fnStr : fnStr\n return fnLatex + grp(body)\n }\n\n // 악센트 (hat/bar/vec/…)\n case \"acc\": {\n const accPr = firstKid(el, \"accPr\")\n let chr = \"\"\n if (accPr) {\n const chrEl = firstKid(accPr, \"chr\")\n if (chrEl) chr = chrEl.getAttribute(\"m:val\") ?? chrEl.getAttribute(\"val\") ?? \"\"\n }\n // default accent = U+0302 (circumflex)\n if (!chr) chr = \"̂\"\n const e = firstKid(el, \"e\")\n const body = e ? childrenToLatex(e) : \"\"\n const cmd = ACCENT_MAP[chr] ?? \"\\\\hat\"\n return cmd + grp(body)\n }\n\n // bar (위/아래 줄)\n case \"bar\": {\n const barPr = firstKid(el, \"barPr\")\n let pos = \"top\"\n if (barPr) {\n const posEl = firstKid(barPr, \"pos\")\n if (posEl) pos = posEl.getAttribute(\"m:val\") ?? posEl.getAttribute(\"val\") ?? pos\n }\n const e = firstKid(el, \"e\")\n const body = e ? childrenToLatex(e) : \"\"\n return (pos === \"bot\" ? \"\\\\underline\" : \"\\\\overline\") + grp(body)\n }\n\n // lim 위/아래\n case \"limLow\": {\n const e = firstKid(el, \"e\")\n const lim = firstKid(el, \"lim\")\n const base = e ? childrenToLatex(e).trim() : \"\"\n const below = lim ? childrenToLatex(lim) : \"\"\n // 만약 base 가 \"lim\"/\"max\"/\"min\" 이면 \\lim_{...} 식으로\n if (FUNC_NAMES.has(base)) return \"\\\\\" + base + \"_\" + grp(below)\n return base + \"_\" + grp(below)\n }\n case \"limUpp\": {\n const e = firstKid(el, \"e\")\n const lim = firstKid(el, \"lim\")\n const base = e ? childrenToLatex(e).trim() : \"\"\n const above = lim ? childrenToLatex(lim) : \"\"\n if (FUNC_NAMES.has(base)) return \"\\\\\" + base + \"^\" + grp(above)\n return base + \"^\" + grp(above)\n }\n\n // group character (over/underset 비슷)\n case \"groupChr\":\n return childrenToLatex(firstKid(el, \"e\") ?? el)\n\n // box/borderBox/phantom/eqArr/… 는 자식 본문만 유지\n case \"borderBox\":\n case \"phant\":\n case \"eqArr\":\n return childrenToLatex(el)\n\n // 최상위 컨테이너\n case \"oMath\":\n case \"oMathPara\":\n return childrenToLatex(el)\n\n // 메타 — 속성만 들어있으므로 출력 제외\n case \"rPr\":\n case \"fPr\":\n case \"sSubPr\":\n case \"sSupPr\":\n case \"sSubSupPr\":\n case \"radPr\":\n case \"naryPr\":\n case \"dPr\":\n case \"accPr\":\n case \"barPr\":\n case \"funcPr\":\n case \"mPr\":\n case \"ctrlPr\":\n return \"\"\n\n default:\n // 자식 연결로 폴백 (모르면 재귀)\n return childrenToLatex(el)\n }\n}\n\n/** 최상위 OMML 엘리먼트인지 */\nexport function isOmmlRoot(el: Element): boolean {\n const t = lname(el)\n return t === \"oMath\" || t === \"oMathPara\"\n}\n\n/**\n * OMML 엘리먼트(`<m:oMath>` 또는 `<m:oMathPara>`) 를 LaTeX 로 변환.\n * 공백은 정규화(중복 제거 + trim)만 하고 delim($/$$)은 호출자가 추가.\n */\nexport function ommlElementToLatex(el: Element): string {\n if (!isOmmlRoot(el)) return \"\"\n const raw = childrenToLatex(el)\n return raw.replace(/\\s+/g, \" \").trim()\n}\n\n/** `<m:oMathPara>` 는 display mode */\nexport function isDisplayMath(el: Element): boolean {\n return lname(el) === \"oMathPara\"\n}\n","/** HWPML 2.x 파서 — XML 기반 한컴 문서 (.hwp with XML content) */\n\nimport { DOMParser } from \"@xmldom/xmldom\"\nimport type { IRBlock, InternalParseResult, ParseOptions, ParseWarning, DocumentMetadata, OutlineItem } from \"../types.js\"\nimport { blocksToMarkdown, buildTable } from \"../table/builder.js\"\nimport { parsePageRange } from \"../page-range.js\"\nimport { stripDtd } from \"../utils.js\"\nimport type { CellContext } from \"../types.js\"\n\nconst MAX_XML_DEPTH = 200\nconst MAX_TABLE_ROWS = 5000\nconst MAX_TABLE_COLS = 500\nconst MAX_HWPML_BYTES = 50 * 1024 * 1024 // 50MB 상한\n\n/** ParaShape 헤딩 정보 */\ninterface ParaShapeInfo {\n headingLevel: number | null // null = 일반 단락, 1-6 = 헤딩 레벨\n}\n\n/** HWPML 문서 파싱 진입점 */\nexport function parseHwpmlDocument(buffer: ArrayBuffer, options?: ParseOptions): InternalParseResult {\n if (buffer.byteLength > MAX_HWPML_BYTES) {\n throw new Error(`HWPML 파일 크기 초과 (${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB > 50MB)`)\n }\n const text = new TextDecoder(\"utf-8\").decode(buffer).replace(/^\\uFEFF/, \"\")\n\n // &nbsp; 엔티티 치환 (DOCTYPE 제거 전에 처리)\n const normalized = text.replace(/&nbsp;/g, \"&#160;\")\n const xml = stripDtd(normalized)\n\n const warnings: ParseWarning[] = []\n const parser = new DOMParser({\n onError: (_level: string, msg: string) => {\n warnings.push({ message: `HWPML XML 파싱 경고: ${msg}`, code: \"MALFORMED_XML\" })\n },\n } as ConstructorParameters<typeof DOMParser>[0])\n\n const doc = parser.parseFromString(xml, \"text/xml\")\n if (!doc.documentElement) {\n return { markdown: \"\", blocks: [], warnings }\n }\n\n const root = doc.documentElement\n\n // ─── 메타데이터 추출 ──────────────────────────────────\n const metadata: DocumentMetadata = {}\n const docSummary = findChild(root, \"DOCSUMMARY\")\n if (docSummary) {\n const title = findChild(docSummary, \"TITLE\")\n const author = findChild(docSummary, \"AUTHOR\")\n const date = findChild(docSummary, \"DATE\")\n if (title) metadata.title = textContent(title).trim()\n if (author) metadata.author = textContent(author).trim()\n if (date) metadata.createdAt = textContent(date).trim() || undefined\n }\n\n // ─── HEAD: ParaShape 맵 구축 ──────────────────────────\n const paraShapeMap = buildParaShapeMap(root)\n\n // ─── BODY 파싱 ────────────────────────────────────────\n const body = findChild(root, \"BODY\")\n if (!body) {\n return { markdown: \"\", blocks: [], metadata, warnings }\n }\n\n const blocks: IRBlock[] = []\n const pageFilter = options?.pages ? parsePageRange(options.pages, countSections(body)) : null\n let sectionIdx = 0\n\n const children = body.childNodes\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType !== 1) continue\n if (localName(el) !== \"SECTION\") continue\n\n sectionIdx++\n if (pageFilter && !pageFilter.has(sectionIdx)) continue\n\n parseSection(el, blocks, paraShapeMap, sectionIdx, warnings)\n }\n\n // ─── 헤딩 트리(outline) 구성 ──────────────────────────\n const outline: OutlineItem[] = blocks\n .filter(b => b.type === \"heading\" && b.text)\n .map(b => ({ level: b.level ?? 1, text: b.text!, pageNumber: b.pageNumber }))\n\n const markdown = blocksToMarkdown(blocks)\n return {\n markdown,\n blocks,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n outline: outline.length > 0 ? outline : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n\n// ─── ParaShape 맵 ────────────────────────────────────────\n\nfunction buildParaShapeMap(root: Element): Map<string, ParaShapeInfo> {\n const map = new Map<string, ParaShapeInfo>()\n const head = findChild(root, \"HEAD\")\n if (!head) return map\n\n const mappingTable = findChild(head, \"MAPPINGTABLE\")\n if (!mappingTable) return map\n\n const paraShapeList = findChild(mappingTable, \"PARASHAPELIST\")\n if (!paraShapeList) return map\n\n const children = paraShapeList.childNodes\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType !== 1 || localName(el) !== \"PARASHAPE\") continue\n const id = el.getAttribute(\"Id\") ?? \"\"\n const headingType = el.getAttribute(\"HeadingType\") ?? \"None\"\n const level = parseInt(el.getAttribute(\"Level\") ?? \"0\", 10)\n let headingLevel: number | null = null\n if (headingType === \"Outline\") {\n const safeLevel = isNaN(level) ? 0 : Math.max(0, level)\n headingLevel = Math.min(safeLevel + 1, 6) // Level 0→H1, 1→H2, ..., 5→H6\n }\n map.set(id, { headingLevel })\n }\n\n return map\n}\n\n// ─── 섹션 파싱 ───────────────────────────────────────────\n\nfunction parseSection(\n section: Element,\n blocks: IRBlock[],\n paraShapeMap: Map<string, ParaShapeInfo>,\n sectionNum: number,\n warnings: ParseWarning[],\n): void {\n walkContent(section, blocks, paraShapeMap, sectionNum, warnings, false)\n}\n\n/**\n * 콘텐츠 노드를 재귀적으로 순회하여 IRBlock 생성.\n * inHeaderFooter=true일 때 단락/표 블록 출력 억제.\n */\nfunction walkContent(\n node: Element,\n blocks: IRBlock[],\n paraShapeMap: Map<string, ParaShapeInfo>,\n sectionNum: number,\n warnings: ParseWarning[],\n inHeaderFooter: boolean,\n depth: number = 0,\n): void {\n if (depth > MAX_XML_DEPTH) return\n const children = node.childNodes\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType !== 1) continue\n const tag = localName(el)\n\n if (tag === \"HEADER\" || tag === \"FOOTER\") {\n // 머리글/바닥글 — 텍스트 콘텐츠 무시\n continue\n }\n\n if (tag === \"P\") {\n if (!inHeaderFooter) {\n parseParagraph(el, blocks, paraShapeMap, sectionNum)\n }\n continue\n }\n\n if (tag === \"TABLE\") {\n if (!inHeaderFooter) {\n parseTable(el, blocks, paraShapeMap, sectionNum, warnings)\n }\n continue\n }\n\n // PARALIST, SUBLIST, SECTION 내부 등 — 재귀\n if (tag === \"PARALIST\" || tag === \"SECTION\" || tag === \"COLDEF\") {\n walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, depth + 1)\n continue\n }\n\n // TEXT, SECDEF 등 내부에서도 P/TABLE이 중첩될 수 있음 — 재귀\n walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, depth + 1)\n }\n}\n\n// ─── 단락 파싱 ───────────────────────────────────────────\n\nfunction parseParagraph(\n el: Element,\n blocks: IRBlock[],\n paraShapeMap: Map<string, ParaShapeInfo>,\n sectionNum: number,\n): void {\n const paraShapeId = el.getAttribute(\"ParaShape\") ?? \"\"\n const shapeInfo = paraShapeMap.get(paraShapeId)\n\n const text = extractParagraphText(el)\n if (!text) return\n\n if (shapeInfo?.headingLevel != null) {\n blocks.push({ type: \"heading\", text, level: shapeInfo.headingLevel, pageNumber: sectionNum })\n } else {\n blocks.push({ type: \"paragraph\", text, pageNumber: sectionNum })\n }\n}\n\n/** <P> 에서 텍스트 추출 — <TEXT><CHAR> 순회 */\nfunction extractParagraphText(p: Element): string {\n const parts: string[] = []\n collectCharText(p, parts)\n return parts.join(\"\").trim()\n}\n\nfunction collectCharText(node: Element, parts: string[], depth: number = 0): void {\n if (depth > MAX_XML_DEPTH) return\n const children = node.childNodes\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType !== 1) continue\n const tag = localName(el)\n\n if (tag === \"CHAR\") {\n // textContent — 자식 텍스트 노드 직접 수집\n const t = textContent(el)\n if (t) parts.push(t)\n } else if (tag === \"TABLE\" || tag === \"PICTURE\" || tag === \"SHAPEOBJECT\") {\n // 단락 내 테이블/이미지는 별도 블록으로 처리되므로 스킵\n } else if (tag === \"AUTONUM\") {\n // 자동 번호 (페이지 번호 등) 스킵\n } else {\n collectCharText(el, parts, depth + 1)\n }\n }\n}\n\n// ─── 테이블 파싱 ─────────────────────────────────────────\n\nfunction parseTable(\n el: Element,\n blocks: IRBlock[],\n paraShapeMap: Map<string, ParaShapeInfo>,\n sectionNum: number,\n warnings: ParseWarning[],\n): void {\n const cells: CellContext[] = []\n const rowCount = parseInt(el.getAttribute(\"RowCount\") ?? \"0\", 10)\n const colCount = parseInt(el.getAttribute(\"ColCount\") ?? \"0\", 10)\n if (isNaN(rowCount) || isNaN(colCount) || rowCount === 0 || colCount === 0) return\n if (rowCount > MAX_TABLE_ROWS || colCount > MAX_TABLE_COLS) {\n warnings.push({ message: `테이블 크기 초과 (${rowCount}x${colCount}) — 스킵`, code: \"TRUNCATED_TABLE\" })\n return\n }\n\n // <ROW> → <CELL> 순회\n const children = el.childNodes\n for (let i = 0; i < children.length; i++) {\n const rowEl = children[i] as Element\n if (rowEl.nodeType !== 1 || localName(rowEl) !== \"ROW\") continue\n\n const rowCells = rowEl.childNodes\n for (let j = 0; j < rowCells.length; j++) {\n const cellEl = rowCells[j] as Element\n if (cellEl.nodeType !== 1 || localName(cellEl) !== \"CELL\") continue\n\n const colAddr = parseInt(cellEl.getAttribute(\"ColAddr\") ?? \"0\", 10)\n const rowAddr = parseInt(cellEl.getAttribute(\"RowAddr\") ?? \"0\", 10)\n // colSpan/rowSpan 클램핑: NaN, 음수, 과대값 방어\n const colSpan = Math.min(Math.max(1, parseInt(cellEl.getAttribute(\"ColSpan\") ?? \"1\", 10) || 1), MAX_TABLE_COLS)\n const rowSpan = Math.min(Math.max(1, parseInt(cellEl.getAttribute(\"RowSpan\") ?? \"1\", 10) || 1), MAX_TABLE_ROWS)\n\n // 셀 텍스트: PARALIST > P 재귀 추출\n const cellText = extractCellText(cellEl)\n\n cells.push({ text: cellText, colSpan, rowSpan, colAddr, rowAddr })\n }\n }\n\n if (cells.length === 0) return\n\n // 그리드 배치 (HWP5와 동일한 방식 — colAddr/rowAddr 사용)\n const grid: (CellContext | null)[][] = Array.from({ length: rowCount }, () => Array(colCount).fill(null))\n for (const cell of cells) {\n const r = cell.rowAddr ?? 0\n const c = cell.colAddr ?? 0\n if (isNaN(r) || isNaN(c) || r >= rowCount || c >= colCount) continue\n grid[r][c] = cell\n for (let dr = 0; dr < cell.rowSpan; dr++) {\n for (let dc = 0; dc < cell.colSpan; dc++) {\n if (dr === 0 && dc === 0) continue\n if (r + dr < rowCount && c + dc < colCount) {\n grid[r + dr][c + dc] = { text: \"\", colSpan: 1, rowSpan: 1 }\n }\n }\n }\n }\n\n const cellRows: CellContext[][] = grid.map(row =>\n row.map(cell => cell ?? { text: \"\", colSpan: 1, rowSpan: 1 })\n )\n\n const table = buildTable(cellRows)\n blocks.push({ type: \"table\", table, pageNumber: sectionNum })\n}\n\n/** 셀 내부 텍스트 추출 — PARALIST > P 재귀, 중첩 테이블은 평탄화 */\nfunction extractCellText(cellEl: Element): string {\n const textParts: string[] = []\n collectCellText(cellEl, textParts, 0)\n return textParts.filter(Boolean).join(\"\\n\").trim()\n}\n\nfunction collectCellText(node: Element, parts: string[], depth: number): void {\n if (depth > 20) return\n const children = node.childNodes\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType !== 1) continue\n const tag = localName(el)\n\n if (tag === \"P\") {\n const t = extractParagraphText(el)\n if (t) parts.push(t)\n } else if (tag === \"TABLE\") {\n // 중첩 테이블 — 텍스트로 평탄화\n parts.push(\"[중첩 테이블]\")\n } else {\n collectCellText(el, parts, depth + 1)\n }\n }\n}\n\n// ─── XML 유틸 ────────────────────────────────────────────\n\nfunction localName(el: Element): string {\n return (el.tagName || el.localName || \"\").replace(/^[^:]+:/, \"\")\n}\n\nfunction findChild(parent: Element, tag: string): Element | null {\n const children = parent.childNodes\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType === 1 && localName(el) === tag) return el\n }\n return null\n}\n\nfunction textContent(el: Element): string {\n const children = el.childNodes\n const parts: string[] = []\n for (let i = 0; i < children.length; i++) {\n const node = children[i]\n if (node.nodeType === 3) { // TEXT_NODE\n parts.push(node.nodeValue || \"\")\n } else if (node.nodeType === 1) {\n parts.push(textContent(node as Element))\n }\n }\n return parts.join(\"\")\n}\n\nfunction countSections(body: Element): number {\n let count = 0\n const children = body.childNodes\n for (let i = 0; i < children.length; i++) {\n const el = children[i] as Element\n if (el.nodeType === 1 && localName(el) === \"SECTION\") count++\n }\n return count\n}\n","/** 양식(서식) 필드 인식 — 테이블 기반 label-value 패턴 매칭 */\n\nimport type { IRBlock, IRTable, FormField, FormResult } from \"../types.js\"\n\n/** 한국 공문서 필드 라벨 키워드 */\nexport const LABEL_KEYWORDS = new Set([\n \"성명\", \"이름\", \"주소\", \"전화\", \"전화번호\", \"휴대폰\", \"핸드폰\", \"연락처\",\n \"생년월일\", \"주민등록번호\", \"소속\", \"직위\", \"직급\", \"부서\",\n \"이메일\", \"팩스\", \"학교\", \"학년\", \"반\", \"번호\",\n \"신청인\", \"대표자\", \"담당자\", \"작성자\", \"확인자\", \"승인자\",\n \"일시\", \"날짜\", \"기간\", \"장소\", \"목적\", \"사유\", \"비고\",\n \"금액\", \"수량\", \"단가\", \"합계\", \"계\", \"소계\",\n \"등록기준지\", \"본적\", \"위임인\", \"청구사유\", \"소명자료\",\n])\n\n/** 라벨처럼 보이는 셀인지 판별 */\nexport function isLabelCell(text: string): boolean {\n // 각주 번호/특수문자 제거 후 판별 (예: \"등록기준지²\" → \"등록기준지\")\n const trimmed = text.trim().replace(/[¹²³⁴⁵⁶⁷⁸⁹⁰*※]+$/g, \"\").trim()\n if (!trimmed || trimmed.length > 30) return false\n // 키워드 매칭\n for (const kw of LABEL_KEYWORDS) {\n if (trimmed.includes(kw)) return true\n }\n // 짧은 한글 텍스트 (2-8자) + 숫자 없음 (공백/괄호/특수기호 허용)\n if (/^[가-힣\\s()()·::]+$/.test(trimmed) && trimmed.replace(/\\s/g, \"\").length >= 2 && trimmed.replace(/\\s/g, \"\").length <= 8 && !/\\d/.test(trimmed)) return true\n // \"라벨:\" 패턴\n if (/^[가-힣A-Za-z\\s]+[::]$/.test(trimmed)) return true\n return false\n}\n\n/**\n * IRBlock[]에서 양식 필드를 인식하여 추출.\n * 테이블의 label-value 패턴을 감지.\n */\nexport function extractFormFields(blocks: IRBlock[]): FormResult {\n const fields: FormField[] = []\n let totalTables = 0\n let formTables = 0\n\n for (const block of blocks) {\n if (block.type !== \"table\" || !block.table) continue\n totalTables++\n\n const tableFields = extractFromTable(block.table)\n if (tableFields.length > 0) {\n formTables++\n fields.push(...tableFields)\n }\n }\n\n // 인라인 \"라벨: 값\" 패턴도 검사 (paragraph만 — heading/list는 양식 필드가 아님)\n for (const block of blocks) {\n if (block.type === \"paragraph\" && block.text) {\n const inlineFields = extractInlineFields(block.text)\n fields.push(...inlineFields)\n }\n }\n\n const confidence = totalTables > 0 ? formTables / totalTables : (fields.length > 0 ? 0.3 : 0)\n return { fields, confidence: Math.min(confidence, 1) }\n}\n\nfunction extractFromTable(table: IRTable): FormField[] {\n const fields: FormField[] = []\n\n // 전략 1: 인접셀 label-value (2열 이상 테이블)\n if (table.cols >= 2) {\n for (let r = 0; r < table.rows; r++) {\n for (let c = 0; c < table.cols - 1; c++) {\n const labelCell = table.cells[r][c]\n const valueCell = table.cells[r][c + 1]\n if (isLabelCell(labelCell.text)) {\n fields.push({\n label: labelCell.text.trim().replace(/[::]\\s*$/, \"\"),\n value: valueCell.text.trim(),\n row: r,\n col: c,\n })\n }\n }\n }\n }\n\n // 전략 2: 헤더+데이터 행 (첫 행이 전부 라벨이면)\n if (fields.length === 0 && table.rows >= 2 && table.cols >= 2) {\n const headerRow = table.cells[0]\n const allLabels = headerRow.every(cell => {\n const t = cell.text.trim()\n return t.length > 0 && t.length <= 20\n })\n if (allLabels) {\n for (let r = 1; r < table.rows; r++) {\n for (let c = 0; c < table.cols; c++) {\n const label = headerRow[c].text.trim()\n const value = table.cells[r][c].text.trim()\n if (label && value) {\n fields.push({ label, value, row: r, col: c })\n }\n }\n }\n }\n }\n\n return fields\n}\n\nfunction extractInlineFields(text: string): FormField[] {\n const fields: FormField[] = []\n // \"라벨: 값\" 또는 \"라벨 : 값\" 패턴\n const pattern = /([가-힣A-Za-z]{2,10})\\s*[::]\\s*([^\\n,;]{1,100})/g\n let match\n while ((match = pattern.exec(text)) !== null) {\n const label = match[1].trim()\n const value = match[2].trim()\n if (value) {\n fields.push({ label, value, row: -1, col: -1 })\n }\n }\n return fields\n}\n","/** 양식 필드 매칭 공용 유틸 — filler.ts, filler-hwpx.ts에서 공유 */\n\nimport { LABEL_KEYWORDS } from \"./recognize.js\"\n\n/** 라벨 정규화 — 콜론/공백/특수문자 제거, 비교용 */\nexport function normalizeLabel(label: string): string {\n return label.trim().replace(/[::\\s()()·]/g, \"\")\n}\n\n/**\n * 정규화된 셀 라벨과 입력 값 맵에서 최적 매칭 키를 찾음.\n *\n * 매칭 우선순위:\n * 1. 정확 매칭 (normalizedCellLabel === key)\n * 2. 접두사 기반 매칭 (60% 이상 겹침 필요)\n */\nexport function findMatchingKey(\n cellLabel: string,\n values: Map<string, string>,\n): string | undefined {\n // 1) 정확 매칭\n if (values.has(cellLabel)) return cellLabel\n\n // 2) 접두사 기반 매칭 — 가장 긴 매칭 우선 (= 가장 구체적)\n // 단, 길이 비율 60% 이상 겹쳐야 매칭 (오탐 방지)\n let bestKey: string | undefined\n let bestLen = 0\n\n for (const key of values.keys()) {\n if (cellLabel.startsWith(key)) {\n if (key.length >= cellLabel.length * 0.6 && key.length > bestLen) {\n bestLen = key.length\n bestKey = key\n }\n } else if (key.startsWith(cellLabel)) {\n if (cellLabel.length >= key.length * 0.6 && cellLabel.length > bestLen) {\n bestLen = cellLabel.length\n bestKey = key\n }\n }\n }\n\n return bestKey\n}\n\n/**\n * 값 셀이 키워드 라벨(섹션 헤더의 하위 라벨)인지 판별.\n * \"성명\", \"주소\" 같은 키워드 라벨이면 true → 스킵 대상.\n * \"(한자:)\" 같은 어노테이션이면 false → 채울 수 있음.\n */\nexport function isKeywordLabel(text: string): boolean {\n const trimmed = text.trim().replace(/[¹²³⁴⁵⁶⁷⁸⁹⁰*※]+$/g, \"\").trim()\n if (!trimmed || trimmed.length > 15) return false\n for (const kw of LABEL_KEYWORDS) {\n if (trimmed.includes(kw)) return true\n }\n return false\n}\n\n/**\n * 셀 텍스트에서 인셀 패턴을 찾아 교체 — 체크박스 + 괄호 빈칸.\n *\n * 지원 패턴:\n * 1. 괄호 빈칸: `일반( )통` → 키 \"일반통\" 또는 \"일반\" 매칭 시 → `일반(값)통`\n * 2. 체크박스: `□부` → 키 \"부\" 매칭 시 → `☑부` (값이 \"☑\",\"✓\",\"v\",\"V\",\"true\",\"1\" 등)\n *\n * @returns 교체된 텍스트 + 매칭된 키 목록. null이면 교체 없음.\n */\nexport function fillInCellPatterns(\n cellText: string,\n values: Map<string, string>,\n matchedLabels: Set<string>,\n): { text: string; matches: Array<{ key: string; label: string; value: string }> } | null {\n let text = cellText\n const matches: Array<{ key: string; label: string; value: string }> = []\n\n // 1) 괄호 빈칸: keyword(\\s+)suffix → keyword(value)suffix\n text = text.replace(\n /([가-힣A-Za-z]+)\\(\\s{1,}\\)([가-힣A-Za-z]*)/g,\n (match, prefix: string, suffix: string) => {\n const label = prefix + suffix // \"일반\" + \"통\" = \"일반통\"\n const normalizedLabel = normalizeLabel(label)\n // 정확 매칭 → 접두사만 매칭 순\n const matchKey = values.has(normalizedLabel)\n ? normalizedLabel\n : values.has(normalizeLabel(prefix))\n ? normalizeLabel(prefix)\n : undefined\n if (matchKey === undefined) return match\n\n const newValue = values.get(matchKey)!\n matchedLabels.add(matchKey)\n matches.push({ key: matchKey, label, value: newValue })\n return `${prefix}(${newValue})${suffix}`\n },\n )\n\n // 2) 체크박스: □keyword → ☑keyword (값이 truthy)\n text = text.replace(\n /□([가-힣A-Za-z]+)/g,\n (match, keyword: string) => {\n const normalizedKw = normalizeLabel(keyword)\n const matchKey = values.has(normalizedKw) ? normalizedKw : undefined\n if (matchKey === undefined) return match\n\n const val = values.get(matchKey)!\n const isTruthy = [\"☑\", \"✓\", \"✔\", \"v\", \"V\", \"true\", \"1\", \"yes\", \"o\", \"O\"].includes(val.trim()) || val.trim() === \"\"\n if (!isTruthy) return match\n\n matchedLabels.add(matchKey)\n matches.push({ key: matchKey, label: `□${keyword}`, value: \"☑\" })\n return `☑${keyword}`\n },\n )\n\n // 3) 어노테이션 빈칸: (keyword:\\s+) → (keyword:value)\n // 예: \"(한자: )\" → \"(한자:金民秀)\"\n // 예: \"(성명: )\" → \"(성명: 홍길동)\"\n text = text.replace(\n /\\(([가-힣A-Za-z]+)[::]\\s{1,}\\)/g,\n (match, keyword: string) => {\n const normalizedKw = normalizeLabel(keyword)\n const matchKey = values.has(normalizedKw) ? normalizedKw : undefined\n if (matchKey === undefined) return match\n\n const newValue = values.get(matchKey)!\n matchedLabels.add(matchKey)\n matches.push({ key: matchKey, label: keyword, value: newValue })\n return `(${keyword}:${newValue})`\n },\n )\n\n return matches.length > 0 ? { text, matches } : null\n}\n\n/** 입력 values 맵을 정규화된 키로 변환 */\nexport function normalizeValues(values: Record<string, string>): Map<string, string> {\n const map = new Map<string, string>()\n for (const [label, value] of Object.entries(values)) {\n map.set(normalizeLabel(label), value)\n }\n return map\n}\n\n/** 매칭 안 된 라벨을 원본 키로 복원 */\nexport function resolveUnmatched(\n normalizedValues: Map<string, string>,\n matchedLabels: Set<string>,\n originalValues: Record<string, string>,\n): string[] {\n return [...normalizedValues.keys()]\n .filter(k => !matchedLabels.has(k))\n .map(k => {\n for (const orig of Object.keys(originalValues)) {\n if (normalizeLabel(orig) === k) return orig\n }\n return k\n })\n}\n","/** 양식 서식 필드 값 채우기 — IRBlock[] 기반 in-place 교체 */\n\nimport type { IRBlock, IRTable, FormField } from \"../types.js\"\nimport { isLabelCell } from \"./recognize.js\"\nimport { normalizeLabel, findMatchingKey, normalizeValues, resolveUnmatched, isKeywordLabel, fillInCellPatterns } from \"./match.js\"\n\n/** 필드 채우기 결과 */\nexport interface FillResult {\n /** 값이 교체된 IRBlock[] */\n blocks: IRBlock[]\n /** 실제 채워진 필드 목록 */\n filled: FormField[]\n /** 매칭 실패한 라벨 (입력에는 있지만 서식에서 못 찾은 것) */\n unmatched: string[]\n}\n\n/**\n * IRBlock[]에서 양식 필드를 찾아 값을 교체.\n *\n * @param blocks 원본 IRBlock[] (변경하지 않음 — deep clone)\n * @param values 채울 값 맵 (라벨 → 새 값). 라벨은 접두사 매칭 지원.\n * @returns FillResult\n *\n * @example\n * ```ts\n * const result = await parse(\"신청서.hwp\")\n * if (!result.success) throw new Error(result.error)\n * const { blocks, filled } = fillFormFields(result.blocks, {\n * \"성명\": \"홍길동\",\n * \"전화번호\": \"010-1234-5678\",\n * \"주소\": \"서울시 강남구\",\n * })\n * ```\n */\nexport function fillFormFields(\n blocks: IRBlock[],\n values: Record<string, string>,\n): FillResult {\n // deep clone — 원본 불변\n const cloned = structuredClone(blocks)\n const filled: FormField[] = []\n const matchedLabels = new Set<string>()\n\n const normalizedValues = normalizeValues(values)\n\n // 1) 인셀 패턴 먼저 (체크박스, 괄호 빈칸, 어노테이션) — 전략 2가 덮어쓰기 전에\n const patternFilledCells = new Set<string>() // \"r,c\" 키\n for (const block of cloned) {\n if (block.type !== \"table\" || !block.table) continue\n for (let r = 0; r < block.table.rows; r++) {\n for (let c = 0; c < block.table.cols; c++) {\n const cell = block.table.cells[r]?.[c]\n if (!cell) continue\n const result = fillInCellPatterns(cell.text, normalizedValues, matchedLabels)\n if (result) {\n cell.text = result.text\n patternFilledCells.add(`${r},${c}`)\n for (const m of result.matches) {\n filled.push({ label: m.label, value: m.value, row: r, col: c })\n }\n }\n }\n }\n }\n\n // 2) 테이블 기반 필드 교체 (라벨-값 셀 패턴)\n for (const block of cloned) {\n if (block.type !== \"table\" || !block.table) continue\n fillTable(block.table, normalizedValues, filled, matchedLabels, patternFilledCells)\n }\n\n // 3) 인라인 \"라벨: 값\" 패턴 교체\n for (const block of cloned) {\n if (block.type !== \"paragraph\" || !block.text) continue\n const newText = fillInlineFields(block.text, normalizedValues, filled, matchedLabels)\n if (newText !== block.text) block.text = newText\n }\n\n const unmatched = resolveUnmatched(normalizedValues, matchedLabels, values)\n return { blocks: cloned, filled, unmatched }\n}\n\n/** 테이블 셀에서 라벨-값 패턴을 찾아 값 교체 */\nfunction fillTable(\n table: IRTable,\n values: Map<string, string>,\n filled: FormField[],\n matchedLabels: Set<string>,\n patternFilledCells?: Set<string>,\n): void {\n if (table.cols < 2) return\n\n // 전략 1: 인접 라벨-값 셀 패턴\n for (let r = 0; r < table.rows; r++) {\n for (let c = 0; c < table.cols - 1; c++) {\n const labelCell = table.cells[r][c]\n const valueCell = table.cells[r][c + 1]\n if (!labelCell || !valueCell) continue\n\n if (!isLabelCell(labelCell.text)) continue\n\n if (isKeywordLabel(valueCell.text)) continue\n\n const normalizedCellLabel = normalizeLabel(labelCell.text)\n if (!normalizedCellLabel) continue\n\n const matchKey = findMatchingKey(normalizedCellLabel, values)\n if (matchKey === undefined) continue\n\n const newValue = values.get(matchKey)!\n // 이미 인셀 패턴이 처리된 셀이면 앞에 삽입 (어노테이션 보존)\n if (patternFilledCells?.has(`${r},${c + 1}`)) {\n valueCell.text = newValue + \" \" + valueCell.text\n } else {\n valueCell.text = newValue\n }\n matchedLabels.add(matchKey)\n filled.push({\n label: labelCell.text.trim().replace(/[::]\\s*$/, \"\"),\n value: newValue,\n row: r,\n col: c,\n })\n }\n }\n\n // 전략 2: 헤더+데이터 행 패턴 (첫 행이 전부 라벨이면)\n // 전략 1에서 이미 채운 필드는 스킵 (matchedLabels 검사)\n if (table.rows >= 2 && table.cols >= 2) {\n const headerRow = table.cells[0]\n const allLabels = headerRow.every(cell => {\n const t = cell.text.trim()\n return t.length > 0 && t.length <= 20 && isLabelCell(t)\n })\n if (!allLabels) return\n\n for (let r = 1; r < table.rows; r++) {\n for (let c = 0; c < table.cols; c++) {\n const headerLabel = normalizeLabel(headerRow[c].text)\n const matchKey = findMatchingKey(headerLabel, values)\n if (matchKey === undefined) continue\n if (matchedLabels.has(matchKey)) continue\n\n const newValue = values.get(matchKey)!\n table.cells[r][c].text = newValue\n matchedLabels.add(matchKey)\n filled.push({\n label: headerRow[c].text.trim(),\n value: newValue,\n row: r,\n col: c,\n })\n }\n }\n }\n}\n\n/** 인라인 \"라벨: 값\" 패턴 교체 */\nfunction fillInlineFields(\n text: string,\n values: Map<string, string>,\n filled: FormField[],\n matchedLabels: Set<string>,\n): string {\n return text.replace(\n /([가-힣A-Za-z]{2,10})\\s*[::]\\s*([^\\n,;]{0,100})/g,\n (match, rawLabel: string, _oldValue: string) => {\n const normalized = normalizeLabel(rawLabel)\n const matchKey = findMatchingKey(normalized, values)\n if (matchKey === undefined) return match\n\n const newValue = values.get(matchKey)!\n matchedLabels.add(matchKey)\n filled.push({\n label: rawLabel.trim(),\n value: newValue,\n row: -1,\n col: -1,\n })\n return `${rawLabel}: ${newValue}`\n },\n )\n}\n","/**\n * HWPX 원본 서식 유지 채우기 — ZIP 내 section XML 직접 수정\n *\n * IRBlock 중간 표현을 거치지 않고, 원본 HWPX ZIP의 section XML에서\n * 테이블 셀 텍스트(<hp:t>)만 교체하여 모든 스타일을 보존합니다.\n */\n\nimport JSZip from \"jszip\"\nimport { DOMParser, XMLSerializer } from \"@xmldom/xmldom\"\nimport { isLabelCell } from \"../form/recognize.js\"\nimport { KordocError, stripDtd } from \"../utils.js\"\nimport { normalizeLabel, findMatchingKey, normalizeValues, resolveUnmatched, isKeywordLabel, fillInCellPatterns } from \"./match.js\"\nimport type { FormField } from \"../types.js\"\n\n/** 채우기 결과 */\nexport interface HwpxFillResult {\n /** 채워진 HWPX 바이너리 */\n buffer: ArrayBuffer\n /** 실제 채워진 필드 목록 */\n filled: FormField[]\n /** 매칭 실패한 라벨 */\n unmatched: string[]\n}\n\n/**\n * HWPX 원본을 직접 수정하여 서식 필드를 채움 — 스타일 100% 보존.\n *\n * @param hwpxBuffer 원본 HWPX 파일 버퍼\n * @param values 채울 값 맵 (라벨 → 값)\n * @returns HwpxFillResult\n */\nexport async function fillHwpx(\n hwpxBuffer: ArrayBuffer,\n values: Record<string, string>,\n): Promise<HwpxFillResult> {\n const zip = await JSZip.loadAsync(hwpxBuffer)\n const filled: FormField[] = []\n const matchedLabels = new Set<string>()\n\n const normalizedValues = normalizeValues(values)\n\n // section XML 파일 찾기\n const sectionFiles = Object.keys(zip.files)\n .filter(name => /[Ss]ection\\d+\\.xml$/i.test(name))\n .sort()\n\n if (sectionFiles.length === 0) {\n throw new KordocError(\"HWPX에서 섹션 파일을 찾을 수 없습니다\")\n }\n\n const xmlParser = new DOMParser()\n const xmlSerializer = new XMLSerializer()\n\n for (const sectionPath of sectionFiles) {\n const zipEntry = zip.file(sectionPath)\n if (!zipEntry) continue // null 방어\n\n const rawXml = await zipEntry.async(\"text\")\n const doc = xmlParser.parseFromString(stripDtd(rawXml), \"text/xml\")\n if (!doc.documentElement) continue\n\n let modified = false\n\n // 모든 테이블 요소 탐색\n const tables = findAllElements(doc.documentElement as unknown as Node, \"tbl\")\n\n // 전략 0: 인셀 패턴 채우기 — 전략 1보다 먼저 실행\n // (체크박스 □→☑, 괄호 빈칸 ( )→(값), 어노테이션 (한자:)→(한자:값))\n // 이렇게 해야 전략 1이 셀을 덮어쓸 때 어노테이션이 보존됨\n const cellPatternApplied = new Set<Element>()\n for (const tblEl of tables) {\n const allCells = findAllElements(tblEl, \"tc\")\n for (const tcEl of allCells) {\n const tNodes = collectCellTextNodes(tcEl)\n const fullText = tNodes.map(n => n.text).join(\"\")\n const result = fillInCellPatterns(fullText, normalizedValues, matchedLabels)\n if (!result) continue\n\n applyTextReplacements(tNodes, fullText, result.text)\n cellPatternApplied.add(tcEl)\n for (const m of result.matches) {\n filled.push({ label: m.label, value: m.value, row: -1, col: -1 })\n }\n modified = true\n }\n }\n\n for (const tblEl of tables) {\n const rows = findDirectChildren(tblEl, \"tr\")\n\n // 전략 1: 인접 라벨-값 셀 (label | value 패턴)\n for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {\n const trEl = rows[rowIdx]\n const cells = findDirectChildren(trEl, \"tc\")\n\n for (let colIdx = 0; colIdx < cells.length - 1; colIdx++) {\n const labelText = extractCellText(cells[colIdx])\n if (!isLabelCell(labelText)) continue\n\n const valueCell = cells[colIdx + 1]\n const valueText = extractCellText(valueCell)\n if (isKeywordLabel(valueText)) continue\n\n const normalizedCellLabel = normalizeLabel(labelText)\n if (!normalizedCellLabel) continue\n\n const matchKey = findMatchingKey(normalizedCellLabel, normalizedValues)\n if (matchKey === undefined) continue\n\n const newValue = normalizedValues.get(matchKey)!\n\n // 전략 0이 이미 어노테이션을 채웠다면, 값을 앞에 삽입 (어노테이션 보존)\n if (cellPatternApplied.has(valueCell)) {\n prependCellText(valueCell, newValue)\n } else {\n replaceCellText(valueCell, newValue)\n }\n matchedLabels.add(matchKey)\n filled.push({\n label: labelText.trim().replace(/[::]\\s*$/, \"\"),\n value: newValue,\n row: rowIdx,\n col: colIdx,\n })\n modified = true\n }\n }\n\n // 전략 2: 헤더+데이터 행 패턴 (첫 행이 전부 라벨이면)\n if (rows.length >= 2) {\n const headerCells = findDirectChildren(rows[0], \"tc\")\n const allLabels = headerCells.every(cell => {\n const t = extractCellText(cell).trim()\n return t.length > 0 && t.length <= 20 && isLabelCell(t)\n })\n\n if (allLabels) {\n for (let rowIdx = 1; rowIdx < rows.length; rowIdx++) {\n const dataCells = findDirectChildren(rows[rowIdx], \"tc\")\n for (let colIdx = 0; colIdx < Math.min(headerCells.length, dataCells.length); colIdx++) {\n const headerLabel = normalizeLabel(extractCellText(headerCells[colIdx]))\n const matchKey = findMatchingKey(headerLabel, normalizedValues)\n if (matchKey === undefined) continue\n if (matchedLabels.has(matchKey)) continue\n\n const newValue = normalizedValues.get(matchKey)!\n replaceCellText(dataCells[colIdx], newValue)\n matchedLabels.add(matchKey)\n filled.push({\n label: extractCellText(headerCells[colIdx]).trim(),\n value: newValue,\n row: rowIdx,\n col: colIdx,\n })\n modified = true\n }\n }\n }\n }\n }\n\n // 인라인 \"라벨: 값\" 패턴도 처리 (테이블 밖 paragraph)\n const allParagraphs = findAllElements(doc.documentElement as unknown as Node, \"p\")\n for (const pEl of allParagraphs) {\n if (isInsideTable(pEl)) continue\n\n // 모든 <hp:t> 텍스트를 위치 정보와 함께 수집\n const tNodes = collectTextNodes(pEl)\n const fullText = tNodes.map(n => n.text).join(\"\")\n\n const pattern = /([가-힣A-Za-z]{2,10})\\s*[::]\\s*([^\\n,;]{0,100})/g\n let match\n while ((match = pattern.exec(fullText)) !== null) {\n const rawLabel = match[1]\n const normalized = normalizeLabel(rawLabel)\n const matchKey = findMatchingKey(normalized, normalizedValues)\n if (matchKey === undefined) continue\n\n const newValue = normalizedValues.get(matchKey)!\n // 값 부분의 시작/끝 오프셋 계산\n const valueStart = match.index + match[0].length - match[2].length\n const valueEnd = match.index + match[0].length\n\n replaceTextRange(tNodes, valueStart, valueEnd, newValue)\n matchedLabels.add(matchKey)\n filled.push({ label: rawLabel.trim(), value: newValue, row: -1, col: -1 })\n modified = true\n // 교체 후 패턴 인덱스 조정 (텍스트 길이 변경됨) — 다음 매칭 건너뜀\n break\n }\n }\n\n if (modified) {\n const newXml = xmlSerializer.serializeToString(doc)\n zip.file(sectionPath, newXml)\n }\n }\n\n const unmatched = resolveUnmatched(normalizedValues, matchedLabels, values)\n const buffer = await zip.generateAsync({ type: \"arraybuffer\" })\n return { buffer, filled, unmatched }\n}\n\n// ─── XML 탐색 헬퍼 ──────────────────────────────────\n\n/** 로컬 태그명 추출 (네임스페이스 프리픽스 제거) */\nfunction localName(el: Element): string {\n return (el.tagName || el.localName || \"\").replace(/^[^:]+:/, \"\")\n}\n\n/** 문서 전체에서 특정 로컬 태그명의 요소를 재귀 탐색 */\nfunction findAllElements(node: Node, tagLocalName: string): Element[] {\n const result: Element[] = []\n const walk = (n: Node) => {\n const children = n.childNodes\n if (!children) return\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as Element\n if (child.nodeType !== 1) continue\n if (localName(child) === tagLocalName) result.push(child)\n walk(child)\n }\n }\n walk(node)\n return result\n}\n\n/** 직계 자식 중 특정 로컬 태그명 요소만 반환 */\nfunction findDirectChildren(parent: Node, tagLocalName: string): Element[] {\n const result: Element[] = []\n const children = parent.childNodes\n if (!children) return result\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as Element\n if (child.nodeType === 1 && localName(child) === tagLocalName) {\n result.push(child)\n }\n }\n return result\n}\n\n/** 요소가 <tbl> 안에 있는지 확인 (부모 체인 탐색) */\nfunction isInsideTable(el: Element): boolean {\n let parent = el.parentNode as Element | null\n while (parent) {\n if (parent.nodeType === 1 && localName(parent) === \"tbl\") return true\n parent = parent.parentNode as Element | null\n }\n return false\n}\n\n// ─── 셀 텍스트 추출/교체 ────────────────────────────\n\n/** 셀(<hp:tc>) 내 모든 <hp:t> 텍스트를 합쳐 반환 */\nfunction extractCellText(tcEl: Element): string {\n const parts: string[] = []\n const walk = (node: Node) => {\n const children = node.childNodes\n if (!children) return\n for (let i = 0; i < children.length; i++) {\n const child = children[i] as Element\n if (child.nodeType === 3) {\n parts.push(child.textContent || \"\")\n } else if (child.nodeType === 1) {\n const tag = localName(child)\n // subList는 tc 아래 p를 감싸는 컨테이너 — 반드시 순회\n if (tag === \"t\") walk(child)\n else if (tag === \"run\" || tag === \"r\" || tag === \"p\" || tag === \"subList\") walk(child)\n else if (tag === \"tab\") parts.push(\"\\t\")\n else if (tag === \"br\") parts.push(\"\\n\")\n }\n }\n }\n walk(tcEl)\n return parts.join(\"\")\n}\n\n/**\n * 셀(<hp:tc>)의 첫 번째 <hp:t> 앞에 텍스트를 삽입 — 어노테이션 보존.\n * 예: \"(한자:金民秀)\" → \"김민수 (한자:金民秀)\"\n */\nfunction prependCellText(tcEl: Element, text: string): void {\n const tElements = findAllElements(tcEl, \"t\")\n if (tElements.length === 0) return\n\n const firstT = tElements[0]\n const existing = firstT.textContent || \"\"\n clearChildren(firstT)\n firstT.appendChild(firstT.ownerDocument!.createTextNode(text + \" \" + existing))\n}\n\n/**\n * 셀(<hp:tc>) 내 텍스트를 새 값으로 교체 — 스타일 보존 전략:\n *\n * 1) 첫 번째 <hp:run>의 <hp:t>에 새 텍스트 설정\n * 2) 나머지 <hp:run>의 <hp:t>는 빈 문자열로\n * 3) 두 번째 이후 <hp:p>는 내용만 비움 (요소 유지 — HWPX 뷰어 호환)\n *\n * 이렇게 하면 첫 번째 run의 charPrIDRef(글꼴, 크기, 굵기 등)가 보존됨\n */\nfunction replaceCellText(tcEl: Element, newValue: string): void {\n const paragraphs = findAllElements(tcEl, \"p\")\n if (paragraphs.length === 0) return\n\n const firstP = paragraphs[0]\n const runs = findAllElements(firstP, \"run\").concat(findAllElements(firstP, \"r\"))\n\n if (runs.length > 0) {\n setRunText(runs[0], newValue)\n for (let i = 1; i < runs.length; i++) {\n setRunText(runs[i], \"\")\n }\n } else {\n const tElements = findAllElements(firstP, \"t\")\n if (tElements.length > 0) {\n clearChildren(tElements[0])\n tElements[0].appendChild(tElements[0].ownerDocument!.createTextNode(newValue))\n for (let i = 1; i < tElements.length; i++) {\n clearChildren(tElements[i])\n }\n }\n }\n\n // 두 번째 이후 paragraph — 내용만 비움\n for (let i = 1; i < paragraphs.length; i++) {\n const p = paragraphs[i]\n if (p.parentNode) {\n const pRuns = findAllElements(p, \"run\").concat(findAllElements(p, \"r\"))\n for (const run of pRuns) setRunText(run, \"\")\n const pTs = findAllElements(p, \"t\")\n for (const t of pTs) clearChildren(t)\n }\n }\n}\n\n/** <hp:run> 요소의 <hp:t> 텍스트를 교체 */\nfunction setRunText(runEl: Element, text: string): void {\n const tElements = findAllElements(runEl, \"t\")\n if (tElements.length > 0) {\n clearChildren(tElements[0])\n tElements[0].appendChild(tElements[0].ownerDocument!.createTextNode(text))\n for (let i = 1; i < tElements.length; i++) {\n clearChildren(tElements[i])\n }\n return\n }\n\n // <hp:t>가 없는 빈 run — 한컴오피스가 HWP→HWPX 변환 시 빈 셀의 run을\n // self-closing(<hp:run charPrIDRef=\"...\"/>)으로 만들면서 <hp:t>를 생략한다.\n // 이 경우 부모 run의 prefix/namespace를 따라 새로 생성해 추가한다.\n // 빈 문자열이면 굳이 노드를 만들지 않는다(다른 호출부에서 run을 비울 때 사용).\n if (!text) return\n\n const doc = runEl.ownerDocument!\n const ns = runEl.namespaceURI\n const qualifiedName = runEl.prefix ? `${runEl.prefix}:t` : \"t\"\n const tEl = ns\n ? doc.createElementNS(ns, qualifiedName)\n : doc.createElement(qualifiedName)\n tEl.appendChild(doc.createTextNode(text))\n runEl.appendChild(tEl)\n}\n\n/** 요소의 모든 자식 노드 제거 */\nfunction clearChildren(el: Element): void {\n while (el.firstChild) el.removeChild(el.firstChild)\n}\n\n// ─── 인라인 텍스트 교체 (분리된 <hp:t> 대응) ─────────\n\n/** <hp:t> 텍스트 노드와 글로벌 오프셋 정보 */\ninterface TextNodeInfo {\n /** <hp:t> 요소 */\n element: Element\n /** 이 요소의 텍스트 */\n text: string\n /** 전체 합산 텍스트에서의 시작 오프셋 */\n offset: number\n}\n\n/** paragraph 내 모든 <hp:t> 텍스트 노드를 오프셋과 함께 수집 */\nfunction collectTextNodes(pEl: Element): TextNodeInfo[] {\n const tElements = findAllElements(pEl, \"t\")\n const result: TextNodeInfo[] = []\n let offset = 0\n for (const t of tElements) {\n const text = t.textContent || \"\"\n result.push({ element: t, text, offset })\n offset += text.length\n }\n return result\n}\n\n/**\n * 여러 <hp:t>에 걸친 텍스트 범위를 새 값으로 교체.\n * 첫 번째 걸리는 <hp:t>에 교체 텍스트를 넣고, 나머지는 해당 범위만큼 잘라냄.\n */\nfunction replaceTextRange(\n tNodes: TextNodeInfo[],\n globalStart: number,\n globalEnd: number,\n newValue: string,\n): void {\n let replaced = false\n for (const node of tNodes) {\n const nodeStart = node.offset\n const nodeEnd = node.offset + node.text.length\n\n if (nodeEnd <= globalStart || nodeStart >= globalEnd) continue\n\n const localStart = Math.max(0, globalStart - nodeStart)\n const localEnd = Math.min(node.text.length, globalEnd - nodeStart)\n\n if (!replaced) {\n const before = node.text.slice(0, localStart)\n const after = node.text.slice(localEnd)\n const newText = before + newValue + after\n clearChildren(node.element)\n node.element.appendChild(node.element.ownerDocument!.createTextNode(newText))\n replaced = true\n } else {\n const before = node.text.slice(0, localStart)\n const after = node.text.slice(localEnd)\n const newText = before + after\n clearChildren(node.element)\n node.element.appendChild(node.element.ownerDocument!.createTextNode(newText))\n }\n }\n}\n\n// ─── 인셀 패턴 교체 (체크박스/괄호 빈칸) ─────────\n\n/** 셀(<hp:tc>) 내 모든 <hp:t> 텍스트 노드를 오프셋과 함께 수집 (subList 순회 포함) */\nfunction collectCellTextNodes(tcEl: Element): TextNodeInfo[] {\n const tElements = findAllElements(tcEl, \"t\")\n const result: TextNodeInfo[] = []\n let offset = 0\n for (const t of tElements) {\n const text = t.textContent || \"\"\n result.push({ element: t, text, offset })\n offset += text.length\n }\n return result\n}\n\n/**\n * 셀 내 <hp:t> 노드들의 텍스트를 원본→교체 결과에 맞춰 반영.\n * 각 노드가 원본 텍스트에서 차지하는 범위를 추적하고,\n * 교체된 텍스트에서 같은 비율의 영역을 할당.\n */\nfunction applyTextReplacements(\n tNodes: TextNodeInfo[],\n originalFull: string,\n replacedFull: string,\n): void {\n if (originalFull === replacedFull) return\n\n // 단일 <hp:t> 노드면 간단히 전체 교체\n if (tNodes.length === 1) {\n clearChildren(tNodes[0].element)\n tNodes[0].element.appendChild(\n tNodes[0].element.ownerDocument!.createTextNode(replacedFull),\n )\n return\n }\n\n // 여러 노드: diff를 노드 경계에 맞춰 적용\n // 변경된 부분의 시작 오프셋을 찾아서 해당 노드만 교체\n let diffStart = 0\n while (diffStart < originalFull.length && diffStart < replacedFull.length &&\n originalFull[diffStart] === replacedFull[diffStart]) {\n diffStart++\n }\n let diffEndOrig = originalFull.length\n let diffEndRepl = replacedFull.length\n while (diffEndOrig > diffStart && diffEndRepl > diffStart &&\n originalFull[diffEndOrig - 1] === replacedFull[diffEndRepl - 1]) {\n diffEndOrig--\n diffEndRepl--\n }\n\n // 변경된 범위를 포함하는 노드에 교체 적용\n const newPart = replacedFull.slice(diffStart, diffEndRepl)\n replaceTextRange(tNodes, diffStart, diffEndOrig, newPart)\n}\n","/**\n * Markdown → HWPX 역변환\n *\n * 지원: 헤딩(h1~h6), 단락, 볼드, 이탤릭, 인라인코드, 코드블록,\n * 순서/비순서 리스트, 수평선, 인용문, 테이블\n * jszip으로 HWPX ZIP 패키징.\n */\n\nimport JSZip from \"jszip\"\n\nconst NS_SECTION = \"http://www.hancom.co.kr/hwpml/2011/section\"\nconst NS_PARA = \"http://www.hancom.co.kr/hwpml/2011/paragraph\"\nconst NS_HEAD = \"http://www.hancom.co.kr/hwpml/2011/head\"\nconst NS_OPF = \"http://www.idpf.org/2007/opf/\"\nconst NS_HPF = \"http://www.hancom.co.kr/schema/2011/hpf\"\nconst NS_OCF = \"urn:oasis:names:tc:opendocument:xmlns:container\"\n\n// ─── 스타일 ID 매핑 ─────────────────────────────────\n// charPr: 0=본문, 1=볼드, 2=이탤릭, 3=볼드이탤릭, 4=인라인코드, 5=h1, 6=h2, 7=h3, 8=h4~h6\n// paraPr: 0=본문, 1=h1, 2=h2, 3=h3, 4=h4~h6, 5=코드블록, 6=인용문, 7=리스트\n\nconst CHAR_NORMAL = 0\nconst CHAR_BOLD = 1\nconst CHAR_ITALIC = 2\nconst CHAR_BOLD_ITALIC = 3\nconst CHAR_CODE = 4\nconst CHAR_H1 = 5\nconst CHAR_H2 = 6\nconst CHAR_H3 = 7\nconst CHAR_H4 = 8\n\nconst PARA_NORMAL = 0\nconst PARA_H1 = 1\nconst PARA_H2 = 2\nconst PARA_H3 = 3\nconst PARA_H4 = 4\nconst PARA_CODE = 5\nconst PARA_QUOTE = 6\nconst PARA_LIST = 7\n\n/**\n * 마크다운 텍스트를 HWPX (ArrayBuffer)로 변환.\n */\nexport async function markdownToHwpx(markdown: string): Promise<ArrayBuffer> {\n const blocks = parseMarkdownToBlocks(markdown)\n const sectionXml = blocksToSectionXml(blocks)\n\n const zip = new JSZip()\n zip.file(\"mimetype\", \"application/hwp+zip\", { compression: \"STORE\" })\n zip.file(\"META-INF/container.xml\", generateContainerXml())\n zip.file(\"Contents/content.hpf\", generateManifest())\n zip.file(\"Contents/header.xml\", generateHeaderXml())\n zip.file(\"Contents/section0.xml\", sectionXml)\n // Preview/ — 한글 프로그램의 일부 버전(특히 macOS)이 존재 여부를 확인함\n zip.file(\"Preview/PrvText.txt\", buildPrvText(blocks))\n\n return await zip.generateAsync({ type: \"arraybuffer\" })\n}\n\n/** Preview/PrvText.txt — 문서 앞부분 텍스트 스냅샷 (최대 1KB) */\nfunction buildPrvText(blocks: MdBlock[]): string {\n const lines: string[] = []\n let bytes = 0\n for (const b of blocks) {\n const text = b.text || (b.rows ? b.rows.map(r => r.join(\" \")).join(\"\\n\") : \"\")\n if (!text) continue\n lines.push(text)\n bytes += text.length * 3\n if (bytes > 1024) break\n }\n return lines.join(\"\\n\").slice(0, 1024)\n}\n\n// ─── 마크다운 파싱 ───────────────────────────────────\n\ninterface MdBlock {\n type: \"paragraph\" | \"heading\" | \"table\" | \"code_block\" | \"hr\" | \"blockquote\" | \"list_item\"\n text?: string\n level?: number\n rows?: string[][]\n lang?: string\n ordered?: boolean\n indent?: number\n}\n\nfunction parseMarkdownToBlocks(md: string): MdBlock[] {\n const lines = md.split(\"\\n\")\n const blocks: MdBlock[] = []\n let i = 0\n\n while (i < lines.length) {\n const line = lines[i]\n\n // 빈 줄 스킵\n if (!line.trim()) { i++; continue }\n\n // 코드블록\n const fenceMatch = line.match(/^(`{3,}|~{3,})(.*)$/)\n if (fenceMatch) {\n const fence = fenceMatch[1]\n const lang = fenceMatch[2].trim()\n const codeLines: string[] = []\n i++\n while (i < lines.length && !lines[i].startsWith(fence)) {\n codeLines.push(lines[i])\n i++\n }\n if (i < lines.length) i++ // 닫는 fence\n blocks.push({ type: \"code_block\", text: codeLines.join(\"\\n\"), lang })\n continue\n }\n\n // 수평선\n if (/^(\\*{3,}|-{3,}|_{3,})\\s*$/.test(line.trim())) {\n blocks.push({ type: \"hr\" })\n i++; continue\n }\n\n // 헤딩\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/)\n if (headingMatch) {\n blocks.push({ type: \"heading\", text: headingMatch[2].trim(), level: headingMatch[1].length })\n i++; continue\n }\n\n // 테이블\n if (line.trimStart().startsWith(\"|\")) {\n const tableRows: string[][] = []\n while (i < lines.length && lines[i].trimStart().startsWith(\"|\")) {\n const row = lines[i]\n if (/^[\\s|:\\-]+$/.test(row)) { i++; continue }\n const cells = row.split(\"|\").slice(1, -1).map(c => c.trim())\n if (cells.length > 0) tableRows.push(cells)\n i++\n }\n if (tableRows.length > 0) blocks.push({ type: \"table\", rows: tableRows })\n continue\n }\n\n // 인용문\n if (line.trimStart().startsWith(\"> \")) {\n const quoteLines: string[] = []\n while (i < lines.length && (lines[i].trimStart().startsWith(\"> \") || lines[i].trimStart().startsWith(\">\"))) {\n quoteLines.push(lines[i].replace(/^>\\s?/, \"\"))\n i++\n }\n for (const ql of quoteLines) {\n blocks.push({ type: \"blockquote\", text: ql.trim() || \"\" })\n }\n continue\n }\n\n // 리스트\n const listMatch = line.match(/^(\\s*)([-*+]|\\d+[.)]) (.+)$/)\n if (listMatch) {\n const indent = Math.floor(listMatch[1].length / 2)\n const ordered = /\\d/.test(listMatch[2])\n blocks.push({ type: \"list_item\", text: listMatch[3].trim(), ordered, indent })\n i++; continue\n }\n\n // 일반 단락\n blocks.push({ type: \"paragraph\", text: line.trim() })\n i++\n }\n\n return blocks\n}\n\n// ─── 인라인 마크다운 → 멀티 run ─────────────────────\n\ninterface InlineSpan {\n text: string\n bold: boolean\n italic: boolean\n code: boolean\n}\n\nfunction parseInlineMarkdown(text: string): InlineSpan[] {\n // 전처리: 마크다운 링크/이미지 → 텍스트만 추출\n text = text.replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, \"$1\") // ![alt](url) → alt\n text = text.replace(/\\[([^\\]]*)\\]\\(([^)]*)\\)/g, (_, t, u) => t || u) // [text](url) → text or url\n // 전처리: ~~취소선~~ → 텍스트만\n text = text.replace(/~~([^~]+)~~/g, \"$1\")\n\n const spans: InlineSpan[] = []\n // 패턴: `code`, ***bolditalic***, **bold**, *italic*, __bold__, _italic_\n const regex = /(`[^`]+`|\\*{3}[^*]+\\*{3}|\\*{2}[^*]+\\*{2}|\\*[^*]+\\*|_{2}[^_]+_{2}|_[^_]+_)/g\n let lastIdx = 0\n\n for (const match of text.matchAll(regex)) {\n const idx = match.index!\n if (idx > lastIdx) {\n spans.push({ text: text.slice(lastIdx, idx), bold: false, italic: false, code: false })\n }\n const raw = match[0]\n if (raw.startsWith(\"`\")) {\n spans.push({ text: raw.slice(1, -1), bold: false, italic: false, code: true })\n } else if (raw.startsWith(\"***\") || raw.startsWith(\"___\")) {\n spans.push({ text: raw.slice(3, -3), bold: true, italic: true, code: false })\n } else if (raw.startsWith(\"**\") || raw.startsWith(\"__\")) {\n spans.push({ text: raw.slice(2, -2), bold: true, italic: false, code: false })\n } else {\n spans.push({ text: raw.slice(1, -1), bold: false, italic: true, code: false })\n }\n lastIdx = idx + raw.length\n }\n if (lastIdx < text.length) {\n spans.push({ text: text.slice(lastIdx), bold: false, italic: false, code: false })\n }\n if (spans.length === 0) {\n spans.push({ text, bold: false, italic: false, code: false })\n }\n return spans\n}\n\nfunction spanToCharPrId(span: InlineSpan): number {\n if (span.code) return CHAR_CODE\n if (span.bold && span.italic) return CHAR_BOLD_ITALIC\n if (span.bold) return CHAR_BOLD\n if (span.italic) return CHAR_ITALIC\n return CHAR_NORMAL\n}\n\n// ─── XML 생성 헬퍼 ───────────────────────────────────\n\nfunction escapeXml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n}\n\nfunction generateRuns(text: string, defaultCharPr: number = CHAR_NORMAL): string {\n const spans = parseInlineMarkdown(text)\n return spans.map(span => {\n const charId = span.code || span.bold || span.italic ? spanToCharPrId(span) : defaultCharPr\n return `<hp:run charPrIDRef=\"${charId}\"><hp:t>${escapeXml(span.text)}</hp:t></hp:run>`\n }).join(\"\")\n}\n\nfunction generateParagraph(text: string, paraPrId: number = PARA_NORMAL, charPrId: number = CHAR_NORMAL): string {\n if (paraPrId === PARA_CODE) {\n // 코드블록은 인라인 파싱 안 함\n return `<hp:p paraPrIDRef=\"${paraPrId}\" styleIDRef=\"0\"><hp:run charPrIDRef=\"${CHAR_CODE}\"><hp:t>${escapeXml(text)}</hp:t></hp:run></hp:p>`\n }\n const runs = generateRuns(text, charPrId)\n return `<hp:p paraPrIDRef=\"${paraPrId}\" styleIDRef=\"0\">${runs}</hp:p>`\n}\n\nfunction headingParaPrId(level: number): number {\n if (level === 1) return PARA_H1\n if (level === 2) return PARA_H2\n if (level === 3) return PARA_H3\n return PARA_H4\n}\n\nfunction headingCharPrId(level: number): number {\n if (level === 1) return CHAR_H1\n if (level === 2) return CHAR_H2\n if (level === 3) return CHAR_H3\n return CHAR_H4\n}\n\n// ─── HWPX 구조 파일 생성 ─────────────────────────────\n\nfunction generateContainerXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n<ocf:container xmlns:ocf=\"${NS_OCF}\" xmlns:hpf=\"${NS_HPF}\">\n <ocf:rootfiles>\n <ocf:rootfile full-path=\"Contents/content.hpf\" media-type=\"application/hwpml-package+xml\"/>\n </ocf:rootfiles>\n</ocf:container>`\n}\n\nfunction generateManifest(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n<opf:package xmlns:opf=\"${NS_OPF}\" xmlns:hpf=\"${NS_HPF}\" xmlns:hh=\"${NS_HEAD}\">\n <opf:manifest>\n <opf:item id=\"header\" href=\"Contents/header.xml\" media-type=\"application/xml\"/>\n <opf:item id=\"section0\" href=\"Contents/section0.xml\" media-type=\"application/xml\"/>\n </opf:manifest>\n <opf:spine>\n <opf:itemref idref=\"header\" linear=\"no\"/>\n <opf:itemref idref=\"section0\" linear=\"yes\"/>\n </opf:spine>\n</opf:package>`\n}\n\n// ─── charPr 생성 헬퍼 ───────────────────────────────\n\nfunction charPr(id: number, height: number, bold: boolean, italic: boolean, fontId: number = 0): string {\n const boldAttr = bold ? ` bold=\"1\"` : \"\"\n const italicAttr = italic ? ` italic=\"1\"` : \"\"\n // 볼드면 fontfaces의 bold variant(id=2: HY견고딕/Arial Black, weight=9) 참조해\n // macOS 한컴에서 합성 굵기 안 되는 케이스 커버. 코드(fontId=1)는 bold 아닌 경우에만\n // 원본 id 유지 (Consolas/함초롬돋움).\n const effFont = bold ? 2 : fontId\n return ` <hh:charPr id=\"${id}\" height=\"${height}\" textColor=\"#000000\" shadeColor=\"none\" useFontSpace=\"0\" useKerning=\"0\" symMark=\"NONE\" borderFillIDRef=\"0\"${boldAttr}${italicAttr}>\n <hh:fontRef hangul=\"${effFont}\" latin=\"${effFont}\" hanja=\"${effFont}\" japanese=\"${effFont}\" other=\"${effFont}\" symbol=\"${effFont}\" user=\"${effFont}\"/>\n <hh:ratio hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/>\n <hh:spacing hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>\n <hh:relSz hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/>\n <hh:offset hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>\n </hh:charPr>`\n}\n\n// ─── paraPr 생성 헬퍼 ───────────────────────────────\n\nfunction paraPr(id: number, opts: { align?: string; spaceBefore?: number; spaceAfter?: number; lineSpacing?: number; indent?: number } = {}): string {\n const { align = \"JUSTIFY\", spaceBefore = 0, spaceAfter = 0, lineSpacing = 160, indent = 0 } = opts\n return ` <hh:paraPr id=\"${id}\" tabPrIDRef=\"0\" condense=\"0\" fontLineHeight=\"0\" snapToGrid=\"1\" suppressLineNumbers=\"0\" checked=\"0\" textDir=\"AUTO\">\n <hh:align horizontal=\"${align}\" vertical=\"BASELINE\"/>\n <hh:heading type=\"NONE\" idRef=\"0\" level=\"0\"/>\n <hh:breakSetting breakLatinWord=\"KEEP_WORD\" breakNonLatinWord=\"BREAK_WORD\" widowOrphan=\"0\" keepWithNext=\"0\" keepLines=\"0\" pageBreakBefore=\"0\" lineWrap=\"BREAK\"/>\n <hh:autoSpacing eAsianEng=\"0\" eAsianNum=\"0\"/>\n <hh:margin indent=\"${indent}\" left=\"0\" right=\"0\" prev=\"${spaceBefore}\" next=\"${spaceAfter}\"/>\n <hh:lineSpacing type=\"PERCENT\" value=\"${lineSpacing}\"/>\n <hh:border borderFillIDRef=\"0\" offsetLeft=\"0\" offsetRight=\"0\" offsetTop=\"0\" offsetBottom=\"0\" connect=\"0\" ignoreMargin=\"0\"/>\n </hh:paraPr>`\n}\n\nfunction generateHeaderXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n<hh:head xmlns:hh=\"${NS_HEAD}\" xmlns:hp=\"${NS_PARA}\" version=\"1.4\" secCnt=\"1\">\n <hh:beginNum page=\"1\" footnote=\"1\" endnote=\"1\" pic=\"1\" tbl=\"1\" equation=\"1\"/>\n <hh:refList>\n <hh:fontfaces itemCnt=\"7\">\n <hh:fontface lang=\"HANGUL\" fontCnt=\"3\">\n <hh:font id=\"0\" face=\"함초롬바탕\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"4\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n <hh:font id=\"1\" face=\"함초롬돋움\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"4\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n <hh:font id=\"2\" face=\"HY견고딕\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"9\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n </hh:fontface>\n <hh:fontface lang=\"LATIN\" fontCnt=\"3\">\n <hh:font id=\"0\" face=\"Times New Roman\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_OLDSTYLE\" weight=\"5\" proportion=\"4\" contrast=\"2\" strokeVariation=\"0\" armStyle=\"0\" letterform=\"0\" midline=\"0\" xHeight=\"4\"/>\n </hh:font>\n <hh:font id=\"1\" face=\"Consolas\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_MODERN\" weight=\"5\" proportion=\"0\" contrast=\"0\" strokeVariation=\"0\" armStyle=\"0\" letterform=\"0\" midline=\"0\" xHeight=\"0\"/>\n </hh:font>\n <hh:font id=\"2\" face=\"Arial Black\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"9\" proportion=\"0\" contrast=\"0\" strokeVariation=\"0\" armStyle=\"0\" letterform=\"0\" midline=\"0\" xHeight=\"0\"/>\n </hh:font>\n </hh:fontface>\n <hh:fontface lang=\"HANJA\" fontCnt=\"1\">\n <hh:font id=\"0\" face=\"함초롬바탕\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"4\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n </hh:fontface>\n <hh:fontface lang=\"JAPANESE\" fontCnt=\"1\">\n <hh:font id=\"0\" face=\"굴림\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n </hh:fontface>\n <hh:fontface lang=\"OTHER\" fontCnt=\"1\">\n <hh:font id=\"0\" face=\"굴림\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n </hh:fontface>\n <hh:fontface lang=\"SYMBOL\" fontCnt=\"1\">\n <hh:font id=\"0\" face=\"Symbol\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n </hh:fontface>\n <hh:fontface lang=\"USER\" fontCnt=\"1\">\n <hh:font id=\"0\" face=\"굴림\" type=\"TTF\" isEmbedded=\"0\">\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\n </hh:font>\n </hh:fontface>\n </hh:fontfaces>\n <hh:borderFills itemCnt=\"2\">\n <hh:borderFill id=\"0\" threeD=\"0\" shadow=\"0\" centerLine=\"0\" breakCellSeparateLine=\"0\">\n <hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\n <hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\n <hh:leftBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\n <hh:rightBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\n <hh:topBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\n <hh:bottomBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\n <hh:diagonal type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\n <hh:fillInfo/>\n </hh:borderFill>\n <hh:borderFill id=\"1\" threeD=\"0\" shadow=\"0\" centerLine=\"0\" breakCellSeparateLine=\"0\">\n <hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\n <hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\n <hh:leftBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\n <hh:rightBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\n <hh:topBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\n <hh:bottomBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\n <hh:diagonal type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\n <hh:fillInfo/>\n </hh:borderFill>\n </hh:borderFills>\n <hh:charProperties itemCnt=\"9\">\n${charPr(0, 1000, false, false)}\n${charPr(1, 1000, true, false)}\n${charPr(2, 1000, false, true)}\n${charPr(3, 1000, true, true)}\n${charPr(4, 900, false, false, 1)}\n${charPr(5, 1800, true, false, 1)}\n${charPr(6, 1400, true, false, 1)}\n${charPr(7, 1200, true, false, 1)}\n${charPr(8, 1100, true, false, 1)}\n </hh:charProperties>\n <hh:tabProperties itemCnt=\"0\"/>\n <hh:numberings itemCnt=\"0\"/>\n <hh:bullets itemCnt=\"0\"/>\n <hh:paraProperties itemCnt=\"8\">\n${paraPr(0)}\n${paraPr(1, { align: \"LEFT\", spaceBefore: 800, spaceAfter: 200, lineSpacing: 180 })}\n${paraPr(2, { align: \"LEFT\", spaceBefore: 600, spaceAfter: 150, lineSpacing: 170 })}\n${paraPr(3, { align: \"LEFT\", spaceBefore: 400, spaceAfter: 100, lineSpacing: 160 })}\n${paraPr(4, { align: \"LEFT\", spaceBefore: 300, spaceAfter: 100, lineSpacing: 160 })}\n${paraPr(5, { align: \"LEFT\", lineSpacing: 130, indent: 400 })}\n${paraPr(6, { align: \"LEFT\", lineSpacing: 150, indent: 600 })}\n${paraPr(7, { align: \"LEFT\", lineSpacing: 160, indent: 600 })}\n </hh:paraProperties>\n <hh:styles itemCnt=\"1\">\n <hh:style id=\"0\" type=\"PARA\" name=\"바탕글\" engName=\"Normal\" paraPrIDRef=\"0\" charPrIDRef=\"0\" nextStyleIDRef=\"0\" langIDRef=\"1042\" lockForm=\"0\"/>\n </hh:styles>\n </hh:refList>\n <hh:compatibleDocument targetProgram=\"HWP2018\"/>\n</hh:head>`\n}\n\n// ─── 섹션 속성 (공문서 표준 여백) ────────────────────\n\nfunction generateSecPr(): string {\n // A4: 210mm × 297mm → 59528 × 84188 HWPUNIT (1mm ≈ 283.46 HWPUNIT)\n // 공문서 표준: 위 30mm(8504), 아래 15mm(4252), 왼쪽 20mm(5670), 오른쪽 15mm(4252)\n // 머리말 10mm(2835), 꼬리말 10mm(2835)\n return `<hp:secPr textDirection=\"HORIZONTAL\" spaceColumns=\"1134\" tabStop=\"8000\" outlineShapeIDRef=\"0\" memoShapeIDRef=\"0\" textVerticalWidthHead=\"0\" masterPageCnt=\"0\">` +\n `<hp:grid lineGrid=\"0\" charGrid=\"0\" wonggojiFormat=\"0\"/>` +\n `<hp:startNum pageStartsOn=\"BOTH\" page=\"0\" pic=\"0\" tbl=\"0\" equation=\"0\"/>` +\n `<hp:visibility hideFirstHeader=\"0\" hideFirstFooter=\"0\" hideFirstMasterPage=\"0\" border=\"SHOW_ALL\" fill=\"SHOW_ALL\" hideFirstPageNum=\"0\" hideFirstEmptyLine=\"0\" showLineNumber=\"0\"/>` +\n `<hp:pagePr landscape=\"WIDELY\" width=\"59528\" height=\"84188\" gutterType=\"LEFT_ONLY\">` +\n `<hp:margin header=\"2835\" footer=\"2835\" gutter=\"0\" left=\"5670\" right=\"4252\" top=\"8504\" bottom=\"4252\"/>` +\n `</hp:pagePr>` +\n `<hp:footNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"-1\" type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"283\" belowLine=\"567\" aboveLine=\"850\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"EACH_COLUMN\" beneathText=\"0\"/></hp:footNotePr>` +\n `<hp:endNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"14692344\" type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"0\" belowLine=\"567\" aboveLine=\"850\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"END_OF_DOCUMENT\" beneathText=\"0\"/></hp:endNotePr>` +\n `</hp:secPr>`\n}\n\n// ─── 테이블 생성 ─────────────────────────────────────\n//\n// HWPX 스펙 완전 준수 버전 — 한글 프로그램(Windows/macOS)이 문서를 거부하지 않으려면\n// <hp:tbl> 필수 속성 + <hp:sz>/<hp:pos>/<hp:outMargin>/<hp:inMargin> + 각 cell의\n// <hp:subList> 래퍼, <hp:cellAddr>, <hp:cellSz>, <hp:cellMargin>이 전부 있어야 함.\n// 또한 테이블은 paragraph 안의 <hp:run><hp:ctrl>... 로 감싸야 한다.\n//\n// 이슈 #4 참고: v2.4.1 이전엔 최소 스켈레톤만 내서 macOS 한글이 \"파일이 깨졌다\"며 거부.\n\n// 기본 셀 크기 (HWPUnit) — A4 기준 적당한 기본값\nconst TABLE_ID_BASE = 1000\nlet tableIdCounter = TABLE_ID_BASE\nfunction nextTableId(): number { return ++tableIdCounter }\n\nfunction generateTable(rows: string[][]): string {\n const rowCnt = rows.length\n const colCnt = Math.max(...rows.map(r => r.length), 1)\n // A4 portrait: 폭 약 44000 HWPUnit 사용 가능 → colCnt로 균등 분배\n const cellW = Math.floor(44000 / colCnt)\n const cellH = 1500 // 기본 행 높이\n const tblW = cellW * colCnt\n const tblH = cellH * rowCnt\n\n const tblId = nextTableId()\n\n const trElements = rows.map((row, rowIdx) => {\n // 부족한 셀은 빈 문자열로 채워 colCnt 맞춤\n const cells = row.length < colCnt ? [...row, ...Array(colCnt - row.length).fill(\"\")] : row\n const tdElements = cells.map((cell, colIdx) => {\n const runs = generateRuns(cell)\n const p = `<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\">${runs}</hp:p>`\n // <hp:tc> 필수 속성 + subList + cellAddr + cellSpan + cellSz + cellMargin\n return `<hp:tc name=\"\" header=\"${rowIdx === 0 ? 1 : 0}\" hasMargin=\"0\" protect=\"0\" editable=\"1\" dirty=\"0\" borderFillIDRef=\"1\">`\n + `<hp:subList id=\"\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"TOP\" linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"0\" textHeight=\"0\" hasTextRef=\"0\" hasNumRef=\"0\">${p}</hp:subList>`\n + `<hp:cellAddr colAddr=\"${colIdx}\" rowAddr=\"${rowIdx}\"/>`\n + `<hp:cellSpan colSpan=\"1\" rowSpan=\"1\"/>`\n + `<hp:cellSz width=\"${cellW}\" height=\"${cellH}\"/>`\n + `<hp:cellMargin left=\"141\" right=\"141\" top=\"141\" bottom=\"141\"/>`\n + `</hp:tc>`\n }).join(\"\")\n return `<hp:tr>${tdElements}</hp:tr>`\n }).join(\"\")\n\n // <hp:tbl>에 필수 속성 + <hp:sz>/<hp:outMargin>/<hp:inMargin> (pos는 inline-level 기준)\n const tblInner = `<hp:sz width=\"${tblW}\" widthRelTo=\"ABSOLUTE\" height=\"${tblH}\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/>`\n + `<hp:pos treatAsChar=\"1\" affectLSpacing=\"0\" flowWithText=\"0\" allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" vertAlign=\"TOP\" horzAlign=\"LEFT\" vertOffset=\"0\" horzOffset=\"0\"/>`\n + `<hp:outMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/>`\n + `<hp:inMargin left=\"510\" right=\"510\" top=\"141\" bottom=\"141\"/>`\n + trElements\n\n const tbl = `<hp:tbl id=\"${tblId}\" zOrder=\"0\" numberingType=\"TABLE\" pageBreak=\"CELL\" repeatHeader=\"0\" rowCnt=\"${rowCnt}\" colCnt=\"${colCnt}\" cellSpacing=\"0\" borderFillIDRef=\"1\" noShading=\"0\">${tblInner}</hp:tbl>`\n\n // 테이블은 paragraph 안의 run → 가 아니라 별도 p로 감쌈 (block-level inline-anchored)\n return `<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\"><hp:run charPrIDRef=\"0\">${tbl}</hp:run></hp:p>`\n}\n\n// ─── 섹션 XML 생성 ──────────────────────────────────\n\nfunction blocksToSectionXml(blocks: MdBlock[]): string {\n const paraXmls: string[] = []\n let isFirst = true\n // 순서 있는 목록 카운터 — indent 레벨별 별도 유지. 다른 블록 만나면 해당 레벨 리셋.\n const orderedCounters: Record<number, number> = {}\n let prevWasOrdered = false\n\n for (const block of blocks) {\n let xml = \"\"\n\n // 순서 있는 list_item이 아니면 카운터 전부 리셋 (연속되지 않은 목록은 다시 1부터)\n if (block.type !== \"list_item\" || !block.ordered) {\n if (prevWasOrdered) {\n for (const k of Object.keys(orderedCounters)) delete orderedCounters[+k]\n }\n prevWasOrdered = false\n }\n\n switch (block.type) {\n case \"heading\": {\n const pId = headingParaPrId(block.level || 1)\n const cId = headingCharPrId(block.level || 1)\n xml = generateParagraph(block.text || \"\", pId, cId)\n break\n }\n case \"paragraph\":\n xml = generateParagraph(block.text || \"\")\n break\n case \"code_block\": {\n const codeLines = (block.text || \"\").split(\"\\n\")\n xml = codeLines.map(line => generateParagraph(line || \" \", PARA_CODE)).join(\"\\n \")\n break\n }\n case \"blockquote\":\n xml = generateParagraph(block.text || \"\", PARA_QUOTE)\n break\n case \"list_item\": {\n const indent = block.indent || 0\n let marker: string\n if (block.ordered) {\n // 러닝 카운터: indent 레벨별로 증가. 하위 레벨(더 깊은 indent)은 별도 세퀀스.\n orderedCounters[indent] = (orderedCounters[indent] || 0) + 1\n // 상위 레벨 번호가 바뀌면 하위는 자동 리셋되어야 함 — 한 레벨 위로 올라갈 때 하위 카운터 초기화\n for (const k of Object.keys(orderedCounters)) {\n if (+k > indent) delete orderedCounters[+k]\n }\n marker = `${orderedCounters[indent]}. `\n prevWasOrdered = true\n } else {\n marker = \"· \"\n if (prevWasOrdered) {\n for (const k of Object.keys(orderedCounters)) delete orderedCounters[+k]\n }\n prevWasOrdered = false\n }\n const indentPrefix = \" \".repeat(indent)\n xml = generateParagraph(indentPrefix + marker + (block.text || \"\"), PARA_LIST)\n break\n }\n case \"hr\":\n // 수평선 — 긴 대시로 대체\n xml = `<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\"><hp:run charPrIDRef=\"0\"><hp:t>────────────────────────────────────────</hp:t></hp:run></hp:p>`\n break\n case \"table\":\n if (block.rows) {\n if (isFirst) {\n // 테이블이 첫 블록이면 빈 단락에 secPr\n const secRun = `<hp:run charPrIDRef=\"0\">${generateSecPr()}<hp:t></hp:t></hp:run>`\n paraXmls.push(`<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\">${secRun}</hp:p>`)\n isFirst = false\n }\n xml = generateTable(block.rows)\n }\n break\n }\n\n if (!xml) continue\n\n // 첫 번째 단락에 secPr 주입\n if (isFirst && block.type !== \"table\") {\n xml = xml.replace(\n /<hp:run charPrIDRef=\"(\\d+)\">/,\n `<hp:run charPrIDRef=\"$1\">${generateSecPr()}`\n )\n isFirst = false\n }\n\n paraXmls.push(xml)\n }\n\n // 블록이 없으면 빈 단락\n if (paraXmls.length === 0) {\n paraXmls.push(`<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\"><hp:run charPrIDRef=\"0\">${generateSecPr()}<hp:t></hp:t></hp:run></hp:p>`)\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n<hs:sec xmlns:hs=\"${NS_SECTION}\" xmlns:hp=\"${NS_PARA}\">\n ${paraXmls.join(\"\\n \")}\n</hs:sec>`\n}\n","/** 텍스트 유사도 및 diff 유틸리티 — 외부 의존성 없음 */\n\nexport interface TextChange {\n type: \"equal\" | \"insert\" | \"delete\"\n text: string\n}\n\n/** 두 문자열의 유사도 (0-1). 1 = 동일, 0 = 완전히 다름 */\nexport function similarity(a: string, b: string): number {\n if (a === b) return 1\n if (!a || !b) return 0\n const maxLen = Math.max(a.length, b.length)\n if (maxLen === 0) return 1\n return 1 - levenshtein(a, b) / maxLen\n}\n\n/** 공백 정규화 후 유사도 비교 (HWP/HWPX 포맷 차이 흡수) */\nexport function normalizedSimilarity(a: string, b: string): number {\n return similarity(normalize(a), normalize(b))\n}\n\nfunction normalize(s: string): string {\n return s.replace(/\\s+/g, \" \").trim()\n}\n\n/** 최대 입력 길이 합 — 초과 시 길이 차이 기반 빠른 추정 (O(m*n) CPU 폭발 방지) */\nconst MAX_LEVENSHTEIN_LEN = 10_000\n\n/** Levenshtein 편집 거리 — O(min(m,n)) 공간 최적화 */\nfunction levenshtein(a: string, b: string): number {\n if (a.length + b.length > MAX_LEVENSHTEIN_LEN) {\n // 길이 차이 + 앞 500자 샘플 비교로 근사 거리 추정\n const sampleLen = Math.min(500, a.length, b.length)\n let diffs = 0\n for (let i = 0; i < sampleLen; i++) if (a[i] !== b[i]) diffs++\n const sampleRate = sampleLen > 0 ? diffs / sampleLen : 1\n return Math.abs(a.length - b.length) + Math.round(Math.min(a.length, b.length) * sampleRate)\n }\n if (a.length > b.length) [a, b] = [b, a]\n const m = a.length\n const n = b.length\n let prev = Array.from({ length: m + 1 }, (_, i) => i)\n let curr = new Array(m + 1)\n\n for (let j = 1; j <= n; j++) {\n curr[0] = j\n for (let i = 1; i <= m; i++) {\n if (a[i - 1] === b[j - 1]) {\n curr[i] = prev[i - 1]\n } else {\n curr[i] = 1 + Math.min(prev[i - 1], prev[i], curr[i - 1])\n }\n }\n ;[prev, curr] = [curr, prev]\n }\n return prev[m]\n}\n\n/** 단어 단위 diff — LCS 기반 */\nexport function textDiff(a: string, b: string): TextChange[] {\n const wordsA = a.split(/(\\s+)/)\n const wordsB = b.split(/(\\s+)/)\n const lcs = lcsWords(wordsA, wordsB)\n\n const changes: TextChange[] = []\n let ia = 0, ib = 0, il = 0\n\n while (il < lcs.length) {\n // lcs 원소 이전에 있는 것들\n while (ia < wordsA.length && wordsA[ia] !== lcs[il]) {\n changes.push({ type: \"delete\", text: wordsA[ia++] })\n }\n while (ib < wordsB.length && wordsB[ib] !== lcs[il]) {\n changes.push({ type: \"insert\", text: wordsB[ib++] })\n }\n changes.push({ type: \"equal\", text: lcs[il] })\n ia++; ib++; il++\n }\n // 나머지\n while (ia < wordsA.length) changes.push({ type: \"delete\", text: wordsA[ia++] })\n while (ib < wordsB.length) changes.push({ type: \"insert\", text: wordsB[ib++] })\n\n return mergeChanges(changes)\n}\n\nfunction lcsWords(a: string[], b: string[]): string[] {\n const m = a.length, n = b.length\n // 대형 문서 보호: 5000 단어 초과 시 간이 비교\n if (m * n > 25_000_000) return simpleIntersect(a, b)\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0))\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1] + 1\n : Math.max(dp[i - 1][j], dp[i][j - 1])\n }\n }\n\n const result: string[] = []\n let i = m, j = n\n while (i > 0 && j > 0) {\n if (a[i - 1] === b[j - 1]) { result.push(a[i - 1]); i--; j-- }\n else if (dp[i - 1][j] >= dp[i][j - 1]) i--\n else j--\n }\n return result.reverse()\n}\n\nfunction simpleIntersect(a: string[], b: string[]): string[] {\n const setB = new Set(b)\n return a.filter(w => setB.has(w))\n}\n\nfunction mergeChanges(changes: TextChange[]): TextChange[] {\n if (changes.length === 0) return changes\n const merged: TextChange[] = [changes[0]]\n for (let i = 1; i < changes.length; i++) {\n const last = merged[merged.length - 1]\n if (last.type === changes[i].type) {\n last.text += changes[i].text\n } else {\n merged.push({ ...changes[i] })\n }\n }\n return merged\n}\n","/** 문서 비교 엔진 — IR 레벨 블록 비교로 신구대조표 생성 */\n\nimport { parse } from \"../index.js\"\nimport { normalizedSimilarity } from \"./text-diff.js\"\nimport type { IRBlock, IRTable, DiffResult, BlockDiff, CellDiff, DiffChangeType, ParseOptions } from \"../types.js\"\n\n/** 유사도 임계값 — 이 이상이면 modified, 미만이면 removed+added */\nconst SIMILARITY_THRESHOLD = 0.4\n\n/**\n * 두 문서를 비교하여 블록 단위 diff 생성.\n * 크로스 포맷 지원 — HWP vs HWPX 비교 가능 (IR 레벨).\n */\nexport async function compare(\n bufferA: ArrayBuffer,\n bufferB: ArrayBuffer,\n options?: ParseOptions\n): Promise<DiffResult> {\n const [resultA, resultB] = await Promise.all([\n parse(bufferA, options),\n parse(bufferB, options),\n ])\n\n if (!resultA.success) throw new Error(`문서A 파싱 실패: ${resultA.error}`)\n if (!resultB.success) throw new Error(`문서B 파싱 실패: ${resultB.error}`)\n\n return diffBlocks(resultA.blocks, resultB.blocks)\n}\n\n/** IRBlock[] 간 diff — LCS 기반 정렬 */\nexport function diffBlocks(blocksA: IRBlock[], blocksB: IRBlock[]): DiffResult {\n const aligned = alignBlocks(blocksA, blocksB)\n const stats = { added: 0, removed: 0, modified: 0, unchanged: 0 }\n const diffs: BlockDiff[] = []\n\n for (const [a, b] of aligned) {\n if (a && b) {\n const sim = blockSimilarity(a, b)\n if (sim >= 0.99) {\n diffs.push({ type: \"unchanged\", before: a, after: b, similarity: 1 })\n stats.unchanged++\n } else {\n const diff: BlockDiff = { type: \"modified\", before: a, after: b, similarity: sim }\n if (a.type === \"table\" && b.type === \"table\" && a.table && b.table) {\n diff.cellDiffs = diffTableCells(a.table, b.table)\n }\n diffs.push(diff)\n stats.modified++\n }\n } else if (a) {\n diffs.push({ type: \"removed\", before: a })\n stats.removed++\n } else if (b) {\n diffs.push({ type: \"added\", after: b })\n stats.added++\n }\n }\n\n return { stats, diffs }\n}\n\n// ─── 블록 정렬 (LCS 기반) ───────────────────────────\n\nfunction alignBlocks(a: IRBlock[], b: IRBlock[]): [IRBlock | null, IRBlock | null][] {\n const m = a.length, n = b.length\n\n // 대형 문서 보호\n if (m * n > 10_000_000) return fallbackAlign(a, b)\n\n // 유사도 매트릭스 캐시\n const simCache = new Map<string, number>()\n const getSim = (i: number, j: number): number => {\n const key = `${i},${j}`\n let v = simCache.get(key)\n if (v === undefined) { v = blockSimilarity(a[i], b[j]); simCache.set(key, v) }\n return v\n }\n\n // LCS with similarity threshold\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0))\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (getSim(i - 1, j - 1) >= SIMILARITY_THRESHOLD) {\n dp[i][j] = dp[i - 1][j - 1] + 1\n } else {\n dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1])\n }\n }\n }\n\n // 역추적\n const pairs: [number, number][] = []\n let i = m, j = n\n while (i > 0 && j > 0) {\n if (getSim(i - 1, j - 1) >= SIMILARITY_THRESHOLD && dp[i][j] === dp[i - 1][j - 1] + 1) {\n pairs.push([i - 1, j - 1]); i--; j--\n } else if (dp[i - 1][j] >= dp[i][j - 1]) {\n i--\n } else {\n j--\n }\n }\n pairs.reverse()\n\n // 정렬 결과 조립\n const result: [IRBlock | null, IRBlock | null][] = []\n let ai = 0, bi = 0\n for (const [pi, pj] of pairs) {\n while (ai < pi) result.push([a[ai++], null])\n while (bi < pj) result.push([null, b[bi++]])\n result.push([a[ai++], b[bi++]])\n }\n while (ai < m) result.push([a[ai++], null])\n while (bi < n) result.push([null, b[bi++]])\n\n return result\n}\n\nfunction fallbackAlign(a: IRBlock[], b: IRBlock[]): [IRBlock | null, IRBlock | null][] {\n const result: [IRBlock | null, IRBlock | null][] = []\n const len = Math.max(a.length, b.length)\n for (let i = 0; i < len; i++) {\n result.push([a[i] || null, b[i] || null])\n }\n return result\n}\n\n// ─── 블록 유사도 ────────────────────────────────────\n\nfunction blockSimilarity(a: IRBlock, b: IRBlock): number {\n if (a.type !== b.type) return 0\n\n // 텍스트 기반 블록: paragraph, heading, list, image(alt text)\n if (a.text !== undefined && b.text !== undefined) {\n return normalizedSimilarity(a.text || \"\", b.text || \"\")\n }\n\n if (a.type === \"table\" && a.table && b.table) {\n return tableSimilarity(a.table, b.table)\n }\n\n // separator 등 텍스트 없는 동일 타입 → 완전 일치\n if (a.type === b.type) return 1\n\n return 0\n}\n\nfunction tableSimilarity(a: IRTable, b: IRTable): number {\n // 구조 유사도 (차원)\n const dimSim = 1 - Math.abs(a.rows * a.cols - b.rows * b.cols) / Math.max(a.rows * a.cols, b.rows * b.cols, 1)\n\n // 내용 유사도 (셀 텍스트)\n const textsA = a.cells.flat().map(c => c.text).join(\" \")\n const textsB = b.cells.flat().map(c => c.text).join(\" \")\n const contentSim = normalizedSimilarity(textsA, textsB)\n\n return dimSim * 0.3 + contentSim * 0.7\n}\n\n// ─── 테이블 셀 diff ─────────────────────────────────\n\nfunction diffTableCells(a: IRTable, b: IRTable): CellDiff[][] {\n const maxRows = Math.max(a.rows, b.rows)\n const maxCols = Math.max(a.cols, b.cols)\n const result: CellDiff[][] = []\n\n for (let r = 0; r < maxRows; r++) {\n const row: CellDiff[] = []\n for (let c = 0; c < maxCols; c++) {\n const cellA = r < a.rows && c < a.cols ? a.cells[r][c].text : undefined\n const cellB = r < b.rows && c < b.cols ? b.cells[r][c].text : undefined\n\n let type: DiffChangeType\n if (cellA === undefined) type = \"added\"\n else if (cellB === undefined) type = \"removed\"\n else if (cellA === cellB) type = \"unchanged\"\n else type = \"modified\"\n\n row.push({ type, before: cellA, after: cellB })\n }\n result.push(row)\n }\n return result\n}\n","/**\n * Print Renderer — Markdown / IRBlock[] → PDF (puppeteer-core 기반).\n *\n * 흐름:\n * blocks → markdown (blocksToMarkdown)\n * markdown → HTML (markdown-it)\n * HTML + 프리셋 CSS → PDF (puppeteer-core)\n *\n * puppeteer-core는 optional peer dep. 미설치 시 markdownToPdf는 명확한 에러를 던지지만\n * `renderHtml()`은 항상 동작 (외부 PDF 엔진과 결합용).\n *\n * 참조: docs/SPEC.md §1.3\n */\n\nimport { existsSync } from \"fs\"\nimport MarkdownIt from \"markdown-it\"\nimport type { IRBlock } from \"../types.js\"\nimport { blocksToMarkdown } from \"../table/builder.js\"\nimport { KordocError } from \"../utils.js\"\n\n// ─── 타입 ─────────────────────────────────────────\n\nexport type PrintPreset = \"default\" | \"gov-formal\" | \"compact\"\n\nexport interface PageMargin {\n top: string | number // mm 또는 CSS string (\"20mm\", \"1in\")\n right: string | number\n bottom: string | number\n left: string | number\n}\n\nexport interface PrintOptions {\n preset?: PrintPreset\n pageSize?: \"A4\" | \"Letter\"\n orientation?: \"portrait\" | \"landscape\"\n margin?: PageMargin\n /** 페이지 머리글 (HTML 허용, gov-formal 프리셋에서 자동 표시) */\n header?: string\n /** 페이지 바닥글 (HTML 허용) */\n footer?: string\n /** 워터마크 텍스트 (대각선 회색) */\n watermark?: string\n /** 사용자 정의 추가 CSS */\n extraCss?: string\n}\n\n// ─── 프리셋 CSS ───────────────────────────────────\n\nconst PRESETS: Record<PrintPreset, string> = {\n default: `\n @page { size: A4; margin: 20mm; }\n body { font-family: 'Pretendard', 'Malgun Gothic', '맑은 고딕', sans-serif; font-size: 11pt; line-height: 1.6; color: #111; }\n h1 { font-size: 20pt; margin: 1em 0 0.5em; }\n h2 { font-size: 16pt; margin: 1em 0 0.4em; }\n h3 { font-size: 13pt; margin: 0.8em 0 0.3em; }\n p { margin: 0.4em 0; }\n table { border-collapse: collapse; margin: 0.6em 0; width: 100%; }\n th, td { border: 1px solid #555; padding: 4px 8px; text-align: left; vertical-align: top; }\n th { background: #f0f0f0; }\n code { background: #f5f5f5; padding: 1px 4px; border-radius: 2px; font-family: 'D2Coding', Consolas, monospace; }\n pre { background: #f5f5f5; padding: 8px; border-radius: 4px; overflow-x: auto; }\n blockquote { border-left: 3px solid #ccc; padding-left: 12px; color: #555; margin: 0.6em 0; }\n img { max-width: 100%; }\n `,\n \"gov-formal\": `\n @page { size: A4; margin: 25mm 20mm; }\n body { font-family: '함초롬바탕', 'HCR Batang', 'Batang', 'Malgun Gothic', serif; font-size: 11pt; line-height: 1.7; color: #000; }\n h1 { font-size: 18pt; text-align: center; margin: 0.5em 0 1em; letter-spacing: 0.05em; }\n h2 { font-size: 14pt; margin: 1em 0 0.4em; border-bottom: 1px solid #999; padding-bottom: 2px; }\n h3 { font-size: 12pt; margin: 0.8em 0 0.3em; }\n p { margin: 0.3em 0; text-indent: 1em; }\n table { border-collapse: collapse; margin: 0.8em 0; width: 100%; }\n th, td { border: 1px solid #000; padding: 5px 8px; vertical-align: top; }\n th { background: #e8e8e8; font-weight: normal; }\n blockquote { border-left: 2px solid #555; padding-left: 12px; margin: 0.6em 0; }\n `,\n compact: `\n @page { size: A4; margin: 10mm; }\n body { font-family: 'Pretendard', 'Malgun Gothic', sans-serif; font-size: 9pt; line-height: 1.4; color: #111; }\n h1 { font-size: 14pt; margin: 0.5em 0 0.3em; }\n h2 { font-size: 12pt; margin: 0.5em 0 0.3em; }\n h3 { font-size: 10pt; margin: 0.4em 0 0.2em; }\n p { margin: 0.2em 0; }\n table { border-collapse: collapse; margin: 0.3em 0; width: 100%; font-size: 8pt; }\n th, td { border: 1px solid #777; padding: 2px 4px; }\n th { background: #f0f0f0; }\n `,\n}\n\n// ─── HTML 생성 ─────────────────────────────────\n\nconst md = new MarkdownIt({\n html: true,\n linkify: true,\n breaks: false,\n})\n\n/**\n * Markdown 또는 IRBlock[] → HTML 문자열.\n * 외부 PDF 엔진(weasyprint, wkhtmltopdf 등)과 결합 가능.\n */\nexport function renderHtml(\n markdown: string,\n options?: PrintOptions,\n): string {\n const preset = options?.preset ?? \"default\"\n const css = PRESETS[preset] + (options?.extraCss ?? \"\")\n const body = md.render(markdown)\n\n const watermark = options?.watermark\n ? `<div class=\"watermark\">${escapeHtml(options.watermark)}</div>`\n : \"\"\n const watermarkCss = options?.watermark\n ? `\n .watermark {\n position: fixed;\n top: 50%; left: 50%;\n transform: translate(-50%, -50%) rotate(-30deg);\n font-size: 80pt;\n color: rgba(0,0,0,0.08);\n pointer-events: none;\n z-index: 9999;\n white-space: nowrap;\n }`\n : \"\"\n\n return `<!DOCTYPE html>\n<html lang=\"ko\">\n<head>\n<meta charset=\"utf-8\">\n<style>${css}${watermarkCss}</style>\n</head>\n<body>\n${watermark}\n${body}\n</body>\n</html>`\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\")\n}\n\n// ─── PDF 생성 ─────────────────────────────────\n\n/**\n * puppeteer-core로 HTML → PDF 변환.\n * 환경에 Chromium 실행 파일 필요 (PUPPETEER_EXECUTABLE_PATH 환경변수 또는 자동 감지).\n */\nasync function htmlToPdf(html: string, options?: PrintOptions): Promise<Buffer> {\n let puppeteer: typeof import(\"puppeteer-core\")\n try {\n puppeteer = await import(\"puppeteer-core\")\n } catch {\n throw new KordocError(\n \"PDF 생성에 puppeteer-core가 필요합니다. 설치: npm install puppeteer-core\",\n )\n }\n\n const executablePath =\n process.env.PUPPETEER_EXECUTABLE_PATH ?? findChromiumPath()\n if (!executablePath) {\n throw new KordocError(\n \"Chromium 실행 파일을 찾을 수 없습니다. PUPPETEER_EXECUTABLE_PATH 환경변수를 설정하세요.\",\n )\n }\n\n const browser = await puppeteer.default.launch({\n executablePath,\n headless: true,\n args: [\"--no-sandbox\", \"--disable-setuid-sandbox\"],\n })\n\n try {\n const page = await browser.newPage()\n await page.setContent(html, { waitUntil: \"networkidle0\" })\n\n const margin = options?.margin\n const pdf = await page.pdf({\n format: options?.pageSize ?? \"A4\",\n landscape: options?.orientation === \"landscape\",\n printBackground: true,\n margin: margin\n ? {\n top: toCss(margin.top),\n right: toCss(margin.right),\n bottom: toCss(margin.bottom),\n left: toCss(margin.left),\n }\n : undefined,\n displayHeaderFooter: !!(options?.header || options?.footer),\n headerTemplate: options?.header ?? \"<div></div>\",\n footerTemplate:\n options?.footer ??\n '<div style=\"font-size:8pt;width:100%;text-align:center;color:#777;\"><span class=\"pageNumber\"></span>/<span class=\"totalPages\"></span></div>',\n })\n return Buffer.from(pdf)\n } finally {\n await browser.close()\n }\n}\n\nfunction toCss(v: string | number): string {\n return typeof v === \"number\" ? `${v}mm` : v\n}\n\n/** Windows/Mac/Linux의 일반적 Chrome 경로 자동 감지 */\nfunction findChromiumPath(): string | null {\n // 사용자가 명시 안 했으면 OS 표준 경로 시도\n // Windows\n const win = [\n \"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n process.env.LOCALAPPDATA + \"\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"C:\\\\Program Files\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\",\n \"C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\",\n ]\n // Mac\n const mac = [\n \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\",\n \"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\",\n ]\n // Linux\n const linux = [\"/usr/bin/google-chrome\", \"/usr/bin/chromium-browser\", \"/usr/bin/chromium\"]\n\n const candidates =\n process.platform === \"win32\" ? win : process.platform === \"darwin\" ? mac : linux\n\n for (const p of candidates) {\n if (p && existsSync(p)) return p\n }\n return null\n}\n\n/** Markdown → PDF (Buffer). */\nexport async function markdownToPdf(\n markdown: string,\n options?: PrintOptions,\n): Promise<Buffer> {\n const html = renderHtml(markdown, options)\n return htmlToPdf(html, options)\n}\n\n/** IRBlock[] → PDF (Buffer). */\nexport async function blocksToPdf(\n blocks: IRBlock[],\n options?: PrintOptions,\n): Promise<Buffer> {\n const markdown = blocksToMarkdown(blocks)\n return markdownToPdf(markdown, options)\n}\n"],"mappings":"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,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAC7E,CAAC;AAED,IAAM,YAAY,IAAI,WAAW;AAAA,EAC/B;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,E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,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA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","names":["JSZip","JSZip","warnings","kids","inflateRawSync","MAX_DECOMPRESS_SIZE","inflateRawSync","start","end","require","cellRows","inflateRawSync","inflateRawSync","JSZip","DOMParser","MAX_DECOMPRESS_SIZE","MAX_ROWS","MAX_COLS","DOMParser","JSZip","parsePageRange","MAX_RECORDS","readRecords","data","MAX_SHEETS","MAX_ROWS","MAX_COLS","sheetToBlocks","readRecords","parsePageRange","JSZip","DOMParser","MAX_DECOMPRESS_SIZE","localName","parseXml","DOMParser","parseRels","runs","text","JSZip","DOMParser","MAX_XML_DEPTH","DOMParser","parseSection","parseParagraph","parseTable","JSZip","DOMParser","JSZip","DOMParser","extractCellText","localName","JSZip","md","i","j"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/detect.ts","../src/hwp5/cfb-lenient.ts","../src/hwpx/parser.ts","../src/hwpx/com-fallback.ts","../src/hwpx/equation.ts","../src/hwp5/record.ts","../src/hwp5/aes.ts","../src/hwp5/crypto.ts","../src/hwp5/equation.ts","../src/hwp5/parser.ts","../src/hwp3/parser.ts","../src/hwp3/johab-symbols.ts","../src/hwp3/johab.ts","../src/hwp3/reader.ts","../src/hwp3/records.ts","../src/hwp5/sentinel.ts","../src/xlsx/parser.ts","../src/xls/record.ts","../src/xls/encoding.ts","../src/xls/sst.ts","../src/xls/cell.ts","../src/xls/parser.ts","../src/docx/parser.ts","../src/docx/equation.ts","../src/hwpml/parser.ts","../src/form/recognize.ts","../src/form/match.ts","../src/form/filler.ts","../src/form/filler-hwpx.ts","../src/hwpx/generator.ts","../src/diff/text-diff.ts","../src/diff/compare.ts","../src/print/renderer.ts"],"sourcesContent":["/**\r\n * kordoc — 모두 파싱해버리겠다\r\n *\r\n * HWP, HWPX, PDF → Markdown 변환 통합 라이브러리\r\n */\r\n\r\nimport { readFile } from \"fs/promises\"\r\nimport { detectFormat, detectOle2Format, detectZipFormat, isHwpxFile, isOldHwpFile, isPdfFile, isZipFile } from \"./detect.js\"\r\nimport { parseHwpxDocument } from \"./hwpx/parser.js\"\r\nimport { parseHwp5Document } from \"./hwp5/parser.js\"\r\nimport { parseHwp3Document } from \"./hwp3/parser.js\"\r\nimport { isComFallbackAvailable, extractTextViaCom, comResultToParseResult } from \"./hwpx/com-fallback.js\"\r\nimport { isDistributionSentinel } from \"./hwp5/sentinel.js\"\r\n// pdfjs-dist는 optional peer dep (37MB) — PDF 안 쓰는 사용자를 위해 dynamic import\r\n// import { parsePdfDocument } from \"./pdf/parser.js\"\r\nimport { parseXlsxDocument } from \"./xlsx/parser.js\"\r\nimport { parseXlsDocument } from \"./xls/parser.js\"\r\nimport { parseDocxDocument } from \"./docx/parser.js\"\r\nimport { parseHwpmlDocument } from \"./hwpml/parser.js\"\r\nimport type { ParseResult, ParseOptions } from \"./types.js\"\r\nimport { classifyError, toArrayBuffer } from \"./utils.js\"\r\nimport { fillFormFields } from \"./form/filler.js\"\r\nimport type { FillResult } from \"./form/filler.js\"\r\nimport { fillHwpx } from \"./form/filler-hwpx.js\"\r\nimport type { HwpxFillResult } from \"./form/filler-hwpx.js\"\r\nimport { blocksToMarkdown } from \"./table/builder.js\"\r\nimport { markdownToHwpx } from \"./hwpx/generator.js\"\r\n\r\n// ─── 메인 API ────────────────────────────────────────\r\n\r\n/**\r\n * 파일 버퍼를 자동 감지하여 Markdown으로 변환\r\n *\r\n * @example\r\n * ```ts\r\n * import { parse } from \"kordoc\"\r\n * // 파일 경로로 파싱\r\n * const result = await parse(\"document.hwp\")\r\n * // 또는 Buffer로 파싱\r\n * const result = await parse(buffer)\r\n * ```\r\n */\r\nexport async function parse(input: string | ArrayBuffer | Buffer, options?: ParseOptions): Promise<ParseResult> {\r\n let buffer: ArrayBuffer\r\n // 파일 경로 입력 시 filePath를 options에 자동 설정 (DRM COM fallback에 필요)\r\n const opts = typeof input === \"string\" && !options?.filePath\r\n ? { ...options, filePath: input }\r\n : options\r\n if (typeof input === \"string\") {\r\n try {\r\n const buf = await readFile(input)\r\n buffer = toArrayBuffer(buf)\r\n } catch (err) {\r\n const msg = err instanceof Error && \"code\" in err && (err as NodeJS.ErrnoException).code === \"ENOENT\"\r\n ? `파일을 찾을 수 없습니다: ${input}`\r\n : `파일 읽기 실패: ${input}`\r\n return { success: false, fileType: \"unknown\", error: msg, code: \"PARSE_ERROR\" }\r\n }\r\n } else if (Buffer.isBuffer(input)) {\r\n buffer = toArrayBuffer(input)\r\n } else {\r\n buffer = input\r\n }\r\n\r\n if (!buffer || buffer.byteLength === 0) {\r\n return { success: false, fileType: \"unknown\", error: \"빈 버퍼이거나 유효하지 않은 입력입니다.\", code: \"EMPTY_INPUT\" }\r\n }\r\n const format = detectFormat(buffer)\r\n\r\n switch (format) {\r\n case \"hwpx\": {\r\n // ZIP 기반 포맷 세분화: HWPX, XLSX, DOCX 구분\r\n const zipFormat = await detectZipFormat(buffer)\r\n if (zipFormat === \"xlsx\") return parseXlsx(buffer, opts)\r\n if (zipFormat === \"docx\") return parseDocx(buffer, opts)\r\n return parseHwpx(buffer, opts)\r\n }\r\n case \"hwp\": {\r\n // OLE2 기반 포맷 세분화: HWP 5.x vs XLS (Excel 97-2003)\r\n const ole2Format = detectOle2Format(buffer)\r\n if (ole2Format === \"xls\") return parseXls(buffer, opts)\r\n return parseHwp(buffer, opts)\r\n }\r\n case \"hwp3\":\r\n return parseHwp3(buffer, opts)\r\n case \"hwpml\":\r\n return parseHwpml(buffer, opts)\r\n case \"pdf\":\r\n return parsePdf(buffer, opts)\r\n default:\r\n return { success: false, fileType: \"unknown\", error: \"지원하지 않는 파일 형식입니다.\", code: \"UNSUPPORTED_FORMAT\" }\r\n }\r\n}\r\n\r\n/** HWP 3.x (구버전 한컴 워드프로세서) 파일을 Markdown 으로 변환. */\r\nexport async function parseHwp3(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n try {\r\n const { markdown, blocks, metadata, outline, warnings } = parseHwp3Document(buffer, options)\r\n return { success: true, fileType: \"hwp3\", markdown, blocks, metadata, outline, warnings }\r\n } catch (err) {\r\n return { success: false, fileType: \"hwp3\", error: err instanceof Error ? err.message : \"HWP3 파싱 실패\", code: classifyError(err) }\r\n }\r\n}\r\n\r\n// ─── 포맷별 API ──────────────────────────────────────\r\n\r\n/** HWPX 파일을 Markdown으로 변환 */\r\nexport async function parseHwpx(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n try {\r\n const { markdown, blocks, metadata, outline, warnings, images } = await parseHwpxDocument(buffer, options)\r\n return { success: true, fileType: \"hwpx\", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : undefined }\r\n } catch (err) {\r\n return { success: false, fileType: \"hwpx\", error: err instanceof Error ? err.message : \"HWPX 파싱 실패\", code: classifyError(err) }\r\n }\r\n}\r\n\r\n/** HWP 5.x 바이너리 파일을 Markdown으로 변환 */\r\nexport async function parseHwp(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n try {\r\n const { markdown, blocks, metadata, outline, warnings, images } = parseHwp5Document(Buffer.from(buffer), options)\r\n\r\n // 배포용 HWP 5.x 감지 — 본문이 \"상위 버전의 배포용 문서입니다...\" 플레이스홀더뿐이면\r\n // COM fallback으로 재시도 (Windows + 한컴오피스 환경에서만). 이슈 #25 대응.\r\n if (isDistributionSentinel(markdown) && isComFallbackAvailable() && options?.filePath) {\r\n try {\r\n const { pages, pageCount, warnings: comWarns } = extractTextViaCom(options.filePath)\r\n if (pages.some(p => p && p.trim().length > 0)) {\r\n const com = comResultToParseResult(pages, pageCount, comWarns)\r\n return {\r\n success: true,\r\n fileType: \"hwp\",\r\n markdown: com.markdown,\r\n blocks: com.blocks,\r\n metadata: com.metadata,\r\n warnings: com.warnings,\r\n }\r\n }\r\n } catch {\r\n // COM 실패 시 기존 결과(경고 문자열 포함) 그대로 반환\r\n }\r\n }\r\n\r\n return { success: true, fileType: \"hwp\", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : undefined }\r\n } catch (err) {\r\n return { success: false, fileType: \"hwp\", error: err instanceof Error ? err.message : \"HWP 파싱 실패\", code: classifyError(err) }\r\n }\r\n}\r\n\r\n/** PDF 파일에서 텍스트를 추출하여 Markdown으로 변환 */\r\nexport async function parsePdf(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n let parsePdfDocument: typeof import(\"./pdf/parser.js\").parsePdfDocument\r\n try {\r\n const mod = await import(\"./pdf/parser.js\")\r\n parsePdfDocument = mod.parsePdfDocument\r\n } catch {\r\n return {\r\n success: false, fileType: \"pdf\",\r\n error: \"PDF 파싱에 pdfjs-dist가 필요합니다. 설치: npm install pdfjs-dist\",\r\n code: \"MISSING_DEPENDENCY\",\r\n }\r\n }\r\n try {\r\n const { markdown, blocks, metadata, outline, warnings, isImageBased } = await parsePdfDocument(buffer, options)\r\n return { success: true, fileType: \"pdf\", markdown, blocks, metadata, outline, warnings, isImageBased }\r\n } catch (err) {\r\n const isImageBased = err instanceof Error && \"isImageBased\" in err ? true : undefined\r\n return { success: false, fileType: \"pdf\", error: err instanceof Error ? err.message : \"PDF 파싱 실패\", code: classifyError(err), isImageBased }\r\n }\r\n}\r\n\r\n/** XLSX 파일을 Markdown으로 변환 */\r\nexport async function parseXlsx(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n try {\r\n const { markdown, blocks, metadata, warnings } = await parseXlsxDocument(buffer, options)\r\n return { success: true, fileType: \"xlsx\", markdown, blocks, metadata, warnings }\r\n } catch (err) {\r\n return { success: false, fileType: \"xlsx\", error: err instanceof Error ? err.message : \"XLSX 파싱 실패\", code: classifyError(err) }\r\n }\r\n}\r\n\r\n/** XLS (Excel 97-2003) 파일을 Markdown으로 변환 */\r\nexport async function parseXls(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n try {\r\n const { markdown, blocks, metadata, warnings } = await parseXlsDocument(buffer, options)\r\n return { success: true, fileType: \"xls\", markdown, blocks, metadata, warnings }\r\n } catch (err) {\r\n return { success: false, fileType: \"xls\", error: err instanceof Error ? err.message : \"XLS 파싱 실패\", code: classifyError(err) }\r\n }\r\n}\r\n\r\n/** DOCX 파일을 Markdown으로 변환 */\r\nexport async function parseDocx(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n try {\r\n const { markdown, blocks, metadata, outline, warnings, images } = await parseDocxDocument(buffer, options)\r\n return { success: true, fileType: \"docx\", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : undefined }\r\n } catch (err) {\r\n return { success: false, fileType: \"docx\", error: err instanceof Error ? err.message : \"DOCX 파싱 실패\", code: classifyError(err) }\r\n }\r\n}\r\n\r\n/** HWPML (XML 기반 한컴 문서) 파일을 Markdown으로 변환 */\r\nexport async function parseHwpml(buffer: ArrayBuffer, options?: ParseOptions): Promise<ParseResult> {\r\n try {\r\n const { markdown, blocks, metadata, outline, warnings } = parseHwpmlDocument(buffer, options)\r\n return { success: true, fileType: \"hwpml\", markdown, blocks, metadata, outline, warnings }\r\n } catch (err) {\r\n return { success: false, fileType: \"hwpml\", error: err instanceof Error ? err.message : \"HWPML 파싱 실패\", code: classifyError(err) }\r\n }\r\n}\r\n\r\n// ─── 서식 채우기 API ────────────────────────────────\r\n\r\n/**\r\n * 서식 채우기 출력 포맷\r\n * - \"markdown\": 마크다운 텍스트\r\n * - \"hwpx\": 새로 생성한 HWPX (스타일 초기화)\r\n * - \"hwpx-preserve\": 원본 HWPX ZIP 직접 수정 (스타일 100% 보존, HWPX 입력만 가능)\r\n */\r\nexport type FillOutputFormat = \"markdown\" | \"hwpx\" | \"hwpx-preserve\"\r\n\r\n/** 서식 채우기 결과 */\r\nexport interface FillFormOutput {\r\n /** 채워진 문서 (markdown: string, hwpx/hwpx-preserve: ArrayBuffer) */\r\n output: string | ArrayBuffer\r\n /** 출력 포맷 */\r\n format: FillOutputFormat\r\n /** 채우기 상세 — filled 필드 목록 + unmatched 라벨 */\r\n fill: { filled: import(\"./types.js\").FormField[]; unmatched: string[] }\r\n}\r\n\r\n/**\r\n * 서식 문서를 파싱하여 필드를 채우고, 원하는 포맷으로 출력.\r\n *\r\n * - \"hwpx-preserve\": HWPX 입력 → 원본 ZIP XML 직접 수정 (테두리/폰트/병합 등 100% 보존)\r\n * - \"hwpx\": 아무 포맷 → IRBlock → Markdown → HWPX 생성 (스타일 초기화됨)\r\n * - \"markdown\": 아무 포맷 → IRBlock → Markdown\r\n *\r\n * @example\r\n * ```ts\r\n * // HWPX 원본 스타일 보존 채우기\r\n * const result = await fillForm(\"신청서.hwpx\", { \"성명\": \"홍길동\" }, \"hwpx-preserve\")\r\n * writeFileSync(\"결과.hwpx\", Buffer.from(result.output as ArrayBuffer))\r\n *\r\n * // 아무 포맷 → 마크다운 채우기\r\n * const result = await fillForm(\"신청서.hwp\", { \"성명\": \"홍길동\" })\r\n * console.log(result.output) // 채워진 마크다운\r\n * ```\r\n */\r\nexport async function fillForm(\r\n input: string | ArrayBuffer | Buffer,\r\n values: Record<string, string>,\r\n outputFormat: FillOutputFormat = \"markdown\",\r\n): Promise<FillFormOutput> {\r\n // 입력 버퍼 준비\r\n let buffer: ArrayBuffer\r\n if (typeof input === \"string\") {\r\n const buf = await readFile(input)\r\n buffer = toArrayBuffer(buf)\r\n } else if (Buffer.isBuffer(input)) {\r\n buffer = toArrayBuffer(input)\r\n } else {\r\n buffer = input\r\n }\r\n\r\n // hwpx-preserve: 원본 HWPX ZIP 직접 수정 (스타일 보존)\r\n if (outputFormat === \"hwpx-preserve\") {\r\n const format = detectFormat(buffer)\r\n // detectFormat은 ZIP이면 \"hwpx\" 반환 (XLSX/DOCX 포함), 세분화 필요\r\n if (format === \"hwpx\") {\r\n const zipFormat = await detectZipFormat(buffer)\r\n if (zipFormat !== \"hwpx\") {\r\n throw new Error(`hwpx-preserve 포맷은 HWPX 입력만 지원합니다 (감지된 포맷: ${zipFormat})`)\r\n }\r\n } else {\r\n throw new Error(`hwpx-preserve 포맷은 HWPX 입력만 지원합니다 (감지된 포맷: ${format})`)\r\n }\r\n const hwpxResult = await fillHwpx(buffer, values)\r\n return {\r\n output: hwpxResult.buffer,\r\n format: \"hwpx-preserve\",\r\n fill: { filled: hwpxResult.filled, unmatched: hwpxResult.unmatched },\r\n }\r\n }\r\n\r\n // 일반 경로: parse → IRBlock → fill → output\r\n const parsed = await parse(buffer)\r\n if (!parsed.success) {\r\n throw new Error(`서식 파싱 실패: ${parsed.error}`)\r\n }\r\n\r\n const fill = fillFormFields(parsed.blocks, values)\r\n const markdown = blocksToMarkdown(fill.blocks)\r\n\r\n if (outputFormat === \"hwpx\") {\r\n const hwpxBuffer = await markdownToHwpx(markdown)\r\n return { output: hwpxBuffer, format: \"hwpx\", fill }\r\n }\r\n\r\n return { output: markdown, format: \"markdown\", fill }\r\n}\r\n\r\n// ─── 게임체인저 API ─────────────────────────────────\r\n\r\nexport { compare, diffBlocks } from \"./diff/compare.js\"\r\nexport { extractFormFields, isLabelCell } from \"./form/recognize.js\"\r\nexport { fillFormFields } from \"./form/filler.js\"\r\nexport type { FillResult } from \"./form/filler.js\"\r\nexport { fillHwpx } from \"./form/filler-hwpx.js\"\r\nexport type { HwpxFillResult } from \"./form/filler-hwpx.js\"\r\nexport { markdownToHwpx } from \"./hwpx/generator.js\"\r\nexport type { HwpxTheme, MarkdownToHwpxOptions } from \"./hwpx/generator.js\"\r\nexport { renderHtml, markdownToPdf, blocksToPdf } from \"./print/renderer.js\"\r\nexport type { PrintPreset, PrintOptions, PageMargin } from \"./print/renderer.js\"\r\n\r\n// ─── Re-exports ──────────────────────────────────────\r\n\r\nexport { detectFormat, detectOle2Format, detectZipFormat, isHwpxFile, isOldHwpFile, isPdfFile, isZipFile } from \"./detect.js\"\r\nexport type {\r\n ParseResult, ParseSuccess, ParseFailure, FileType,\r\n IRBlock, IRBlockType, IRTable, IRCell, CellContext,\r\n BoundingBox, InlineStyle, ImageData, ExtractedImage,\r\n DocumentMetadata, ParseOptions, ErrorCode,\r\n ParseWarning, WarningCode, OutlineItem,\r\n DiffResult, BlockDiff, CellDiff, DiffChangeType,\r\n FormField, FormResult,\r\n OcrProvider, WatchOptions,\r\n} from \"./types.js\"\r\nexport { blocksToMarkdown } from \"./table/builder.js\"\r\nexport { VERSION } from \"./utils.js\"\r\n","/** 매직 바이트 기반 파일 포맷 감지 */\r\n\r\nimport JSZip from \"jszip\"\r\nimport type { FileType } from \"./types.js\"\r\nimport { parseLenientCfb } from \"./hwp5/cfb-lenient.js\"\r\n\r\n/** 매직 바이트 뷰 생성 (복사 없이 view) */\r\nfunction magicBytes(buffer: ArrayBuffer): Uint8Array {\r\n return new Uint8Array(buffer, 0, Math.min(4, buffer.byteLength))\r\n}\r\n\r\n/** ZIP 파일 여부: PK\\x03\\x04 */\r\nexport function isZipFile(buffer: ArrayBuffer): boolean {\r\n const b = magicBytes(buffer)\r\n return b[0] === 0x50 && b[1] === 0x4b && b[2] === 0x03 && b[3] === 0x04\r\n}\r\n\r\n/** HWPX (ZIP 기반 한컴 문서): PK\\x03\\x04 — 하위 호환용 */\r\nexport function isHwpxFile(buffer: ArrayBuffer): boolean {\r\n return isZipFile(buffer)\r\n}\r\n\r\n/** HWP 5.x (OLE2 바이너리 한컴 문서): \\xD0\\xCF\\x11\\xE0 */\r\nexport function isOldHwpFile(buffer: ArrayBuffer): boolean {\r\n const b = magicBytes(buffer)\r\n return b[0] === 0xd0 && b[1] === 0xcf && b[2] === 0x11 && b[3] === 0xe0\r\n}\r\n\r\n/**\r\n * HWP 3.x (한글 워드프로세서 3.0): \"HWP Document File V3.00 \\x1A\\x01\\x02\\x03\\x04\\x05\" 30 byte.\r\n * CFB(OLE2) 컨테이너 아닌 단일 binary stream — isOldHwpFile 과 magic 이 다르다.\r\n */\r\nconst HWP3_PREFIX = new TextEncoder().encode(\"HWP Document File V3.00\")\r\nexport function isHwp3File(buffer: ArrayBuffer): boolean {\r\n if (buffer.byteLength < HWP3_PREFIX.length) return false\r\n const head = new Uint8Array(buffer, 0, HWP3_PREFIX.length)\r\n for (let i = 0; i < HWP3_PREFIX.length; i++) {\r\n if (head[i] !== HWP3_PREFIX[i]) return false\r\n }\r\n return true\r\n}\r\n\r\n/** PDF 문서: %PDF */\r\nexport function isPdfFile(buffer: ArrayBuffer): boolean {\r\n const b = magicBytes(buffer)\r\n return b[0] === 0x25 && b[1] === 0x50 && b[2] === 0x44 && b[3] === 0x46\r\n}\r\n\r\n/** HWPML (XML 기반 한컴 문서): <?xml ... <HWPML */\r\nexport function isHwpmlFile(buffer: ArrayBuffer): boolean {\r\n const bytes = new Uint8Array(buffer, 0, Math.min(512, buffer.byteLength))\r\n const head = new TextDecoder(\"utf-8\", { fatal: false }).decode(bytes).replace(/^\\uFEFF/, \"\")\r\n return head.trimStart().startsWith(\"<?xml\") && head.includes(\"<HWPML\")\r\n}\r\n\r\n/** 동기 포맷 감지 — ZIP은 모두 \"hwpx\"로 반환 (하위 호환) */\r\nexport function detectFormat(buffer: ArrayBuffer): FileType {\r\n if (buffer.byteLength < 4) return \"unknown\"\r\n if (isHwp3File(buffer)) return \"hwp3\"\r\n if (isZipFile(buffer)) return \"hwpx\"\r\n if (isOldHwpFile(buffer)) return \"hwp\"\r\n if (isPdfFile(buffer)) return \"pdf\"\r\n if (isHwpmlFile(buffer)) return \"hwpml\"\r\n return \"unknown\"\r\n}\r\n\r\n/**\r\n * OLE2 컨테이너 내부 스트림 기반 포맷 세분화.\r\n * HWP 5.x, XLS 모두 OLE2이므로 스트림 이름으로 구분.\r\n * - \"Workbook\" 또는 \"Book\" → 'xls'\r\n * - 그 외 (FileHeader 등) → 'hwp'\r\n */\r\nexport function detectOle2Format(buffer: ArrayBuffer): \"hwp\" | \"xls\" | \"unknown\" {\r\n try {\r\n const cfb = parseLenientCfb(Buffer.from(buffer))\r\n const names = cfb.entries().map(e => e.name)\r\n if (names.includes(\"Workbook\") || names.includes(\"Book\")) return \"xls\"\r\n if (names.includes(\"FileHeader\")) return \"hwp\"\r\n // FileHeader 없어도 BodyText/DocInfo 있으면 hwp\r\n if (names.some(n => n === \"DocInfo\" || n.startsWith(\"Section\"))) return \"hwp\"\r\n return \"unknown\"\r\n } catch {\r\n return \"unknown\"\r\n }\r\n}\r\n\r\n/**\r\n * ZIP 내부 구조 기반 포맷 세분화.\r\n * HWPX, XLSX, DOCX 모두 ZIP이므로 내부 파일로 구분.\r\n */\r\nexport async function detectZipFormat(buffer: ArrayBuffer): Promise<\"hwpx\" | \"xlsx\" | \"docx\" | \"unknown\"> {\r\n try {\r\n const zip = await JSZip.loadAsync(buffer)\r\n // XLSX: xl/workbook.xml\r\n if (zip.file(\"xl/workbook.xml\")) return \"xlsx\"\r\n // DOCX: word/document.xml\r\n if (zip.file(\"word/document.xml\")) return \"docx\"\r\n // HWPX: Contents/ 또는 content.hpf 또는 mimetype\r\n if (zip.file(\"Contents/content.hpf\") || zip.file(\"mimetype\")) return \"hwpx\"\r\n // 기타 ZIP 내에 section 파일이 있으면 HWPX로 추정\r\n const hasSection = Object.keys(zip.files).some(f => f.startsWith(\"Contents/\"))\r\n if (hasSection) return \"hwpx\"\r\n return \"unknown\"\r\n } catch {\r\n return \"unknown\"\r\n }\r\n}\r\n","/**\n * Lenient CFB (Compound File Binary / OLE2) 파서.\n *\n * 표준 cfb 모듈이 FAT 검증 실패로 거부하는 손상된 HWP 파일을 열기 위한 폴백.\n * 직접 헤더/FAT/디렉토리를 파싱하여 스트림 데이터를 추출.\n *\n * 참조: rhwp (MIT) src/parser/cfb_reader.rs (LenientCfbReader)\n * 참조: MS-CFB spec (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb)\n */\n\nimport { decompressStream } from \"./record.js\"\n\n// ── 상수 ──\n\nconst CFB_MAGIC = Buffer.from([0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1])\nconst END_OF_CHAIN = 0xfffffffe\nconst FREE_SECT = 0xffffffff\n\n/** 순환 감지용 최대 체인 길이 */\nconst MAX_CHAIN_LENGTH = 1_000_000\n/** 최대 디렉토리 엔트리 수 */\nconst MAX_DIR_ENTRIES = 100_000\n/** 최대 스트림 크기 (100MB) */\nconst MAX_STREAM_SIZE = 100 * 1024 * 1024\n\n// ── 디렉토리 엔트리 ──\n\ninterface DirEntry {\n name: string\n type: number // 0=unknown, 1=storage, 2=stream, 5=root\n startSector: number\n size: number\n}\n\n// ── CFB 컨테이너 ──\n\nexport interface LenientCfbContainer {\n /** 이름 기반 스트림 탐색 */\n findStream(path: string): Buffer | null\n /** 디렉토리 엔트리 목록 */\n entries(): DirEntry[]\n}\n\n// ── 구현 ──\n\nexport function parseLenientCfb(data: Buffer): LenientCfbContainer {\n if (data.length < 512) throw new Error(\"CFB 파일이 너무 짧습니다 (최소 512바이트)\")\n if (!data.subarray(0, 8).equals(CFB_MAGIC)) throw new Error(\"CFB 매직 바이트 불일치\")\n\n // ── 헤더 파싱 ──\n\n const sectorSizeShift = data.readUInt16LE(30)\n if (sectorSizeShift < 7 || sectorSizeShift > 16) throw new Error(\"유효하지 않은 섹터 크기 시프트: \" + sectorSizeShift)\n const sectorSize = 1 << sectorSizeShift // 보통 512\n const miniSectorSizeShift = data.readUInt16LE(32)\n if (miniSectorSizeShift > 16) throw new Error(\"유효하지 않은 미니 섹터 크기 시프트: \" + miniSectorSizeShift)\n const miniSectorSize = 1 << miniSectorSizeShift // 보통 64\n\n const fatSectorCount = data.readUInt32LE(44)\n if (fatSectorCount > 10000) throw new Error(\"FAT 섹터 수가 너무 많습니다: \" + fatSectorCount)\n const firstDirSector = data.readUInt32LE(48)\n const miniStreamCutoff = data.readUInt32LE(56) // 보통 4096\n const firstMiniFatSector = data.readUInt32LE(60)\n const miniFatSectorCount = data.readUInt32LE(64)\n const firstDifatSector = data.readUInt32LE(68)\n const difatSectorCount = data.readUInt32LE(72)\n\n // ── 유틸 ──\n\n function sectorOffset(id: number): number {\n return 512 + id * sectorSize\n }\n\n function readSectorData(id: number): Buffer {\n const off = sectorOffset(id)\n if (off + sectorSize > data.length) return Buffer.alloc(0)\n return data.subarray(off, off + sectorSize)\n }\n\n // ── DIFAT → FAT 섹터 목록 ──\n\n const fatSectors: number[] = []\n\n // 헤더 내 DIFAT (최대 109개)\n for (let i = 0; i < 109 && fatSectors.length < fatSectorCount; i++) {\n const sid = data.readUInt32LE(76 + i * 4)\n if (sid === FREE_SECT || sid === END_OF_CHAIN) break\n fatSectors.push(sid)\n }\n\n // 추가 DIFAT 섹터 체인\n let difatSector = firstDifatSector\n const visitedDifat = new Set<number>()\n for (let d = 0; d < difatSectorCount && difatSector !== END_OF_CHAIN && difatSector !== FREE_SECT; d++) {\n if (visitedDifat.has(difatSector)) break\n visitedDifat.add(difatSector)\n\n const buf = readSectorData(difatSector)\n const entriesPerSector = (sectorSize / 4) - 1 // 마지막 4바이트는 다음 DIFAT 포인터\n for (let i = 0; i < entriesPerSector && fatSectors.length < fatSectorCount; i++) {\n const sid = buf.readUInt32LE(i * 4)\n if (sid === FREE_SECT || sid === END_OF_CHAIN) continue\n fatSectors.push(sid)\n }\n difatSector = buf.readUInt32LE(entriesPerSector * 4)\n }\n\n // ── FAT 테이블 구축 ──\n\n const entriesPerFatSector = sectorSize / 4\n const fatTable = new Uint32Array(fatSectors.length * entriesPerFatSector)\n\n for (let fi = 0; fi < fatSectors.length; fi++) {\n const buf = readSectorData(fatSectors[fi])\n for (let i = 0; i < entriesPerFatSector; i++) {\n fatTable[fi * entriesPerFatSector + i] = i * 4 + 3 < buf.length\n ? buf.readUInt32LE(i * 4)\n : FREE_SECT\n }\n }\n\n // ── 체인 리더 (순환 방지) ──\n\n function readChain(startSector: number, maxBytes: number): Buffer {\n if (startSector === END_OF_CHAIN || startSector === FREE_SECT) return Buffer.alloc(0)\n if (maxBytes > MAX_STREAM_SIZE) throw new Error(\"스트림이 너무 큽니다\")\n\n const chunks: Buffer[] = []\n let current = startSector\n let totalRead = 0\n const visited = new Set<number>()\n\n while (current !== END_OF_CHAIN && current !== FREE_SECT && totalRead < maxBytes) {\n if (visited.has(current)) break // 순환 감지\n if (visited.size > MAX_CHAIN_LENGTH) break\n visited.add(current)\n\n const buf = readSectorData(current)\n const remaining = maxBytes - totalRead\n chunks.push(remaining < sectorSize ? buf.subarray(0, remaining) : buf)\n totalRead += Math.min(buf.length, remaining)\n\n current = current < fatTable.length ? fatTable[current] : END_OF_CHAIN\n }\n\n return Buffer.concat(chunks)\n }\n\n // ── Mini-FAT 테이블 ──\n\n let miniFatTable: Uint32Array | null = null\n\n function getMiniFatTable(): Uint32Array {\n if (miniFatTable) return miniFatTable\n\n if (miniFatSectorCount === 0 || firstMiniFatSector === END_OF_CHAIN) {\n miniFatTable = new Uint32Array(0)\n return miniFatTable\n }\n\n const miniFatData = readChain(firstMiniFatSector, miniFatSectorCount * sectorSize)\n const entries = miniFatData.length / 4\n miniFatTable = new Uint32Array(entries)\n for (let i = 0; i < entries; i++) {\n miniFatTable[i] = miniFatData.readUInt32LE(i * 4)\n }\n return miniFatTable\n }\n\n // ── 디렉토리 엔트리 파싱 ──\n\n const dirData = readChain(firstDirSector, MAX_DIR_ENTRIES * 128)\n const dirEntries: DirEntry[] = []\n\n for (let offset = 0; offset + 128 <= dirData.length && dirEntries.length < MAX_DIR_ENTRIES; offset += 128) {\n const nameLen = dirData.readUInt16LE(offset + 64) // 바이트 수 (null 포함)\n if (nameLen <= 0 || nameLen > 64) {\n dirEntries.push({ name: \"\", type: 0, startSector: 0, size: 0 })\n continue\n }\n\n const nameBytes = nameLen - 2 // null terminator 제외\n const name = nameBytes > 0\n ? dirData.subarray(offset, offset + nameBytes).toString(\"utf16le\")\n : \"\"\n\n const type = dirData[offset + 66]\n const startSector = dirData.readUInt32LE(offset + 116)\n // CFBv3에서는 size가 u32 (offset 120), v4에서는 u64\n const size = dirData.readUInt32LE(offset + 120)\n\n dirEntries.push({ name, type, startSector, size })\n }\n\n // ── Root 엔트리에서 미니 스트림 추출 ──\n\n let miniStreamData: Buffer | null = null\n\n function getMiniStream(): Buffer {\n if (miniStreamData) return miniStreamData\n const root = dirEntries[0]\n if (!root || root.type !== 5) {\n miniStreamData = Buffer.alloc(0)\n return miniStreamData\n }\n miniStreamData = readChain(root.startSector, root.size || MAX_STREAM_SIZE)\n return miniStreamData\n }\n\n // ── 미니 스트림에서 읽기 ──\n\n function readMiniStream(startSector: number, size: number): Buffer {\n const mft = getMiniFatTable()\n const ms = getMiniStream()\n if (mft.length === 0 || ms.length === 0) return Buffer.alloc(0)\n\n const chunks: Buffer[] = []\n let current = startSector\n let totalRead = 0\n const visited = new Set<number>()\n\n while (current !== END_OF_CHAIN && current !== FREE_SECT && totalRead < size) {\n if (visited.has(current)) break\n if (visited.size > MAX_CHAIN_LENGTH) break\n visited.add(current)\n\n const off = current * miniSectorSize\n const remaining = size - totalRead\n const chunkSize = Math.min(miniSectorSize, remaining)\n if (off + chunkSize <= ms.length) {\n chunks.push(ms.subarray(off, off + chunkSize))\n }\n totalRead += chunkSize\n\n current = current < mft.length ? mft[current] : END_OF_CHAIN\n }\n\n return Buffer.concat(chunks)\n }\n\n // ── 스트림 읽기 (일반/미니 자동 분기) ──\n\n function readStreamData(entry: DirEntry): Buffer {\n if (entry.size === 0) return Buffer.alloc(0)\n if (entry.size < miniStreamCutoff) {\n const miniResult = readMiniStream(entry.startSector, entry.size)\n // 미니스트림이 비어있으면 일반 체인으로 폴백 (lenient)\n if (miniResult.length > 0) return miniResult\n }\n return readChain(entry.startSector, entry.size)\n }\n\n // ── 경로 기반 탐색 ──\n\n // 전체 경로 맵 구축 (간이: 이름 기반 flat lookup)\n // HWP 파일의 디렉토리 구조는 보통 1~2 depth이므로 이름 매칭으로 충분\n function findEntryByPath(path: string): DirEntry | null {\n // \"/FileHeader\" → \"FileHeader\"\n // \"/BodyText/Section0\" → path component matching\n const parts = path.replace(/^\\//, \"\").split(\"/\")\n\n if (parts.length === 1) {\n // 단일 이름 매칭\n return dirEntries.find(e => e.name === parts[0] && e.type === 2) ?? null\n }\n\n // 2-depth: storage/stream\n // HWP 구조: Root/BodyText/Section0, Root/DocInfo, Root/BinData/BIN0001 등\n const storageName = parts[0]\n const streamName = parts.slice(1).join(\"/\")\n\n // 디렉토리 구조 대신 이름 패턴으로 찾기 (lenient)\n for (const e of dirEntries) {\n if (e.type === 2 && e.name === streamName) {\n // 부모 확인은 생략 (lenient) — 중복 이름 시 첫 번째 반환\n return e\n }\n }\n\n // 정확한 이름이 아닌 경우 (ViewText/Section0 등)\n const lastPart = parts[parts.length - 1]\n return dirEntries.find(e => e.type === 2 && e.name === lastPart) ?? null\n }\n\n // ── 공개 API ──\n\n return {\n findStream(path: string): Buffer | null {\n // \\005 prefix 처리 (SummaryInformation)\n const normalized = path.replace(/^\\//, \"\")\n const entry = findEntryByPath(normalized)\n if (!entry || entry.type !== 2) return null\n const stream = readStreamData(entry)\n return stream.length > 0 ? stream : null\n },\n\n entries(): DirEntry[] {\n return dirEntries.filter(e => e.type === 2) // stream만\n },\n }\n}\n","/**\r\n * HWPX 파서 — manifest 멀티섹션, colSpan/rowSpan, 중첩테이블\r\n *\r\n * lexdiff 기반 + edu-facility-ai 손상ZIP 복구\r\n */\r\n\r\nimport JSZip from \"jszip\"\r\nimport { inflateRawSync } from \"zlib\"\r\nimport { DOMParser } from \"@xmldom/xmldom\"\r\nimport { buildTable, convertTableToText, blocksToMarkdown, MAX_COLS, MAX_ROWS } from \"../table/builder.js\"\r\nimport type { CellContext, IRBlock, DocumentMetadata, InternalParseResult, ParseOptions, ParseWarning, OutlineItem, InlineStyle, ExtractedImage } from \"../types.js\"\r\nimport { HEADING_RATIO_H1, HEADING_RATIO_H2, HEADING_RATIO_H3 } from \"../types.js\"\r\nimport { KordocError, isPathTraversal, sanitizeHref, precheckZipSize, stripDtd } from \"../utils.js\"\r\n// 테스트 호환성 re-export\r\nexport { precheckZipSize } from \"../utils.js\"\r\nimport { parsePageRange } from \"../page-range.js\"\r\nimport { isComFallbackAvailable, isEncryptedHwpx, extractTextViaCom, comResultToParseResult } from \"./com-fallback.js\"\r\nimport { hmlToLatex } from \"./equation.js\"\r\n\r\n/** 압축 해제 최대 크기 (100MB) — ZIP bomb 방지 */\r\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\r\n/** 손상 ZIP 복구 시 최대 엔트리 수 */\r\nconst MAX_ZIP_ENTRIES = 500\r\n\r\n/** colSpan/rowSpan을 안전한 범위로 클램핑 */\r\nfunction clampSpan(val: number, max: number): number {\r\n return Math.max(1, Math.min(val, max))\r\n}\r\n\r\n/** XML DOM 재귀 최대 깊이 — 악성 파일의 스택 오버플로 방지 */\r\nconst MAX_XML_DEPTH = 200\r\n\r\ninterface TableState { rows: CellContext[][]; currentRow: CellContext[]; cell: CellContext | null }\r\n\r\n/** walk 함수들이 공유하는 파싱 컨텍스트 — 개별 optional 파라미터를 하나로 묶어 시그니처 안정화 */\r\ninterface WalkCtx {\r\n styleMap?: HwpxStyleMap\r\n warnings?: ParseWarning[]\r\n sectionNum?: number\r\n counter?: { count: number }\r\n}\r\n\r\n/** xmldom DOMParser 생성 — onError 콜백으로 malformed XML 경고 수집 */\r\nfunction createXmlParser(warnings?: ParseWarning[]): DOMParser {\r\n return new DOMParser({\r\n onError(level: \"warn\" | \"error\" | \"fatalError\", msg: string) {\r\n if (level === \"fatalError\") throw new KordocError(`XML 파싱 실패: ${msg}`)\r\n warnings?.push({ code: \"MALFORMED_XML\", message: `XML ${level === \"warn\" ? \"경고\" : \"오류\"}: ${msg}` })\r\n },\r\n })\r\n}\r\n\r\n// ─── HWPX 스타일 정보 ──────────────────────────────\r\n\r\ninterface HwpxCharProperty {\r\n fontSize?: number // 단위: pt (hwpx는 centi-pt → /100)\r\n bold?: boolean\r\n italic?: boolean\r\n fontName?: string\r\n}\r\n\r\ninterface HwpxStyleMap {\r\n charProperties: Map<string, HwpxCharProperty> // id → property\r\n styles: Map<string, { name: string; charPrId?: string; paraPrId?: string }> // id → style\r\n}\r\n\r\n/** head.xml 또는 header.xml에서 스타일 정보 추출 */\r\nasync function extractHwpxStyles(zip: JSZip, decompressed?: { total: number }): Promise<HwpxStyleMap> {\r\n const result: HwpxStyleMap = {\r\n charProperties: new Map(),\r\n styles: new Map(),\r\n }\r\n\r\n const headerPaths = [\"Contents/header.xml\", \"header.xml\", \"Contents/head.xml\", \"head.xml\"]\r\n for (const hp of headerPaths) {\r\n const hpLower = hp.toLowerCase()\r\n const file = zip.file(hp) || Object.values(zip.files).find(f => f.name.toLowerCase() === hpLower) || null\r\n if (!file) continue\r\n\r\n try {\r\n const xml = await file.async(\"text\")\r\n if (decompressed) {\r\n decompressed.total += xml.length * 2\r\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\r\n }\r\n const parser = createXmlParser()\r\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\r\n if (!doc.documentElement) continue\r\n\r\n // charProperties 파싱\r\n parseCharProperties(doc, result.charProperties)\r\n // styles 파싱\r\n parseStyleElements(doc, result.styles)\r\n break\r\n } catch { continue }\r\n }\r\n\r\n return result\r\n}\r\n\r\nfunction parseCharProperties(doc: Document, map: Map<string, HwpxCharProperty>): void {\r\n // <hh:charPr> 또는 <charPr> 요소 탐색\r\n const tagNames = [\"hh:charPr\", \"charPr\", \"hp:charPr\"]\r\n for (const tagName of tagNames) {\r\n const elements = doc.getElementsByTagName(tagName)\r\n for (let i = 0; i < elements.length; i++) {\r\n const el = elements[i]\r\n const id = el.getAttribute(\"id\") || el.getAttribute(\"IDRef\") || \"\"\r\n if (!id) continue\r\n\r\n const prop: HwpxCharProperty = {}\r\n\r\n // height 속성 (centi-pt 단위)\r\n const height = el.getAttribute(\"height\")\r\n if (height) {\r\n const parsedHeight = parseInt(height, 10)\r\n if (!isNaN(parsedHeight) && parsedHeight > 0) {\r\n prop.fontSize = parsedHeight / 100\r\n }\r\n }\r\n\r\n // bold/italic\r\n const bold = el.getAttribute(\"bold\")\r\n if (bold === \"true\" || bold === \"1\") prop.bold = true\r\n const italic = el.getAttribute(\"italic\")\r\n if (italic === \"true\" || italic === \"1\") prop.italic = true\r\n\r\n // 하위 요소에서 fontface 탐색\r\n const fontFaces = el.getElementsByTagName(\"*\")\r\n for (let j = 0; j < fontFaces.length; j++) {\r\n const ff = fontFaces[j]\r\n const localTag = (ff.tagName || \"\").replace(/^[^:]+:/, \"\")\r\n if (localTag === \"fontface\" || localTag === \"fontRef\") {\r\n const face = ff.getAttribute(\"face\") || ff.getAttribute(\"FontFace\")\r\n if (face) { prop.fontName = face; break }\r\n }\r\n }\r\n\r\n map.set(id, prop)\r\n }\r\n }\r\n}\r\n\r\nfunction parseStyleElements(doc: Document, map: Map<string, { name: string; charPrId?: string; paraPrId?: string }>): void {\r\n const tagNames = [\"hh:style\", \"style\", \"hp:style\"]\r\n for (const tagName of tagNames) {\r\n const elements = doc.getElementsByTagName(tagName)\r\n for (let i = 0; i < elements.length; i++) {\r\n const el = elements[i]\r\n const id = el.getAttribute(\"id\") || el.getAttribute(\"IDRef\") || String(i)\r\n const name = el.getAttribute(\"name\") || el.getAttribute(\"engName\") || \"\"\r\n const charPrId = el.getAttribute(\"charPrIDRef\") || undefined\r\n const paraPrId = el.getAttribute(\"paraPrIDRef\") || undefined\r\n map.set(id, { name, charPrId, paraPrId })\r\n }\r\n }\r\n}\r\n\r\n// stripDtd는 utils.js에서 import\r\n\r\nexport async function parseHwpxDocument(buffer: ArrayBuffer, options?: ParseOptions): Promise<InternalParseResult> {\r\n // Best-effort 사전 검증 — CD 선언 크기 기반 (위조 가능, 실제 방어는 per-file 누적 체크)\r\n precheckZipSize(buffer, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES)\r\n\r\n let zip: JSZip\r\n\r\n try {\r\n zip = await JSZip.loadAsync(buffer)\r\n } catch {\r\n return extractFromBrokenZip(buffer)\r\n }\r\n\r\n // loadAsync 후 실제 엔트리 수 검증 — CD 위조와 무관한 진짜 방어선\r\n const actualEntryCount = Object.keys(zip.files).length\r\n if (actualEntryCount > MAX_ZIP_ENTRIES) {\r\n throw new KordocError(\"ZIP 엔트리 수 초과 (ZIP bomb 의심)\")\r\n }\r\n\r\n // ── DRM 감지: manifest.xml에 encryption-data가 있으면 COM fallback ──\r\n const manifestFile = zip.file(\"META-INF/manifest.xml\")\r\n if (manifestFile) {\r\n const manifestXml = await manifestFile.async(\"text\")\r\n if (isEncryptedHwpx(manifestXml)) {\r\n // 파일 경로가 options에 있으면 COM fallback 시도\r\n if (isComFallbackAvailable() && options?.filePath) {\r\n const { pages, pageCount, warnings } = extractTextViaCom(options.filePath)\r\n if (pages.some(p => p && p.trim().length > 0)) {\r\n return comResultToParseResult(pages, pageCount, warnings)\r\n }\r\n }\r\n throw new KordocError(\"DRM 암호화된 HWPX 파일입니다. Windows + 한컴 오피스 설치 시 자동 추출됩니다.\")\r\n }\r\n }\r\n\r\n // ZIP 전체 파일 누적 압축해제 크기 추적 (비섹션 파일 포함)\r\n const decompressed = { total: 0 }\r\n\r\n // 메타데이터 추출 (best-effort)\r\n const metadata: DocumentMetadata = {}\r\n await extractHwpxMetadata(zip, metadata, decompressed)\r\n\r\n // 스타일 정보 추출 (best-effort)\r\n const styleMap = await extractHwpxStyles(zip, decompressed)\r\n const warnings: ParseWarning[] = []\r\n\r\n const sectionPaths = await resolveSectionPaths(zip)\r\n if (sectionPaths.length === 0) throw new KordocError(\"HWPX에서 섹션 파일을 찾을 수 없습니다\")\r\n\r\n metadata.pageCount = sectionPaths.length\r\n\r\n // 페이지 범위 필터링 (섹션 단위 근사치)\r\n const pageFilter = options?.pages ? parsePageRange(options.pages, sectionPaths.length) : null\r\n const totalTarget = pageFilter ? pageFilter.size : sectionPaths.length\r\n const blocks: IRBlock[] = []\r\n const nestedTableCounter = { count: 0 }\r\n let parsedSections = 0\r\n for (let si = 0; si < sectionPaths.length; si++) {\r\n if (pageFilter && !pageFilter.has(si + 1)) continue\r\n const file = zip.file(sectionPaths[si])\r\n if (!file) continue\r\n try {\r\n const xml = await file.async(\"text\")\r\n decompressed.total += xml.length * 2\r\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\r\n blocks.push(...parseSectionXml(xml, styleMap, warnings, si + 1, nestedTableCounter))\r\n parsedSections++\r\n options?.onProgress?.(parsedSections, totalTarget)\r\n } catch (secErr) {\r\n if (secErr instanceof KordocError) throw secErr\r\n warnings.push({ page: si + 1, message: `섹션 ${si + 1} 파싱 실패: ${secErr instanceof Error ? secErr.message : \"알 수 없는 오류\"}`, code: \"PARTIAL_PARSE\" })\r\n }\r\n }\r\n\r\n // 이미지 블록에서 ZIP 바이너리 추출\r\n const images = await extractImagesFromZip(zip, blocks, decompressed, warnings)\r\n\r\n // 스타일 기반 헤딩 감지\r\n detectHwpxHeadings(blocks, styleMap)\r\n\r\n // outline 구축\r\n const outline: OutlineItem[] = blocks\r\n .filter(b => b.type === \"heading\" && b.level && b.text)\r\n .map(b => ({ level: b.level!, text: b.text!, pageNumber: b.pageNumber }))\r\n\r\n const markdown = blocksToMarkdown(blocks)\r\n return { markdown, blocks, metadata, outline: outline.length > 0 ? outline : undefined, warnings: warnings.length > 0 ? warnings : undefined, images: images.length > 0 ? images : undefined }\r\n}\r\n\r\n// ─── 이미지 추출 ───────────────────────────────────\r\n\r\n/** 확장자 → MIME 타입 */\r\nfunction imageExtToMime(ext: string): string {\r\n switch (ext.toLowerCase()) {\r\n case \"jpg\": case \"jpeg\": return \"image/jpeg\"\r\n case \"png\": return \"image/png\"\r\n case \"gif\": return \"image/gif\"\r\n case \"bmp\": return \"image/bmp\"\r\n case \"tif\": case \"tiff\": return \"image/tiff\"\r\n case \"wmf\": return \"image/wmf\"\r\n case \"emf\": return \"image/emf\"\r\n case \"svg\": return \"image/svg+xml\"\r\n default: return \"application/octet-stream\"\r\n }\r\n}\r\n\r\n/** MIME → 확장자 */\r\nfunction mimeToExt(mime: string): string {\r\n if (mime.includes(\"jpeg\")) return \"jpg\"\r\n if (mime.includes(\"png\")) return \"png\"\r\n if (mime.includes(\"gif\")) return \"gif\"\r\n if (mime.includes(\"bmp\")) return \"bmp\"\r\n if (mime.includes(\"tiff\")) return \"tif\"\r\n if (mime.includes(\"wmf\")) return \"wmf\"\r\n if (mime.includes(\"emf\")) return \"emf\"\r\n if (mime.includes(\"svg\")) return \"svg\"\r\n return \"bin\"\r\n}\r\n\r\n/** blocks에서 type=\"image\" 블록의 참조를 ZIP에서 실제 바이너리로 변환 */\r\nasync function extractImagesFromZip(\r\n zip: JSZip,\r\n blocks: IRBlock[],\r\n decompressed: { total: number },\r\n warnings?: ParseWarning[],\r\n): Promise<ExtractedImage[]> {\r\n const images: ExtractedImage[] = []\r\n let imageIndex = 0\r\n\r\n for (const block of blocks) {\r\n if (block.type !== \"image\" || !block.text) continue\r\n\r\n const ref = block.text\r\n // BinData/ 폴더 내에서 참조 파일 찾기\r\n // HWPX binaryItemIDRef는 확장자 없이 오는 경우가 많음 (예: \"image1\" → \"BinData/image1.bmp\")\r\n const candidates = [\r\n `BinData/${ref}`,\r\n `Contents/BinData/${ref}`,\r\n ref, // 절대 경로일 수도 있음\r\n ]\r\n\r\n // 확장자 없는 ref인 경우 ZIP에서 매칭 파일 탐색\r\n let resolvedPath: string | null = null\r\n if (!ref.includes(\".\")) {\r\n const prefixes = [`BinData/${ref}`, `Contents/BinData/${ref}`]\r\n for (const prefix of prefixes) {\r\n const match = zip.file(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\.[a-zA-Z0-9]+$`))\r\n if (match.length > 0) { resolvedPath = match[0].name; break }\r\n }\r\n }\r\n\r\n let found = false\r\n const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates\r\n for (const path of allCandidates) {\r\n if (isPathTraversal(path)) continue\r\n const file = zip.file(path)\r\n if (!file) continue\r\n\r\n try {\r\n const data = await file.async(\"uint8array\")\r\n decompressed.total += data.length\r\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\r\n\r\n const actualPath = path\r\n const ext = actualPath.includes(\".\") ? (actualPath.split(\".\").pop() || \"png\") : \"png\"\r\n const mimeType = imageExtToMime(ext)\r\n imageIndex++\r\n const filename = `image_${String(imageIndex).padStart(3, \"0\")}.${mimeToExt(mimeType)}`\r\n\r\n images.push({ filename, data, mimeType })\r\n // 블록 텍스트를 참조 파일명으로 교체\r\n block.text = filename\r\n block.imageData = { data, mimeType, filename: ref }\r\n found = true\r\n break\r\n } catch (err) {\r\n if (err instanceof KordocError) throw err\r\n // 개별 이미지 실패는 경고로 처리\r\n }\r\n }\r\n\r\n if (!found) {\r\n warnings?.push({ page: block.pageNumber, message: `이미지 파일 없음: ${ref}`, code: \"SKIPPED_IMAGE\" })\r\n // image 블록을 paragraph로 전환 (참조만 남김)\r\n block.type = \"paragraph\"\r\n block.text = `[이미지: ${ref}]`\r\n }\r\n }\r\n\r\n return images\r\n}\r\n\r\n// ─── 메타데이터 추출 (best-effort) ───────────────────\r\n\r\n/**\r\n * HWPX ZIP 내 메타데이터 파일에서 Dublin Core 정보 추출.\r\n * 표준 경로: meta.xml, docProps/core.xml, META-INF/container.xml\r\n */\r\nasync function extractHwpxMetadata(zip: JSZip, metadata: DocumentMetadata, decompressed?: { total: number }): Promise<void> {\r\n try {\r\n // meta.xml (HWPX 표준) 또는 docProps/core.xml (OOXML 호환)\r\n const metaPaths = [\"meta.xml\", \"META-INF/meta.xml\", \"docProps/core.xml\"]\r\n for (const mp of metaPaths) {\r\n const file = zip.file(mp) || Object.values(zip.files).find(f => f.name.toLowerCase() === mp.toLowerCase()) || null\r\n if (!file) continue\r\n const xml = await file.async(\"text\")\r\n if (decompressed) {\r\n decompressed.total += xml.length * 2\r\n if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError(\"ZIP 압축 해제 크기 초과 (ZIP bomb 의심)\")\r\n }\r\n parseDublinCoreMetadata(xml, metadata)\r\n if (metadata.title || metadata.author) return\r\n }\r\n } catch {\r\n // best-effort\r\n }\r\n}\r\n\r\n/** Dublin Core (dc:) 메타데이터 XML 파싱 */\r\nfunction parseDublinCoreMetadata(xml: string, metadata: DocumentMetadata): void {\r\n const parser = createXmlParser()\r\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\r\n if (!doc.documentElement) return\r\n\r\n const getText = (tagNames: string[]): string | undefined => {\r\n for (const tag of tagNames) {\r\n const els = doc.getElementsByTagName(tag)\r\n if (els.length > 0) {\r\n const text = els[0].textContent?.trim()\r\n if (text) return text\r\n }\r\n }\r\n return undefined\r\n }\r\n\r\n metadata.title = metadata.title || getText([\"dc:title\", \"title\"])\r\n metadata.author = metadata.author || getText([\"dc:creator\", \"creator\", \"cp:lastModifiedBy\"])\r\n metadata.description = metadata.description || getText([\"dc:description\", \"description\", \"dc:subject\", \"subject\"])\r\n metadata.createdAt = metadata.createdAt || getText([\"dcterms:created\", \"meta:creation-date\"])\r\n metadata.modifiedAt = metadata.modifiedAt || getText([\"dcterms:modified\", \"meta:date\"])\r\n\r\n const keywords = getText([\"dc:keyword\", \"cp:keywords\", \"meta:keyword\"])\r\n if (keywords && !metadata.keywords) {\r\n metadata.keywords = keywords.split(/[,;]/).map(k => k.trim()).filter(Boolean)\r\n }\r\n}\r\n\r\n/** 메타데이터만 추출 (전체 파싱 없이) — MCP parse_metadata용 */\r\nexport async function extractHwpxMetadataOnly(buffer: ArrayBuffer): Promise<DocumentMetadata> {\r\n let zip: JSZip\r\n try {\r\n zip = await JSZip.loadAsync(buffer)\r\n } catch {\r\n throw new KordocError(\"HWPX ZIP을 열 수 없습니다\")\r\n }\r\n\r\n const metadata: DocumentMetadata = {}\r\n await extractHwpxMetadata(zip, metadata)\r\n\r\n const sectionPaths = await resolveSectionPaths(zip)\r\n metadata.pageCount = sectionPaths.length\r\n\r\n return metadata\r\n}\r\n\r\n// ─── 손상 ZIP 복구 (edu-facility-ai에서 포팅) ──────────\r\n\r\nfunction extractFromBrokenZip(buffer: ArrayBuffer): InternalParseResult {\r\n const data = new Uint8Array(buffer)\r\n const view = new DataView(buffer)\r\n let pos = 0\r\n const blocks: IRBlock[] = []\r\n const warnings: ParseWarning[] = [\r\n { code: \"BROKEN_ZIP_RECOVERY\", message: \"손상된 ZIP 구조 — Local File Header 기반 복구 모드\" },\r\n ]\r\n let totalDecompressed = 0\r\n let entryCount = 0\r\n let sectionNum = 0\r\n const nestedTableCounter = { count: 0 }\r\n\r\n while (pos < data.length - 30) {\r\n // PK\\x03\\x04 시그니처 확인 — 미매칭 시 다음 PK 시그니처까지 스캔 (중간 손상 복구)\r\n if (data[pos] !== 0x50 || data[pos + 1] !== 0x4b || data[pos + 2] !== 0x03 || data[pos + 3] !== 0x04) {\r\n pos++\r\n while (pos < data.length - 30) {\r\n if (data[pos] === 0x50 && data[pos + 1] === 0x4b && data[pos + 2] === 0x03 && data[pos + 3] === 0x04) break\r\n pos++\r\n }\r\n continue\r\n }\r\n\r\n if (++entryCount > MAX_ZIP_ENTRIES) break\r\n\r\n const method = view.getUint16(pos + 8, true)\r\n const compSize = view.getUint32(pos + 18, true)\r\n const nameLen = view.getUint16(pos + 26, true)\r\n const extraLen = view.getUint16(pos + 28, true)\r\n\r\n // nameLen 상한 — 비정상 값에 의한 대규모 버퍼 할당 방지\r\n if (nameLen > 1024 || extraLen > 65535) { pos += 30 + nameLen + extraLen; continue }\r\n\r\n const fileStart = pos + 30 + nameLen + extraLen\r\n // 범위 초과 검증 — OOB 및 무한 루프 방지\r\n if (fileStart + compSize > data.length) break\r\n if (compSize === 0 && method !== 0) { pos = fileStart; continue }\r\n\r\n const nameBytes = data.slice(pos + 30, pos + 30 + nameLen)\r\n const name = new TextDecoder().decode(nameBytes)\r\n\r\n // 경로 순회 방지 — 상위 디렉토리 참조 및 절대 경로 차단\r\n if (isPathTraversal(name)) { pos = fileStart + compSize; continue }\r\n const fileData = data.slice(fileStart, fileStart + compSize)\r\n pos = fileStart + compSize\r\n\r\n if (!name.toLowerCase().includes(\"section\") || !name.endsWith(\".xml\")) continue\r\n\r\n try {\r\n let content: string\r\n if (method === 0) {\r\n content = new TextDecoder().decode(fileData)\r\n } else if (method === 8) {\r\n const decompressed = inflateRawSync(Buffer.from(fileData), { maxOutputLength: MAX_DECOMPRESS_SIZE })\r\n content = new TextDecoder().decode(decompressed)\r\n } else {\r\n continue\r\n }\r\n totalDecompressed += content.length * 2\r\n if (totalDecompressed > MAX_DECOMPRESS_SIZE) throw new KordocError(\"압축 해제 크기 초과\")\r\n sectionNum++\r\n blocks.push(...parseSectionXml(content, undefined, warnings, sectionNum, nestedTableCounter))\r\n } catch {\r\n continue\r\n }\r\n }\r\n\r\n if (blocks.length === 0) throw new KordocError(\"손상된 HWPX에서 섹션 데이터를 복구할 수 없습니다\")\r\n const markdown = blocksToMarkdown(blocks)\r\n return { markdown, blocks, warnings: warnings.length > 0 ? warnings : undefined }\r\n}\r\n\r\n// ─── Manifest 해석 ───────────────────────────────────\r\n\r\nasync function resolveSectionPaths(zip: JSZip): Promise<string[]> {\r\n const manifestPaths = [\"Contents/content.hpf\", \"content.hpf\"]\r\n for (const mp of manifestPaths) {\r\n const mpLower = mp.toLowerCase()\r\n const file = zip.file(mp) || Object.values(zip.files).find(f => f.name.toLowerCase() === mpLower) || null\r\n if (!file) continue\r\n const xml = await file.async(\"text\")\r\n const paths = parseSectionPathsFromManifest(xml)\r\n if (paths.length > 0) return paths\r\n }\r\n\r\n // fallback: section*.xml 직접 검색\r\n const sectionFiles = zip.file(/[Ss]ection\\d+\\.xml$/)\r\n return sectionFiles.map(f => f.name).sort()\r\n}\r\n\r\nfunction parseSectionPathsFromManifest(xml: string): string[] {\r\n const parser = createXmlParser()\r\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\r\n const items = doc.getElementsByTagName(\"opf:item\")\r\n const spine = doc.getElementsByTagName(\"opf:itemref\")\r\n\r\n const isSectionId = (id: string) => /^s/i.test(id) || id.toLowerCase().includes(\"section\")\r\n const idToHref = new Map<string, string>()\r\n for (let i = 0; i < items.length; i++) {\r\n const item = items[i]\r\n const id = item.getAttribute(\"id\") || \"\"\r\n let href = item.getAttribute(\"href\") || \"\"\r\n const mediaType = item.getAttribute(\"media-type\") || \"\"\r\n if (!isSectionId(id) && !mediaType.includes(\"xml\")) continue\r\n if (!href.startsWith(\"/\") && !href.startsWith(\"Contents/\") && isSectionId(id))\r\n href = \"Contents/\" + href\r\n idToHref.set(id, href)\r\n }\r\n\r\n if (spine.length > 0) {\r\n const ordered: string[] = []\r\n for (let i = 0; i < spine.length; i++) {\r\n const href = idToHref.get(spine[i].getAttribute(\"idref\") || \"\")\r\n if (href) ordered.push(href)\r\n }\r\n if (ordered.length > 0) return ordered\r\n }\r\n return Array.from(idToHref.entries())\r\n .filter(([id]) => isSectionId(id))\r\n .sort((a, b) => a[0].localeCompare(b[0]))\r\n .map(([, href]) => href)\r\n}\r\n\r\n// ─── 헤딩 감지 (스타일 기반) ────────────────────────\r\n\r\n/** HWPX 스타일 기반 헤딩 감지 */\r\nfunction detectHwpxHeadings(blocks: IRBlock[], styleMap: HwpxStyleMap): void {\r\n // 본문 폰트 크기 결정\r\n let baseFontSize = 0\r\n const sizeFreq = new Map<number, number>()\r\n for (const b of blocks) {\r\n if (b.style?.fontSize) {\r\n sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + 1)\r\n }\r\n }\r\n let maxCount = 0\r\n for (const [size, count] of sizeFreq) {\r\n if (count > maxCount) { maxCount = count; baseFontSize = size }\r\n }\r\n\r\n for (const block of blocks) {\r\n if (block.type !== \"paragraph\" || !block.text) continue\r\n const text = block.text.trim()\r\n if (text.length === 0 || text.length > 200 || /^\\d+$/.test(text)) continue\r\n\r\n let level = 0\r\n\r\n // 폰트 크기 기반\r\n if (baseFontSize > 0 && block.style?.fontSize) {\r\n const ratio = block.style.fontSize / baseFontSize\r\n if (ratio >= HEADING_RATIO_H1) level = 1\r\n else if (ratio >= HEADING_RATIO_H2) level = 2\r\n else if (ratio >= HEADING_RATIO_H3) level = 3\r\n }\r\n\r\n // \"제N조/장/절\" 패턴 — 균등배분 공백 허용 (\"제 1 장\" → \"제1장\")\r\n const compactText = text.replace(/\\s+/g, \"\")\r\n if (/^제\\d+[조장절편]/.test(compactText) && text.length <= 50) {\r\n if (level === 0) level = 3\r\n }\r\n\r\n if (level > 0) {\r\n block.type = \"heading\"\r\n block.level = level\r\n }\r\n }\r\n}\r\n\r\n// ─── 섹션 XML 파싱 ──────────────────────────────────\r\n\r\n/** 중첩 테이블 마커 생성 — 순번 + 첫 행 힌트(있는 경우) */\r\nfunction makeNestedTableMarker(counter: { count: number }, rows: CellContext[][]): string {\r\n counter.count++\r\n const firstRow = rows[0] ?? []\r\n const hint = firstRow.map(c => c.text.trim().replace(/\\n/g, \" \")).filter(Boolean).join(\" | \")\r\n const hintChars = [...hint]\r\n const truncated = hintChars.length > 60 ? hintChars.slice(0, 60).join(\"\") + \"…\" : hint\r\n return truncated\r\n ? `[중첩 테이블 #${counter.count}: ${truncated}]`\r\n : `[중첩 테이블 #${counter.count}]`\r\n}\r\n\r\n/**\r\n * 중첩 테이블 처리 공통 로직 — walkSection/walkParagraphChildren 중복 제거\r\n * 큰 중첩 테이블(≥3행, ≥2열)은 별도 블록으로 분리, 작은 것은 텍스트로 평탄화.\r\n * 두 경우 모두 부모 셀에 마커 삽입. parentTable을 반환하여 tableCtx 갱신에 사용.\r\n */\r\nfunction handleNestedTable(\r\n newTable: TableState,\r\n tableStack: TableState[],\r\n blocks: IRBlock[],\r\n ctx: WalkCtx\r\n): TableState {\r\n const parentTable = tableStack.pop()!\r\n let nestedCols = 0\r\n for (const r of newTable.rows) if (r.length > nestedCols) nestedCols = r.length\r\n if (newTable.rows.length >= 3 && nestedCols >= 2) {\r\n blocks.push({ type: \"table\", table: buildTable(newTable.rows), pageNumber: ctx.sectionNum })\r\n if (parentTable.cell) {\r\n const marker = ctx.counter ? makeNestedTableMarker(ctx.counter, newTable.rows) : \"[중첩 테이블]\"\r\n parentTable.cell.text += (parentTable.cell.text ? \"\\n\" : \"\") + marker\r\n }\r\n } else {\r\n const nestedText = convertTableToText(newTable.rows)\r\n if (parentTable.cell) {\r\n const marker = ctx.counter ? makeNestedTableMarker(ctx.counter, newTable.rows) : \"[중첩 테이블]\"\r\n parentTable.cell.text += (parentTable.cell.text ? \"\\n\" : \"\") + marker + \"\\n\" + nestedText\r\n }\r\n }\r\n return parentTable\r\n}\r\n\r\nfunction parseSectionXml(xml: string, styleMap?: HwpxStyleMap, warnings?: ParseWarning[], sectionNum?: number, counter?: { count: number }): IRBlock[] {\r\n const parser = createXmlParser(warnings)\r\n const doc = parser.parseFromString(stripDtd(xml), \"text/xml\")\r\n if (!doc.documentElement) return []\r\n\r\n const blocks: IRBlock[] = []\r\n const ctx: WalkCtx = { styleMap, warnings, sectionNum, counter }\r\n walkSection(doc.documentElement, blocks, null, [], ctx)\r\n return blocks\r\n}\r\n\r\n/** pic/shape 요소에서 이미지 참조 경로 추출 (binaryItemIDRef 또는 href) */\r\nfunction extractImageRef(el: Element): string | null {\r\n // HWPX: <hp:imgRect> 또는 <hp:img> 내 binaryItemIDRef 속성\r\n // 또는 하위에서 img 관련 속성 탐색\r\n const children = el.childNodes\r\n if (!children) return null\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i] as Element\r\n if (child.nodeType !== 1) continue\r\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\r\n if (tag === \"imgRect\" || tag === \"img\" || tag === \"imgClip\") {\r\n const ref = child.getAttribute(\"binaryItemIDRef\") || child.getAttribute(\"href\") || \"\"\r\n if (ref) return ref\r\n }\r\n // lineShape > imgRect 같은 중첩 구조\r\n const nested = extractImageRef(child)\r\n if (nested) return nested\r\n }\r\n // 직접 속성 체크\r\n const directRef = el.getAttribute(\"binaryItemIDRef\") || \"\"\r\n if (directRef) return directRef\r\n return null\r\n}\r\n\r\nfunction walkSection(\r\n node: Node, blocks: IRBlock[],\r\n tableCtx: TableState | null, tableStack: TableState[],\r\n ctx: WalkCtx, depth: number = 0\r\n): void {\r\n if (depth > MAX_XML_DEPTH) return\r\n const children = node.childNodes\r\n if (!children) return\r\n\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType !== 1) continue\r\n\r\n const tag = el.tagName || el.localName || \"\"\r\n const localTag = tag.replace(/^[^:]+:/, \"\")\r\n\r\n switch (localTag) {\r\n case \"tbl\": {\r\n if (tableCtx) tableStack.push(tableCtx)\r\n const newTable: TableState = { rows: [], currentRow: [], cell: null }\r\n walkSection(el, blocks, newTable, tableStack, ctx, depth + 1)\r\n\r\n if (newTable.rows.length > 0) {\r\n if (tableStack.length > 0) {\r\n tableCtx = handleNestedTable(newTable, tableStack, blocks, ctx)\r\n } else {\r\n blocks.push({ type: \"table\", table: buildTable(newTable.rows), pageNumber: ctx.sectionNum })\r\n tableCtx = null\r\n }\r\n } else {\r\n tableCtx = tableStack.length > 0 ? tableStack.pop()! : null\r\n }\r\n break\r\n }\r\n\r\n case \"tr\":\r\n if (tableCtx) {\r\n tableCtx.currentRow = []\r\n walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1)\r\n if (tableCtx.currentRow.length > 0) tableCtx.rows.push(tableCtx.currentRow)\r\n tableCtx.currentRow = []\r\n }\r\n break\r\n\r\n case \"tc\":\r\n if (tableCtx) {\r\n tableCtx.cell = { text: \"\", colSpan: 1, rowSpan: 1 }\r\n walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1)\r\n if (tableCtx.cell) {\r\n tableCtx.currentRow.push(tableCtx.cell)\r\n tableCtx.cell = null\r\n }\r\n }\r\n break\r\n\r\n case \"cellAddr\":\r\n if (tableCtx?.cell) {\r\n const ca = parseInt(el.getAttribute(\"colAddr\") || \"\", 10)\r\n const ra = parseInt(el.getAttribute(\"rowAddr\") || \"\", 10)\r\n if (!isNaN(ca)) tableCtx.cell.colAddr = ca\r\n if (!isNaN(ra)) tableCtx.cell.rowAddr = ra\r\n }\r\n break\r\n\r\n case \"cellSpan\":\r\n if (tableCtx?.cell) {\r\n const rawCs = parseInt(el.getAttribute(\"colSpan\") || \"1\", 10)\r\n const cs = isNaN(rawCs) ? 1 : rawCs\r\n const rawRs = parseInt(el.getAttribute(\"rowSpan\") || \"1\", 10)\r\n const rs = isNaN(rawRs) ? 1 : rawRs\r\n tableCtx.cell.colSpan = clampSpan(cs, MAX_COLS)\r\n tableCtx.cell.rowSpan = clampSpan(rs, MAX_ROWS)\r\n }\r\n break\r\n\r\n case \"p\": {\r\n const { text, href, footnote, style } = extractParagraphInfo(el, ctx.styleMap)\r\n if (text) {\r\n if (tableCtx?.cell) {\r\n tableCtx.cell.text += (tableCtx.cell.text ? \"\\n\" : \"\") + text\r\n } else if (!tableCtx) {\r\n const block: IRBlock = { type: \"paragraph\", text, pageNumber: ctx.sectionNum }\r\n if (style) block.style = style\r\n if (href) block.href = href\r\n if (footnote) block.footnoteText = footnote\r\n blocks.push(block)\r\n }\r\n }\r\n // <p> 내부의 <tbl>만 별도 처리 — extractParagraphInfo가 이미 텍스트를 추출했으므로\r\n // 전체 walkSection 재귀 대신 테이블/이미지 자식만 선택적으로 처리\r\n tableCtx = walkParagraphChildren(el, blocks, tableCtx, tableStack, ctx, depth + 1)\r\n break\r\n }\r\n\r\n // 이미지/그림 — 경로 추출 또는 경고\r\n case \"pic\": case \"shape\": case \"drawingObject\": {\r\n const imgRef = extractImageRef(el)\r\n if (imgRef) {\r\n blocks.push({ type: \"image\", text: imgRef, pageNumber: ctx.sectionNum })\r\n } else if (ctx.warnings && ctx.sectionNum) {\r\n ctx.warnings.push({ page: ctx.sectionNum, message: `스킵된 요소: ${localTag}`, code: \"SKIPPED_IMAGE\" })\r\n }\r\n break\r\n }\r\n\r\n default:\r\n walkSection(el, blocks, tableCtx, tableStack, ctx, depth + 1)\r\n break\r\n }\r\n }\r\n}\r\n\r\n/** <p> 내부에서 텍스트가 아닌 구조적 자식만 처리 (tbl, pic, shape). tableCtx 반환으로 상태 전파 */\r\nfunction walkParagraphChildren(\r\n node: Node, blocks: IRBlock[],\r\n tableCtx: TableState | null, tableStack: TableState[],\r\n ctx: WalkCtx, depth: number = 0\r\n): TableState | null {\r\n if (depth > MAX_XML_DEPTH) return tableCtx\r\n const children = node.childNodes\r\n if (!children) return tableCtx\r\n const walkChildren = (parent: Node, d: number) => {\r\n if (d > MAX_XML_DEPTH) return\r\n const kids = parent.childNodes\r\n if (!kids) return\r\n for (let i = 0; i < kids.length; i++) {\r\n const el = kids[i] as Element\r\n if (el.nodeType !== 1) continue\r\n const tag = el.tagName || el.localName || \"\"\r\n const localTag = tag.replace(/^[^:]+:/, \"\")\r\n\r\n if (localTag === \"tbl\") {\r\n // 테이블은 walkSection으로 위임\r\n if (tableCtx) tableStack.push(tableCtx)\r\n const newTable: TableState = { rows: [], currentRow: [], cell: null }\r\n walkSection(el, blocks, newTable, tableStack, ctx, d + 1)\r\n if (newTable.rows.length > 0) {\r\n if (tableStack.length > 0) {\r\n tableCtx = handleNestedTable(newTable, tableStack, blocks, ctx)\r\n } else {\r\n blocks.push({ type: \"table\", table: buildTable(newTable.rows), pageNumber: ctx.sectionNum })\r\n tableCtx = null\r\n }\r\n } else {\r\n tableCtx = tableStack.length > 0 ? tableStack.pop()! : null\r\n }\r\n } else if (localTag === \"pic\" || localTag === \"shape\" || localTag === \"drawingObject\") {\r\n // 도형/이미지 안에 drawText(글상자)가 있으면 텍스트 추출 우선\r\n const drawTextChild = findDescendant(el, \"drawText\")\r\n if (drawTextChild) {\r\n extractDrawTextBlocks(drawTextChild, blocks, ctx.styleMap, ctx.sectionNum)\r\n } else {\r\n const imgRef = extractImageRef(el)\r\n if (imgRef) {\r\n blocks.push({ type: \"image\", text: imgRef, pageNumber: ctx.sectionNum })\r\n } else if (ctx.warnings && ctx.sectionNum) {\r\n ctx.warnings.push({ page: ctx.sectionNum, message: `스킵된 요소: ${localTag}`, code: \"SKIPPED_IMAGE\" })\r\n }\r\n }\r\n } else if (localTag === \"drawText\") {\r\n // 글상자(TextBox) 안 텍스트 추출 — <hp:p> 순회\r\n extractDrawTextBlocks(el, blocks, ctx.styleMap, ctx.sectionNum)\r\n } else if (localTag === \"r\" || localTag === \"run\" || localTag === \"ctrl\"\r\n || localTag === \"rect\" || localTag === \"ellipse\" || localTag === \"polygon\"\r\n || localTag === \"line\" || localTag === \"arc\" || localTag === \"curve\"\r\n || localTag === \"connectLine\" || localTag === \"container\") {\r\n // <hp:run>, <hp:ctrl>, 도형 요소 내부에 테이블/이미지/글상자가 포함될 수 있음 — 재귀\r\n walkChildren(el, d + 1)\r\n } else if (localTag === \"run\") {\r\n tableCtx = walkParagraphChildren(el, blocks, tableCtx, tableStack, ctx, depth + 1)\r\n }\r\n }\r\n }\r\n walkChildren(node, depth)\r\n return tableCtx\r\n}\r\n\r\n/** 자손에서 특정 태그명의 첫 번째 요소 탐색 (최대 깊이 5) */\r\nfunction findDescendant(node: Node, targetTag: string, depth = 0): Element | null {\r\n if (depth > 5) return null\r\n const children = node.childNodes\r\n if (!children) return null\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i] as Element\r\n if (child.nodeType !== 1) continue\r\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\r\n if (tag === targetTag) return child\r\n const found = findDescendant(child, targetTag, depth + 1)\r\n if (found) return found\r\n }\r\n return null\r\n}\r\n\r\n/** drawText(글상자) 내부의 <p> 요소들에서 텍스트를 추출하여 paragraph 블록 생성 */\r\nfunction extractDrawTextBlocks(drawTextNode: Node, blocks: IRBlock[], styleMap?: HwpxStyleMap, sectionNum?: number): void {\r\n const children = drawTextNode.childNodes\r\n if (!children) return\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i] as Element\r\n if (child.nodeType !== 1) continue\r\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\r\n if (tag === \"subList\" || tag === \"p\" || tag === \"para\") {\r\n // subList 안의 <p>들을 순회\r\n if (tag === \"subList\") {\r\n extractDrawTextBlocks(child, blocks, styleMap, sectionNum)\r\n } else {\r\n const info = extractParagraphInfo(child, styleMap)\r\n const text = info.text.trim()\r\n if (text) {\r\n blocks.push({ type: \"paragraph\", text, style: info.style ?? undefined, pageNumber: sectionNum })\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\ninterface ParagraphInfo {\r\n text: string\r\n href?: string\r\n footnote?: string\r\n style?: InlineStyle\r\n}\r\n\r\nfunction extractParagraphInfo(para: Element, styleMap?: HwpxStyleMap): ParagraphInfo {\r\n let text = \"\"\r\n let href: string | undefined\r\n let footnote: string | undefined\r\n let charPrId: string | undefined\r\n\r\n // 문단의 스타일 참조 → charPr로 간접 조회\r\n // HWPX <p>에는 paraPrIDRef/styleIDRef가 있고, charPrIDRef는 <r> 요소에 있음\r\n // 여기서는 일단 null — <r> 요소에서 charPrIDRef를 가져옴\r\n\r\n const walk = (node: Node) => {\r\n const children = node.childNodes\r\n if (!children) return\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i] as Element\r\n if (child.nodeType === 3) { text += child.textContent || \"\"; continue }\r\n if (child.nodeType !== 1) continue\r\n\r\n const tag = (child.tagName || child.localName || \"\").replace(/^[^:]+:/, \"\")\r\n switch (tag) {\r\n case \"t\": walk(child); break // 자식 순회 (tab 등 하위 요소 처리)\r\n case \"tab\": {\r\n const leader = child.getAttribute(\"leader\")\r\n if (leader && leader !== \"0\") {\r\n // 목차 리더 탭 (점선/실선 등) — 뒤에 페이지번호가 오므로 이후 텍스트 무시\r\n text += \"\\x1F\" // 특수 마커: 이후 텍스트 제거용\r\n } else {\r\n text += \"\\t\"\r\n }\r\n break\r\n }\r\n case \"br\":\r\n if ((child.getAttribute(\"type\") || \"line\") === \"line\") text += \"\\n\"\r\n break\r\n case \"fwSpace\": case \"hwSpace\": text += \" \"; break\r\n case \"tbl\": break // 테이블은 walkSection에서 처리\r\n\r\n // 하이퍼링크\r\n case \"hyperlink\": {\r\n const url = child.getAttribute(\"url\") || child.getAttribute(\"href\") || \"\"\r\n if (url) {\r\n // XSS 방지: 추출 시점에서 href 살균\r\n const safe = sanitizeHref(url)\r\n if (safe) href = safe\r\n }\r\n // 하이퍼링크 내 텍스트 추출\r\n walk(child)\r\n break\r\n }\r\n\r\n // 각주/미주\r\n case \"footNote\": case \"endNote\": case \"fn\": case \"en\": {\r\n const noteText = extractTextFromNode(child)\r\n if (noteText) footnote = (footnote ? footnote + \"; \" : \"\") + noteText\r\n break\r\n }\r\n\r\n // 제어 요소 — 필드, 컨트롤, 매개변수 등 스킵\r\n case \"ctrl\": case \"fieldBegin\": case \"fieldEnd\":\r\n case \"parameters\": case \"stringParam\": case \"integerParam\":\r\n case \"boolParam\": case \"floatParam\":\r\n case \"secPr\": // 섹션 속성 (페이지 설정 등)\r\n case \"colPr\": // 다단 속성\r\n case \"linesegarray\": case \"lineseg\": // 레이아웃 정보\r\n // 도형/이미지 요소 — 대체텍스트(\"사각형입니다.\" 등) 누출 방지\r\n case \"pic\": case \"shape\": case \"drawingObject\":\r\n case \"shapeComment\": case \"drawText\":\r\n break\r\n\r\n // 수식: <hp:equation> 내부의 <hp:script> 에 HULK-style equation\r\n // 스크립트가 담겨 있음. hml-equation-parser 로 LaTeX 변환 후 `$...$`\r\n // 로 래핑. 실패/빈 스크립트면 무시 (대체 텍스트 누출 방지).\r\n case \"equation\": {\r\n const script = findChildByLocalName(child, \"script\")\r\n const raw = script ? extractTextFromNode(script) : \"\"\r\n if (raw.trim()) {\r\n try {\r\n const latex = hmlToLatex(raw).trim()\r\n if (latex) text += \" $\" + latex + \"$ \"\r\n } catch {\r\n // 변환 실패 시 조용히 드롭 — 텍스트 품질이 우선\r\n }\r\n }\r\n break\r\n }\r\n\r\n // run 요소에서 charPrIDRef 추출\r\n case \"r\": {\r\n const runCharPr = child.getAttribute(\"charPrIDRef\")\r\n if (runCharPr && !charPrId) charPrId = runCharPr\r\n walk(child)\r\n break\r\n }\r\n\r\n default: walk(child); break\r\n }\r\n }\r\n }\r\n walk(para)\r\n\r\n // 목차 리더 마커(\\x1F) 이후 텍스트(페이지번호) 제거\r\n const leaderIdx = text.indexOf(\"\\x1F\")\r\n if (leaderIdx >= 0) text = text.substring(0, leaderIdx)\r\n\r\n let cleanText = text.replace(/[ \\t]+/g, \" \").trim()\r\n\r\n // 한글 이미지 OLE 대체 텍스트 필터링 (\"그림입니다. 원본 그림의 이름: ...\")\r\n if (/^그림입니다\\.?\\s*원본\\s*그림의\\s*(이름|크기)/.test(cleanText)) cleanText = \"\"\r\n // 멀티라인으로 삽입된 OLE 대체 텍스트도 제거\r\n cleanText = cleanText.replace(/그림입니다\\.?\\s*원본\\s*그림의\\s*(이름|크기)[^\\n]*(\\n[^\\n]*원본\\s*그림의\\s*(이름|크기)[^\\n]*)*/g, \"\").trim()\r\n // HWP 도형/개체 대체텍스트 제거 (\"사각형입니다.\", \"개체 입니다.\" 등)\r\n // NOTE: \"수식\" 은 제거 목록에서 빠져있음 — <hp:equation> 파싱으로 LaTeX 본문이 이미\r\n // `$...$` 형태로 삽입되기 때문에 여기서 지울 alt-text 는 존재하지 않는다.\r\n cleanText = cleanText.replace(/(?:모서리가 둥근 |둥근 )?(?:사각형|직사각형|정사각형|원|타원|삼각형|선|직선|곡선|화살표|오각형|육각형|팔각형|별|십자|구름|마름모|도넛|평행사변형|사다리꼴|개체|그리기\\s?개체|묶음\\s?개체|글상자|표|그림|OLE\\s?개체)\\s?입니다\\.?/g, \"\").trim()\r\n\r\n // 스타일 정보 조회\r\n let style: InlineStyle | undefined\r\n if (styleMap && charPrId) {\r\n const charProp = styleMap.charProperties.get(charPrId)\r\n if (charProp) {\r\n style = {}\r\n if (charProp.fontSize) style.fontSize = charProp.fontSize\r\n if (charProp.bold) style.bold = true\r\n if (charProp.italic) style.italic = true\r\n if (charProp.fontName) style.fontName = charProp.fontName\r\n if (!style.fontSize && !style.bold && !style.italic) style = undefined\r\n }\r\n }\r\n\r\n return { text: cleanText, href, footnote, style }\r\n}\r\n\r\n/** 자식 중 지정된 localName(접두사 제거)을 가진 첫 번째 Element 반환 */\r\nfunction findChildByLocalName(parent: Element, name: string): Element | null {\r\n const children = parent.childNodes\r\n if (!children) return null\r\n for (let i = 0; i < children.length; i++) {\r\n const ch = children[i] as Element\r\n if (ch.nodeType !== 1) continue\r\n const tag = (ch.tagName || ch.localName || \"\").replace(/^[^:]+:/, \"\")\r\n if (tag === name) return ch\r\n }\r\n return null\r\n}\r\n\r\n/** 노드 내 모든 텍스트를 재귀적으로 추출 */\r\nfunction extractTextFromNode(node: Node): string {\r\n let result = \"\"\r\n const children = node.childNodes\r\n if (!children) return result\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i]\r\n if (child.nodeType === 3) result += child.textContent || \"\"\r\n else if (child.nodeType === 1) result += extractTextFromNode(child)\r\n }\r\n return result.trim()\r\n}\r\n","/**\r\n * HWPX DRM 문서 COM fallback — 한컴 오피스 COM API (GetPageText) 활용\r\n *\r\n * DRM 암호화된 HWPX 파일을 한컴 오피스의 HWPFrame.HwpObject COM으로 열어\r\n * 페이지별 텍스트를 추출한다. Windows + 한컴 오피스 설치 필수.\r\n *\r\n * 흐름: manifest.xml에 encryption-data 발견 → COM으로 Open → GetPageText(1..N) → Markdown\r\n */\r\n\r\nimport { execFileSync } from \"child_process\"\r\nimport { platform } from \"os\"\r\nimport type { InternalParseResult, ParseWarning, DocumentMetadata, IRBlock } from \"../types.js\"\r\n\r\n/** COM fallback 사용 가능 여부 (Windows만) */\r\nexport function isComFallbackAvailable(): boolean {\r\n return platform() === \"win32\"\r\n}\r\n\r\n/** manifest.xml 내용에서 encryption-data 존재 여부 확인 */\r\nexport function isEncryptedHwpx(manifestXml: string): boolean {\r\n return manifestXml.includes(\"encryption-data\")\r\n}\r\n\r\n/**\r\n * COM API로 DRM HWPX 파일의 텍스트를 추출\r\n * @param filePath 디스크 상의 HWPX 파일 절대 경로\r\n */\r\nexport function extractTextViaCom(filePath: string): { pages: string[]; pageCount: number; warnings: ParseWarning[] } {\r\n if (!isComFallbackAvailable()) {\r\n throw new Error(\"COM fallback은 Windows에서만 사용 가능합니다\")\r\n }\r\n\r\n // PowerShell 스크립트를 인라인으로 실행\r\n //\r\n // 핵심 우회: 파일을 %TEMP%로 복사한 뒤 해당 경로로 Open.\r\n // 한컴 오피스는 파일 경로가 \"신뢰 영역\"(사용자 Temp/AppData 등) 밖일 때\r\n // FilePathChecker가 경고 팝업을 띄운다. FilePathCheckerModuleExample DLL이\r\n // 등록된 개발 환경에서는 RegisterModule이 작동해 경고가 억제되지만, 일반\r\n // 사용자 환경에는 해당 DLL이 없다.\r\n // %TEMP% 하위 경로로 복사하면 신뢰 영역 규칙에 의해 경고가 나오지 않아\r\n // DLL 등록 없이도 안정적으로 DRM 텍스트를 추출할 수 있다.\r\n //\r\n // - RegisterModule: 보안 경고 1차 억제(DLL 없어도 해가 없음)\r\n // - GetPageText: DRM 우회 텍스트 추출\r\n // filePath를 single-quote로 이스케이프 (내부 ' → '')\r\n const escaped = filePath.replace(/'/g, \"''\")\r\n const ps1 = `\r\n[Console]::OutputEncoding = [System.Text.Encoding]::UTF8\r\n$ErrorActionPreference = 'Stop'\r\n\r\n$src = '${escaped}'\r\n$tmpDir = Join-Path $env:TEMP ('hwp-com-' + [guid]::NewGuid().ToString('N'))\r\n[void](New-Item -ItemType Directory -Path $tmpDir -Force)\r\n$tmpFile = Join-Path $tmpDir (Split-Path $src -Leaf)\r\nCopy-Item -LiteralPath $src -Destination $tmpFile -Force\r\n\r\ntry {\r\n $hwp = New-Object -ComObject HWPFrame.HwpObject\r\n $hwp.RegisterModule('FilePathCheckerModule', 'FilePathCheckerModuleExample') | Out-Null\r\n $hwp.Open($tmpFile, '', '') | Out-Null\r\n $pc = $hwp.PageCount\r\n $result = @{ pageCount = $pc; pages = @() }\r\n for ($p = 1; $p -le $pc; $p++) {\r\n $t = $hwp.GetPageText($p, 0)\r\n $result.pages += @($t)\r\n }\r\n $hwp.Clear(1) | Out-Null\r\n try { $hwp.Quit() | Out-Null } catch { }\r\n [System.Runtime.InteropServices.Marshal]::ReleaseComObject($hwp) | Out-Null\r\n [GC]::Collect()\r\n [GC]::WaitForPendingFinalizers()\r\n $result | ConvertTo-Json -Depth 3 -Compress\r\n} catch {\r\n @{ error = $_.Exception.Message } | ConvertTo-Json -Compress\r\n} finally {\r\n # 임시 파일 정리 + 좀비 Hwp.exe 방지용 garbage collect\r\n try { Remove-Item -LiteralPath $tmpDir -Recurse -Force -ErrorAction SilentlyContinue } catch { }\r\n [GC]::Collect()\r\n [GC]::WaitForPendingFinalizers()\r\n}\r\n`\r\n\r\n const stdout = execFileSync(\"powershell\", [\r\n \"-NoProfile\",\r\n \"-NonInteractive\",\r\n \"-ExecutionPolicy\", \"Bypass\",\r\n \"-Command\", ps1,\r\n ], {\r\n encoding: \"utf-8\",\r\n timeout: 120_000, // 2분 타임아웃\r\n windowsHide: true,\r\n maxBuffer: 50 * 1024 * 1024, // 50MB\r\n })\r\n\r\n // COM 메서드 반환값 등 JSON 앞의 garbage 제거\r\n const trimmed = stdout.trim()\r\n const jsonStart = trimmed.indexOf(\"{\")\r\n if (jsonStart < 0) throw new Error(`COM 출력에 JSON이 없습니다: ${trimmed.slice(0, 200)}`)\r\n const json = JSON.parse(trimmed.slice(jsonStart))\r\n if (json.error) {\r\n throw new Error(`COM 텍스트 추출 실패: ${json.error}`)\r\n }\r\n\r\n const warnings: ParseWarning[] = []\r\n const pages: string[] = Array.isArray(json.pages) ? json.pages : []\r\n const pageCount: number = json.pageCount ?? pages.length\r\n\r\n if (pages.length === 0) {\r\n warnings.push({ message: \"COM으로 텍스트를 추출하지 못했습니다\", code: \"COM_EMPTY\" })\r\n }\r\n\r\n return { pages, pageCount, warnings }\r\n}\r\n\r\n/**\r\n * COM 추출 결과를 InternalParseResult로 변환\r\n */\r\nexport function comResultToParseResult(\r\n pages: string[],\r\n pageCount: number,\r\n warnings: ParseWarning[],\r\n): InternalParseResult {\r\n const blocks: IRBlock[] = []\r\n const lines: string[] = []\r\n\r\n for (let i = 0; i < pages.length; i++) {\r\n const text = (pages[i] ?? \"\").trim()\r\n if (!text) continue\r\n\r\n // 페이지 텍스트를 paragraph 블록들로 변환\r\n const paragraphs = text.split(/\\n/)\r\n for (const para of paragraphs) {\r\n const trimmed = para.trim()\r\n if (!trimmed) continue\r\n blocks.push({ type: \"paragraph\", text: trimmed, pageNumber: i + 1 })\r\n lines.push(trimmed)\r\n }\r\n }\r\n\r\n const markdown = lines.join(\"\\n\\n\")\r\n const metadata: DocumentMetadata = { pageCount }\r\n\r\n warnings.push({\r\n message: \"DRM 문서: 한컴 COM API로 텍스트 추출 (서식/표 정보 제한적)\",\r\n code: \"DRM_COM_FALLBACK\",\r\n })\r\n\r\n return {\r\n markdown,\r\n blocks,\r\n metadata,\r\n warnings: warnings.length > 0 ? warnings : undefined,\r\n }\r\n}\r\n","/**\n * HWPX/HWP equation script → LaTeX\n *\n * Ported from hml-equation-parser (Python, Apache 2.0)\n * https://github.com/OpenBapul/hml-equation-parser\n * Copyright 2018 Open Bapul\n * See THIRD_PARTY/hml-equation-parser.txt for the full license.\n *\n * Entry point: `hmlToLatex(script)`.\n *\n * Notes:\n * - The input is the raw text of <hp:script> inside <hp:equation>, i.e.\n * Hancom's mini equation language (\"HULK-style\"). Example:\n * x = { -b +- SQRT { b^2 -4ac } } over {2a}\n * is converted to:\n * x = \\frac { -b +- \\sqrt { b^2 -4ac } }{2a}\n * - The algorithm is a direct port of hulkEqParser.py / hulkReplaceMethod.py\n * with the same 5-pass rewrite (frac → rootOf → matrix → bar → brace).\n */\n\ninterface MatrixMapping {\n begin: string\n end: string\n removeOutterBrackets: boolean\n}\n\n// ─── convertMap (from convertMap.json) ────────────────────────────────────\n// Single-token replacements (applied to each whitespace-delimited token).\nconst CONVERT_MAP: Record<string, string> = {\n TIMES: \"\\\\times\", times: \"\\\\times\",\n LEFT: \"\\\\left\", RIGHT: \"\\\\right\",\n under: \"\\\\underline\",\n SMALLSUM: \"\\\\sum\", sum: \"\\\\sum\",\n SMALLPROD: \"\\\\prod\", prod: \"\\\\prod\",\n SMALLINTER: \"\\\\cap\",\n CUP: \"\\\\cup\",\n OPLUS: \"\\\\oplus\", OMINUS: \"\\\\ominus\", OTIMES: \"\\\\otimes\", ODIV: \"\\\\oslash\", ODOT: \"\\\\odot\",\n LOR: \"\\\\lor\", LAND: \"\\\\land\",\n SUBSET: \"\\\\subset\", SUPERSET: \"\\\\supset\", SUBSETEQ: \"\\\\subseteq\", SUPSETEQ: \"\\\\supseteq\",\n IN: \"\\\\in\", OWNS: \"\\\\owns\", NOTIN: \"\\\\notin\",\n LEQ: \"\\\\leq\", GEQ: \"\\\\geq\",\n \"<<\": \"\\\\ll\", \">>\": \"\\\\gg\", \"<<<\": \"\\\\lll\", \">>>\": \"\\\\ggg\",\n PREC: \"\\\\prec\", SUCC: \"\\\\succ\",\n UPLUS: \"\\\\uplus\",\n \"±\": \"\\\\pm\", \"-+\": \"\\\\mp\", \"÷\": \"\\\\div\",\n CIRC: \"\\\\circ\", BULLET: \"\\\\bullet\", DEG: \" ^\\\\circ\",\n AST: \"\\\\ast\", STAR: \"\\\\bigstar\", BIGCIRC: \"\\\\bigcirc\",\n EMPTYSET: \"\\\\emptyset\",\n THEREFORE: \"\\\\therefore\", BECAUSE: \"\\\\because\", EXIST: \"\\\\exists\",\n \"!=\": \"\\\\neq\",\n SMCOPROD: \"\\\\coprod\", coprod: \"\\\\coprod\",\n SQCAP: \"\\\\sqcap\", SQCUP: \"\\\\sqcup\",\n SQSUBSET: \"\\\\sqsubset\", SQSUBSETEQ: \"\\\\sqsubseteq\",\n BIGSQCUP: \"\\\\bigsqcup\",\n BIGOPLUS: \"\\\\bigoplus\", BIGOTIMES: \"\\\\bigotimes\", BIGODOT: \"\\\\bigodot\", BIGUPLUS: \"\\\\biguplus\",\n inter: \"\\\\bigcap\", union: \"\\\\bigcup\",\n BIGOMINUS: \"{\\\\Large\\\\ominus}\", BIGODIV: \"{\\\\Large\\\\oslash}\",\n UNDEROVER: \"\",\n SIM: \"\\\\sim\", APPROX: \"\\\\approx\", SIMEQ: \"\\\\simeq\", CONG: \"\\\\cong\",\n \"==\": \"\\\\equiv\",\n DIAMOND: \"\\\\diamond\", FORALL: \"\\\\forall\",\n prime: \"'\", Partial: \"\\\\partial\", INF: \"\\\\infty\", PROPTO: \"\\\\propto\",\n lim: \"\\\\lim\", Lim: \"\\\\lim\",\n larrow: \"\\\\leftarrow\", \"->\": \"\\\\rightarrow\",\n uparrow: \"\\\\uparrow\", downarrow: \"\\\\downarrow\",\n LARROW: \"\\\\Leftarrow\", RARROW: \"\\\\Rightarrow\",\n UPARROW: \"\\\\Uparrow\", DOWNARROW: \"\\\\Downarrow\",\n udarrow: \"\\\\updownarrow\",\n \"<->\": \"\\\\leftrightarrow\",\n UDARROW: \"\\\\Updownarrow\", LRARROW: \"\\\\Leftrightarrow\",\n NWARROW: \"\\\\nwarrow\", SEARROW: \"\\\\searrow\", NEARROW: \"\\\\nearrow\", SWARROW: \"\\\\swarrow\",\n HOOKLEFT: \"\\\\hookleftarrow\", HOOKRIGHT: \"\\\\hookrightarrow\",\n PVER: \"\\\\|\", MAPSTO: \"\\\\mapsto\",\n CDOTS: \"\\\\cdots\", LDOTS: \"\\\\ldots\", VDOTS: \"\\\\vdots\", DDOTS: \"\\\\ddots\",\n DAGGER: \"\\\\dagger\", DDAGGER: \"\\\\ddagger\", DOTEQ: \"\\\\doteq\",\n image: \"\\\\fallingdotseq\", REIMAGE: \"\\\\risingdotseq\",\n ASYMP: \"\\\\asymp\", ISO: \"\\\\Bumpeq\",\n DSUM: \"\\\\dotplus\", XOR: \"\\\\veebar\",\n TRIANGLE: \"\\\\triangle\", NABLA: \"\\\\nabla\",\n ANGLE: \"\\\\angle\", MSANGLE: \"\\\\measuredangle\", SANGLE: \"\\\\sphericalangle\",\n VDASH: \"\\\\vdash\", DASHV: \"\\\\dashv\",\n BOT: \"\\\\bot\", TOP: \"\\\\top\", MODELS: \"\\\\models\",\n LAPLACE: \"\\\\mathcal{L}\",\n CENTIGRADE: \"^{\\\\circ}C\", FAHRENHEIT: \"^{\\\\circ}F\",\n LSLANT: \"\\\\diagup\", RSLANT: \"\\\\diagdown\",\n\n sqrt: \"\\\\sqrt\",\n int: \"\\\\int\", dint: \"\\\\iint\", tint: \"\\\\iiint\", oint: \"\\\\oint\",\n\n alpha: \"\\\\alpha\", beta: \"\\\\beta\", gamma: \"\\\\gamma\", delta: \"\\\\delta\",\n epsilon: \"\\\\epsilon\", zeta: \"\\\\zeta\", eta: \"\\\\eta\", theta: \"\\\\theta\",\n iota: \"\\\\iota\", kappa: \"\\\\kappa\", lambda: \"\\\\lambda\", mu: \"\\\\mu\",\n nu: \"\\\\nu\", xi: \"\\\\xi\", omicron: \"\\\\omicron\", pi: \"\\\\pi\",\n rho: \"\\\\rho\", sigma: \"\\\\sigma\", tau: \"\\\\tau\", upsilon: \"\\\\upsilon\",\n phi: \"\\\\phi\", chi: \"\\\\chi\", psi: \"\\\\psi\", omega: \"\\\\omega\",\n ALPHA: \"A\", BETA: \"B\", GAMMA: \"\\\\Gamma\", DELTA: \"\\\\Delta\",\n EPSILON: \"E\", ZETA: \"Z\", ETA: \"H\", THETA: \"\\\\Theta\",\n IOTA: \"I\", KAPPA: \"K\", LAMBDA: \"\\\\Lambda\", MU: \"M\",\n NU: \"N\", XI: \"\\\\Xi\", OMICRON: \"O\", PI: \"\\\\Pi\",\n RHO: \"P\", SIGMA: \"\\\\Sigma\", TAU: \"T\", UPSILON: \"\\\\Upsilon\",\n PHI: \"\\\\Phi\", CHI: \"X\", PSI: \"\\\\Psi\", OMEGA: \"\\\\Omega\",\n\n \"⌈\": \"\\\\lceil\", \"⌉\": \"\\\\rceil\",\n \"⌊\": \"\\\\lfloor\", \"⌋\": \"\\\\rfloor\",\n \"∥\": \"\\\\|\",\n \"⊐\": \"\\\\sqsupset\", \"⊒\": \"\\\\sqsupseteq\",\n\n odint: \"\\\\mathop ∯\",\n otint: \"\\\\mathop ∰\",\n BIGSQCAP: \"\\\\mathop ⨅\",\n ATT: \"\\\\mathop ※\",\n HUND: \"\\\\mathop ‰\",\n THOU: \"\\\\mathop ‱\",\n IDENTICAL: \"\\\\mathop ∷\",\n RTANGLE: \"\\\\mathop ⊾\",\n BASE: \"\\\\mathop ⌂\",\n BENZENE: \"\\\\mathop ⌬\",\n}\n\n// Tokens rewritten to a HULK-prefixed marker, then expanded in second passes.\nconst MIDDLE_CONVERT_MAP: Record<string, string> = {\n matrix: \"HULKMATRIX\",\n pmatrix: \"HULKPMATRIX\",\n bmatrix: \"HULKBMATRIX\",\n dmatrix: \"HULKDMATRIX\",\n eqalign: \"HULKEQALIGN\",\n cases: \"HULKCASE\",\n vec: \"HULKVEC\",\n dyad: \"HULKDYAD\",\n acute: \"HULKACUTE\",\n grave: \"HULKGRAVE\",\n dot: \"HULKDOT\",\n ddot: \"HULKDDOT\",\n bar: \"HULKBAR\",\n hat: \"HULKHAT\",\n check: \"HULKCHECK\",\n arch: \"HULKARCH\",\n tilde: \"HULKTILDE\",\n BOX: \"HULKBOX\",\n OVERBRACE: \"HULKOVERBRACE\",\n UNDERBRACE: \"HULKUNDERBRACE\",\n}\n\nconst BAR_CONVERT_MAP: Record<string, string> = {\n HULKVEC: \"\\\\overrightarrow\",\n HULKDYAD: \"\\\\overleftrightarrow\",\n HULKACUTE: \"\\\\acute\",\n HULKGRAVE: \"\\\\grave\",\n HULKDOT: \"\\\\dot\",\n HULKDDOT: \"\\\\ddot\",\n HULKBAR: \"\\\\overline\",\n HULKHAT: \"\\\\widehat\",\n HULKCHECK: \"\\\\check\",\n HULKARCH: \"\\\\overset{\\\\frown}\",\n HULKTILDE: \"\\\\widetilde\",\n HULKBOX: \"\\\\boxed\",\n}\n\nconst MATRIX_CONVERT_MAP: Record<string, MatrixMapping> = {\n HULKMATRIX: { begin: \"\\\\begin{matrix}\", end: \"\\\\end{matrix}\", removeOutterBrackets: true },\n HULKPMATRIX: { begin: \"\\\\begin{pmatrix}\", end: \"\\\\end{pmatrix}\", removeOutterBrackets: true },\n HULKBMATRIX: { begin: \"\\\\begin{bmatrix}\", end: \"\\\\end{bmatrix}\", removeOutterBrackets: true },\n HULKDMATRIX: { begin: \"\\\\begin{vmatrix}\", end: \"\\\\end{vmatrix}\", removeOutterBrackets: true },\n HULKCASE: { begin: \"\\\\begin{cases}\", end: \"\\\\end{cases}\", removeOutterBrackets: true },\n HULKEQALIGN: { begin: \"\\\\eqalign{\", end: \"}\", removeOutterBrackets: false },\n}\n\nconst BRACE_CONVERT_MAP: Record<string, string> = {\n HULKOVERBRACE: \"\\\\overbrace\",\n HULKUNDERBRACE: \"\\\\underbrace\",\n}\n\n// ─── Bracket scanning helpers ─────────────────────────────────────────────\n\n/**\n * Find a matching `{...}` pair at/after `startIdx` (direction=1) or before\n * (direction=0). Returns [start, end) such that eqString.slice(start, end)\n * is the full bracketed substring including the `{` and `}`.\n * Throws when no matching bracket exists.\n */\nfunction findBrackets(eqString: string, startIdx: number, direction: 0 | 1): [number, number] {\n if (direction === 1) {\n const startCur = eqString.indexOf(\"{\", startIdx)\n if (startCur === -1) throw new Error(\"cannot find bracket\")\n let bracketCount = 1\n for (let i = startCur + 1; i < eqString.length; i++) {\n const ch = eqString[i]\n if (ch === \"{\") bracketCount += 1\n else if (ch === \"}\") bracketCount -= 1\n if (bracketCount === 0) return [startCur, i + 1]\n }\n throw new Error(\"cannot find bracket\")\n }\n\n // direction=0: reverse the string (and swap braces) then reuse dir=1 search.\n const reversed = Array.from(eqString).reverse()\n for (let i = 0; i < reversed.length; i++) {\n if (reversed[i] === \"{\") reversed[i] = \"}\"\n else if (reversed[i] === \"}\") reversed[i] = \"{\"\n }\n const flipped = reversed.join(\"\")\n const newStartIdx = flipped.length - (startIdx + 1)\n const [s, e] = findBrackets(flipped, newStartIdx, 1)\n return [flipped.length - e, flipped.length - s]\n}\n\n/**\n * From a cursor inside a bracketed group, walk backward to the enclosing\n * `{` and return the outer `{...}` span.\n */\nfunction findOutterBrackets(eqString: string, startIdx: number): [number, number] {\n let idx = startIdx\n while (true) {\n idx -= 1\n if (idx < 0) throw new Error(\"cannot find bracket\")\n if (eqString[idx] === \"{\") break\n }\n return findBrackets(eqString, idx, 1)\n}\n\n// ─── Rewrite passes ───────────────────────────────────────────────────────\n\n/** `{1} over {2}` → `\\frac{1}{2}` */\nfunction replaceFrac(eqString: string): string {\n const hmlFrac = \"over\"\n while (true) {\n const cursor = eqString.indexOf(hmlFrac)\n if (cursor === -1) break\n try {\n const [numStart, numEnd] = findBrackets(eqString, cursor, 0)\n const numerator = eqString.slice(numStart, numEnd)\n const beforeFrac = eqString.slice(0, numStart)\n const afterFrac = eqString.slice(cursor + hmlFrac.length)\n eqString = beforeFrac + \"\\\\frac\" + numerator + afterFrac\n } catch {\n return eqString\n }\n }\n return eqString\n}\n\n/** `root {1} of {2}` → `\\sqrt[1]{2}` */\nfunction replaceRootOf(eqString: string): string {\n while (true) {\n const rootCursor = eqString.indexOf(\"root\")\n if (rootCursor === -1) break\n try {\n const ofCursor = eqString.indexOf(\"of\")\n if (ofCursor === -1) return eqString\n const elem1 = findBrackets(eqString, rootCursor, 1)\n const elem2 = findBrackets(eqString, ofCursor, 1)\n const e1 = eqString.slice(elem1[0] + 1, elem1[1] - 1)\n const e2 = eqString.slice(elem2[0] + 1, elem2[1] - 1)\n eqString =\n eqString.slice(0, rootCursor) +\n \"\\\\sqrt\" +\n \"[\" + e1 + \"]\" +\n \"{\" + e2 + \"}\" +\n eqString.slice(elem2[1] + 1)\n } catch {\n return eqString\n }\n }\n return eqString\n}\n\n/** matrix/pmatrix/bmatrix/dmatrix/cases/eqalign expansion. */\nfunction replaceAllMatrix(eqString: string): string {\n const replaceElements = (bracketStr: string): string => {\n let inner = bracketStr.slice(1, -1) // strip outer `{` `}`\n inner = inner.replace(/#/g, \" \\\\\\\\ \")\n inner = inner.replace(/&amp;/g, \"&\")\n return inner\n }\n\n const replaceMatrix = (input: string, matStr: string, matElem: MatrixMapping): string => {\n while (true) {\n const cursor = input.indexOf(matStr)\n if (cursor === -1) break\n try {\n const [eStart, eEnd] = findBrackets(input, cursor, 1)\n const elem = replaceElements(input.slice(eStart, eEnd))\n let beforeMat: string\n let afterMat: string\n if (matElem.removeOutterBrackets) {\n const [bStart, bEnd] = findOutterBrackets(input, cursor)\n beforeMat = input.slice(0, bStart)\n afterMat = input.slice(bEnd)\n } else {\n beforeMat = input.slice(0, cursor)\n afterMat = input.slice(eEnd)\n }\n input = beforeMat + matElem.begin + elem + matElem.end + afterMat\n } catch {\n return input\n }\n }\n return input\n }\n\n for (const [matKey, matElem] of Object.entries(MATRIX_CONVERT_MAP)) {\n eqString = replaceMatrix(eqString, matKey, matElem)\n }\n return eqString\n}\n\n/** vec/hat/bar/dot/ddot/tilde/… (HULK-prefixed) → LaTeX accent. */\nfunction replaceAllBar(eqString: string): string {\n const replaceBar = (input: string, barStr: string, barElem: string): string => {\n while (true) {\n const cursor = input.indexOf(barStr)\n if (cursor === -1) break\n try {\n const [eStart, eEnd] = findBrackets(input, cursor, 1)\n const [bStart, bEnd] = findOutterBrackets(input, cursor)\n const elem = input.slice(eStart, eEnd)\n const beforeBar = input.slice(0, bStart)\n const afterBar = input.slice(bEnd)\n input = beforeBar + barElem + elem + afterBar\n } catch {\n return input\n }\n }\n return input\n }\n\n for (const [barKey, barElem] of Object.entries(BAR_CONVERT_MAP)) {\n eqString = replaceBar(eqString, barKey, barElem)\n }\n return eqString\n}\n\n/** overbrace/underbrace: `BRACE {body} {label}` → `\\overbrace{body}^{label}` */\nfunction replaceAllBrace(eqString: string): string {\n const replaceBrace = (input: string, braceStr: string, braceElem: string): string => {\n while (true) {\n const cursor = input.indexOf(braceStr)\n if (cursor === -1) break\n try {\n const [eStart1, eEnd1] = findBrackets(input, cursor, 1)\n const [eStart2, eEnd2] = findBrackets(input, eEnd1, 1)\n const elem1 = input.slice(eStart1, eEnd1)\n const elem2 = input.slice(eStart2, eEnd2)\n const beforeBrace = input.slice(0, cursor)\n const afterBrace = input.slice(eEnd2)\n input = beforeBrace + braceElem + elem1 + \"^\" + elem2 + afterBrace\n } catch {\n return input\n }\n }\n return input\n }\n\n for (const [braceKey, braceElem] of Object.entries(BRACE_CONVERT_MAP)) {\n eqString = replaceBrace(eqString, braceKey, braceElem)\n }\n return eqString\n}\n\n/** After single-token pass, fix `\\left {` → `\\left \\{` and `\\right }` → `\\right \\}`. */\nfunction replaceBracket(strList: string[]): string[] {\n for (let i = 0; i < strList.length; i++) {\n if (strList[i] === \"{\" && i > 0 && strList[i - 1] === \"\\\\left\") strList[i] = \"\\\\{\"\n if (strList[i] === \"}\" && i > 0 && strList[i - 1] === \"\\\\right\") strList[i] = \"\\\\}\"\n }\n return strList\n}\n\n/**\n * Convert an HWPX equation script (mini Hancom equation language) to LaTeX.\n * Returns the converted LaTeX body (without `$` delimiters).\n */\nexport function hmlToLatex(hmlEqStr: string): string {\n if (!hmlEqStr) return \"\"\n\n let s = hmlEqStr.replace(/`/g, \" \")\n s = s.replace(/\\{/g, \" { \").replace(/\\}/g, \" } \").replace(/&/g, \" & \")\n\n let tokens = s.split(\" \")\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i]\n if (t in CONVERT_MAP) tokens[i] = CONVERT_MAP[t]\n else if (t in MIDDLE_CONVERT_MAP) tokens[i] = MIDDLE_CONVERT_MAP[t]\n }\n tokens = tokens.filter(tok => tok.length !== 0)\n tokens = replaceBracket(tokens)\n\n let out = tokens.join(\" \")\n out = replaceFrac(out)\n out = replaceRootOf(out)\n out = replaceAllMatrix(out)\n out = replaceAllBar(out)\n out = replaceAllBrace(out)\n\n return out\n}\n","/** HWP 5.x 레코드 리더, UTF-16LE 텍스트 추출, 스트림 압축해제 */\r\n\r\nimport { inflateRawSync, inflateSync } from \"zlib\"\r\nimport { KordocError } from \"../utils.js\"\r\n\r\n// ─── 레코드 태그 상수 ────────────────────────────────\r\n\r\nexport const TAG_PARA_HEADER = 0x0042\r\nexport const TAG_PARA_TEXT = 0x0043\r\nexport const TAG_CHAR_SHAPE = 0x0044\r\nexport const TAG_PARA_SHAPE = 0x0045\r\nexport const TAG_CTRL_HEADER = 0x0047\r\nexport const TAG_LIST_HEADER = 0x0048\r\nexport const TAG_TABLE = 0x004d\r\nexport const TAG_EQEDIT = 0x0058\r\n\r\n// DocInfo 태그 (스타일 정보 해석용) — HWPTAG_BEGIN(0x0010) 기준\r\nexport const TAG_ID_MAPPINGS = 0x0011 // HWPTAG_BEGIN + 1\r\nexport const TAG_FACE_NAME = 0x0013 // HWPTAG_BEGIN + 3\r\nexport const TAG_DOC_CHAR_SHAPE = 0x0015 // HWPTAG_BEGIN + 5\r\nexport const TAG_DOC_PARA_SHAPE = 0x0019 // HWPTAG_BEGIN + 9\r\nexport const TAG_DOC_STYLE = 0x001a // HWPTAG_BEGIN + 10\r\n\r\n// 특수 문자 코드 (UTF-16LE) — HWP 5.0 바이너리 스펙 + rhwp 검증\r\n// 3가지 카테고리: char(2바이트), inline(16바이트), extended(16바이트)\r\n// char: 0, 13, 24-31 — 제어문자만, 확장 데이터 없음\r\n// inline: 4-9, 19-20 — 제어문자(2) + 확장(14) = 16바이트\r\n// extended: 1-3, 10-12, 14-18, 21-23 — 제어문자(2) + 확장(14) = 16바이트\r\nconst CHAR_LINE = 0x0000 // char: 줄바꿈\r\nconst CHAR_SECTION_BREAK = 0x000a // extended: 구역/단 정의 (14바이트 확장 데이터)\r\nconst CHAR_PARA = 0x000d // char: 문단 끝\r\nconst CHAR_TAB = 0x0009 // inline: 탭\r\nconst CHAR_HYPHEN = 0x001e // char: 하이픈\r\nconst CHAR_NBSP = 0x001f // char: 비분리 공백\r\nconst CHAR_FIXED_NBSP = 0x0018 // char: 고정 비분리 공백\r\nconst CHAR_FIXED_WIDTH = 0x0019 // char: 고정폭 공백\r\n\r\n// FileHeader 플래그\r\nexport const FLAG_COMPRESSED = 1 << 0\r\nexport const FLAG_ENCRYPTED = 1 << 1\r\nexport const FLAG_DISTRIBUTION = 1 << 2\r\nexport const FLAG_DRM = 1 << 4\r\n\r\n// ─── 레코드 구조 ─────────────────────────────────────\r\n\r\nexport interface HwpRecord {\r\n tagId: number\r\n level: number\r\n size: number\r\n data: Buffer\r\n}\r\n\r\nexport interface HwpFileHeader {\r\n signature: string\r\n versionMajor: number\r\n flags: number\r\n}\r\n\r\n// ─── 레코드 리더 ─────────────────────────────────────\r\n\r\n/** 최대 레코드 수 — 비정상 파일에 의한 메모리 폭주 방지 */\r\nconst MAX_RECORDS = 500_000\r\n\r\nexport function readRecords(data: Buffer): HwpRecord[] {\r\n const records: HwpRecord[] = []\r\n let offset = 0\r\n\r\n while (offset + 4 <= data.length && records.length < MAX_RECORDS) {\r\n const header = data.readUInt32LE(offset)\r\n offset += 4\r\n\r\n const tagId = header & 0x3ff\r\n const level = (header >> 10) & 0x3ff\r\n let size = (header >> 20) & 0xfff\r\n\r\n // 확장 크기\r\n if (size === 0xfff) {\r\n if (offset + 4 > data.length) break\r\n size = data.readUInt32LE(offset)\r\n offset += 4\r\n }\r\n\r\n if (offset + size > data.length) break\r\n records.push({ tagId, level, size, data: data.subarray(offset, offset + size) })\r\n offset += size\r\n }\r\n\r\n return records\r\n}\r\n\r\n// ─── 스트림 압축 해제 ────────────────────────────────\r\n\r\n/** 압축 해제 최대 크기 (100MB) — decompression bomb 방지 */\r\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\r\n\r\nexport function decompressStream(data: Buffer): Buffer {\r\n const opts = { maxOutputLength: MAX_DECOMPRESS_SIZE }\r\n if (data.length >= 2 && data[0] === 0x78) {\r\n try { return inflateSync(data, opts) } catch { /* fallback to raw */ }\r\n }\r\n return inflateRawSync(data, opts)\r\n}\r\n\r\n// ─── FileHeader 파싱 ─────────────────────────────────\r\n\r\nexport function parseFileHeader(data: Buffer): HwpFileHeader {\r\n if (data.length < 40) throw new KordocError(\"FileHeader가 너무 짧습니다 (최소 40바이트)\")\r\n const sig = data.subarray(0, 32).toString(\"utf8\").replace(/\\0+$/, \"\")\r\n return {\r\n signature: sig,\r\n versionMajor: data[35],\r\n flags: data.readUInt32LE(36),\r\n }\r\n}\r\n\r\n// ─── 스타일 정보 구조 ────────────────────────────────\r\n\r\n/** DocInfo에서 추출한 문단 모양 (PARA_SHAPE) */\r\nexport interface HwpParaShape {\r\n /** 개요 수준: 0=본문, 1-7=개요수준 1-7 (heading 계층) */\r\n outlineLevel: number\r\n}\r\n\r\n/** DocInfo에서 추출한 글자 모양 (CHAR_SHAPE) */\r\nexport interface HwpCharShape {\r\n /** 글꼴 크기 (단위: 0.1pt, 예: 100 = 10pt) */\r\n fontSize: number\r\n /**\r\n * 속성 플래그 (HWP5 바이너리 스펙 1.1 기준):\r\n * bit 0 = italic, bit 1 = bold, bit 2 = underline, bit 3 = outline\r\n * 검증 완료: 공식 스펙 + pyhwp/hwp.js 등 오픈소스 파서와 일치 (v1.7)\r\n */\r\n attrFlags: number\r\n}\r\n\r\n/** DocInfo에서 추출한 스타일 */\r\nexport interface HwpStyle {\r\n name: string\r\n /** 한글 이름 (UTF-16LE) */\r\n nameKo: string\r\n /** 연결된 charShape 인덱스 */\r\n charShapeId: number\r\n /** 연결된 paraShape 인덱스 */\r\n paraShapeId: number\r\n /** 스타일 타입: 0=paragraph, 1=character */\r\n type: number\r\n}\r\n\r\n/** DocInfo 파싱 결과 */\r\nexport interface HwpDocInfo {\r\n charShapes: HwpCharShape[]\r\n paraShapes: HwpParaShape[]\r\n styles: HwpStyle[]\r\n}\r\n\r\n/** DocInfo 레코드들에서 스타일 정보 추출 */\r\nexport function parseDocInfo(records: HwpRecord[]): HwpDocInfo {\r\n const charShapes: HwpCharShape[] = []\r\n const paraShapes: HwpParaShape[] = []\r\n const styles: HwpStyle[] = []\r\n\r\n for (const rec of records) {\r\n // PARA_SHAPE — 문단 모양 (개요 수준 추출)\r\n // 첫 4바이트(u32) 비트 팩: bits 25-27 = 개요 수준 (0=본문, 1-7=heading)\r\n if (rec.tagId === TAG_DOC_PARA_SHAPE && rec.data.length >= 4) {\r\n const flags = rec.data.readUInt32LE(0)\r\n const outlineLevel = (flags >> 25) & 0x07 // bits 25-27 → 3bit (0-7)\r\n paraShapes.push({ outlineLevel })\r\n }\r\n\r\n if (rec.tagId === TAG_DOC_CHAR_SHAPE && rec.data.length >= 18) {\r\n // HWP5 CHAR_SHAPE 구조 (바이너리 스펙 1.1 기준):\r\n // faceId: 7개 언어 * u16 = 14바이트 (offset 0-13)\r\n // ratio: 7개 언어 * u8 = 7바이트 (offset 14-20)\r\n // spacing: 7개 언어 * s8 = 7바이트 (offset 21-27)\r\n // relSize: 7개 언어 * u8 = 7바이트 (offset 28-34)\r\n // charOffset: 7개 언어 * s8 = 7바이트 (offset 35-41)\r\n // baseSize: u32 at offset 42 (단위: 0.1pt)\r\n // attrFlags: u32 at offset 46 (bit0=italic, bit1=bold) — 공식 스펙 검증 완료\r\n if (rec.data.length >= 50) {\r\n const fontSize = rec.data.readUInt32LE(42) // 단위: 0.1pt\r\n const attrFlags = rec.data.readUInt32LE(46)\r\n charShapes.push({ fontSize, attrFlags })\r\n } else {\r\n // 짧은 레코드 — 스타일 정보 없음\r\n charShapes.push({ fontSize: 0, attrFlags: 0 })\r\n }\r\n }\r\n\r\n if (rec.tagId === TAG_DOC_STYLE && rec.data.length >= 8) {\r\n try {\r\n // STYLE 구조: nameLen(u16) + name(UTF-16LE) + nameKoLen(u16) + nameKo(UTF-16LE)\r\n // + type(u8) + nextStyleId(u16) + langId(s16) + paraShapeId(u16) + charShapeId(u16)\r\n let offset = 0\r\n const nameLen = rec.data.readUInt16LE(offset); offset += 2\r\n const nameBytes = nameLen * 2\r\n const name = nameBytes > 0 && offset + nameBytes <= rec.data.length\r\n ? rec.data.subarray(offset, offset + nameBytes).toString(\"utf16le\")\r\n : \"\"\r\n offset += nameBytes\r\n\r\n let nameKo = \"\"\r\n if (offset + 2 <= rec.data.length) {\r\n const nameKoLen = rec.data.readUInt16LE(offset); offset += 2\r\n const nameKoBytes = nameKoLen * 2\r\n if (nameKoBytes > 0 && offset + nameKoBytes <= rec.data.length) {\r\n nameKo = rec.data.subarray(offset, offset + nameKoBytes).toString(\"utf16le\")\r\n }\r\n offset += nameKoBytes\r\n }\r\n\r\n // type(u8) + nextStyleId(u16) + langId(s16) + paraShapeId(u16) + charShapeId(u16)\r\n const type = offset < rec.data.length ? rec.data.readUInt8(offset) : 0; offset += 1\r\n offset += 2 // nextStyleId\r\n offset += 2 // langId\r\n const paraShapeId = offset + 2 <= rec.data.length ? rec.data.readUInt16LE(offset) : 0; offset += 2\r\n const charShapeId = offset + 2 <= rec.data.length ? rec.data.readUInt16LE(offset) : 0\r\n\r\n styles.push({ name, nameKo, charShapeId, paraShapeId, type })\r\n } catch {\r\n // 파싱 실패 — 스킵\r\n }\r\n }\r\n }\r\n\r\n return { charShapes, paraShapes, styles }\r\n}\r\n\r\n// ─── UTF-16LE 텍스트 추출 (21가지 제어문자 처리) ─────\r\n\r\nexport type InlineControlResolver = (ctrlId: string) => string | null | undefined\r\n\r\nexport function extractText(data: Buffer): string {\r\n return extractTextWithControls(data)\r\n}\r\n\r\nexport function extractTextWithControls(data: Buffer, resolveControl?: InlineControlResolver): string {\r\n let result = \"\"\r\n let i = 0\r\n\r\n while (i + 1 < data.length) {\r\n const ch = data.readUInt16LE(i)\r\n i += 2\r\n\r\n switch (ch) {\r\n // ── char 타입 (2바이트만, 확장 데이터 없음) ──\r\n case CHAR_LINE: result += \"\\n\"; break\r\n case CHAR_SECTION_BREAK: { // 구역/단 정의 또는 일부 inline control 래퍼\r\n // 일부 HWP5 문서는 수식 placeholder를 0x000a + 0x000b + ctrlId + payload + 0x000b로 저장한다.\r\n if (i + 16 <= data.length && data.readUInt16LE(i) === 0x000b) {\r\n const ctrlId = data.subarray(i + 2, i + 6).toString(\"ascii\")\r\n const replacement = resolveControl?.(ctrlId)\r\n if (replacement) result += replacement\r\n i += 16\r\n break\r\n }\r\n result += \"\\n\"\r\n if (i + 14 <= data.length) i += 14\r\n break\r\n }\r\n case CHAR_PARA: break // 문단 끝\r\n case CHAR_HYPHEN: result += \"-\"; break\r\n case CHAR_NBSP: result += \" \"; break\r\n case CHAR_FIXED_NBSP: result += \"\\u00a0\"; break // 진짜 NBSP\r\n case CHAR_FIXED_WIDTH: result += \" \"; break // 고정폭 공백\r\n\r\n // ── inline 타입 (2바이트 + 14바이트 확장) ──\r\n case CHAR_TAB:\r\n result += \"\\t\"\r\n if (i + 14 <= data.length) i += 14\r\n break\r\n\r\n default:\r\n if (ch >= 0x0001 && ch <= 0x001f) {\r\n // rhwp 기준 3-카테고리 분류:\r\n // extended(1-3, 11-12, 14-18, 21-23) + inline(4-9, 19-20) → 14바이트 스킵\r\n // char(24-31) → 스킵 없음 (이미 switch에서 24,25,30,31 처리됨)\r\n const isExtended = (ch >= 1 && ch <= 3) || (ch >= 11 && ch <= 12) || (ch >= 14 && ch <= 18) || (ch >= 21 && ch <= 23)\r\n const isInline = (ch >= 4 && ch <= 9) || (ch >= 19 && ch <= 20)\r\n if ((isExtended || isInline) && i + 14 <= data.length) {\r\n const ctrlId = data.subarray(i, i + 4).toString(\"ascii\")\r\n const replacement = resolveControl?.(ctrlId)\r\n if (replacement) result += replacement\r\n i += 14\r\n }\r\n } else if (ch >= 0x0020) {\r\n // UTF-16 surrogate pair 처리 (BMP 외 문자: 이모지, CJK 확장 등)\r\n if (ch >= 0xd800 && ch <= 0xdbff && i + 1 < data.length) {\r\n const lo = data.readUInt16LE(i)\r\n if (lo >= 0xdc00 && lo <= 0xdfff) {\r\n i += 2\r\n const codePoint = ((ch - 0xd800) << 10) + (lo - 0xdc00) + 0x10000\r\n result += String.fromCodePoint(codePoint)\r\n break\r\n }\r\n }\r\n result += String.fromCharCode(ch)\r\n }\r\n break\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\n/** HWP5 EQEDIT(0x58) 레코드에서 한글 수식 스크립트 원문 추출 */\r\nexport function extractEquationText(data: Buffer): string | null {\r\n if (data.length < 6) return null\r\n\r\n const scriptLength = data.readUInt16LE(4)\r\n const scriptStart = 6\r\n const scriptEnd = scriptStart + scriptLength * 2\r\n if (scriptLength <= 0 || scriptEnd > data.length) return null\r\n\r\n const equation = data.subarray(scriptStart, scriptEnd).toString(\"utf16le\").replace(/\\0+/g, \"\").trim()\r\n return equation || null\r\n}\r\n","/**\n * AES-128 ECB 순수 JS 구현 — 배포용 HWP 복호화 전용.\n * 외부 의존성 없음 (kordoc 제로 네이티브 의존성 원칙 유지).\n * 참조: rhwp (MIT) src/parser/crypto.rs + FIPS-197 (AES 표준)\n */\n\n// ── S-Box & 역 S-Box ──\n\nconst S_BOX = new Uint8Array([\n 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,\n 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,\n 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,\n 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,\n 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,\n 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,\n 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,\n 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,\n 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,\n 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,\n 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,\n 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,\n 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,\n 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,\n 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,\n 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16,\n])\n\nconst INV_S_BOX = new Uint8Array([\n 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,\n 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,\n 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,\n 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,\n 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,\n 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,\n 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,\n 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,\n 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,\n 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,\n 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,\n 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,\n 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,\n 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,\n 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,\n 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d,\n])\n\n// ── RCON (라운드 상수) ──\n\nconst RCON = new Uint8Array([0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36])\n\n// ── GF(2^8) 곱셈 ──\n\nfunction gmul(a: number, b: number): number {\n let p = 0\n for (let i = 0; i < 8; i++) {\n if (b & 1) p ^= a\n const hi = a & 0x80\n a = (a << 1) & 0xff\n if (hi) a ^= 0x1b\n b >>= 1\n }\n return p\n}\n\n// ── 키 확장 (AES-128: 4 words → 44 words) ──\n\nfunction expandKey(key: Uint8Array): Uint32Array {\n const w = new Uint32Array(44)\n\n // 첫 4 words: 원본 키\n for (let i = 0; i < 4; i++) {\n w[i] = (key[4 * i] << 24) | (key[4 * i + 1] << 16) | (key[4 * i + 2] << 8) | key[4 * i + 3]\n }\n\n for (let i = 4; i < 44; i++) {\n let temp = w[i - 1]\n if (i % 4 === 0) {\n // RotWord + SubWord + RCON\n temp = ((temp << 8) | (temp >>> 24)) >>> 0\n temp = (S_BOX[(temp >>> 24) & 0xff] << 24) |\n (S_BOX[(temp >>> 16) & 0xff] << 16) |\n (S_BOX[(temp >>> 8) & 0xff] << 8) |\n S_BOX[temp & 0xff]\n temp = (temp ^ (RCON[i / 4 - 1] << 24)) >>> 0\n }\n w[i] = (w[i - 4] ^ temp) >>> 0\n }\n\n return w\n}\n\n// ── AES-128 단일 블록 복호화 (16바이트) ──\n\nfunction decryptBlock(block: Uint8Array, roundKeys: Uint32Array): Uint8Array {\n // state를 4x4 column-major 배열로 로드\n const s = new Uint8Array(16)\n for (let i = 0; i < 16; i++) s[i] = block[i]\n\n // AddRoundKey (round 10)\n addRoundKey(s, roundKeys, 10)\n\n // Rounds 9 → 1\n for (let round = 9; round >= 1; round--) {\n invShiftRows(s)\n invSubBytes(s)\n addRoundKey(s, roundKeys, round)\n invMixColumns(s)\n }\n\n // Final round (round 0)\n invShiftRows(s)\n invSubBytes(s)\n addRoundKey(s, roundKeys, 0)\n\n return s\n}\n\nfunction addRoundKey(s: Uint8Array, w: Uint32Array, round: number): void {\n const base = round * 4\n for (let c = 0; c < 4; c++) {\n const k = w[base + c]\n s[c * 4] ^= (k >>> 24) & 0xff\n s[c * 4 + 1] ^= (k >>> 16) & 0xff\n s[c * 4 + 2] ^= (k >>> 8) & 0xff\n s[c * 4 + 3] ^= k & 0xff\n }\n}\n\nfunction invSubBytes(s: Uint8Array): void {\n for (let i = 0; i < 16; i++) s[i] = INV_S_BOX[s[i]]\n}\n\nfunction invShiftRows(s: Uint8Array): void {\n // Row 0: no shift\n // Row 1: shift right 1\n let t = s[13]; s[13] = s[9]; s[9] = s[5]; s[5] = s[1]; s[1] = t\n // Row 2: shift right 2\n t = s[2]; s[2] = s[10]; s[10] = t\n t = s[6]; s[6] = s[14]; s[14] = t\n // Row 3: shift right 3 (= left 1)\n t = s[3]; s[3] = s[7]; s[7] = s[11]; s[11] = s[15]; s[15] = t\n}\n\nfunction invMixColumns(s: Uint8Array): void {\n for (let c = 0; c < 4; c++) {\n const i = c * 4\n const a0 = s[i], a1 = s[i + 1], a2 = s[i + 2], a3 = s[i + 3]\n s[i] = gmul(a0, 0x0e) ^ gmul(a1, 0x0b) ^ gmul(a2, 0x0d) ^ gmul(a3, 0x09)\n s[i + 1] = gmul(a0, 0x09) ^ gmul(a1, 0x0e) ^ gmul(a2, 0x0b) ^ gmul(a3, 0x0d)\n s[i + 2] = gmul(a0, 0x0d) ^ gmul(a1, 0x09) ^ gmul(a2, 0x0e) ^ gmul(a3, 0x0b)\n s[i + 3] = gmul(a0, 0x0b) ^ gmul(a1, 0x0d) ^ gmul(a2, 0x09) ^ gmul(a3, 0x0e)\n }\n}\n\n// ── 공개 API ──\n\n/** AES-128 ECB 복호화. data 길이는 16의 배수여야 함. */\nexport function aes128EcbDecrypt(data: Uint8Array, key: Uint8Array): Uint8Array {\n if (key.length !== 16) throw new Error(\"AES-128 키는 16바이트여야 합니다\")\n if (data.length % 16 !== 0) throw new Error(\"AES ECB 입력은 16바이트의 배수여야 합니다\")\n\n const roundKeys = expandKey(key)\n const out = new Uint8Array(data.length)\n\n for (let offset = 0; offset < data.length; offset += 16) {\n const block = data.subarray(offset, offset + 16)\n const decrypted = decryptBlock(block, roundKeys)\n out.set(decrypted, offset)\n }\n\n return out\n}\n","/**\n * HWP 배포용(distribution) 문서 복호화.\n *\n * 배포용 HWP는 ViewText/Section{N} 스트림에 암호화된 본문을 저장.\n * 첫 레코드(HWPTAG_DISTRIBUTE_DOC_DATA)의 256바이트 payload에서 AES 키를 추출한 뒤\n * 나머지 데이터를 AES-128 ECB로 복호화.\n *\n * 알고리즘 참조: rhwp (MIT) src/parser/crypto.rs\n * 포맷 참조: HWP 5.0 바이너리 스펙 — 배포용 문서 구조\n */\n\nimport { aes128EcbDecrypt } from \"./aes.js\"\nimport { decompressStream } from \"./record.js\"\n\n// ── MSVC LCG (Linear Congruential Generator) ──\n\n/** MSVC CRT rand() 호환 LCG */\nclass MsvcLcg {\n private seed: number\n\n constructor(seed: number) {\n this.seed = seed >>> 0 // u32로 강제\n }\n\n /** 0 ~ 0x7FFF 범위 난수 반환 (MSVC rand() 호환) */\n rand(): number {\n // MSVC LCG: seed = seed * 214013 + 2531011\n // JS에서 32bit 정수 오버플로우를 정확히 재현하기 위해 Math.imul 사용\n this.seed = (Math.imul(this.seed, 214013) + 2531011) >>> 0\n return (this.seed >>> 16) & 0x7fff\n }\n}\n\n// ── 배포용 문서 256바이트 payload 복호화 ──\n\n/**\n * DISTRIBUTE_DOC_DATA 레코드의 256바이트 payload를 LCG+XOR로 복호화.\n *\n * 구조:\n * - bytes[0..4]: LCG seed (u32 LE)\n * - bytes[4..256]: XOR 암호화된 데이터\n *\n * XOR 규칙: LCG에서 키 바이트를 뽑고, n = (lcg.rand() & 0xF) + 1 바이트마다 키 교체\n */\nfunction decryptDistributePayload(payload: Uint8Array): Uint8Array {\n if (payload.length < 256) throw new Error(\"배포용 payload가 256바이트 미만입니다\")\n\n const seed = (payload[0] | (payload[1] << 8) | (payload[2] << 16) | (payload[3] << 24)) >>> 0\n const lcg = new MsvcLcg(seed)\n\n const result = new Uint8Array(payload.subarray(0, 256)) // 원본 복사\n\n // rhwp 호환: i=0부터 시작하여 n 카운터를 소비하되, i<4는 XOR 스킵 (seed 보존)\n // i=4부터 시작하면 LCG 시퀀스가 어긋남 — i=0~3에서도 n을 소비해야 정확함\n let i = 0\n let n = 0\n let key = 0\n\n while (i < 256) {\n if (n === 0) {\n key = lcg.rand() & 0xff\n n = (lcg.rand() & 0x0f) + 1\n }\n if (i >= 4) {\n result[i] ^= key\n }\n i++\n n--\n }\n\n return result\n}\n\n// ── AES 키 추출 ──\n\n/**\n * 복호화된 256바이트 payload에서 AES-128 키(16바이트) 추출.\n * offset = 4 + (decrypted[0] & 0x0F)\n */\nfunction extractAesKey(decryptedPayload: Uint8Array): Uint8Array {\n const offset = 4 + (decryptedPayload[0] & 0x0f)\n if (offset + 16 > decryptedPayload.length) {\n throw new Error(\"AES 키 추출 실패: 오프셋이 payload 범위를 초과합니다\")\n }\n return decryptedPayload.slice(offset, offset + 16)\n}\n\n// ── 레코드 헤더 파싱 ──\n\n/** HWP 레코드 헤더에서 tag_id와 size 추출 */\nfunction parseRecordHeader(data: Uint8Array, offset: number): { tagId: number; size: number; headerSize: number } {\n if (offset + 4 > data.length) throw new Error(\"레코드 헤더 파싱 실패: 데이터 부족\")\n\n const header = (data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)) >>> 0\n const tagId = header & 0x3ff\n let size = (header >>> 20) & 0xfff\n let headerSize = 4\n\n if (size === 0xfff) {\n if (offset + 8 > data.length) throw new Error(\"확장 레코드 크기 파싱 실패: 데이터 부족\")\n size = (data[offset + 4] | (data[offset + 5] << 8) | (data[offset + 6] << 16) | (data[offset + 7] << 24)) >>> 0\n headerSize = 8\n }\n\n return { tagId, size, headerSize }\n}\n\n// ── 공개 API ──\n\n/** HWPTAG_DISTRIBUTE_DOC_DATA 태그 ID (HWPTAG_BEGIN + 12 = 0x10 + 12 = 0x1C = 28) */\nconst TAG_DISTRIBUTE_DOC_DATA = 0x10 + 12 // = 28\n\n/**\n * ViewText 스트림을 복호화하여 일반 BodyText 레코드 데이터로 변환.\n *\n * @param viewTextRaw ViewText/Section{N} 스트림의 원본 바이트\n * @param compressed FileHeader의 compressed 플래그\n * @returns 복호화된 레코드 데이터 (readRecords()로 파싱 가능)\n */\nexport function decryptViewText(viewTextRaw: Buffer, compressed: boolean): Buffer {\n const data = new Uint8Array(viewTextRaw)\n\n // 1. 첫 레코드 파싱 (DISTRIBUTE_DOC_DATA)\n const rec = parseRecordHeader(data, 0)\n if (rec.tagId !== TAG_DISTRIBUTE_DOC_DATA) {\n throw new Error(`배포용 문서의 첫 레코드가 DISTRIBUTE_DOC_DATA(${TAG_DISTRIBUTE_DOC_DATA})가 아닙니다 (실제: ${rec.tagId})`)\n }\n\n const payloadStart = rec.headerSize\n const payloadEnd = payloadStart + rec.size\n if (payloadEnd > data.length || rec.size < 256) {\n throw new Error(\"배포용 payload가 유효하지 않습니다\")\n }\n\n // 2. 256바이트 payload 복호화 (LCG + XOR)\n const payload = data.subarray(payloadStart, payloadStart + 256)\n const decryptedPayload = decryptDistributePayload(payload)\n\n // 3. AES-128 키 추출\n const aesKey = extractAesKey(decryptedPayload)\n\n // 4. 나머지 데이터를 AES-128 ECB 복호화\n const encryptedStart = payloadEnd\n const encryptedData = data.subarray(encryptedStart)\n\n if (encryptedData.length === 0) {\n throw new Error(\"배포용 문서에 암호화된 본문 데이터가 없습니다\")\n }\n\n // AES ECB는 16바이트 블록 단위 — 패딩 처리\n const alignedLen = encryptedData.length - (encryptedData.length % 16)\n if (alignedLen === 0) {\n throw new Error(\"암호화된 데이터가 너무 짧습니다 (16바이트 미만)\")\n }\n\n const alignedData = encryptedData.subarray(0, alignedLen)\n const decrypted = aes128EcbDecrypt(alignedData, aesKey)\n\n // 5. 압축 해제 (compressed 플래그가 설정된 경우)\n if (compressed) {\n try {\n return decompressStream(Buffer.from(decrypted))\n } catch {\n // 압축이 아닐 수도 있음 — 그대로 반환\n return Buffer.from(decrypted)\n }\n }\n\n return Buffer.from(decrypted)\n}\n\n// 테스트용 내부 함수 export\nexport { MsvcLcg as _MsvcLcg, decryptDistributePayload as _decryptDistributePayload, extractAesKey as _extractAesKey }\n","const WORD_COMMANDS = new Map<string, string>([\r\n [\"alpha\", \"\\\\alpha\"],\r\n [\"beta\", \"\\\\beta\"],\r\n [\"gamma\", \"\\\\gamma\"],\r\n [\"delta\", \"\\\\delta\"],\r\n [\"epsilon\", \"\\\\epsilon\"],\r\n [\"theta\", \"\\\\theta\"],\r\n [\"lambda\", \"\\\\lambda\"],\r\n [\"mu\", \"\\\\mu\"],\r\n [\"pi\", \"\\\\pi\"],\r\n [\"sigma\", \"\\\\sigma\"],\r\n [\"tau\", \"\\\\tau\"],\r\n [\"phi\", \"\\\\phi\"],\r\n [\"omega\", \"\\\\omega\"],\r\n [\"sin\", \"\\\\sin\"],\r\n [\"cos\", \"\\\\cos\"],\r\n [\"tan\", \"\\\\tan\"],\r\n [\"sec\", \"\\\\sec\"],\r\n [\"csc\", \"\\\\csc\"],\r\n [\"cot\", \"\\\\cot\"],\r\n [\"log\", \"\\\\log\"],\r\n [\"ln\", \"\\\\ln\"],\r\n [\"lim\", \"\\\\lim\"],\r\n [\"inf\", \"\\\\infty\"],\r\n [\"sum\", \"\\\\sum\"],\r\n [\"smallsum\", \"\\\\sum\"],\r\n [\"prod\", \"\\\\prod\"],\r\n [\"int\", \"\\\\int\"],\r\n [\"oint\", \"\\\\oint\"],\r\n [\"rightarrow\", \"\\\\rightarrow\"],\r\n [\"leftarrow\", \"\\\\leftarrow\"],\r\n [\"partial\", \"\\\\partial\"],\r\n [\"nabla\", \"\\\\nabla\"],\r\n [\"angle\", \"\\\\angle\"],\r\n [\"triangle\", \"\\\\triangle\"],\r\n [\"vec\", \"\\\\vec\"],\r\n [\"bar\", \"\\\\overline\"],\r\n [\"dot\", \"\\\\dot\"],\r\n [\"hat\", \"\\\\hat\"],\r\n [\"left\", \"\\\\left\"],\r\n [\"right\", \"\\\\right\"],\r\n])\r\n\r\nconst SYMBOL_WORDS = new Map<string, string>([\r\n [\"times\", \"\\\\times\"],\r\n [\"divide\", \"\\\\div\"],\r\n [\"div\", \"\\\\div\"],\r\n [\"le\", \"\\\\leq\"],\r\n [\"ge\", \"\\\\geq\"],\r\n [\"geq\", \"\\\\geq\"],\r\n [\"deg\", \"^\\\\circ\"],\r\n [\"rarrow\", \"\\\\rightarrow\"],\r\n [\"larrow\", \"\\\\leftarrow\"],\r\n [\"lrarrow\", \"\\\\leftrightarrow\"],\r\n [\"in\", \"\\\\in\"],\r\n [\"notin\", \"\\\\notin\"],\r\n [\"emptyset\", \"\\\\emptyset\"],\r\n [\"subset\", \"\\\\subset\"],\r\n [\"nsubset\", \"\\\\nsubseteq\"],\r\n [\"cup\", \"\\\\cup\"],\r\n [\"cap\", \"\\\\cap\"],\r\n [\"smallinter\", \"\\\\cap\"],\r\n [\"sim\", \"\\\\sim\"],\r\n [\"circ\", \"\\\\circ\"],\r\n [\"bot\", \"\\\\perp\"],\r\n [\"dyad\", \"\\\\overleftrightarrow\"],\r\n [\"arch\", \"\\\\overset{\\\\frown}\"],\r\n])\r\n\r\nexport function hwpEquationToLatex(equation: string): string {\r\n return convertEquation(equation.replace(/\\0/g, \"\").trim(), 0)\r\n}\r\n\r\nfunction convertEquation(equation: string, depth: number): string {\r\n if (!equation || depth > 12) return equation\r\n\r\n let result = equation\r\n .replace(/\\s+/g, \" \")\r\n .replace(/`+/g, \"\\\\,\")\r\n .replace(/~+/g, \"\\\\,\")\r\n .trim()\r\n\r\n result = convertMatrixLike(result)\r\n result = convertRoots(result, depth)\r\n result = convertOver(result, depth)\r\n result = convertSqrt(result, depth)\r\n result = convertScripts(result)\r\n result = convertOperators(result)\r\n result = removeFontDirectives(result)\r\n result = convertWords(result)\r\n result = cleanupLatexSpacing(result)\r\n\r\n return result\r\n}\r\n\r\nfunction convertMatrixLike(input: string): string {\r\n return input\r\n .replace(/\\bmatrix\\s*\\{([^{}]*)\\}/gi, (_match, body: string) =>\r\n `\\\\begin{matrix} ${body.split(\"#\").map(part => part.trim()).join(\" & \")} \\\\end{matrix}`\r\n )\r\n .replace(/\\bcases\\s*\\{([^{}]*)\\}/gi, (_match, body: string) =>\r\n `\\\\begin{cases} ${body.split(\"#\").map(part => part.trim()).join(\" \\\\\\\\ \")} \\\\end{cases}`\r\n )\r\n}\r\n\r\nfunction convertRoots(input: string, depth: number): string {\r\n return input.replace(/(?<!\\\\)\\broot\\s+({[^{}]*}|\\S+)\\s+of\\s+({[^{}]*}|\\S+)/gi, (_match, degree: string, radicand: string) => {\r\n return `\\\\sqrt[${convertEquation(unwrapGroup(degree), depth + 1)}]{${convertEquation(unwrapGroup(radicand), depth + 1)}}`\r\n })\r\n}\r\n\r\nfunction convertSqrt(input: string, depth: number): string {\r\n return input.replace(/(?<!\\\\)\\bsqrt\\s*({[^{}]*}|\\S+)/gi, (_match, radicand: string) => {\r\n return `\\\\sqrt{${convertEquation(unwrapGroup(radicand), depth + 1)}}`\r\n })\r\n}\r\n\r\nfunction convertOver(input: string, depth: number): string {\r\n let result = input\r\n for (let guard = 0; guard < 50; guard++) {\r\n const over = findTopLevelWord(result, \"over\")\r\n if (over < 0) break\r\n\r\n const left = readLeftAtom(result, over)\r\n const right = readRightAtom(result, over + \"over\".length)\r\n if (!left || !right) break\r\n\r\n const numerator = convertEquation(unwrapGroup(left.atom), depth + 1)\r\n const denominator = convertEquation(unwrapGroup(right.atom), depth + 1)\r\n result =\r\n result.slice(0, left.start) +\r\n `\\\\frac{${numerator}}{${denominator}}` +\r\n result.slice(right.end)\r\n }\r\n return result\r\n}\r\n\r\nfunction convertScripts(input: string): string {\r\n return input\r\n .replace(/\\s*\\^\\s*/g, \"^\")\r\n .replace(/\\s*_\\s*/g, \"_\")\r\n .replace(/\\^(?!\\{)([^\\s{}_^]+)/g, \"^{$1}\")\r\n .replace(/_(?!\\{)([^\\s{}_^]+)/g, \"_{$1}\")\r\n}\r\n\r\nfunction convertOperators(input: string): string {\r\n return input\r\n .replace(/\\+-/g, \"\\\\pm\")\r\n .replace(/-\\+/g, \"\\\\mp\")\r\n .replace(/\\/\\//g, \"\\\\parallel\")\r\n .replace(/△/g, \"\\\\triangle \")\r\n .replace(/□/g, \"\\\\square \")\r\n .replace(/‧/g, \"\\\\cdot \")\r\n .replace(/!=/g, \"\\\\neq\")\r\n .replace(/<=/g, \"\\\\leq\")\r\n .replace(/>=/g, \"\\\\geq\")\r\n .replace(/==/g, \"\\\\equiv\")\r\n}\r\n\r\nfunction removeFontDirectives(input: string): string {\r\n return input.replace(/(?<!\\\\)\\b(?:rm|it)\\b\\s*/gi, \"\")\r\n}\r\n\r\nfunction convertWords(input: string): string {\r\n return input.replace(/(?<![\\\\A-Za-z0-9])([A-Za-z][A-Za-z0-9]*)(?![A-Za-z0-9])/g, word => {\r\n const exact = SYMBOL_WORDS.get(word)\r\n if (exact) return exact\r\n const lower = word.toLowerCase()\r\n return SYMBOL_WORDS.get(lower) ?? WORD_COMMANDS.get(lower) ?? word\r\n })\r\n}\r\n\r\nfunction cleanupLatexSpacing(input: string): string {\r\n return input\r\n .replace(/\\\\left\\s*\\{/g, \"\\\\left\\\\{\")\r\n .replace(/\\\\right\\s*\\}/g, \"\\\\right\\\\}\")\r\n .replace(/\\\\left\\s*([\\[\\]\\(\\)\\|])/g, \"\\\\left$1\")\r\n .replace(/\\\\right\\s*([\\[\\]\\(\\)\\|])/g, \"\\\\right$1\")\r\n .replace(/\\s*\\\\,\\s*/g, \"\\\\,\")\r\n .replace(/\\s+/g, \" \")\r\n .replace(/\\{\\s+/g, \"{\")\r\n .replace(/\\s+\\}/g, \"}\")\r\n .trim()\r\n}\r\n\r\nfunction findTopLevelWord(input: string, word: string): number {\r\n let curly = 0\r\n let paren = 0\r\n for (let i = 0; i <= input.length - word.length; i++) {\r\n const ch = input[i]\r\n if (ch === \"{\") curly++\r\n else if (ch === \"}\") curly = Math.max(0, curly - 1)\r\n else if (ch === \"(\") paren++\r\n else if (ch === \")\") paren = Math.max(0, paren - 1)\r\n\r\n if (curly !== 0 || paren !== 0) continue\r\n if (input.slice(i, i + word.length).toLowerCase() !== word) continue\r\n if (isWordChar(input[i - 1]) || isWordChar(input[i + word.length])) continue\r\n return i\r\n }\r\n return -1\r\n}\r\n\r\nfunction readLeftAtom(input: string, end: number): { start: number; atom: string } | null {\r\n let pos = end - 1\r\n while (pos >= 0 && /\\s/.test(input[pos])) pos--\r\n if (pos < 0) return null\r\n\r\n if (input[pos] === \"}\") {\r\n const start = findMatchingLeft(input, pos, \"{\", \"}\")\r\n if (start >= 0) return { start, atom: input.slice(start, pos + 1) }\r\n }\r\n if (input[pos] === \")\") {\r\n const start = findMatchingLeft(input, pos, \"(\", \")\")\r\n if (start >= 0) return { start, atom: input.slice(start, pos + 1) }\r\n }\r\n\r\n let start = pos\r\n while (start >= 0 && !/\\s/.test(input[start]) && !/[+\\-=<>]/.test(input[start])) start--\r\n return { start: start + 1, atom: input.slice(start + 1, pos + 1) }\r\n}\r\n\r\nfunction readRightAtom(input: string, start: number): { end: number; atom: string } | null {\r\n let pos = start\r\n while (pos < input.length && /\\s/.test(input[pos])) pos++\r\n if (pos >= input.length) return null\r\n\r\n if (input[pos] === \"{\") {\r\n const end = findMatchingRight(input, pos, \"{\", \"}\")\r\n if (end >= 0) return { end: end + 1, atom: input.slice(pos, end + 1) }\r\n }\r\n if (input[pos] === \"(\") {\r\n const end = findMatchingRight(input, pos, \"(\", \")\")\r\n if (end >= 0) return { end: end + 1, atom: input.slice(pos, end + 1) }\r\n }\r\n\r\n let end = pos\r\n while (end < input.length && !/\\s/.test(input[end]) && !/[+\\-=<>]/.test(input[end])) end++\r\n return { end, atom: input.slice(pos, end) }\r\n}\r\n\r\nfunction findMatchingLeft(input: string, closeIndex: number, open: string, close: string): number {\r\n let depth = 0\r\n for (let i = closeIndex; i >= 0; i--) {\r\n if (input[i] === close) depth++\r\n else if (input[i] === open) {\r\n depth--\r\n if (depth === 0) return i\r\n }\r\n }\r\n return -1\r\n}\r\n\r\nfunction findMatchingRight(input: string, openIndex: number, open: string, close: string): number {\r\n let depth = 0\r\n for (let i = openIndex; i < input.length; i++) {\r\n if (input[i] === open) depth++\r\n else if (input[i] === close) {\r\n depth--\r\n if (depth === 0) return i\r\n }\r\n }\r\n return -1\r\n}\r\n\r\nfunction unwrapGroup(input: string): string {\r\n const trimmed = input.trim()\r\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) return trimmed.slice(1, -1)\r\n return trimmed\r\n}\r\n\r\nfunction isWordChar(ch: string | undefined): boolean {\r\n return !!ch && /[A-Za-z0-9_]/.test(ch)\r\n}\r\n","/** HWP 5.x 바이너리 파서 — OLE2 컨테이너 → 섹션 → Markdown */\r\n\r\nimport {\r\n readRecords, decompressStream, parseFileHeader, extractTextWithControls, extractEquationText, parseDocInfo,\r\n TAG_PARA_HEADER, TAG_PARA_TEXT, TAG_CHAR_SHAPE, TAG_CTRL_HEADER, TAG_LIST_HEADER, TAG_TABLE,\r\n TAG_EQEDIT,\r\n FLAG_COMPRESSED, FLAG_ENCRYPTED, FLAG_DISTRIBUTION, FLAG_DRM,\r\n type HwpRecord, type HwpDocInfo, type HwpCharShape, type HwpParaShape,\r\n} from \"./record.js\"\r\nimport { decryptViewText } from \"./crypto.js\"\r\nimport { hwpEquationToLatex } from \"./equation.js\"\r\nimport { parseLenientCfb, type LenientCfbContainer } from \"./cfb-lenient.js\"\r\nimport { buildTable, blocksToMarkdown, flattenLayoutTables, MAX_COLS, MAX_ROWS } from \"../table/builder.js\"\r\nimport type { CellContext, IRBlock, IRTable, DocumentMetadata, InternalParseResult, ParseOptions, ParseWarning, OutlineItem, InlineStyle, ExtractedImage } from \"../types.js\"\r\nimport { HEADING_RATIO_H1, HEADING_RATIO_H2, HEADING_RATIO_H3 } from \"../types.js\"\r\nimport { KordocError, sanitizeHref } from \"../utils.js\"\r\nimport { parsePageRange } from \"../page-range.js\"\r\n\r\nimport { createRequire } from \"module\"\r\nconst require = createRequire(import.meta.url)\r\nconst CFB: CfbModule = require(\"cfb\")\r\n\r\ninterface CfbEntry { name?: string; content?: Buffer | Uint8Array }\r\ninterface CfbContainer { FileIndex?: CfbEntry[] }\r\ninterface CfbModule {\r\n parse(data: Buffer): CfbContainer\r\n find(cfb: CfbContainer, path: string): CfbEntry | null\r\n}\r\n\r\n/** 최대 섹션 수 — 비정상 파일에 의한 무한 루프 방지 */\r\nconst MAX_SECTIONS = 100\r\n/** 누적 압축 해제 최대 크기 (100MB) */\r\nconst MAX_TOTAL_DECOMPRESS = 100 * 1024 * 1024\r\n\r\nexport function parseHwp5Document(buffer: Buffer, options?: ParseOptions): InternalParseResult {\r\n // CFB 파싱: strict 먼저, 실패 시 lenient 폴백\r\n let cfb: CfbContainer | null = null\r\n let lenientCfb: LenientCfbContainer | null = null\r\n const warnings: ParseWarning[] = []\r\n\r\n try {\r\n cfb = CFB.parse(buffer)\r\n } catch {\r\n try {\r\n lenientCfb = parseLenientCfb(buffer)\r\n warnings.push({ message: \"손상된 CFB 컨테이너 — lenient 모드로 복구\", code: \"LENIENT_CFB_RECOVERY\" })\r\n } catch {\r\n throw new KordocError(\"CFB 컨테이너 파싱 실패 (strict 및 lenient 모두)\")\r\n }\r\n }\r\n\r\n // CFB 래퍼: strict/lenient 통합 인터페이스\r\n const findStream = (path: string): Buffer | null => {\r\n if (cfb) {\r\n const entry = CFB.find(cfb, path)\r\n return entry?.content ? Buffer.from(entry.content) : null\r\n }\r\n return lenientCfb!.findStream(path)\r\n }\r\n\r\n const headerData = findStream(\"/FileHeader\")\r\n if (!headerData) throw new KordocError(\"FileHeader 스트림 없음\")\r\n const header = parseFileHeader(headerData)\r\n if (header.signature !== \"HWP Document File\") throw new KordocError(\"HWP 시그니처 불일치\")\r\n if (header.flags & FLAG_ENCRYPTED) throw new KordocError(\"암호화된 HWP는 지원하지 않습니다\")\r\n if (header.flags & FLAG_DRM) throw new KordocError(\"DRM 보호된 HWP는 지원하지 않습니다\")\r\n const compressed = (header.flags & FLAG_COMPRESSED) !== 0\r\n const distribution = (header.flags & FLAG_DISTRIBUTION) !== 0\r\n\r\n const metadata: DocumentMetadata = {\r\n version: `${header.versionMajor}.x`,\r\n }\r\n if (cfb) extractHwp5Metadata(cfb, metadata)\r\n\r\n // DocInfo 파싱 (스타일 정보 추출)\r\n const docInfo = cfb\r\n ? parseDocInfoStream(cfb, compressed)\r\n : parseDocInfoFromStream(findStream(\"/DocInfo\"), compressed)\r\n\r\n const sections = distribution\r\n ? (cfb ? findViewTextSections(cfb, compressed) : findViewTextSectionsLenient(lenientCfb!, compressed))\r\n : (cfb ? findSections(cfb) : findSectionsLenient(lenientCfb!, compressed))\r\n if (sections.length === 0) throw new KordocError(\"섹션 스트림을 찾을 수 없습니다\")\r\n\r\n metadata.pageCount = sections.length\r\n\r\n // 페이지 범위 필터링 (섹션 단위 근사치)\r\n const pageFilter = options?.pages ? parsePageRange(options.pages, sections.length) : null\r\n const totalTarget = pageFilter ? pageFilter.size : sections.length\r\n\r\n const blocks: IRBlock[] = []\r\n const nestedTableCounter = { count: 0 }\r\n let totalDecompressed = 0\r\n let parsedSections = 0\r\n for (let si = 0; si < sections.length; si++) {\r\n if (pageFilter && !pageFilter.has(si + 1)) continue\r\n try {\r\n const sectionData = sections[si]\r\n // 배포용 문서는 findViewTextSections에서 이미 복호화+압축해제 완료\r\n const data = (!distribution && compressed) ? decompressStream(Buffer.from(sectionData)) : Buffer.from(sectionData)\r\n totalDecompressed += data.length\r\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\r\n const records = readRecords(data)\r\n const sectionBlocks = parseSection(records, docInfo, warnings, si + 1, nestedTableCounter)\r\n blocks.push(...sectionBlocks)\r\n parsedSections++\r\n options?.onProgress?.(parsedSections, totalTarget)\r\n } catch (secErr) {\r\n if (secErr instanceof KordocError) throw secErr\r\n warnings.push({ page: si + 1, message: `섹션 ${si + 1} 파싱 실패: ${secErr instanceof Error ? secErr.message : \"알 수 없는 오류\"}`, code: \"PARTIAL_PARSE\" })\r\n }\r\n }\r\n\r\n // BinData에서 이미지 추출\r\n const images = cfb\r\n ? extractHwp5Images(cfb, blocks, compressed, warnings)\r\n : extractHwp5ImagesLenient(lenientCfb!, blocks, compressed, warnings)\r\n\r\n // 레이아웃 테이블 해체 (heading 감지 전에 수행하여 해체된 텍스트도 heading 감지 대상)\r\n const flatBlocks = flattenLayoutTables(blocks)\r\n\r\n // 스타일 기반 헤딩 감지\r\n if (docInfo) {\r\n detectHwp5Headings(flatBlocks, docInfo)\r\n }\r\n\r\n // outline 구축\r\n const outline: OutlineItem[] = flatBlocks\r\n .filter(b => b.type === \"heading\" && b.level && b.text)\r\n .map(b => ({ level: b.level!, text: b.text!, pageNumber: b.pageNumber }))\r\n\r\n const markdown = blocksToMarkdown(flatBlocks)\r\n return { markdown, blocks: flatBlocks, metadata, outline: outline.length > 0 ? outline : undefined, warnings: warnings.length > 0 ? warnings : undefined, images: images.length > 0 ? images : undefined }\r\n}\r\n\r\n/** DocInfo 스트림 파싱 (best-effort) */\r\nfunction parseDocInfoStream(cfb: CfbContainer, compressed: boolean): HwpDocInfo | null {\r\n try {\r\n const entry = CFB.find(cfb, \"/DocInfo\")\r\n if (!entry?.content) return null\r\n const data = compressed ? decompressStream(Buffer.from(entry.content)) : Buffer.from(entry.content)\r\n const records = readRecords(data)\r\n return parseDocInfo(records)\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\n/** DocInfo — Buffer에서 직접 파싱 (lenient용) */\r\nfunction parseDocInfoFromStream(raw: Buffer | null, compressed: boolean): HwpDocInfo | null {\r\n if (!raw) return null\r\n try {\r\n const data = compressed ? decompressStream(raw) : raw\r\n return parseDocInfo(readRecords(data))\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\n/** 스타일 기반 헤딩 감지 — 큰 폰트 + 짧은 텍스트 → heading */\r\nfunction detectHwp5Headings(blocks: IRBlock[], docInfo: HwpDocInfo): void {\r\n // 기본 폰트 크기 결정 (본문 스타일 또는 가장 많이 사용되는 크기)\r\n let baseFontSize = 0\r\n\r\n // \"바탕글\", \"본문\" 등 본문 스타일 찾기\r\n for (const style of docInfo.styles) {\r\n const name = (style.nameKo || style.name).toLowerCase()\r\n if (name.includes(\"바탕\") || name.includes(\"본문\") || name === \"normal\" || name === \"body\") {\r\n const cs = docInfo.charShapes[style.charShapeId]\r\n // cs.fontSize는 0.1pt 단위 → pt로 변환 (블록의 style.fontSize와 동일 단위)\r\n if (cs?.fontSize > 0) { baseFontSize = cs.fontSize / 10; break }\r\n }\r\n }\r\n\r\n // 본문 스타일 못 찾으면 블록의 폰트 크기 중 최빈값 사용\r\n if (baseFontSize === 0) {\r\n const sizeFreq = new Map<number, number>()\r\n for (const b of blocks) {\r\n if (b.style?.fontSize) {\r\n sizeFreq.set(b.style.fontSize, (sizeFreq.get(b.style.fontSize) || 0) + 1)\r\n }\r\n }\r\n let maxCount = 0\r\n for (const [size, count] of sizeFreq) {\r\n if (count > maxCount) { maxCount = count; baseFontSize = size }\r\n }\r\n }\r\n\r\n if (baseFontSize <= 0) return\r\n\r\n for (const block of blocks) {\r\n // 개요 수준(outlineLevel)으로 이미 heading이 된 블록은 스킵\r\n if (block.type === \"heading\") continue\r\n if (block.type !== \"paragraph\" || !block.text) continue\r\n const text = block.text.trim()\r\n if (text.length === 0 || text.length > 200) continue\r\n if (/^\\d+$/.test(text)) continue\r\n\r\n let level = 0\r\n\r\n // 폰트 크기 비율 기반 헤딩 감지 (스타일 정보가 있을 때만)\r\n if (block.style?.fontSize && baseFontSize > 0) {\r\n const ratio = block.style.fontSize / baseFontSize\r\n if (ratio >= HEADING_RATIO_H1) level = 1\r\n else if (ratio >= HEADING_RATIO_H2) level = 2\r\n else if (ratio >= HEADING_RATIO_H3) level = 3\r\n }\r\n\r\n // \"제N장/절/편\" 패턴 → H2, \"제N조\" 패턴 → H3 (스타일 유무 무관)\r\n if (/^제\\d+[장절편]\\s/.test(text) && text.length <= 50) {\r\n if (level === 0) level = 2\r\n } else if (/^제\\d+(조의?\\d*)\\s*[\\((]/.test(text) && text.length <= 80) {\r\n if (level === 0) level = 3\r\n }\r\n\r\n if (level > 0) {\r\n block.type = \"heading\"\r\n block.level = level\r\n }\r\n }\r\n}\r\n\r\n// ─── 메타데이터 추출 (best-effort) ───────────────────\r\n\r\n/**\r\n * OLE2 SummaryInformation 스트림에서 제목/작성자 추출.\r\n * HWP5는 \\005HwpSummaryInformation 또는 \\005SummaryInformation에 저장.\r\n * OLE2 Property Set 포맷의 간이 파싱 — 실패 시 조용히 무시.\r\n */\r\nfunction extractHwp5Metadata(cfb: CfbContainer, metadata: DocumentMetadata): void {\r\n try {\r\n // HWP 전용 SummaryInformation 먼저, 없으면 표준 OLE2\r\n const summaryEntry =\r\n CFB.find(cfb, \"/\\x05HwpSummaryInformation\") ||\r\n CFB.find(cfb, \"/\\x05SummaryInformation\")\r\n if (!summaryEntry?.content) return\r\n\r\n const data = Buffer.from(summaryEntry.content)\r\n if (data.length < 48) return\r\n\r\n // OLE2 Property Set Header: byte order(2) + version(2) + OS(4) + CLSID(16) + numSets(4) = 28\r\n // Then FMTID(16) + offset(4)\r\n const numSets = data.readUInt32LE(24)\r\n if (numSets === 0) return\r\n\r\n const setOffset = data.readUInt32LE(44)\r\n if (setOffset >= data.length - 8) return\r\n\r\n // Property Set: size(4) + numProperties(4) + [propertyId(4) + offset(4)] * N\r\n const numProps = data.readUInt32LE(setOffset + 4)\r\n if (numProps === 0 || numProps > 100) return\r\n\r\n for (let i = 0; i < numProps; i++) {\r\n const entryOffset = setOffset + 8 + i * 8\r\n if (entryOffset + 8 > data.length) break\r\n\r\n const propId = data.readUInt32LE(entryOffset)\r\n const propOffset = setOffset + data.readUInt32LE(entryOffset + 4)\r\n if (propOffset + 8 > data.length) continue\r\n\r\n // Property ID: 2=Title, 4=Author, 6=Subject/Description\r\n if (propId !== 2 && propId !== 4 && propId !== 6) continue\r\n\r\n const propType = data.readUInt32LE(propOffset)\r\n // Type 0x1E = VT_LPSTR (ANSI string)\r\n if (propType !== 0x1e) continue\r\n\r\n const strLen = data.readUInt32LE(propOffset + 4)\r\n if (strLen === 0 || strLen > 10000 || propOffset + 8 + strLen > data.length) continue\r\n\r\n const str = data.subarray(propOffset + 8, propOffset + 8 + strLen).toString(\"utf8\").replace(/\\0+$/, \"\").trim()\r\n if (!str) continue\r\n\r\n if (propId === 2) metadata.title = str\r\n else if (propId === 4) metadata.author = str\r\n else if (propId === 6) metadata.description = str\r\n }\r\n } catch {\r\n // best-effort — 실패 시 조용히 무시\r\n }\r\n}\r\n\r\n/** 메타데이터만 추출 (전체 파싱 없이) — MCP parse_metadata용 */\r\nexport function extractHwp5MetadataOnly(buffer: Buffer): DocumentMetadata {\r\n const cfb = CFB.parse(buffer)\r\n const headerEntry = CFB.find(cfb, \"/FileHeader\")\r\n if (!headerEntry?.content) throw new KordocError(\"FileHeader 스트림 없음\")\r\n const header = parseFileHeader(Buffer.from(headerEntry.content))\r\n if (header.signature !== \"HWP Document File\") throw new KordocError(\"HWP 시그니처 불일치\")\r\n\r\n const metadata: DocumentMetadata = {\r\n version: `${header.versionMajor}.x`,\r\n }\r\n extractHwp5Metadata(cfb, metadata)\r\n\r\n const sections = findSections(cfb)\r\n metadata.pageCount = sections.length\r\n\r\n return metadata\r\n}\r\n\r\n/** 배포용 문서: ViewText/Section{N} 스트림을 복호화하여 반환 */\r\nfunction findViewTextSections(cfb: CfbContainer, compressed: boolean): Buffer[] {\r\n const sections: Array<{ idx: number; content: Buffer }> = []\r\n\r\n for (let i = 0; i < MAX_SECTIONS; i++) {\r\n const entry = CFB.find(cfb, `/ViewText/Section${i}`)\r\n if (!entry?.content) break\r\n try {\r\n const decrypted = decryptViewText(Buffer.from(entry.content), compressed)\r\n sections.push({ idx: i, content: decrypted })\r\n } catch {\r\n // 복호화 실패 시 해당 섹션 스킵\r\n break\r\n }\r\n }\r\n\r\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\r\n}\r\n\r\nfunction findSections(cfb: CfbContainer): Buffer[] {\r\n const sections: Array<{ idx: number; content: Buffer }> = []\r\n\r\n for (let i = 0; i < MAX_SECTIONS; i++) {\r\n const entry = CFB.find(cfb, `/BodyText/Section${i}`)\r\n if (!entry?.content) break\r\n sections.push({ idx: i, content: Buffer.from(entry.content) })\r\n }\r\n\r\n if (sections.length === 0 && cfb.FileIndex) {\r\n for (const entry of cfb.FileIndex) {\r\n if (sections.length >= MAX_SECTIONS) break\r\n if (entry.name?.startsWith(\"Section\") && entry.content) {\r\n const idx = parseInt(entry.name.replace(\"Section\", \"\"), 10) || 0\r\n sections.push({ idx, content: Buffer.from(entry.content) })\r\n }\r\n }\r\n }\r\n\r\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\r\n}\r\n\r\n/** Lenient CFB: BodyText/Section{N} 탐색 — 누적 압축해제 크기 추적 */\r\nfunction findSectionsLenient(lcfb: LenientCfbContainer, compressed: boolean): Buffer[] {\r\n const sections: Array<{ idx: number; content: Buffer }> = []\r\n let totalDecompressed = 0\r\n for (let i = 0; i < MAX_SECTIONS; i++) {\r\n const raw = lcfb.findStream(`/BodyText/Section${i}`) ?? lcfb.findStream(`Section${i}`)\r\n if (!raw) break\r\n const content = compressed ? decompressStream(raw) : raw\r\n totalDecompressed += content.length\r\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\r\n sections.push({ idx: i, content })\r\n }\r\n if (sections.length === 0) {\r\n // fallback: 이름에 \"Section\" 포함된 스트림\r\n for (const e of lcfb.entries()) {\r\n if (sections.length >= MAX_SECTIONS) break\r\n if (e.name.startsWith(\"Section\")) {\r\n const idx = parseInt(e.name.replace(\"Section\", \"\"), 10) || 0\r\n const raw = lcfb.findStream(e.name)\r\n if (raw) {\r\n const content = compressed ? decompressStream(raw) : raw\r\n totalDecompressed += content.length\r\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\r\n sections.push({ idx, content })\r\n }\r\n }\r\n }\r\n }\r\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\r\n}\r\n\r\n/** Lenient CFB: ViewText/Section{N} 복호화 — 누적 크기 추적 */\r\nfunction findViewTextSectionsLenient(lcfb: LenientCfbContainer, compressed: boolean): Buffer[] {\r\n const sections: Array<{ idx: number; content: Buffer }> = []\r\n let totalDecompressed = 0\r\n for (let i = 0; i < MAX_SECTIONS; i++) {\r\n const raw = lcfb.findStream(`/ViewText/Section${i}`) ?? lcfb.findStream(`Section${i}`)\r\n if (!raw) break\r\n try {\r\n const content = decryptViewText(raw, compressed)\r\n totalDecompressed += content.length\r\n if (totalDecompressed > MAX_TOTAL_DECOMPRESS) throw new KordocError(\"총 압축 해제 크기 초과 (decompression bomb 의심)\")\r\n sections.push({ idx: i, content })\r\n } catch { break }\r\n }\r\n return sections.sort((a, b) => a.idx - b.idx).map(s => s.content)\r\n}\r\n\r\n// ─── BinData ���미지 추출 ─────��─────────────────��────\r\n\r\n/** SHAPE_COMPONENT 태그 — HWP5 스펙 */\r\nconst TAG_SHAPE_COMPONENT = 0x004a\r\nconst CTRL_ID_EQEDIT = \"deqe\"\r\n\r\n/** gso 제어 뒤의 하위 레코드에서 binDataId 추출 (best-effort) */\r\nfunction extractBinDataId(records: HwpRecord[], ctrlIdx: number): number {\r\n const ctrlLevel = records[ctrlIdx].level\r\n // CTRL_HEADER 이후의 하위 레코드들을 순회\r\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 50; j++) {\r\n const r = records[j]\r\n if (r.level <= ctrlLevel) break // 같은/상위 레벨이면 이 제어 블록 끝\r\n // SHAPE_COMPONENT에서 picture 타입이면 binDataId 추출\r\n // picture 데이터는 SHAPE_COMPONENT 뒤에 오는 하위 레코드에 있음\r\n // HWP5에서 그림 정보는 level이 높은 하위 레코드에 binDataId가 uint16LE로 저장\r\n if (r.data.length >= 2) {\r\n // 매직바이트로 이미지인지 확인하는 대신, SHAPE_COMPONENT 뒤의 하위 레코드에서 binDataId를 읽음\r\n // HWP5 picture 구조: CTRL_HEADER(gso) → LIST_HEADER → SHAPE_COMPONENT → [picture data record]\r\n // picture data record에서 offset 0부터 uint16LE = binDataId\r\n if (r.tagId > TAG_SHAPE_COMPONENT && r.level > ctrlLevel + 1 && r.data.length >= 4) {\r\n const possibleId = r.data.readUInt16LE(0)\r\n if (possibleId < 10000) return possibleId // 합리적 범위\r\n }\r\n }\r\n }\r\n return -1\r\n}\r\n\r\nfunction isEquationControlId(ctrlId: string): boolean {\r\n return ctrlId === CTRL_ID_EQEDIT || ctrlId === \"eqed\"\r\n}\r\n\r\nfunction formatEquationForMarkdown(equation: string): string {\r\n const normalized = hwpEquationToLatex(equation)\r\n if (!normalized) return \"\"\r\n return `$${normalized.replace(/\\$/g, \"\\\\$\")}$`\r\n}\r\n\r\nfunction extractEquationFromControl(records: HwpRecord[], ctrlIdx: number): string | null {\r\n const ctrlLevel = records[ctrlIdx].level\r\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 10; j++) {\r\n const r = records[j]\r\n if (r.level <= ctrlLevel) break\r\n if (r.tagId !== TAG_EQEDIT) continue\r\n const equation = extractEquationText(r.data)\r\n return equation ? formatEquationForMarkdown(equation) : null\r\n }\r\n return null\r\n}\r\n\r\nfunction renderTextWithEquations(textRecords: Buffer[], equations: string[]): string {\r\n const queue = [...equations]\r\n return textRecords\r\n .map(data => extractTextWithControls(data, ctrlId => {\r\n if (!isEquationControlId(ctrlId) || queue.length === 0) return null\r\n return queue.shift()\r\n }))\r\n .join(\"\")\r\n .replace(/\\$\\$/g, \"$ $\")\r\n}\r\n\r\n/** MIME 타입 매직바이트 판별 */\r\nfunction detectImageMime(data: Buffer | Uint8Array): string | null {\r\n if (data.length < 4) return null\r\n if (data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4e && data[3] === 0x47) return \"image/png\"\r\n if (data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff) return \"image/jpeg\"\r\n if (data[0] === 0x47 && data[1] === 0x49 && data[2] === 0x46) return \"image/gif\"\r\n if (data[0] === 0x42 && data[1] === 0x4d) return \"image/bmp\"\r\n if (data[0] === 0xd7 && data[1] === 0xcd && data[2] === 0xc6 && data[3] === 0x9a) return \"image/wmf\"\r\n if (data[0] === 0x01 && data[1] === 0x00 && data[2] === 0x00 && data[3] === 0x00) return \"image/emf\"\r\n return null\r\n}\r\n\r\n/** OLE2 BinData 스토리지에서 이미지 추출, blocks의 image 블록과 매핑 */\r\nfunction extractHwp5Images(\r\n cfb: CfbContainer,\r\n blocks: IRBlock[],\r\n compressed: boolean,\r\n warnings: ParseWarning[],\r\n): ExtractedImage[] {\r\n // BinData 스토리지의 모든 파일을 FileIndex 순회로 수집 (O(n), 기존 O(20000) CFB.find 제거)\r\n const binDataMap = new Map<number, { data: Buffer; name: string }>()\r\n const binDataRe = /\\/BinData\\/[Bb][Ii][Nn](\\d{4})$/\r\n if (cfb.FileIndex) {\r\n for (const entry of cfb.FileIndex) {\r\n if (!entry?.name || !entry.content) continue\r\n const match = entry.name.match(binDataRe)\r\n if (!match) continue\r\n const idx = parseInt(match[1], 10)\r\n let data = Buffer.from(entry.content)\r\n if (compressed) {\r\n try { data = decompressStream(data) } catch { /* 이미 비압축일 수 있음 */ }\r\n }\r\n binDataMap.set(idx, { data, name: entry.name })\r\n }\r\n }\r\n\r\n if (binDataMap.size === 0) return []\r\n\r\n const images: ExtractedImage[] = []\r\n let imageIndex = 0\r\n\r\n for (const block of blocks) {\r\n if (block.type !== \"image\" || !block.text) continue\r\n const binId = parseInt(block.text, 10)\r\n if (isNaN(binId)) continue\r\n\r\n const bin = binDataMap.get(binId)\r\n if (!bin) {\r\n warnings.push({ page: block.pageNumber, message: `BinData ${binId} 없음`, code: \"SKIPPED_IMAGE\" })\r\n block.type = \"paragraph\"\r\n block.text = `[이미지: BinData ${binId}]`\r\n continue\r\n }\r\n\r\n const mime = detectImageMime(bin.data)\r\n if (!mime) {\r\n warnings.push({ page: block.pageNumber, message: `BinData ${binId}: 알 수 없는 이미지 형식`, code: \"SKIPPED_IMAGE\" })\r\n block.type = \"paragraph\"\r\n block.text = `[이미지: ${bin.name}]`\r\n continue\r\n }\r\n\r\n imageIndex++\r\n const ext = mime.includes(\"jpeg\") ? \"jpg\" : mime.includes(\"png\") ? \"png\" : mime.includes(\"gif\") ? \"gif\" : mime.includes(\"bmp\") ? \"bmp\" : \"bin\"\r\n const filename = `image_${String(imageIndex).padStart(3, \"0\")}.${ext}`\r\n\r\n images.push({ filename, data: new Uint8Array(bin.data), mimeType: mime })\r\n block.text = filename\r\n block.imageData = { data: new Uint8Array(bin.data), mimeType: mime, filename: bin.name }\r\n }\r\n\r\n return images\r\n}\r\n\r\n/** Lenient CFB: BinData 이미지 추출 */\r\nfunction extractHwp5ImagesLenient(\r\n lcfb: LenientCfbContainer,\r\n blocks: IRBlock[],\r\n compressed: boolean,\r\n warnings: ParseWarning[],\r\n): ExtractedImage[] {\r\n // BinData 엔트리 수집\r\n const binDataMap = new Map<number, { data: Buffer; name: string }>()\r\n const binRe = /^BIN(\\d{4})/i\r\n for (const e of lcfb.entries()) {\r\n const match = e.name.match(binRe)\r\n if (!match) continue\r\n const idx = parseInt(match[1], 10)\r\n let raw = lcfb.findStream(e.name)\r\n if (!raw) continue\r\n if (compressed) {\r\n try { raw = decompressStream(raw) } catch { /* 이미 비압축일 수 있음 */ }\r\n }\r\n binDataMap.set(idx, { data: raw, name: e.name })\r\n }\r\n if (binDataMap.size === 0) return []\r\n\r\n const images: ExtractedImage[] = []\r\n let imageIndex = 0\r\n for (const block of blocks) {\r\n if (block.type !== \"image\" || !block.text) continue\r\n const binId = parseInt(block.text, 10)\r\n if (isNaN(binId)) continue\r\n const bin = binDataMap.get(binId)\r\n if (!bin) {\r\n warnings.push({ page: block.pageNumber, message: `BinData ${binId} ���음`, code: \"SKIPPED_IMAGE\" })\r\n block.type = \"paragraph\"; block.text = `[이미지: BinData ${binId}]`; continue\r\n }\r\n const mime = detectImageMime(bin.data)\r\n if (!mime) {\r\n warnings.push({ page: block.pageNumber, message: `BinData ${binId}: 알 수 없는 이미지 형식`, code: \"SKIPPED_IMAGE\" })\r\n block.type = \"paragraph\"; block.text = `[이미지: ${bin.name}]`; continue\r\n }\r\n imageIndex++\r\n const ext = mime.includes(\"jpeg\") ? \"jpg\" : mime.includes(\"png\") ? \"png\" : mime.includes(\"gif\") ? \"gif\" : mime.includes(\"bmp\") ? \"bmp\" : \"bin\"\r\n const filename = `image_${String(imageIndex).padStart(3, \"0\")}.${ext}`\r\n images.push({ filename, data: new Uint8Array(bin.data), mimeType: mime })\r\n block.text = filename\r\n block.imageData = { data: new Uint8Array(bin.data), mimeType: mime, filename: bin.name }\r\n }\r\n return images\r\n}\r\n\r\nfunction parseSection(records: HwpRecord[], docInfo: HwpDocInfo | null, warnings: ParseWarning[], sectionNum: number, counter?: { count: number }): IRBlock[] {\r\n const blocks: IRBlock[] = []\r\n let i = 0\r\n\r\n while (i < records.length) {\r\n const rec = records[i]\r\n\r\n if (rec.tagId === TAG_PARA_HEADER && rec.level === 0) {\r\n const { paragraph, tables, nextIdx, charShapeIds, paraShapeId } = parseParagraphWithTables(records, i, counter)\r\n if (paragraph) {\r\n const block: IRBlock = { type: \"paragraph\", text: paragraph, pageNumber: sectionNum }\r\n // CHAR_SHAPE 기반 스타일 정보 추가\r\n if (docInfo && charShapeIds.length > 0) {\r\n const style = resolveCharStyle(charShapeIds, docInfo)\r\n if (style) block.style = style\r\n }\r\n // PARA_SHAPE 개요 수준으로 heading 즉시 설정\r\n if (docInfo && paraShapeId >= 0 && paraShapeId < docInfo.paraShapes.length) {\r\n const ol = docInfo.paraShapes[paraShapeId].outlineLevel\r\n if (ol >= 1 && ol <= 6) {\r\n block.type = \"heading\"\r\n block.level = ol\r\n }\r\n }\r\n blocks.push(block)\r\n }\r\n for (const t of tables) blocks.push({ type: \"table\", table: t, pageNumber: sectionNum })\r\n i = nextIdx\r\n continue\r\n }\r\n\r\n if (rec.tagId === TAG_CTRL_HEADER && rec.level <= 1 && rec.data.length >= 4) {\r\n const ctrlId = rec.data.subarray(0, 4).toString(\"ascii\")\r\n if (ctrlId === \" lbt\" || ctrlId === \"tbl \") {\r\n const { table, nextIdx } = parseTableBlock(records, i, counter)\r\n if (table) blocks.push({ type: \"table\", table, pageNumber: sectionNum })\r\n i = nextIdx\r\n continue\r\n }\r\n // 그리기 객체(gso) — 이미지 또는 글상자\r\n if (ctrlId === \"gso \" || ctrlId === \" osg\") {\r\n const binId = extractBinDataId(records, i)\r\n if (binId >= 0) {\r\n blocks.push({ type: \"image\", text: String(binId), pageNumber: sectionNum })\r\n } else {\r\n // 이미지가 아니면 글상자(TextBox) 텍스트 추출 시도\r\n const boxText = extractTextBoxText(records, i)\r\n if (boxText) {\r\n blocks.push({ type: \"paragraph\", text: boxText, pageNumber: sectionNum })\r\n }\r\n // 텍스트도 없으면 조용히 스킵 (장식용 도형)\r\n }\r\n } else if (ctrlId === \" elo\" || ctrlId === \"ole \") {\r\n warnings.push({ page: sectionNum, message: `스킵된 제어 요소: ${ctrlId.trim()}`, code: \"SKIPPED_IMAGE\" })\r\n }\r\n // 각주/미주 — CTRL_HEADER 아래의 텍스트를 추출하여 footnoteText로 연결\r\n else if (ctrlId === \"fn \" || ctrlId === \" nf \" || ctrlId === \"en \" || ctrlId === \" ne \") {\r\n const noteText = extractNoteText(records, i)\r\n if (noteText && blocks.length > 0) {\r\n // 직전 paragraph 블록에 footnoteText 연결\r\n const lastBlock = blocks[blocks.length - 1]\r\n if (lastBlock.type === \"paragraph\") {\r\n lastBlock.footnoteText = lastBlock.footnoteText\r\n ? lastBlock.footnoteText + \"; \" + noteText\r\n : noteText\r\n }\r\n }\r\n }\r\n // 하이퍼링크 — CTRL_HEADER 데이터에서 URL 추출\r\n else if (ctrlId === \"%tok\" || ctrlId === \"klnk\") {\r\n const url = extractHyperlinkUrl(rec.data)\r\n if (url && blocks.length > 0) {\r\n const lastBlock = blocks[blocks.length - 1]\r\n if (lastBlock.type === \"paragraph\" && !lastBlock.href) {\r\n lastBlock.href = sanitizeHref(url) ?? undefined\r\n }\r\n }\r\n }\r\n }\r\n\r\n i++\r\n }\r\n\r\n return blocks\r\n}\r\n\r\n/** 각주/미주 CTRL_HEADER 아래의 본문 텍스트 추출 */\r\nfunction extractNoteText(records: HwpRecord[], ctrlIdx: number): string | null {\r\n const ctrlLevel = records[ctrlIdx].level\r\n const texts: string[] = []\r\n let textRecords: Buffer[] = []\r\n let equations: string[] = []\r\n\r\n const flushText = () => {\r\n const text = renderTextWithEquations(textRecords, equations).trim()\r\n if (text) texts.push(text)\r\n textRecords = []\r\n equations = []\r\n }\r\n\r\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 100; j++) {\r\n const r = records[j]\r\n if (r.level <= ctrlLevel) break // 상위 레벨 도달 → 이 컨트롤 블록 끝\r\n\r\n if (r.tagId === TAG_PARA_HEADER) {\r\n flushText()\r\n }\r\n\r\n if (r.tagId === TAG_PARA_TEXT) {\r\n textRecords.push(r.data)\r\n }\r\n\r\n if (r.tagId === TAG_CTRL_HEADER && r.data.length >= 4) {\r\n const ctrlId = r.data.subarray(0, 4).toString(\"ascii\")\r\n if (isEquationControlId(ctrlId)) {\r\n const equation = extractEquationFromControl(records, j)\r\n if (equation) equations.push(equation)\r\n }\r\n }\r\n }\r\n\r\n flushText()\r\n return texts.length > 0 ? texts.join(\" \") : null\r\n}\r\n\r\n/** 글상자(TextBox) 제어 요소 아래의 텍스트 추출 — extractNoteText와 동일 패턴 */\r\nfunction extractTextBoxText(records: HwpRecord[], ctrlIdx: number): string | null {\r\n const ctrlLevel = records[ctrlIdx].level\r\n const texts: string[] = []\r\n let textRecords: Buffer[] = []\r\n let equations: string[] = []\r\n\r\n const flushText = () => {\r\n const text = renderTextWithEquations(textRecords, equations).trim()\r\n if (text) texts.push(text)\r\n textRecords = []\r\n equations = []\r\n }\r\n\r\n for (let j = ctrlIdx + 1; j < records.length && j < ctrlIdx + 200; j++) {\r\n const r = records[j]\r\n if (r.level <= ctrlLevel) break\r\n\r\n if (r.tagId === TAG_PARA_HEADER) {\r\n flushText()\r\n }\r\n\r\n if (r.tagId === TAG_PARA_TEXT) {\r\n textRecords.push(r.data)\r\n }\r\n\r\n if (r.tagId === TAG_CTRL_HEADER && r.data.length >= 4) {\r\n const ctrlId = r.data.subarray(0, 4).toString(\"ascii\")\r\n if (isEquationControlId(ctrlId)) {\r\n const equation = extractEquationFromControl(records, j)\r\n if (equation) equations.push(equation)\r\n }\r\n }\r\n }\r\n\r\n flushText()\r\n return texts.length > 0 ? texts.join(\"\\n\") : null\r\n}\r\n\r\n/** 하이퍼링크 CTRL_HEADER에서 URL 추출 (best-effort) */\r\nfunction extractHyperlinkUrl(data: Buffer): string | null {\r\n // HWP5 하이퍼링크 CTRL_HEADER 구조:\r\n // ctrlId(4) + 기타 필드들... + URL 문자열 (UTF-16LE, length-prefixed)\r\n // 정확한 오프셋은 버전마다 다를 수 있으므로 URL 패턴 스캔으로 폴백\r\n try {\r\n // UTF-16LE에서 \"http\" 시그니처 스캔\r\n const httpSig = Buffer.from(\"http\", \"utf16le\") // \"h\\0t\\0t\\0p\\0\"\r\n const idx = data.indexOf(httpSig)\r\n if (idx >= 0) {\r\n // null terminator(0x0000 0x0000)까지 UTF-16LE로 읽기\r\n let end = idx\r\n while (end + 1 < data.length) {\r\n const ch = data.readUInt16LE(end)\r\n if (ch === 0) break\r\n end += 2\r\n }\r\n const url = data.subarray(idx, end).toString(\"utf16le\")\r\n // 기본 URL 검증\r\n if (/^https?:\\/\\/.+/.test(url) && url.length < 2000) {\r\n return url\r\n }\r\n }\r\n } catch { /* best-effort */ }\r\n return null\r\n}\r\n\r\n/** CHAR_SHAPE ID 배열에서 대표 스타일 결정 (최빈값) */\r\nfunction resolveCharStyle(charShapeIds: number[], docInfo: HwpDocInfo): InlineStyle | undefined {\r\n if (charShapeIds.length === 0 || docInfo.charShapes.length === 0) return undefined\r\n\r\n // 가장 많이 나타나는 charShapeId 사용\r\n const freq = new Map<number, number>()\r\n let maxCount = 0, dominantId = charShapeIds[0]\r\n for (const id of charShapeIds) {\r\n const count = (freq.get(id) || 0) + 1\r\n freq.set(id, count)\r\n if (count > maxCount) { maxCount = count; dominantId = id }\r\n }\r\n\r\n const cs = docInfo.charShapes[dominantId]\r\n if (!cs) return undefined\r\n\r\n const style: InlineStyle = {}\r\n if (cs.fontSize > 0) style.fontSize = cs.fontSize / 10 // 0.1pt → pt\r\n if (cs.attrFlags & 0x01) style.italic = true\r\n if (cs.attrFlags & 0x02) style.bold = true\r\n\r\n return (style.fontSize || style.bold || style.italic) ? style : undefined\r\n}\r\n\r\nfunction parseParagraphWithTables(records: HwpRecord[], startIdx: number, counter?: { count: number }) {\r\n const startLevel = records[startIdx].level\r\n const textRecords: Buffer[] = []\r\n const equations: string[] = []\r\n const tables: ReturnType<typeof buildTable>[] = []\r\n const charShapeIds: number[] = []\r\n\r\n // PARA_HEADER에서 paraShapeId 추출 (offset 8-9, u16)\r\n const paraHeaderData = records[startIdx].data\r\n const paraShapeId = paraHeaderData.length >= 10 ? paraHeaderData.readUInt16LE(8) : -1\r\n\r\n let i = startIdx + 1\r\n\r\n while (i < records.length) {\r\n const rec = records[i]\r\n if (rec.tagId === TAG_PARA_HEADER && rec.level <= startLevel) break\r\n\r\n if (rec.tagId === TAG_PARA_TEXT) {\r\n textRecords.push(rec.data)\r\n }\r\n\r\n // CHAR_SHAPE 레코드 — 문단 내 글자 모양 인덱스 배열\r\n if (rec.tagId === TAG_CHAR_SHAPE && rec.data.length >= 8) {\r\n // 구조: [position(u32) + charShapeId(u32)] * N\r\n for (let offset = 0; offset + 7 < rec.data.length; offset += 8) {\r\n charShapeIds.push(rec.data.readUInt32LE(offset + 4))\r\n }\r\n }\r\n\r\n if (rec.tagId === TAG_CTRL_HEADER && rec.data.length >= 4) {\r\n const ctrlId = rec.data.subarray(0, 4).toString(\"ascii\")\r\n if (isEquationControlId(ctrlId)) {\r\n const equation = extractEquationFromControl(records, i)\r\n if (equation) equations.push(equation)\r\n } else if (ctrlId === \" lbt\" || ctrlId === \"tbl \") {\r\n const { table, nextIdx } = parseTableBlock(records, i, counter)\r\n if (table) tables.push(table)\r\n i = nextIdx\r\n continue\r\n }\r\n }\r\n i++\r\n }\r\n\r\n const text = renderTextWithEquations(textRecords, equations)\r\n const trimmed = text.trim()\r\n return { paragraph: trimmed || null, tables, nextIdx: i, charShapeIds, paraShapeId }\r\n}\r\n\r\nfunction parseTableBlock(records: HwpRecord[], startIdx: number, counter?: { count: number }) {\r\n const tableLevel = records[startIdx].level\r\n let i = startIdx + 1\r\n let rows = 0, cols = 0\r\n const cells: CellContext[] = []\r\n\r\n while (i < records.length) {\r\n const rec = records[i]\r\n if (rec.tagId === TAG_PARA_HEADER && rec.level <= tableLevel) break\r\n if (rec.tagId === TAG_CTRL_HEADER && rec.level <= tableLevel) break\r\n\r\n if (rec.tagId === TAG_TABLE && rec.data.length >= 8) {\r\n rows = Math.min(rec.data.readUInt16LE(4), MAX_ROWS)\r\n cols = Math.min(rec.data.readUInt16LE(6), MAX_COLS)\r\n }\r\n\r\n if (rec.tagId === TAG_LIST_HEADER) {\r\n const { cell, nextIdx } = parseCellBlock(records, i, tableLevel, counter)\r\n if (cell) cells.push(cell)\r\n i = nextIdx\r\n continue\r\n }\r\n i++\r\n }\r\n\r\n if (rows === 0 || cols === 0 || cells.length === 0) return { table: null, nextIdx: i }\r\n\r\n // colAddr/rowAddr가 있으면 arrangeCells가 이미 완성된 그리드를 반환하므로\r\n // buildTable(2-pass) 없이 직접 IRTable 생성 — 이중 colSpan 확장 방지\r\n const hasAddr = cells.some(c => c.colAddr !== undefined && c.rowAddr !== undefined)\r\n if (hasAddr) {\r\n const cellRows = arrangeCells(rows, cols, cells)\r\n const irCells = cellRows.map(row => row.map(c => ({\r\n text: c.text.trim(),\r\n colSpan: c.colSpan,\r\n rowSpan: c.rowSpan,\r\n })))\r\n return { table: { rows, cols, cells: irCells, hasHeader: rows > 1 }, nextIdx: i }\r\n }\r\n\r\n const cellRows = arrangeCells(rows, cols, cells)\r\n return { table: buildTable(cellRows), nextIdx: i }\r\n}\r\n\r\nfunction parseCellBlock(records: HwpRecord[], startIdx: number, tableLevel: number, counter?: { count: number }) {\r\n const rec = records[startIdx]\r\n const cellLevel = rec.level\r\n const texts: string[] = []\r\n let textRecords: Buffer[] = []\r\n let equations: string[] = []\r\n\r\n const flushText = () => {\r\n const text = renderTextWithEquations(textRecords, equations).trim()\r\n if (text) texts.push(text)\r\n textRecords = []\r\n equations = []\r\n }\r\n\r\n // LIST_HEADER에서 셀 위치 및 병합 정보 추출\r\n // HWP5 셀 LIST_HEADER 구조:\r\n // paraCount(u16) + flags(u32) + width(u16) + colAddr(u16) + rowAddr(u16) + colSpan(u16) + rowSpan(u16)\r\n // offset: 0 2 6 8 10 12 14\r\n let colSpan = 1\r\n let rowSpan = 1\r\n let colAddr: number | undefined\r\n let rowAddr: number | undefined\r\n if (rec.data.length >= 16) {\r\n colAddr = rec.data.readUInt16LE(8)\r\n rowAddr = rec.data.readUInt16LE(10)\r\n const cs = rec.data.readUInt16LE(12)\r\n const rs = rec.data.readUInt16LE(14)\r\n if (cs > 0) colSpan = Math.min(cs, MAX_COLS)\r\n if (rs > 0) rowSpan = Math.min(rs, MAX_ROWS)\r\n }\r\n\r\n let i = startIdx + 1\r\n\r\n while (i < records.length) {\r\n const r = records[i]\r\n if (r.tagId === TAG_LIST_HEADER && r.level <= cellLevel) break\r\n if (r.level <= tableLevel && (r.tagId === TAG_PARA_HEADER || r.tagId === TAG_CTRL_HEADER)) break\r\n\r\n if (r.tagId === TAG_PARA_HEADER) {\r\n flushText()\r\n }\r\n\r\n if (r.tagId === TAG_PARA_TEXT) {\r\n textRecords.push(r.data)\r\n }\r\n\r\n // 셀 내부 중첩 테이블 감지 (HWP5에서는 내용 파싱 없이 마커만 표시)\r\n // 힌트 없음 — HWP5는 이 단계에서 중첩 테이블 내부를 파싱하지 않으므로 첫 행 추출 불가\r\n if (r.tagId === TAG_CTRL_HEADER && r.data.length >= 4) {\r\n const ctrlId = r.data.subarray(0, 4).toString(\"ascii\")\r\n if (isEquationControlId(ctrlId)) {\r\n const equation = extractEquationFromControl(records, i)\r\n if (equation) equations.push(equation)\r\n } else if (ctrlId === \" lbt\" || ctrlId === \"tbl \") {\r\n flushText()\r\n if (counter) {\r\n counter.count++\r\n texts.push(`[중첩 테이블 #${counter.count}]`)\r\n } else {\r\n texts.push(\"[중첩 테이블]\")\r\n }\r\n }\r\n }\r\n\r\n i++\r\n }\r\n\r\n flushText()\r\n return { cell: { text: texts.join(\"\\n\"), colSpan, rowSpan, colAddr, rowAddr } as CellContext, nextIdx: i }\r\n}\r\n\r\nfunction arrangeCells(rows: number, cols: number, cells: CellContext[]): CellContext[][] {\r\n const grid: (CellContext | null)[][] = Array.from({ length: rows }, () => Array(cols).fill(null))\r\n\r\n // colAddr/rowAddr가 있으면 직접 배치 (HWP5 병합 테이블 정확도 향상)\r\n const hasAddr = cells.some(c => c.colAddr !== undefined && c.rowAddr !== undefined)\r\n\r\n if (hasAddr) {\r\n for (const cell of cells) {\r\n const r = cell.rowAddr ?? 0\r\n const c = cell.colAddr ?? 0\r\n if (r >= rows || c >= cols) continue\r\n grid[r][c] = cell\r\n\r\n for (let dr = 0; dr < cell.rowSpan; dr++) {\r\n for (let dc = 0; dc < cell.colSpan; dc++) {\r\n if (dr === 0 && dc === 0) continue\r\n if (r + dr < rows && c + dc < cols)\r\n grid[r + dr][c + dc] = { text: \"\", colSpan: 1, rowSpan: 1 }\r\n }\r\n }\r\n }\r\n } else {\r\n // fallback: 순차 배치 (colAddr 없는 경우)\r\n let cellIdx = 0\r\n for (let r = 0; r < rows && cellIdx < cells.length; r++) {\r\n for (let c = 0; c < cols && cellIdx < cells.length; c++) {\r\n if (grid[r][c] !== null) continue\r\n const cell = cells[cellIdx++]\r\n grid[r][c] = cell\r\n\r\n for (let dr = 0; dr < cell.rowSpan; dr++) {\r\n for (let dc = 0; dc < cell.colSpan; dc++) {\r\n if (dr === 0 && dc === 0) continue\r\n if (r + dr < rows && c + dc < cols)\r\n grid[r + dr][c + dc] = { text: \"\", colSpan: 1, rowSpan: 1 }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return grid.map(row => row.map(c => c || { text: \"\", colSpan: 1, rowSpan: 1 }))\r\n}\r\n","/**\r\n * HWP 3.0 (한글 워드프로세서 3.x) 텍스트 추출 파서.\r\n *\r\n * 1996~2002년 한컴이 사용한 binary 포맷. CFB(OLE2) 컨테이너가 아닌 단일 binary stream.\r\n * 내부 구조 요약:\r\n * 30 byte signature\r\n * + 128 byte DocInfo (compressed/encrypted 플래그 + InfoBlock 길이)\r\n * + 1008 byte DocSummary (제목/저자/날짜)\r\n * + InfoBlock (가변 — 폰트/스타일 메타데이터)\r\n * + Body (compressed!=0 이면 raw deflate 압축)\r\n *\r\n * Body 는 paragraph 의 list. 각 paragraph 는 헤더 + LineInfos + (inline char shapes) + char stream.\r\n * char stream 은 hchar (u16 little-endian) 의 시퀀스로, 1..31 영역(13 제외) 은 제어 문자\r\n * (제어 문자별로 추가 byte 를 소비하고 일부는 nested paragraph list 가짐).\r\n *\r\n * 본 구현은 **텍스트 추출 전용** — 표/그림 레이아웃, 글자 속성, 캡션 위치 등은 모두 무시한다.\r\n * 표 셀과 그림 캡션, 머리말/꼬리말, 각주의 본문 텍스트는 재귀로 모아서 결과에 포함시킨다.\r\n *\r\n * 출처: rhwp/src/parser/hwp3/mod.rs (Apache-2.0). 알고리즘 1:1 포팅 + minimal 변형.\r\n */\r\n\r\nimport { inflateRawSync } from \"zlib\"\r\nimport type { DocumentMetadata, IRBlock, InternalParseResult, ParseOptions, ParseWarning } from \"../types.js\"\r\nimport { JOHAB_UNMAPPED, decodeJohab } from \"./johab.js\"\r\nimport { Reader } from \"./reader.js\"\r\nimport { readHeader } from \"./records.js\"\r\n\r\nconst PARA_HEADER_FIXED_SIZE = 43 // follow_prev(1) + char_count(2) + line_count(2) + include_cs(1) + flags(1) + sc_flags(4) + style_idx(1) + rep_char_shape(31)\r\nconst PARA_SHAPE_SIZE = 187 // ParaShape 구조 (rhwp records.rs Hwp3ParaShape::read 합산)\r\nconst LINE_INFO_SIZE = 14 // Hwp3LineInfo (u16 × 7)\r\nconst INLINE_CHAR_SHAPE_SIZE = 31 // Hwp3CharShape (rep_char_shape 와 동일)\r\n// 제어 문자별 ch 외 추가 read byte 수. (ch 는 이미 paragraph loop 가 read 한 후라 여기엔 미포함.)\r\n// 단위: byte. 동시에 char_count 에서 차지하는 hchar 도 다름 — 아래 EXTRA_HCHAR.\r\n//\r\n// rhwp/src/parser/hwp3/mod.rs ch 분기 그대로 옮긴 표.\r\n// 9 (Tab) : extra=0 byte, hchar=1\r\n// 18~21 (각종 번호) : extra=6 byte, hchar=4\r\n// 22 (메일머지) : extra=22 byte, hchar=12\r\n// 23 (글자겹침) : extra=8 byte, hchar=5\r\n// 24,25 (하이픈) : extra=4 byte, hchar=3\r\n// 26 (찾아보기) : extra=244 byte, hchar=123 (1 + 122 추가)\r\n// 28 (개요번호) : extra=62 byte, hchar=32 (1 + 31 추가)\r\n// 30 (묶음빈칸) : extra=2 byte, hchar=2\r\n// 31 (고정폭빈칸) : extra=2 byte, hchar=2\r\n// 7,8 (날짜) : extra=6 byte, hchar=4\r\n// default (10/11/12/15/16/17/27/29 등): 8 byte 헤더 + 종류별 추가\r\ntype CtrlSimple = { extraBytes: number; extraHchar: number; emit: string | null }\r\nconst SIMPLE_CTRL: ReadonlyMap<number, CtrlSimple> = new Map([\r\n [9, { extraBytes: 0, extraHchar: 0, emit: \"\\t\" }],\r\n [7, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\r\n [8, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\r\n [18, { extraBytes: 6, extraHchar: 3, emit: \" \" }], // AutoNumber → 공백 (HWP5 패턴)\r\n [19, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\r\n [20, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\r\n [21, { extraBytes: 6, extraHchar: 3, emit: \"\" }],\r\n [22, { extraBytes: 22, extraHchar: 11, emit: \"\" }],\r\n [23, { extraBytes: 8, extraHchar: 4, emit: \"\" }],\r\n [24, { extraBytes: 4, extraHchar: 2, emit: \"-\" }],\r\n [25, { extraBytes: 4, extraHchar: 2, emit: \"-\" }],\r\n [26, { extraBytes: 244, extraHchar: 122, emit: \"\" }],\r\n [28, { extraBytes: 62, extraHchar: 31, emit: \"\" }],\r\n [30, { extraBytes: 2, extraHchar: 1, emit: \" \" }],\r\n [31, { extraBytes: 2, extraHchar: 1, emit: \" \" }],\r\n])\r\n\r\ninterface ParaContext {\r\n /** 누적된 paragraph text 의 array — 각 entry 가 한 paragraph */\r\n paragraphs: string[]\r\n warnings: ParseWarning[]\r\n}\r\n\r\nexport interface Hwp3ParseOptions extends ParseOptions {\r\n /** 표/그림 nested paragraph 본문도 출력 (기본 true). */\r\n includeNested?: boolean\r\n}\r\n\r\n/**\r\n * HWP3 buffer → InternalParseResult.\r\n * encrypted 본문은 복호화 못하고 ENCRYPTED 코드로 throw.\r\n */\r\nexport function parseHwp3Document(\r\n buffer: ArrayBuffer,\r\n _options?: Hwp3ParseOptions,\r\n): InternalParseResult {\r\n const headReader = new Reader(Buffer.from(buffer))\r\n const header = readHeader(headReader)\r\n\r\n if (header.encrypted !== 0) {\r\n const e: Error & { code?: string } = new Error(\"HWP3 본문이 암호로 보호되어 있어 추출할 수 없습니다.\")\r\n e.code = \"ENCRYPTED\"\r\n throw e\r\n }\r\n\r\n // InfoBlock skip — 폰트/스타일 메타데이터, 텍스트 추출엔 불필요.\r\n headReader.skip(header.infoBlockLength)\r\n\r\n // Body: compressed != 0 이면 raw deflate (zlib 헤더 없는 RFC 1951)\r\n const tail = headReader.readToEnd()\r\n let body: Buffer\r\n const warnings: ParseWarning[] = []\r\n if (header.compressed !== 0) {\r\n try {\r\n body = inflateRawSync(tail)\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err)\r\n throw new Error(`HWP3 압축 해제 실패: ${msg}`)\r\n }\r\n } else {\r\n body = tail\r\n }\r\n\r\n const bodyReader = new Reader(body)\r\n const ctx: ParaContext = { paragraphs: [], warnings }\r\n try {\r\n skipFontFacesAndStyles(bodyReader)\r\n parseParagraphList(bodyReader, ctx)\r\n } catch (err) {\r\n // 부분 파싱 실패 — 모은 만큼이라도 반환. truncated 경고 추가.\r\n warnings.push({\r\n code: \"PARTIAL_PARSE\",\r\n message: `HWP3 paragraph stream 도중 파싱 중단: ${err instanceof Error ? err.message : String(err)}`,\r\n })\r\n }\r\n\r\n const text = ctx.paragraphs.filter(p => p.length > 0).join(\"\\n\\n\")\r\n const blocks: IRBlock[] = ctx.paragraphs.map(p => ({ type: \"paragraph\", text: p }))\r\n\r\n const metadata: DocumentMetadata = {\r\n title: header.title || undefined,\r\n author: header.author || undefined,\r\n description: header.subject || undefined,\r\n createdAt: header.date || undefined,\r\n version: \"3.0\",\r\n }\r\n\r\n return {\r\n markdown: text,\r\n blocks,\r\n metadata,\r\n warnings: warnings.length ? warnings : undefined,\r\n }\r\n}\r\n\r\n/**\r\n * 본문 paragraph_list 진입 전 — 압축 해제된 body 의 앞쪽에는 font / style 메타데이터가 있다.\r\n * rhwp/src/parser/hwp3/mod.rs:1654~1700 흐름 그대로:\r\n * - 7개 언어별 font face: n_fonts(u16) + n_fonts × 40 byte name\r\n * - n_styles(u16) + n_styles × (20 byte name + 31 byte char_shape + 187 byte para_shape)\r\n */\r\nfunction skipFontFacesAndStyles(reader: Reader): void {\r\n const STYLE_RECORD_SIZE = 20 + 31 + 187 // = 238\r\n for (let lang = 0; lang < 7; lang++) {\r\n const n = reader.readU16()\r\n reader.skip(n * 40)\r\n }\r\n const nStyles = reader.readU16()\r\n reader.skip(nStyles * STYLE_RECORD_SIZE)\r\n}\r\n\r\n/** char_count==0 빈 paragraph 가 list 끝. */\r\nfunction parseParagraphList(reader: Reader, ctx: ParaContext): void {\r\n for (;;) {\r\n if (reader.eof()) return\r\n\r\n // ParaInfo 헤더 (가변 size). list 끝 sentinel(empty para)이 아니어도 stream sync 가\r\n // 어긋난 이전 paragraph 의 잔재로 비정상 헤더가 들어올 수 있다. char_count 가\r\n // 1 paragraph 한도(64K) 를 넘는다거나 lineCount 가 비정상적이면 list 종료로 간주.\r\n const followPrev = reader.readU8()\r\n const charCount = reader.readU16()\r\n if (charCount === 0) {\r\n // 빈 paragraph: 이미 3 byte 읽었으므로 40 byte 더 read 후 종료\r\n reader.skip(40)\r\n return\r\n }\r\n const lineCount = reader.readU16()\r\n // 방어: 한 paragraph 의 line 수가 4096 을 넘는 건 stream 어긋남으로 간주.\r\n if (charCount > 60000 || lineCount > 4096) {\r\n ctx.warnings.push({\r\n code: \"PARTIAL_PARSE\",\r\n message: `HWP3 비정상 paragraph 헤더 (char_count=${charCount}, line_count=${lineCount}) → 이후 stream 포기`,\r\n })\r\n return\r\n }\r\n const includeCharShape = reader.readU8()\r\n reader.skip(1) // flags\r\n reader.skip(4) // special_char_flags\r\n reader.skip(1) // style_index\r\n reader.skip(31) // rep_char_shape\r\n if (followPrev === 0) reader.skip(PARA_SHAPE_SIZE)\r\n\r\n // LineInfos\r\n reader.skip(lineCount * LINE_INFO_SIZE)\r\n\r\n // Inline char shapes — char_count 만큼 (flag u8, flag != 1 이면 charshape 31 byte)\r\n if (includeCharShape !== 0) {\r\n for (let i = 0; i < charCount; i++) {\r\n const flag = reader.readU8()\r\n if (flag !== 1) reader.skip(INLINE_CHAR_SHAPE_SIZE)\r\n }\r\n }\r\n\r\n // Char stream — paragraph 단위로 try/catch 해서 한 paragraph 가 깨져도 list 전체는\r\n // 살리되, sync 가 어긋난 후의 후속 paragraph 들도 비정상 헤더가 나올 가능성이 커서\r\n // 헤더 sanity check 로 방어한다.\r\n try {\r\n const text = parseCharStream(reader, charCount, ctx)\r\n ctx.paragraphs.push(text)\r\n } catch (err) {\r\n ctx.warnings.push({\r\n code: \"PARTIAL_PARSE\",\r\n message: `HWP3 paragraph #${ctx.paragraphs.length} char stream 파싱 실패: ${err instanceof Error ? err.message : String(err)}`,\r\n })\r\n return\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * paragraph 본문 char_count 개의 hchar 를 처리해 텍스트 추출.\r\n * 제어 문자는 제어 byte 만큼 정확히 소비하고 일부 (10/11/15/16/17 등) 는\r\n * nested paragraph list 를 별도로 ctx 에 모은다.\r\n */\r\nfunction parseCharStream(reader: Reader, charCount: number, ctx: ParaContext): string {\r\n let out = \"\"\r\n let i = 0\r\n while (i < charCount) {\r\n const ch = reader.readU16()\r\n i += 1\r\n\r\n if (ch === 13) {\r\n out += \"\\n\"\r\n continue\r\n }\r\n if (ch === 0) {\r\n // 일부 패딩/오류 케이스 — 무시\r\n continue\r\n }\r\n if (ch >= 32) {\r\n // 일반 hchar (ASCII < 0x80 영역도 u16 으로 들어옴)\r\n const cp = decodeJohab(ch)\r\n if (cp !== JOHAB_UNMAPPED) out += String.fromCodePoint(cp)\r\n continue\r\n }\r\n\r\n // 1..31 (13 제외) 제어 문자\r\n const simple = SIMPLE_CTRL.get(ch)\r\n if (simple) {\r\n reader.skip(simple.extraBytes)\r\n i += simple.extraHchar\r\n if (simple.emit) out += simple.emit\r\n continue\r\n }\r\n\r\n // ch=10/11/12/14/15/16/17/27/29 등: 8 byte 추가 헤더 + 종류별 추가 처리\r\n // 8 byte = u32 header_val1 + u16 ch2 + 2 byte (hchar 정렬)\r\n const headerVal1 = reader.readU32() // size 또는 type-specific\r\n reader.readU16() // ch2 (sanity, ch와 같아야 함)\r\n i += 3 // 8 byte 헤더는 char_count 에서 4 hchar 차지 (1 이미 + 3)\r\n\r\n // 종류별 분기\r\n switch (ch) {\r\n case 10:\r\n // 표 / 글상자 / 수식 / 버튼: 84 byte info + cells + caption\r\n out += parseTableLike(reader, ctx)\r\n break\r\n case 11:\r\n // 그림: 348 byte info + n_ext byte\r\n parsePicture(reader, ctx)\r\n break\r\n case 12:\r\n // 선: 84 byte info\r\n reader.skip(84)\r\n break\r\n case 14:\r\n // 선 (alternate path) — rhwp mod.rs line 943: 84 byte info\r\n reader.skip(84)\r\n break\r\n case 15: {\r\n // 숨은 설명: 8 byte info + nested paragraph list\r\n reader.skip(8)\r\n parseParagraphList(reader, ctx)\r\n break\r\n }\r\n case 16: {\r\n // 머리말/꼬리말: 10 byte info + nested\r\n reader.skip(10)\r\n parseParagraphList(reader, ctx)\r\n break\r\n }\r\n case 17: {\r\n // 각주/미주: 14 byte info + nested\r\n reader.skip(14)\r\n parseParagraphList(reader, ctx)\r\n break\r\n }\r\n case 29:\r\n // 상호참조: header_val1 size raw skip (1MB 이상 비정상)\r\n if (headerVal1 < 1_000_000) reader.skip(headerVal1)\r\n break\r\n default:\r\n // ch=2/3/4/5/6/27 등: rhwp mod.rs:1011 의 \"알 수 없음\" 분기에서\r\n // header_val1 을 길이로 사용하지 않는다고 명시 (\"ch=3 실증: 헤더 직후가 정상 단락\r\n // 내용이므로 추가 skip 없음\"). 즉 8 byte 헤더만 소비하고 다음 char 로.\r\n // 경고는 첫 등장만 기록 — 본문에 페이지번호/필드코드가 많이 깔린 paragraph 가\r\n // 전형적인 케이스라 logging 폭주 방지.\r\n if (!ctx.warnings.some(w => w.code === \"UNSUPPORTED_ELEMENT\")) {\r\n ctx.warnings.push({\r\n code: \"UNSUPPORTED_ELEMENT\",\r\n message: `HWP3 부분 처리 제어 문자 ch=${ch} (이후 동일 코드 경고 생략)`,\r\n })\r\n }\r\n break\r\n }\r\n }\r\n return out.trim()\r\n}\r\n\r\n/** ch=10 표/글상자/수식/버튼 본문 텍스트 추출. */\r\nfunction parseTableLike(reader: Reader, ctx: ParaContext): string {\r\n // 84 byte info_buf\r\n const info = reader.readBytes(84)\r\n const cellCount = info.readUInt16LE(80) || 1\r\n // 방어: cellCount 가 비정상적으로 크면 stream 어긋남으로 간주, 추가 처리 포기.\r\n // 한 표에 cell 256 개 초과는 사실상 없음 (HWP3 spec 상 행/열 한계도 그 미만).\r\n if (cellCount > 256) {\r\n ctx.warnings.push({\r\n code: \"PARTIAL_PARSE\",\r\n message: `HWP3 표 cell_count=${cellCount} 비정상 — 표 본문 추출 포기`,\r\n })\r\n throw new Error(`HWP3 비정상 cell_count=${cellCount}`)\r\n }\r\n // 각 셀: 27 byte 정보 → 셀별 nested paragraph list (재귀)\r\n reader.skip(27 * cellCount)\r\n\r\n // 셀별 텍스트 collect — 셀 내부 paragraph 는 ctx 에 직접 push 되므로\r\n // 본 paragraph 의 \"표 자리\" 에는 placeholder 만 남기고 셀 텍스트는 ctx 안에서 별도 paragraph 로 보존.\r\n for (let i = 0; i < cellCount; i++) {\r\n parseParagraphList(reader, ctx)\r\n }\r\n // 캡션 paragraph list 1회\r\n parseParagraphList(reader, ctx)\r\n return \"\" // 표 자리에는 빈 문자열 (셀 텍스트는 이미 ctx.paragraphs 에 포함됨)\r\n}\r\n\r\n/** ch=11 그림 — info 348 byte + n_ext bytes (info[0..4] 가 n_ext). */\r\nfunction parsePicture(reader: Reader, _ctx: ParaContext): void {\r\n const info = reader.readBytes(348)\r\n const nExt = info.readUInt32LE(0)\r\n if (nExt > 0 && nExt < 100 * 1024 * 1024) reader.skip(nExt)\r\n}\r\n","// Auto-generated from rhwp/src/parser/hwp3/johab_map.rs — DO NOT EDIT.\r\n// Pairs of (johab-code, unicode-codepoint), sorted by key for binary search.\r\n// Total entries: 5893\r\n\r\nexport const JOHAB_SYMBOLS: ReadonlyArray<number> = Object.freeze([\r\n 0x8441,0x3000, 0x8442,0x3131, 0x8443,0x3132, 0x8444,0x3133, 0x8445,0x3134, 0x8446,0x3135, 0x8447,0x3136, 0x8448,0x3137,\r\n 0x8449,0x3139, 0x844A,0x313A, 0x844B,0x313B, 0x844C,0x313C, 0x844D,0x313D, 0x844E,0x313E, 0x844F,0x313F, 0x8450,0x3140,\r\n 0x8451,0x3141, 0x8453,0x3142, 0x8454,0x3144, 0x8455,0x3145, 0x8456,0x3146, 0x8457,0x3147, 0x8458,0x3148, 0x8459,0x314A,\r\n 0x845A,0x314B, 0x845B,0x314C, 0x845C,0x314D, 0x845D,0x314E, 0x8461,0x314F, 0x8481,0x3150, 0x84A1,0x3151, 0x84C1,0x3152,\r\n 0x84E1,0x3153, 0x8541,0x3154, 0x8561,0x3155, 0x8581,0x3156, 0x85A1,0x3157, 0x85C1,0x3158, 0x85E1,0x3159, 0x8641,0x315A,\r\n 0x8661,0x315B, 0x8681,0x315C, 0x86A1,0x315D, 0x86C1,0x315E, 0x86E1,0x315F, 0x8741,0x3160, 0x8761,0x3161, 0x8781,0x3162,\r\n 0x87A1,0x3163, 0x8841,0x3131, 0x8C41,0x3132, 0x9041,0x3134, 0x9441,0x3137, 0x9841,0x3138, 0x9C41,0x3139, 0xA041,0x3141,\r\n 0xA441,0x3142, 0xA841,0x3143, 0xAC41,0x3145, 0xB041,0x3146, 0xB441,0x3147, 0xB841,0x3148, 0xBC41,0x3149, 0xC041,0x314A,\r\n 0xC441,0x314B, 0xC841,0x314C, 0xCC41,0x314D, 0xD041,0x314E, 0xD931,0x3000, 0xD932,0x3001, 0xD933,0x3002, 0xD934,0x00B7,\r\n 0xD935,0x2025, 0xD936,0x2026, 0xD937,0x00A8, 0xD938,0x3003, 0xD939,0x00AD, 0xD93A,0x2015, 0xD93B,0x2225, 0xD93C,0xFF3C,\r\n 0xD93D,0x223C, 0xD93E,0x2018, 0xD93F,0x2019, 0xD940,0x201C, 0xD941,0x201D, 0xD942,0x3014, 0xD943,0x3015, 0xD944,0x3008,\r\n 0xD945,0x3009, 0xD946,0x300A, 0xD947,0x300B, 0xD948,0x300C, 0xD949,0x300D, 0xD94A,0x300E, 0xD94B,0x300F, 0xD94C,0x3010,\r\n 0xD94D,0x3011, 0xD94E,0x00B1, 0xD94F,0x00D7, 0xD950,0x00F7, 0xD951,0x2260, 0xD952,0x2264, 0xD953,0x2265, 0xD954,0x221E,\r\n 0xD955,0x2234, 0xD956,0x00B0, 0xD957,0x2032, 0xD958,0x2033, 0xD959,0x2103, 0xD95A,0x212B, 0xD95B,0xFFE0, 0xD95C,0xFFE1,\r\n 0xD95D,0xFFE5, 0xD95E,0x2642, 0xD95F,0x2640, 0xD960,0x2220, 0xD961,0x22A5, 0xD962,0x2312, 0xD963,0x2202, 0xD964,0x2207,\r\n 0xD965,0x2261, 0xD966,0x2252, 0xD967,0x00A7, 0xD968,0x203B, 0xD969,0x2606, 0xD96A,0x2605, 0xD96B,0x25CB, 0xD96C,0x25CF,\r\n 0xD96D,0x25CE, 0xD96E,0x25C7, 0xD96F,0x25C6, 0xD970,0x25A1, 0xD971,0x25A0, 0xD972,0x25B3, 0xD973,0x25B2, 0xD974,0x25BD,\r\n 0xD975,0x25BC, 0xD976,0x2192, 0xD977,0x2190, 0xD978,0x2191, 0xD979,0x2193, 0xD97A,0x2194, 0xD97B,0x3013, 0xD97C,0x226A,\r\n 0xD97D,0x226B, 0xD97E,0x221A, 0xD991,0x223D, 0xD992,0x221D, 0xD993,0x2235, 0xD994,0x222B, 0xD995,0x222C, 0xD996,0x2208,\r\n 0xD997,0x220B, 0xD998,0x2286, 0xD999,0x2287, 0xD99A,0x2282, 0xD99B,0x2283, 0xD99C,0x222A, 0xD99D,0x2229, 0xD99E,0x2227,\r\n 0xD99F,0x2228, 0xD9A0,0xFFE2, 0xD9A1,0x21D2, 0xD9A2,0x21D4, 0xD9A3,0x2200, 0xD9A4,0x2203, 0xD9A5,0x00B4, 0xD9A6,0xFF5E,\r\n 0xD9A7,0x02C7, 0xD9A8,0x02D8, 0xD9A9,0x02DD, 0xD9AA,0x02DA, 0xD9AB,0x02D9, 0xD9AC,0x00B8, 0xD9AD,0x02DB, 0xD9AE,0x00A1,\r\n 0xD9AF,0x00BF, 0xD9B0,0x02D0, 0xD9B1,0x222E, 0xD9B2,0x2211, 0xD9B3,0x220F, 0xD9B4,0x00A4, 0xD9B5,0x2109, 0xD9B6,0x2030,\r\n 0xD9B7,0x25C1, 0xD9B8,0x25C0, 0xD9B9,0x25B7, 0xD9BA,0x25B6, 0xD9BB,0x2664, 0xD9BC,0x2660, 0xD9BD,0x2661, 0xD9BE,0x2665,\r\n 0xD9BF,0x2667, 0xD9C0,0x2663, 0xD9C1,0x2299, 0xD9C2,0x25C8, 0xD9C3,0x25A3, 0xD9C4,0x25D0, 0xD9C5,0x25D1, 0xD9C6,0x2592,\r\n 0xD9C7,0x25A4, 0xD9C8,0x25A5, 0xD9C9,0x25A8, 0xD9CA,0x25A7, 0xD9CB,0x25A6, 0xD9CC,0x25A9, 0xD9CD,0x2668, 0xD9CE,0x260F,\r\n 0xD9CF,0x260E, 0xD9D0,0x261C, 0xD9D1,0x261E, 0xD9D2,0x00B6, 0xD9D3,0x2020, 0xD9D4,0x2021, 0xD9D5,0x2195, 0xD9D6,0x2197,\r\n 0xD9D7,0x2199, 0xD9D8,0x2196, 0xD9D9,0x2198, 0xD9DA,0x266D, 0xD9DB,0x2669, 0xD9DC,0x266A, 0xD9DD,0x266C, 0xD9DE,0x327F,\r\n 0xD9DF,0x321C, 0xD9E0,0x2116, 0xD9E1,0x33C7, 0xD9E2,0x2122, 0xD9E3,0x33C2, 0xD9E4,0x33D8, 0xD9E5,0x2121, 0xD9E6,0x20AC,\r\n 0xD9E7,0x00AE, 0xDA31,0xFF01, 0xDA32,0xFF02, 0xDA33,0xFF03, 0xDA34,0xFF04, 0xDA35,0xFF05, 0xDA36,0xFF06, 0xDA37,0xFF07,\r\n 0xDA38,0xFF08, 0xDA39,0xFF09, 0xDA3A,0xFF0A, 0xDA3B,0xFF0B, 0xDA3C,0xFF0C, 0xDA3D,0xFF0D, 0xDA3E,0xFF0E, 0xDA3F,0xFF0F,\r\n 0xDA40,0xFF10, 0xDA41,0xFF11, 0xDA42,0xFF12, 0xDA43,0xFF13, 0xDA44,0xFF14, 0xDA45,0xFF15, 0xDA46,0xFF16, 0xDA47,0xFF17,\r\n 0xDA48,0xFF18, 0xDA49,0xFF19, 0xDA4A,0xFF1A, 0xDA4B,0xFF1B, 0xDA4C,0xFF1C, 0xDA4D,0xFF1D, 0xDA4E,0xFF1E, 0xDA4F,0xFF1F,\r\n 0xDA50,0xFF20, 0xDA51,0xFF21, 0xDA52,0xFF22, 0xDA53,0xFF23, 0xDA54,0xFF24, 0xDA55,0xFF25, 0xDA56,0xFF26, 0xDA57,0xFF27,\r\n 0xDA58,0xFF28, 0xDA59,0xFF29, 0xDA5A,0xFF2A, 0xDA5B,0xFF2B, 0xDA5C,0xFF2C, 0xDA5D,0xFF2D, 0xDA5E,0xFF2E, 0xDA5F,0xFF2F,\r\n 0xDA60,0xFF30, 0xDA61,0xFF31, 0xDA62,0xFF32, 0xDA63,0xFF33, 0xDA64,0xFF34, 0xDA65,0xFF35, 0xDA66,0xFF36, 0xDA67,0xFF37,\r\n 0xDA68,0xFF38, 0xDA69,0xFF39, 0xDA6A,0xFF3A, 0xDA6B,0xFF3B, 0xDA6C,0xFFE6, 0xDA6D,0xFF3D, 0xDA6E,0xFF3E, 0xDA6F,0xFF3F,\r\n 0xDA70,0xFF40, 0xDA71,0xFF41, 0xDA72,0xFF42, 0xDA73,0xFF43, 0xDA74,0xFF44, 0xDA75,0xFF45, 0xDA76,0xFF46, 0xDA77,0xFF47,\r\n 0xDA78,0xFF48, 0xDA79,0xFF49, 0xDA7A,0xFF4A, 0xDA7B,0xFF4B, 0xDA7C,0xFF4C, 0xDA7D,0xFF4D, 0xDA7E,0xFF4E, 0xDA91,0xFF4F,\r\n 0xDA92,0xFF50, 0xDA93,0xFF51, 0xDA94,0xFF52, 0xDA95,0xFF53, 0xDA96,0xFF54, 0xDA97,0xFF55, 0xDA98,0xFF56, 0xDA99,0xFF57,\r\n 0xDA9A,0xFF58, 0xDA9B,0xFF59, 0xDA9C,0xFF5A, 0xDA9D,0xFF5B, 0xDA9E,0xFF5C, 0xDA9F,0xFF5D, 0xDAA0,0xFFE3, 0xDAD4,0x3164,\r\n 0xDAD5,0x3165, 0xDAD6,0x3166, 0xDAD7,0x3167, 0xDAD8,0x3168, 0xDAD9,0x3169, 0xDADA,0x316A, 0xDADB,0x316B, 0xDADC,0x316C,\r\n 0xDADD,0x316D, 0xDADE,0x316E, 0xDADF,0x316F, 0xDAE0,0x3170, 0xDAE1,0x3171, 0xDAE2,0x3172, 0xDAE3,0x3173, 0xDAE4,0x3174,\r\n 0xDAE5,0x3175, 0xDAE6,0x3176, 0xDAE7,0x3177, 0xDAE8,0x3178, 0xDAE9,0x3179, 0xDAEA,0x317A, 0xDAEB,0x317B, 0xDAEC,0x317C,\r\n 0xDAED,0x317D, 0xDAEE,0x317E, 0xDAEF,0x317F, 0xDAF0,0x3180, 0xDAF1,0x3181, 0xDAF2,0x3182, 0xDAF3,0x3183, 0xDAF4,0x3184,\r\n 0xDAF5,0x3185, 0xDAF6,0x3186, 0xDAF7,0x3187, 0xDAF8,0x3188, 0xDAF9,0x3189, 0xDAFA,0x318A, 0xDAFB,0x318B, 0xDAFC,0x318C,\r\n 0xDAFD,0x318D, 0xDAFE,0x318E, 0xDB31,0x2170, 0xDB32,0x2171, 0xDB33,0x2172, 0xDB34,0x2173, 0xDB35,0x2174, 0xDB36,0x2175,\r\n 0xDB37,0x2176, 0xDB38,0x2177, 0xDB39,0x2178, 0xDB3A,0x2179, 0xDB40,0x2160, 0xDB41,0x2161, 0xDB42,0x2162, 0xDB43,0x2163,\r\n 0xDB44,0x2164, 0xDB45,0x2165, 0xDB46,0x2166, 0xDB47,0x2167, 0xDB48,0x2168, 0xDB49,0x2169, 0xDB51,0x0391, 0xDB52,0x0392,\r\n 0xDB53,0x0393, 0xDB54,0x0394, 0xDB55,0x0395, 0xDB56,0x0396, 0xDB57,0x0397, 0xDB58,0x0398, 0xDB59,0x0399, 0xDB5A,0x039A,\r\n 0xDB5B,0x039B, 0xDB5C,0x039C, 0xDB5D,0x039D, 0xDB5E,0x039E, 0xDB5F,0x039F, 0xDB60,0x03A0, 0xDB61,0x03A1, 0xDB62,0x03A3,\r\n 0xDB63,0x03A4, 0xDB64,0x03A5, 0xDB65,0x03A6, 0xDB66,0x03A7, 0xDB67,0x03A8, 0xDB68,0x03A9, 0xDB71,0x03B1, 0xDB72,0x03B2,\r\n 0xDB73,0x03B3, 0xDB74,0x03B4, 0xDB75,0x03B5, 0xDB76,0x03B6, 0xDB77,0x03B7, 0xDB78,0x03B8, 0xDB79,0x03B9, 0xDB7A,0x03BA,\r\n 0xDB7B,0x03BB, 0xDB7C,0x03BC, 0xDB7D,0x03BD, 0xDB7E,0x03BE, 0xDB91,0x03BF, 0xDB92,0x03C0, 0xDB93,0x03C1, 0xDB94,0x03C3,\r\n 0xDB95,0x03C4, 0xDB96,0x03C5, 0xDB97,0x03C6, 0xDB98,0x03C7, 0xDB99,0x03C8, 0xDB9A,0x03C9, 0xDBA1,0x2500, 0xDBA2,0x2502,\r\n 0xDBA3,0x250C, 0xDBA4,0x2510, 0xDBA5,0x2518, 0xDBA6,0x2514, 0xDBA7,0x251C, 0xDBA8,0x252C, 0xDBA9,0x2524, 0xDBAA,0x2534,\r\n 0xDBAB,0x253C, 0xDBAC,0x2501, 0xDBAD,0x2503, 0xDBAE,0x250F, 0xDBAF,0x2513, 0xDBB0,0x251B, 0xDBB1,0x2517, 0xDBB2,0x2523,\r\n 0xDBB3,0x2533, 0xDBB4,0x252B, 0xDBB5,0x253B, 0xDBB6,0x254B, 0xDBB7,0x2520, 0xDBB8,0x252F, 0xDBB9,0x2528, 0xDBBA,0x2537,\r\n 0xDBBB,0x253F, 0xDBBC,0x251D, 0xDBBD,0x2530, 0xDBBE,0x2525, 0xDBBF,0x2538, 0xDBC0,0x2542, 0xDBC1,0x2512, 0xDBC2,0x2511,\r\n 0xDBC3,0x251A, 0xDBC4,0x2519, 0xDBC5,0x2516, 0xDBC6,0x2515, 0xDBC7,0x250E, 0xDBC8,0x250D, 0xDBC9,0x251E, 0xDBCA,0x251F,\r\n 0xDBCB,0x2521, 0xDBCC,0x2522, 0xDBCD,0x2526, 0xDBCE,0x2527, 0xDBCF,0x2529, 0xDBD0,0x252A, 0xDBD1,0x252D, 0xDBD2,0x252E,\r\n 0xDBD3,0x2531, 0xDBD4,0x2532, 0xDBD5,0x2535, 0xDBD6,0x2536, 0xDBD7,0x2539, 0xDBD8,0x253A, 0xDBD9,0x253D, 0xDBDA,0x253E,\r\n 0xDBDB,0x2540, 0xDBDC,0x2541, 0xDBDD,0x2543, 0xDBDE,0x2544, 0xDBDF,0x2545, 0xDBE0,0x2546, 0xDBE1,0x2547, 0xDBE2,0x2548,\r\n 0xDBE3,0x2549, 0xDBE4,0x254A, 0xDC31,0x3395, 0xDC32,0x3396, 0xDC33,0x3397, 0xDC34,0x2113, 0xDC35,0x3398, 0xDC36,0x33C4,\r\n 0xDC37,0x33A3, 0xDC38,0x33A4, 0xDC39,0x33A5, 0xDC3A,0x33A6, 0xDC3B,0x3399, 0xDC3C,0x339A, 0xDC3D,0x339B, 0xDC3E,0x339C,\r\n 0xDC3F,0x339D, 0xDC40,0x339E, 0xDC41,0x339F, 0xDC42,0x33A0, 0xDC43,0x33A1, 0xDC44,0x33A2, 0xDC45,0x33CA, 0xDC46,0x338D,\r\n 0xDC47,0x338E, 0xDC48,0x338F, 0xDC49,0x33CF, 0xDC4A,0x3388, 0xDC4B,0x3389, 0xDC4C,0x33C8, 0xDC4D,0x33A7, 0xDC4E,0x33A8,\r\n 0xDC4F,0x33B0, 0xDC50,0x33B1, 0xDC51,0x33B2, 0xDC52,0x33B3, 0xDC53,0x33B4, 0xDC54,0x33B5, 0xDC55,0x33B6, 0xDC56,0x33B7,\r\n 0xDC57,0x33B8, 0xDC58,0x33B9, 0xDC59,0x3380, 0xDC5A,0x3381, 0xDC5B,0x3382, 0xDC5C,0x3383, 0xDC5D,0x3384, 0xDC5E,0x33BA,\r\n 0xDC5F,0x33BB, 0xDC60,0x33BC, 0xDC61,0x33BD, 0xDC62,0x33BE, 0xDC63,0x33BF, 0xDC64,0x3390, 0xDC65,0x3391, 0xDC66,0x3392,\r\n 0xDC67,0x3393, 0xDC68,0x3394, 0xDC69,0x2126, 0xDC6A,0x33C0, 0xDC6B,0x33C1, 0xDC6C,0x338A, 0xDC6D,0x338B, 0xDC6E,0x338C,\r\n 0xDC6F,0x33D6, 0xDC70,0x33C5, 0xDC71,0x33AD, 0xDC72,0x33AE, 0xDC73,0x33AF, 0xDC74,0x33DB, 0xDC75,0x33A9, 0xDC76,0x33AA,\r\n 0xDC77,0x33AB, 0xDC78,0x33AC, 0xDC79,0x33DD, 0xDC7A,0x33D0, 0xDC7B,0x33D3, 0xDC7C,0x33C3, 0xDC7D,0x33C9, 0xDC7E,0x33DC,\r\n 0xDC91,0x33C6, 0xDCA1,0x00C6, 0xDCA2,0x00D0, 0xDCA3,0x00AA, 0xDCA4,0x0126, 0xDCA6,0x0132, 0xDCA8,0x013F, 0xDCA9,0x0141,\r\n 0xDCAA,0x00D8, 0xDCAB,0x0152, 0xDCAC,0x00BA, 0xDCAD,0x00DE, 0xDCAE,0x0166, 0xDCAF,0x014A, 0xDCB1,0x3260, 0xDCB2,0x3261,\r\n 0xDCB3,0x3262, 0xDCB4,0x3263, 0xDCB5,0x3264, 0xDCB6,0x3265, 0xDCB7,0x3266, 0xDCB8,0x3267, 0xDCB9,0x3268, 0xDCBA,0x3269,\r\n 0xDCBB,0x326A, 0xDCBC,0x326B, 0xDCBD,0x326C, 0xDCBE,0x326D, 0xDCBF,0x326E, 0xDCC0,0x326F, 0xDCC1,0x3270, 0xDCC2,0x3271,\r\n 0xDCC3,0x3272, 0xDCC4,0x3273, 0xDCC5,0x3274, 0xDCC6,0x3275, 0xDCC7,0x3276, 0xDCC8,0x3277, 0xDCC9,0x3278, 0xDCCA,0x3279,\r\n 0xDCCB,0x327A, 0xDCCC,0x327B, 0xDCCD,0x24D0, 0xDCCE,0x24D1, 0xDCCF,0x24D2, 0xDCD0,0x24D3, 0xDCD1,0x24D4, 0xDCD2,0x24D5,\r\n 0xDCD3,0x24D6, 0xDCD4,0x24D7, 0xDCD5,0x24D8, 0xDCD6,0x24D9, 0xDCD7,0x24DA, 0xDCD8,0x24DB, 0xDCD9,0x24DC, 0xDCDA,0x24DD,\r\n 0xDCDB,0x24DE, 0xDCDC,0x24DF, 0xDCDD,0x24E0, 0xDCDE,0x24E1, 0xDCDF,0x24E2, 0xDCE0,0x24E3, 0xDCE1,0x24E4, 0xDCE2,0x24E5,\r\n 0xDCE3,0x24E6, 0xDCE4,0x24E7, 0xDCE5,0x24E8, 0xDCE6,0x24E9, 0xDCE7,0x2460, 0xDCE8,0x2461, 0xDCE9,0x2462, 0xDCEA,0x2463,\r\n 0xDCEB,0x2464, 0xDCEC,0x2465, 0xDCED,0x2466, 0xDCEE,0x2467, 0xDCEF,0x2468, 0xDCF0,0x2469, 0xDCF1,0x246A, 0xDCF2,0x246B,\r\n 0xDCF3,0x246C, 0xDCF4,0x246D, 0xDCF5,0x246E, 0xDCF6,0x00BD, 0xDCF7,0x2153, 0xDCF8,0x2154, 0xDCF9,0x00BC, 0xDCFA,0x00BE,\r\n 0xDCFB,0x215B, 0xDCFC,0x215C, 0xDCFD,0x215D, 0xDCFE,0x215E, 0xDD31,0x00E6, 0xDD32,0x0111, 0xDD33,0x00F0, 0xDD34,0x0127,\r\n 0xDD35,0x0131, 0xDD36,0x0133, 0xDD37,0x0138, 0xDD38,0x0140, 0xDD39,0x0142, 0xDD3A,0x00F8, 0xDD3B,0x0153, 0xDD3C,0x00DF,\r\n 0xDD3D,0x00FE, 0xDD3E,0x0167, 0xDD3F,0x014B, 0xDD40,0x0149, 0xDD41,0x3200, 0xDD42,0x3201, 0xDD43,0x3202, 0xDD44,0x3203,\r\n 0xDD45,0x3204, 0xDD46,0x3205, 0xDD47,0x3206, 0xDD48,0x3207, 0xDD49,0x3208, 0xDD4A,0x3209, 0xDD4B,0x320A, 0xDD4C,0x320B,\r\n 0xDD4D,0x320C, 0xDD4E,0x320D, 0xDD4F,0x320E, 0xDD50,0x320F, 0xDD51,0x3210, 0xDD52,0x3211, 0xDD53,0x3212, 0xDD54,0x3213,\r\n 0xDD55,0x3214, 0xDD56,0x3215, 0xDD57,0x3216, 0xDD58,0x3217, 0xDD59,0x3218, 0xDD5A,0x3219, 0xDD5B,0x321A, 0xDD5C,0x321B,\r\n 0xDD5D,0x249C, 0xDD5E,0x249D, 0xDD5F,0x249E, 0xDD60,0x249F, 0xDD61,0x24A0, 0xDD62,0x24A1, 0xDD63,0x24A2, 0xDD64,0x24A3,\r\n 0xDD65,0x24A4, 0xDD66,0x24A5, 0xDD67,0x24A6, 0xDD68,0x24A7, 0xDD69,0x24A8, 0xDD6A,0x24A9, 0xDD6B,0x24AA, 0xDD6C,0x24AB,\r\n 0xDD6D,0x24AC, 0xDD6E,0x24AD, 0xDD6F,0x24AE, 0xDD70,0x24AF, 0xDD71,0x24B0, 0xDD72,0x24B1, 0xDD73,0x24B2, 0xDD74,0x24B3,\r\n 0xDD75,0x24B4, 0xDD76,0x24B5, 0xDD77,0x2474, 0xDD78,0x2475, 0xDD79,0x2476, 0xDD7A,0x2477, 0xDD7B,0x2478, 0xDD7C,0x2479,\r\n 0xDD7D,0x247A, 0xDD7E,0x247B, 0xDD91,0x247C, 0xDD92,0x247D, 0xDD93,0x247E, 0xDD94,0x247F, 0xDD95,0x2480, 0xDD96,0x2481,\r\n 0xDD97,0x2482, 0xDD98,0x00B9, 0xDD99,0x00B2, 0xDD9A,0x00B3, 0xDD9B,0x2074, 0xDD9C,0x207F, 0xDD9D,0x2081, 0xDD9E,0x2082,\r\n 0xDD9F,0x2083, 0xDDA0,0x2084, 0xDDA1,0x3041, 0xDDA2,0x3042, 0xDDA3,0x3043, 0xDDA4,0x3044, 0xDDA5,0x3045, 0xDDA6,0x3046,\r\n 0xDDA7,0x3047, 0xDDA8,0x3048, 0xDDA9,0x3049, 0xDDAA,0x304A, 0xDDAB,0x304B, 0xDDAC,0x304C, 0xDDAD,0x304D, 0xDDAE,0x304E,\r\n 0xDDAF,0x304F, 0xDDB0,0x3050, 0xDDB1,0x3051, 0xDDB2,0x3052, 0xDDB3,0x3053, 0xDDB4,0x3054, 0xDDB5,0x3055, 0xDDB6,0x3056,\r\n 0xDDB7,0x3057, 0xDDB8,0x3058, 0xDDB9,0x3059, 0xDDBA,0x305A, 0xDDBB,0x305B, 0xDDBC,0x305C, 0xDDBD,0x305D, 0xDDBE,0x305E,\r\n 0xDDBF,0x305F, 0xDDC0,0x3060, 0xDDC1,0x3061, 0xDDC2,0x3062, 0xDDC3,0x3063, 0xDDC4,0x3064, 0xDDC5,0x3065, 0xDDC6,0x3066,\r\n 0xDDC7,0x3067, 0xDDC8,0x3068, 0xDDC9,0x3069, 0xDDCA,0x306A, 0xDDCB,0x306B, 0xDDCC,0x306C, 0xDDCD,0x306D, 0xDDCE,0x306E,\r\n 0xDDCF,0x306F, 0xDDD0,0x3070, 0xDDD1,0x3071, 0xDDD2,0x3072, 0xDDD3,0x3073, 0xDDD4,0x3074, 0xDDD5,0x3075, 0xDDD6,0x3076,\r\n 0xDDD7,0x3077, 0xDDD8,0x3078, 0xDDD9,0x3079, 0xDDDA,0x307A, 0xDDDB,0x307B, 0xDDDC,0x307C, 0xDDDD,0x307D, 0xDDDE,0x307E,\r\n 0xDDDF,0x307F, 0xDDE0,0x3080, 0xDDE1,0x3081, 0xDDE2,0x3082, 0xDDE3,0x3083, 0xDDE4,0x3084, 0xDDE5,0x3085, 0xDDE6,0x3086,\r\n 0xDDE7,0x3087, 0xDDE8,0x3088, 0xDDE9,0x3089, 0xDDEA,0x308A, 0xDDEB,0x308B, 0xDDEC,0x308C, 0xDDED,0x308D, 0xDDEE,0x308E,\r\n 0xDDEF,0x308F, 0xDDF0,0x3090, 0xDDF1,0x3091, 0xDDF2,0x3092, 0xDDF3,0x3093, 0xDE31,0x30A1, 0xDE32,0x30A2, 0xDE33,0x30A3,\r\n 0xDE34,0x30A4, 0xDE35,0x30A5, 0xDE36,0x30A6, 0xDE37,0x30A7, 0xDE38,0x30A8, 0xDE39,0x30A9, 0xDE3A,0x30AA, 0xDE3B,0x30AB,\r\n 0xDE3C,0x30AC, 0xDE3D,0x30AD, 0xDE3E,0x30AE, 0xDE3F,0x30AF, 0xDE40,0x30B0, 0xDE41,0x30B1, 0xDE42,0x30B2, 0xDE43,0x30B3,\r\n 0xDE44,0x30B4, 0xDE45,0x30B5, 0xDE46,0x30B6, 0xDE47,0x30B7, 0xDE48,0x30B8, 0xDE49,0x30B9, 0xDE4A,0x30BA, 0xDE4B,0x30BB,\r\n 0xDE4C,0x30BC, 0xDE4D,0x30BD, 0xDE4E,0x30BE, 0xDE4F,0x30BF, 0xDE50,0x30C0, 0xDE51,0x30C1, 0xDE52,0x30C2, 0xDE53,0x30C3,\r\n 0xDE54,0x30C4, 0xDE55,0x30C5, 0xDE56,0x30C6, 0xDE57,0x30C7, 0xDE58,0x30C8, 0xDE59,0x30C9, 0xDE5A,0x30CA, 0xDE5B,0x30CB,\r\n 0xDE5C,0x30CC, 0xDE5D,0x30CD, 0xDE5E,0x30CE, 0xDE5F,0x30CF, 0xDE60,0x30D0, 0xDE61,0x30D1, 0xDE62,0x30D2, 0xDE63,0x30D3,\r\n 0xDE64,0x30D4, 0xDE65,0x30D5, 0xDE66,0x30D6, 0xDE67,0x30D7, 0xDE68,0x30D8, 0xDE69,0x30D9, 0xDE6A,0x30DA, 0xDE6B,0x30DB,\r\n 0xDE6C,0x30DC, 0xDE6D,0x30DD, 0xDE6E,0x30DE, 0xDE6F,0x30DF, 0xDE70,0x30E0, 0xDE71,0x30E1, 0xDE72,0x30E2, 0xDE73,0x30E3,\r\n 0xDE74,0x30E4, 0xDE75,0x30E5, 0xDE76,0x30E6, 0xDE77,0x30E7, 0xDE78,0x30E8, 0xDE79,0x30E9, 0xDE7A,0x30EA, 0xDE7B,0x30EB,\r\n 0xDE7C,0x30EC, 0xDE7D,0x30ED, 0xDE7E,0x30EE, 0xDE91,0x30EF, 0xDE92,0x30F0, 0xDE93,0x30F1, 0xDE94,0x30F2, 0xDE95,0x30F3,\r\n 0xDE96,0x30F4, 0xDE97,0x30F5, 0xDE98,0x30F6, 0xDEA1,0x0410, 0xDEA2,0x0411, 0xDEA3,0x0412, 0xDEA4,0x0413, 0xDEA5,0x0414,\r\n 0xDEA6,0x0415, 0xDEA7,0x0401, 0xDEA8,0x0416, 0xDEA9,0x0417, 0xDEAA,0x0418, 0xDEAB,0x0419, 0xDEAC,0x041A, 0xDEAD,0x041B,\r\n 0xDEAE,0x041C, 0xDEAF,0x041D, 0xDEB0,0x041E, 0xDEB1,0x041F, 0xDEB2,0x0420, 0xDEB3,0x0421, 0xDEB4,0x0422, 0xDEB5,0x0423,\r\n 0xDEB6,0x0424, 0xDEB7,0x0425, 0xDEB8,0x0426, 0xDEB9,0x0427, 0xDEBA,0x0428, 0xDEBB,0x0429, 0xDEBC,0x042A, 0xDEBD,0x042B,\r\n 0xDEBE,0x042C, 0xDEBF,0x042D, 0xDEC0,0x042E, 0xDEC1,0x042F, 0xDED1,0x0430, 0xDED2,0x0431, 0xDED3,0x0432, 0xDED4,0x0433,\r\n 0xDED5,0x0434, 0xDED6,0x0435, 0xDED7,0x0451, 0xDED8,0x0436, 0xDED9,0x0437, 0xDEDA,0x0438, 0xDEDB,0x0439, 0xDEDC,0x043A,\r\n 0xDEDD,0x043B, 0xDEDE,0x043C, 0xDEDF,0x043D, 0xDEE0,0x043E, 0xDEE1,0x043F, 0xDEE2,0x0440, 0xDEE3,0x0441, 0xDEE4,0x0442,\r\n 0xDEE5,0x0443, 0xDEE6,0x0444, 0xDEE7,0x0445, 0xDEE8,0x0446, 0xDEE9,0x0447, 0xDEEA,0x0448, 0xDEEB,0x0449, 0xDEEC,0x044A,\r\n 0xDEED,0x044B, 0xDEEE,0x044C, 0xDEEF,0x044D, 0xDEF0,0x044E, 0xDEF1,0x044F, 0xE031,0x4F3D, 0xE032,0x4F73, 0xE033,0x5047,\r\n 0xE034,0x50F9, 0xE035,0x52A0, 0xE036,0x53EF, 0xE037,0x5475, 0xE038,0x54E5, 0xE039,0x5609, 0xE03A,0x5AC1, 0xE03B,0x5BB6,\r\n 0xE03C,0x6687, 0xE03D,0x67B6, 0xE03E,0x67B7, 0xE03F,0x67EF, 0xE040,0x6B4C, 0xE041,0x73C2, 0xE042,0x75C2, 0xE043,0x7A3C,\r\n 0xE044,0x82DB, 0xE045,0x8304, 0xE046,0x8857, 0xE047,0x8888, 0xE048,0x8A36, 0xE049,0x8CC8, 0xE04A,0x8DCF, 0xE04B,0x8EFB,\r\n 0xE04C,0x8FE6, 0xE04D,0x99D5, 0xE04E,0x523B, 0xE04F,0x5374, 0xE050,0x5404, 0xE051,0x606A, 0xE052,0x6164, 0xE053,0x6BBC,\r\n 0xE054,0x73CF, 0xE055,0x811A, 0xE056,0x89BA, 0xE057,0x89D2, 0xE058,0x95A3, 0xE059,0x4F83, 0xE05A,0x520A, 0xE05B,0x58BE,\r\n 0xE05C,0x5978, 0xE05D,0x59E6, 0xE05E,0x5E72, 0xE05F,0x5E79, 0xE060,0x61C7, 0xE061,0x63C0, 0xE062,0x6746, 0xE063,0x67EC,\r\n 0xE064,0x687F, 0xE065,0x6F97, 0xE066,0x764E, 0xE067,0x770B, 0xE068,0x78F5, 0xE069,0x7A08, 0xE06A,0x7AFF, 0xE06B,0x7C21,\r\n 0xE06C,0x809D, 0xE06D,0x826E, 0xE06E,0x8271, 0xE06F,0x8AEB, 0xE070,0x9593, 0xE071,0x4E6B, 0xE072,0x559D, 0xE073,0x66F7,\r\n 0xE074,0x6E34, 0xE075,0x78A3, 0xE076,0x7AED, 0xE077,0x845B, 0xE078,0x8910, 0xE079,0x874E, 0xE07A,0x97A8, 0xE07B,0x52D8,\r\n 0xE07C,0x574E, 0xE07D,0x582A, 0xE07E,0x5D4C, 0xE091,0x611F, 0xE092,0x61BE, 0xE093,0x6221, 0xE094,0x6562, 0xE095,0x67D1,\r\n 0xE096,0x6A44, 0xE097,0x6E1B, 0xE098,0x7518, 0xE099,0x75B3, 0xE09A,0x76E3, 0xE09B,0x77B0, 0xE09C,0x7D3A, 0xE09D,0x90AF,\r\n 0xE09E,0x9451, 0xE09F,0x9452, 0xE0A0,0x9F95, 0xE0A1,0x5323, 0xE0A2,0x5CAC, 0xE0A3,0x7532, 0xE0A4,0x80DB, 0xE0A5,0x9240,\r\n 0xE0A6,0x9598, 0xE0A7,0x525B, 0xE0A8,0x5808, 0xE0A9,0x59DC, 0xE0AA,0x5CA1, 0xE0AB,0x5D17, 0xE0AC,0x5EB7, 0xE0AD,0x5F3A,\r\n 0xE0AE,0x5F4A, 0xE0AF,0x6177, 0xE0B0,0x6C5F, 0xE0B1,0x757A, 0xE0B2,0x7586, 0xE0B3,0x7CE0, 0xE0B4,0x7D73, 0xE0B5,0x7DB1,\r\n 0xE0B6,0x7F8C, 0xE0B7,0x8154, 0xE0B8,0x8221, 0xE0B9,0x8591, 0xE0BA,0x8941, 0xE0BB,0x8B1B, 0xE0BC,0x92FC, 0xE0BD,0x964D,\r\n 0xE0BE,0x9C47, 0xE0BF,0x4ECB, 0xE0C0,0x4EF7, 0xE0C1,0x500B, 0xE0C2,0x51F1, 0xE0C3,0x584F, 0xE0C4,0x6137, 0xE0C5,0x613E,\r\n 0xE0C6,0x6168, 0xE0C7,0x6539, 0xE0C8,0x69EA, 0xE0C9,0x6F11, 0xE0CA,0x75A5, 0xE0CB,0x7686, 0xE0CC,0x76D6, 0xE0CD,0x7B87,\r\n 0xE0CE,0x82A5, 0xE0CF,0x84CB, 0xE0D0,0xF900, 0xE0D1,0x93A7, 0xE0D2,0x958B, 0xE0D3,0x5580, 0xE0D4,0x5BA2, 0xE0D5,0x5751,\r\n 0xE0D6,0xF901, 0xE0D7,0x7CB3, 0xE0D8,0x7FB9, 0xE0D9,0x91B5, 0xE0DA,0x5028, 0xE0DB,0x53BB, 0xE0DC,0x5C45, 0xE0DD,0x5DE8,\r\n 0xE0DE,0x62D2, 0xE0DF,0x636E, 0xE0E0,0x64DA, 0xE0E1,0x64E7, 0xE0E2,0x6E20, 0xE0E3,0x70AC, 0xE0E4,0x795B, 0xE0E5,0x8DDD,\r\n 0xE0E6,0x8E1E, 0xE0E7,0xF902, 0xE0E8,0x907D, 0xE0E9,0x9245, 0xE0EA,0x92F8, 0xE0EB,0x4E7E, 0xE0EC,0x4EF6, 0xE0ED,0x5065,\r\n 0xE0EE,0x5DFE, 0xE0EF,0x5EFA, 0xE0F0,0x6106, 0xE0F1,0x6957, 0xE0F2,0x8171, 0xE0F3,0x8654, 0xE0F4,0x8E47, 0xE0F5,0x9375,\r\n 0xE0F6,0x9A2B, 0xE0F7,0x4E5E, 0xE0F8,0x5091, 0xE0F9,0x6770, 0xE0FA,0x6840, 0xE0FB,0x5109, 0xE0FC,0x528D, 0xE0FD,0x5292,\r\n 0xE0FE,0x6AA2, 0xE131,0x77BC, 0xE132,0x9210, 0xE133,0x9ED4, 0xE134,0x52AB, 0xE135,0x602F, 0xE136,0x8FF2, 0xE137,0x5048,\r\n 0xE138,0x61A9, 0xE139,0x63ED, 0xE13A,0x64CA, 0xE13B,0x683C, 0xE13C,0x6A84, 0xE13D,0x6FC0, 0xE13E,0x8188, 0xE13F,0x89A1,\r\n 0xE140,0x9694, 0xE141,0x5805, 0xE142,0x727D, 0xE143,0x72AC, 0xE144,0x7504, 0xE145,0x7D79, 0xE146,0x7E6D, 0xE147,0x80A9,\r\n 0xE148,0x898B, 0xE149,0x8B74, 0xE14A,0x9063, 0xE14B,0x9D51, 0xE14C,0x6289, 0xE14D,0x6C7A, 0xE14E,0x6F54, 0xE14F,0x7D50,\r\n 0xE150,0x7F3A, 0xE151,0x8A23, 0xE152,0x517C, 0xE153,0x614A, 0xE154,0x7B9D, 0xE155,0x8B19, 0xE156,0x9257, 0xE157,0x938C,\r\n 0xE158,0x4EAC, 0xE159,0x4FD3, 0xE15A,0x501E, 0xE15B,0x50BE, 0xE15C,0x5106, 0xE15D,0x52C1, 0xE15E,0x52CD, 0xE15F,0x537F,\r\n 0xE160,0x5770, 0xE161,0x5883, 0xE162,0x5E9A, 0xE163,0x5F91, 0xE164,0x6176, 0xE165,0x61AC, 0xE166,0x64CE, 0xE167,0x656C,\r\n 0xE168,0x666F, 0xE169,0x66BB, 0xE16A,0x66F4, 0xE16B,0x6897, 0xE16C,0x6D87, 0xE16D,0x7085, 0xE16E,0x70F1, 0xE16F,0x749F,\r\n 0xE170,0x74A5, 0xE171,0x74CA, 0xE172,0x75D9, 0xE173,0x786C, 0xE174,0x78EC, 0xE175,0x7ADF, 0xE176,0x7AF6, 0xE177,0x7D45,\r\n 0xE178,0x7D93, 0xE179,0x8015, 0xE17A,0x803F, 0xE17B,0x811B, 0xE17C,0x8396, 0xE17D,0x8B66, 0xE17E,0x8F15, 0xE191,0x9015,\r\n 0xE192,0x93E1, 0xE193,0x9803, 0xE194,0x9838, 0xE195,0x9A5A, 0xE196,0x9BE8, 0xE197,0x4FC2, 0xE198,0x5553, 0xE199,0x583A,\r\n 0xE19A,0x5951, 0xE19B,0x5B63, 0xE19C,0x5C46, 0xE19D,0x60B8, 0xE19E,0x6212, 0xE19F,0x6842, 0xE1A0,0x68B0, 0xE1A1,0x68E8,\r\n 0xE1A2,0x6EAA, 0xE1A3,0x754C, 0xE1A4,0x7678, 0xE1A5,0x78CE, 0xE1A6,0x7A3D, 0xE1A7,0x7CFB, 0xE1A8,0x7E6B, 0xE1A9,0x7E7C,\r\n 0xE1AA,0x8A08, 0xE1AB,0x8AA1, 0xE1AC,0x8C3F, 0xE1AD,0x968E, 0xE1AE,0x9DC4, 0xE1AF,0x53E4, 0xE1B0,0x53E9, 0xE1B1,0x544A,\r\n 0xE1B2,0x5471, 0xE1B3,0x56FA, 0xE1B4,0x59D1, 0xE1B5,0x5B64, 0xE1B6,0x5C3B, 0xE1B7,0x5EAB, 0xE1B8,0x62F7, 0xE1B9,0x6537,\r\n 0xE1BA,0x6545, 0xE1BB,0x6572, 0xE1BC,0x66A0, 0xE1BD,0x67AF, 0xE1BE,0x69C1, 0xE1BF,0x6CBD, 0xE1C0,0x75FC, 0xE1C1,0x7690,\r\n 0xE1C2,0x777E, 0xE1C3,0x7A3F, 0xE1C4,0x7F94, 0xE1C5,0x8003, 0xE1C6,0x80A1, 0xE1C7,0x818F, 0xE1C8,0x82E6, 0xE1C9,0x82FD,\r\n 0xE1CA,0x83F0, 0xE1CB,0x85C1, 0xE1CC,0x8831, 0xE1CD,0x88B4, 0xE1CE,0x8AA5, 0xE1CF,0xF903, 0xE1D0,0x8F9C, 0xE1D1,0x932E,\r\n 0xE1D2,0x96C7, 0xE1D3,0x9867, 0xE1D4,0x9AD8, 0xE1D5,0x9F13, 0xE1D6,0x54ED, 0xE1D7,0x659B, 0xE1D8,0x66F2, 0xE1D9,0x688F,\r\n 0xE1DA,0x7A40, 0xE1DB,0x8C37, 0xE1DC,0x9D60, 0xE1DD,0x56F0, 0xE1DE,0x5764, 0xE1DF,0x5D11, 0xE1E0,0x6606, 0xE1E1,0x68B1,\r\n 0xE1E2,0x68CD, 0xE1E3,0x6EFE, 0xE1E4,0x7428, 0xE1E5,0x889E, 0xE1E6,0x9BE4, 0xE1E7,0x6C68, 0xE1E8,0xF904, 0xE1E9,0x9AA8,\r\n 0xE1EA,0x4F9B, 0xE1EB,0x516C, 0xE1EC,0x5171, 0xE1ED,0x529F, 0xE1EE,0x5B54, 0xE1EF,0x5DE5, 0xE1F0,0x6050, 0xE1F1,0x606D,\r\n 0xE1F2,0x62F1, 0xE1F3,0x63A7, 0xE1F4,0x653B, 0xE1F5,0x73D9, 0xE1F6,0x7A7A, 0xE1F7,0x86A3, 0xE1F8,0x8CA2, 0xE1F9,0x978F,\r\n 0xE1FA,0x4E32, 0xE1FB,0x5BE1, 0xE1FC,0x6208, 0xE1FD,0x679C, 0xE1FE,0x74DC, 0xE231,0x79D1, 0xE232,0x83D3, 0xE233,0x8A87,\r\n 0xE234,0x8AB2, 0xE235,0x8DE8, 0xE236,0x904E, 0xE237,0x934B, 0xE238,0x9846, 0xE239,0x5ED3, 0xE23A,0x69E8, 0xE23B,0x85FF,\r\n 0xE23C,0x90ED, 0xE23D,0xF905, 0xE23E,0x51A0, 0xE23F,0x5B98, 0xE240,0x5BEC, 0xE241,0x6163, 0xE242,0x68FA, 0xE243,0x6B3E,\r\n 0xE244,0x704C, 0xE245,0x742F, 0xE246,0x74D8, 0xE247,0x7BA1, 0xE248,0x7F50, 0xE249,0x83C5, 0xE24A,0x89C0, 0xE24B,0x8CAB,\r\n 0xE24C,0x95DC, 0xE24D,0x9928, 0xE24E,0x522E, 0xE24F,0x605D, 0xE250,0x62EC, 0xE251,0x9002, 0xE252,0x4F8A, 0xE253,0x5149,\r\n 0xE254,0x5321, 0xE255,0x58D9, 0xE256,0x5EE3, 0xE257,0x66E0, 0xE258,0x6D38, 0xE259,0x709A, 0xE25A,0x72C2, 0xE25B,0x73D6,\r\n 0xE25C,0x7B50, 0xE25D,0x80F1, 0xE25E,0x945B, 0xE25F,0x5366, 0xE260,0x639B, 0xE261,0x7F6B, 0xE262,0x4E56, 0xE263,0x5080,\r\n 0xE264,0x584A, 0xE265,0x58DE, 0xE266,0x602A, 0xE267,0x6127, 0xE268,0x62D0, 0xE269,0x69D0, 0xE26A,0x9B41, 0xE26B,0x5B8F,\r\n 0xE26C,0x7D18, 0xE26D,0x80B1, 0xE26E,0x8F5F, 0xE26F,0x4EA4, 0xE270,0x50D1, 0xE271,0x54AC, 0xE272,0x55AC, 0xE273,0x5B0C,\r\n 0xE274,0x5DA0, 0xE275,0x5DE7, 0xE276,0x652A, 0xE277,0x654E, 0xE278,0x6821, 0xE279,0x6A4B, 0xE27A,0x72E1, 0xE27B,0x768E,\r\n 0xE27C,0x77EF, 0xE27D,0x7D5E, 0xE27E,0x7FF9, 0xE291,0x81A0, 0xE292,0x854E, 0xE293,0x86DF, 0xE294,0x8F03, 0xE295,0x8F4E,\r\n 0xE296,0x90CA, 0xE297,0x9903, 0xE298,0x9A55, 0xE299,0x9BAB, 0xE29A,0x4E18, 0xE29B,0x4E45, 0xE29C,0x4E5D, 0xE29D,0x4EC7,\r\n 0xE29E,0x4FF1, 0xE29F,0x5177, 0xE2A0,0x52FE, 0xE2A1,0x5340, 0xE2A2,0x53E3, 0xE2A3,0x53E5, 0xE2A4,0x548E, 0xE2A5,0x5614,\r\n 0xE2A6,0x5775, 0xE2A7,0x57A2, 0xE2A8,0x5BC7, 0xE2A9,0x5D87, 0xE2AA,0x5ED0, 0xE2AB,0x61FC, 0xE2AC,0x62D8, 0xE2AD,0x6551,\r\n 0xE2AE,0x67B8, 0xE2AF,0x67E9, 0xE2B0,0x69CB, 0xE2B1,0x6B50, 0xE2B2,0x6BC6, 0xE2B3,0x6BEC, 0xE2B4,0x6C42, 0xE2B5,0x6E9D,\r\n 0xE2B6,0x7078, 0xE2B7,0x72D7, 0xE2B8,0x7396, 0xE2B9,0x7403, 0xE2BA,0x77BF, 0xE2BB,0x77E9, 0xE2BC,0x7A76, 0xE2BD,0x7D7F,\r\n 0xE2BE,0x8009, 0xE2BF,0x81FC, 0xE2C0,0x8205, 0xE2C1,0x820A, 0xE2C2,0x82DF, 0xE2C3,0x8862, 0xE2C4,0x8B33, 0xE2C5,0x8CFC,\r\n 0xE2C6,0x8EC0, 0xE2C7,0x9011, 0xE2C8,0x90B1, 0xE2C9,0x9264, 0xE2CA,0x92B6, 0xE2CB,0x99D2, 0xE2CC,0x9A45, 0xE2CD,0x9CE9,\r\n 0xE2CE,0x9DD7, 0xE2CF,0x9F9C, 0xE2D0,0x570B, 0xE2D1,0x5C40, 0xE2D2,0x83CA, 0xE2D3,0x97A0, 0xE2D4,0x97AB, 0xE2D5,0x9EB4,\r\n 0xE2D6,0x541B, 0xE2D7,0x7A98, 0xE2D8,0x7FA4, 0xE2D9,0x88D9, 0xE2DA,0x8ECD, 0xE2DB,0x90E1, 0xE2DC,0x5800, 0xE2DD,0x5C48,\r\n 0xE2DE,0x6398, 0xE2DF,0x7A9F, 0xE2E0,0x5BAE, 0xE2E1,0x5F13, 0xE2E2,0x7A79, 0xE2E3,0x7AAE, 0xE2E4,0x828E, 0xE2E5,0x8EAC,\r\n 0xE2E6,0x5026, 0xE2E7,0x5238, 0xE2E8,0x52F8, 0xE2E9,0x5377, 0xE2EA,0x5708, 0xE2EB,0x62F3, 0xE2EC,0x6372, 0xE2ED,0x6B0A,\r\n 0xE2EE,0x6DC3, 0xE2EF,0x7737, 0xE2F0,0x53A5, 0xE2F1,0x7357, 0xE2F2,0x8568, 0xE2F3,0x8E76, 0xE2F4,0x95D5, 0xE2F5,0x673A,\r\n 0xE2F6,0x6AC3, 0xE2F7,0x6F70, 0xE2F8,0x8A6D, 0xE2F9,0x8ECC, 0xE2FA,0x994B, 0xE2FB,0xF906, 0xE2FC,0x6677, 0xE2FD,0x6B78,\r\n 0xE2FE,0x8CB4, 0xE331,0x9B3C, 0xE332,0xF907, 0xE333,0x53EB, 0xE334,0x572D, 0xE335,0x594E, 0xE336,0x63C6, 0xE337,0x69FB,\r\n 0xE338,0x73EA, 0xE339,0x7845, 0xE33A,0x7ABA, 0xE33B,0x7AC5, 0xE33C,0x7CFE, 0xE33D,0x8475, 0xE33E,0x898F, 0xE33F,0x8D73,\r\n 0xE340,0x9035, 0xE341,0x95A8, 0xE342,0x52FB, 0xE343,0x5747, 0xE344,0x7547, 0xE345,0x7B60, 0xE346,0x83CC, 0xE347,0x921E,\r\n 0xE348,0xF908, 0xE349,0x6A58, 0xE34A,0x514B, 0xE34B,0x524B, 0xE34C,0x5287, 0xE34D,0x621F, 0xE34E,0x68D8, 0xE34F,0x6975,\r\n 0xE350,0x9699, 0xE351,0x50C5, 0xE352,0x52A4, 0xE353,0x52E4, 0xE354,0x61C3, 0xE355,0x65A4, 0xE356,0x6839, 0xE357,0x69FF,\r\n 0xE358,0x747E, 0xE359,0x7B4B, 0xE35A,0x82B9, 0xE35B,0x83EB, 0xE35C,0x89B2, 0xE35D,0x8B39, 0xE35E,0x8FD1, 0xE35F,0x9949,\r\n 0xE360,0xF909, 0xE361,0x4ECA, 0xE362,0x5997, 0xE363,0x64D2, 0xE364,0x6611, 0xE365,0x6A8E, 0xE366,0x7434, 0xE367,0x7981,\r\n 0xE368,0x79BD, 0xE369,0x82A9, 0xE36A,0x887E, 0xE36B,0x887F, 0xE36C,0x895F, 0xE36D,0xF90A, 0xE36E,0x9326, 0xE36F,0x4F0B,\r\n 0xE370,0x53CA, 0xE371,0x6025, 0xE372,0x6271, 0xE373,0x6C72, 0xE374,0x7D1A, 0xE375,0x7D66, 0xE376,0x4E98, 0xE377,0x5162,\r\n 0xE378,0x77DC, 0xE379,0x80AF, 0xE37A,0x4F01, 0xE37B,0x4F0E, 0xE37C,0x5176, 0xE37D,0x5180, 0xE37E,0x55DC, 0xE391,0x5668,\r\n 0xE392,0x573B, 0xE393,0x57FA, 0xE394,0x57FC, 0xE395,0x5914, 0xE396,0x5947, 0xE397,0x5993, 0xE398,0x5BC4, 0xE399,0x5C90,\r\n 0xE39A,0x5D0E, 0xE39B,0x5DF1, 0xE39C,0x5E7E, 0xE39D,0x5FCC, 0xE39E,0x6280, 0xE39F,0x65D7, 0xE3A0,0x65E3, 0xE3A1,0x671E,\r\n 0xE3A2,0x671F, 0xE3A3,0x675E, 0xE3A4,0x68CB, 0xE3A5,0x68C4, 0xE3A6,0x6A5F, 0xE3A7,0x6B3A, 0xE3A8,0x6C23, 0xE3A9,0x6C7D,\r\n 0xE3AA,0x6C82, 0xE3AB,0x6DC7, 0xE3AC,0x7398, 0xE3AD,0x7426, 0xE3AE,0x742A, 0xE3AF,0x7482, 0xE3B0,0x74A3, 0xE3B1,0x7578,\r\n 0xE3B2,0x757F, 0xE3B3,0x7881, 0xE3B4,0x78EF, 0xE3B5,0x7941, 0xE3B6,0x7947, 0xE3B7,0x7948, 0xE3B8,0x797A, 0xE3B9,0x7B95,\r\n 0xE3BA,0x7D00, 0xE3BB,0x7DBA, 0xE3BC,0x7F88, 0xE3BD,0x8006, 0xE3BE,0x802D, 0xE3BF,0x808C, 0xE3C0,0x8A18, 0xE3C1,0x8B4F,\r\n 0xE3C2,0x8C48, 0xE3C3,0x8D77, 0xE3C4,0x9321, 0xE3C5,0x9324, 0xE3C6,0x98E2, 0xE3C7,0x9951, 0xE3C8,0x9A0E, 0xE3C9,0x9A0F,\r\n 0xE3CA,0x9A65, 0xE3CB,0x9E92, 0xE3CC,0x7DCA, 0xE3CD,0x4F76, 0xE3CE,0x5409, 0xE3CF,0x62EE, 0xE3D0,0x6854, 0xE3D1,0x91D1,\r\n 0xE3D2,0x55AB, 0xE3D3,0x513A, 0xE3D4,0xF90B, 0xE3D5,0xF90C, 0xE3D6,0x5A1C, 0xE3D7,0x61E6, 0xE3D8,0xF90D, 0xE3D9,0x62CF,\r\n 0xE3DA,0x62FF, 0xE3DB,0xF90E, 0xE3DC,0xF90F, 0xE3DD,0xF910, 0xE3DE,0xF911, 0xE3DF,0xF912, 0xE3E0,0xF913, 0xE3E1,0x90A3,\r\n 0xE3E2,0xF914, 0xE3E3,0xF915, 0xE3E4,0xF916, 0xE3E5,0xF917, 0xE3E6,0xF918, 0xE3E7,0x8AFE, 0xE3E8,0xF919, 0xE3E9,0xF91A,\r\n 0xE3EA,0xF91B, 0xE3EB,0xF91C, 0xE3EC,0x6696, 0xE3ED,0xF91D, 0xE3EE,0x7156, 0xE3EF,0xF91E, 0xE3F0,0xF91F, 0xE3F1,0x96E3,\r\n 0xE3F2,0xF920, 0xE3F3,0x634F, 0xE3F4,0x637A, 0xE3F5,0x5357, 0xE3F6,0xF921, 0xE3F7,0x678F, 0xE3F8,0x6960, 0xE3F9,0x6E73,\r\n 0xE3FA,0xF922, 0xE3FB,0x7537, 0xE3FC,0xF923, 0xE3FD,0xF924, 0xE3FE,0xF925, 0xE431,0x7D0D, 0xE432,0xF926, 0xE433,0xF927,\r\n 0xE434,0x8872, 0xE435,0x56CA, 0xE436,0x5A18, 0xE437,0xF928, 0xE438,0xF929, 0xE439,0xF92A, 0xE43A,0xF92B, 0xE43B,0xF92C,\r\n 0xE43C,0x4E43, 0xE43D,0xF92D, 0xE43E,0x5167, 0xE43F,0x5948, 0xE440,0x67F0, 0xE441,0x8010, 0xE442,0xF92E, 0xE443,0x5973,\r\n 0xE444,0x5E74, 0xE445,0x649A, 0xE446,0x79CA, 0xE447,0x5FF5, 0xE448,0x606C, 0xE449,0x62C8, 0xE44A,0x637B, 0xE44B,0x5BE7,\r\n 0xE44C,0x5BD7, 0xE44D,0x52AA, 0xE44E,0xF92F, 0xE44F,0x5974, 0xE450,0x5F29, 0xE451,0x6012, 0xE452,0xF930, 0xE453,0xF931,\r\n 0xE454,0xF932, 0xE455,0x7459, 0xE456,0xF933, 0xE457,0xF934, 0xE458,0xF935, 0xE459,0xF936, 0xE45A,0xF937, 0xE45B,0xF938,\r\n 0xE45C,0x99D1, 0xE45D,0xF939, 0xE45E,0xF93A, 0xE45F,0xF93B, 0xE460,0xF93C, 0xE461,0xF93D, 0xE462,0xF93E, 0xE463,0xF93F,\r\n 0xE464,0xF940, 0xE465,0xF941, 0xE466,0xF942, 0xE467,0xF943, 0xE468,0x6FC3, 0xE469,0xF944, 0xE46A,0xF945, 0xE46B,0x81BF,\r\n 0xE46C,0x8FB2, 0xE46D,0x60F1, 0xE46E,0xF946, 0xE46F,0xF947, 0xE470,0x8166, 0xE471,0xF948, 0xE472,0xF949, 0xE473,0x5C3F,\r\n 0xE474,0xF94A, 0xE475,0xF94B, 0xE476,0xF94C, 0xE477,0xF94D, 0xE478,0xF94E, 0xE479,0xF94F, 0xE47A,0xF950, 0xE47B,0xF951,\r\n 0xE47C,0x5AE9, 0xE47D,0x8A25, 0xE47E,0x677B, 0xE491,0x7D10, 0xE492,0xF952, 0xE493,0xF953, 0xE494,0xF954, 0xE495,0xF955,\r\n 0xE496,0xF956, 0xE497,0xF957, 0xE498,0x80FD, 0xE499,0xF958, 0xE49A,0xF959, 0xE49B,0x5C3C, 0xE49C,0x6CE5, 0xE49D,0x533F,\r\n 0xE49E,0x6EBA, 0xE49F,0x591A, 0xE4A0,0x8336, 0xE4A1,0x4E39, 0xE4A2,0x4EB6, 0xE4A3,0x4F46, 0xE4A4,0x55AE, 0xE4A5,0x5718,\r\n 0xE4A6,0x58C7, 0xE4A7,0x5F56, 0xE4A8,0x65B7, 0xE4A9,0x65E6, 0xE4AA,0x6A80, 0xE4AB,0x6BB5, 0xE4AC,0x6E4D, 0xE4AD,0x77ED,\r\n 0xE4AE,0x7AEF, 0xE4AF,0x7C1E, 0xE4B0,0x7DDE, 0xE4B1,0x86CB, 0xE4B2,0x8892, 0xE4B3,0x9132, 0xE4B4,0x935B, 0xE4B5,0x64BB,\r\n 0xE4B6,0x6FBE, 0xE4B7,0x737A, 0xE4B8,0x75B8, 0xE4B9,0x9054, 0xE4BA,0x5556, 0xE4BB,0x574D, 0xE4BC,0x61BA, 0xE4BD,0x64D4,\r\n 0xE4BE,0x66C7, 0xE4BF,0x6DE1, 0xE4C0,0x6E5B, 0xE4C1,0x6F6D, 0xE4C2,0x6FB9, 0xE4C3,0x75F0, 0xE4C4,0x8043, 0xE4C5,0x81BD,\r\n 0xE4C6,0x8541, 0xE4C7,0x8983, 0xE4C8,0x8AC7, 0xE4C9,0x8B5A, 0xE4CA,0x931F, 0xE4CB,0x6C93, 0xE4CC,0x7553, 0xE4CD,0x7B54,\r\n 0xE4CE,0x8E0F, 0xE4CF,0x905D, 0xE4D0,0x5510, 0xE4D1,0x5802, 0xE4D2,0x5858, 0xE4D3,0x5E62, 0xE4D4,0x6207, 0xE4D5,0x649E,\r\n 0xE4D6,0x68E0, 0xE4D7,0x7576, 0xE4D8,0x7CD6, 0xE4D9,0x87B3, 0xE4DA,0x9EE8, 0xE4DB,0x4EE3, 0xE4DC,0x5788, 0xE4DD,0x576E,\r\n 0xE4DE,0x5927, 0xE4DF,0x5C0D, 0xE4E0,0x5CB1, 0xE4E1,0x5E36, 0xE4E2,0x5F85, 0xE4E3,0x6234, 0xE4E4,0x64E1, 0xE4E5,0x73B3,\r\n 0xE4E6,0x81FA, 0xE4E7,0x888B, 0xE4E8,0x8CB8, 0xE4E9,0x968A, 0xE4EA,0x9EDB, 0xE4EB,0x5B85, 0xE4EC,0x5FB7, 0xE4ED,0x60B3,\r\n 0xE4EE,0x5012, 0xE4EF,0x5200, 0xE4F0,0x5230, 0xE4F1,0x5716, 0xE4F2,0x5835, 0xE4F3,0x5857, 0xE4F4,0x5C0E, 0xE4F5,0x5C60,\r\n 0xE4F6,0x5CF6, 0xE4F7,0x5D8B, 0xE4F8,0x5EA6, 0xE4F9,0x5F92, 0xE4FA,0x60BC, 0xE4FB,0x6311, 0xE4FC,0x6389, 0xE4FD,0x6417,\r\n 0xE4FE,0x6843, 0xE531,0x68F9, 0xE532,0x6AC2, 0xE533,0x6DD8, 0xE534,0x6E21, 0xE535,0x6ED4, 0xE536,0x6FE4, 0xE537,0x71FE,\r\n 0xE538,0x76DC, 0xE539,0x7779, 0xE53A,0x79B1, 0xE53B,0x7A3B, 0xE53C,0x8404, 0xE53D,0x89A9, 0xE53E,0x8CED, 0xE53F,0x8DF3,\r\n 0xE540,0x8E48, 0xE541,0x9003, 0xE542,0x9014, 0xE543,0x9053, 0xE544,0x90FD, 0xE545,0x934D, 0xE546,0x9676, 0xE547,0x97DC,\r\n 0xE548,0x6BD2, 0xE549,0x7006, 0xE54A,0x7258, 0xE54B,0x72A2, 0xE54C,0x7368, 0xE54D,0x7763, 0xE54E,0x79BF, 0xE54F,0x7BE4,\r\n 0xE550,0x7E9B, 0xE551,0x8B80, 0xE552,0x58A9, 0xE553,0x60C7, 0xE554,0x6566, 0xE555,0x65FD, 0xE556,0x66BE, 0xE557,0x6C8C,\r\n 0xE558,0x711E, 0xE559,0x71C9, 0xE55A,0x8C5A, 0xE55B,0x9813, 0xE55C,0x4E6D, 0xE55D,0x7A81, 0xE55E,0x4EDD, 0xE55F,0x51AC,\r\n 0xE560,0x51CD, 0xE561,0x52D5, 0xE562,0x540C, 0xE563,0x61A7, 0xE564,0x6771, 0xE565,0x6850, 0xE566,0x68DF, 0xE567,0x6D1E,\r\n 0xE568,0x6F7C, 0xE569,0x75BC, 0xE56A,0x77B3, 0xE56B,0x7AE5, 0xE56C,0x80F4, 0xE56D,0x8463, 0xE56E,0x9285, 0xE56F,0x515C,\r\n 0xE570,0x6597, 0xE571,0x675C, 0xE572,0x6793, 0xE573,0x75D8, 0xE574,0x7AC7, 0xE575,0x8373, 0xE576,0xF95A, 0xE577,0x8C46,\r\n 0xE578,0x9017, 0xE579,0x982D, 0xE57A,0x5C6F, 0xE57B,0x81C0, 0xE57C,0x829A, 0xE57D,0x9041, 0xE57E,0x906F, 0xE591,0x920D,\r\n 0xE592,0x5F97, 0xE593,0x5D9D, 0xE594,0x6A59, 0xE595,0x71C8, 0xE596,0x767B, 0xE597,0x7B49, 0xE598,0x85E4, 0xE599,0x8B04,\r\n 0xE59A,0x9127, 0xE59B,0x9A30, 0xE59C,0x5587, 0xE59D,0x61F6, 0xE59E,0xF95B, 0xE59F,0x7669, 0xE5A0,0x7F85, 0xE5A1,0x863F,\r\n 0xE5A2,0x87BA, 0xE5A3,0x88F8, 0xE5A4,0x908F, 0xE5A5,0xF95C, 0xE5A6,0x6D1B, 0xE5A7,0x70D9, 0xE5A8,0x73DE, 0xE5A9,0x7D61,\r\n 0xE5AA,0x843D, 0xE5AB,0xF95D, 0xE5AC,0x916A, 0xE5AD,0x99F1, 0xE5AE,0xF95E, 0xE5AF,0x4E82, 0xE5B0,0x5375, 0xE5B1,0x6B04,\r\n 0xE5B2,0x6B12, 0xE5B3,0x703E, 0xE5B4,0x721B, 0xE5B5,0x862D, 0xE5B6,0x9E1E, 0xE5B7,0x524C, 0xE5B8,0x8FA3, 0xE5B9,0x5D50,\r\n 0xE5BA,0x64E5, 0xE5BB,0x652C, 0xE5BC,0x6B16, 0xE5BD,0x6FEB, 0xE5BE,0x7C43, 0xE5BF,0x7E9C, 0xE5C0,0x85CD, 0xE5C1,0x8964,\r\n 0xE5C2,0x89BD, 0xE5C3,0x62C9, 0xE5C4,0x81D8, 0xE5C5,0x881F, 0xE5C6,0x5ECA, 0xE5C7,0x6717, 0xE5C8,0x6D6A, 0xE5C9,0x72FC,\r\n 0xE5CA,0x7405, 0xE5CB,0x746F, 0xE5CC,0x8782, 0xE5CD,0x90DE, 0xE5CE,0x4F86, 0xE5CF,0x5D0D, 0xE5D0,0x5FA0, 0xE5D1,0x840A,\r\n 0xE5D2,0x51B7, 0xE5D3,0x63A0, 0xE5D4,0x7565, 0xE5D5,0x4EAE, 0xE5D6,0x5006, 0xE5D7,0x5169, 0xE5D8,0x51C9, 0xE5D9,0x6881,\r\n 0xE5DA,0x6A11, 0xE5DB,0x7CAE, 0xE5DC,0x7CB1, 0xE5DD,0x7CE7, 0xE5DE,0x826F, 0xE5DF,0x8AD2, 0xE5E0,0x8F1B, 0xE5E1,0x91CF,\r\n 0xE5E2,0x4FB6, 0xE5E3,0x5137, 0xE5E4,0x52F5, 0xE5E5,0x5442, 0xE5E6,0x5EEC, 0xE5E7,0x616E, 0xE5E8,0x623E, 0xE5E9,0x65C5,\r\n 0xE5EA,0x6ADA, 0xE5EB,0x6FFE, 0xE5EC,0x792A, 0xE5ED,0x85DC, 0xE5EE,0x8823, 0xE5EF,0x95AD, 0xE5F0,0x9A62, 0xE5F1,0x9A6A,\r\n 0xE5F2,0x9E97, 0xE5F3,0x9ECE, 0xE5F4,0x529B, 0xE5F5,0x66C6, 0xE5F6,0x6B77, 0xE5F7,0x701D, 0xE5F8,0x792B, 0xE5F9,0x8F62,\r\n 0xE5FA,0x9742, 0xE5FB,0x6190, 0xE5FC,0x6200, 0xE5FD,0x6523, 0xE5FE,0x6F23, 0xE631,0x7149, 0xE632,0x7489, 0xE633,0x7DF4,\r\n 0xE634,0x806F, 0xE635,0x84EE, 0xE636,0x8F26, 0xE637,0x9023, 0xE638,0x934A, 0xE639,0x51BD, 0xE63A,0x5217, 0xE63B,0x52A3,\r\n 0xE63C,0x6D0C, 0xE63D,0x70C8, 0xE63E,0x88C2, 0xE63F,0x5EC9, 0xE640,0x6582, 0xE641,0x6BAE, 0xE642,0x6FC2, 0xE643,0x7C3E,\r\n 0xE644,0x7375, 0xE645,0x4EE4, 0xE646,0x4F36, 0xE647,0x56F9, 0xE648,0xF95F, 0xE649,0x5CBA, 0xE64A,0x5DBA, 0xE64B,0x601C,\r\n 0xE64C,0x73B2, 0xE64D,0x7B2D, 0xE64E,0x7F9A, 0xE64F,0x7FCE, 0xE650,0x8046, 0xE651,0x901E, 0xE652,0x9234, 0xE653,0x96F6,\r\n 0xE654,0x9748, 0xE655,0x9818, 0xE656,0x9F61, 0xE657,0x4F8B, 0xE658,0x6FA7, 0xE659,0x79AE, 0xE65A,0x91B4, 0xE65B,0x96B7,\r\n 0xE65C,0x52DE, 0xE65D,0xF960, 0xE65E,0x6488, 0xE65F,0x64C4, 0xE660,0x6AD3, 0xE661,0x6F5E, 0xE662,0x7018, 0xE663,0x7210,\r\n 0xE664,0x76E7, 0xE665,0x8001, 0xE666,0x8606, 0xE667,0x865C, 0xE668,0x8DEF, 0xE669,0x8F05, 0xE66A,0x9732, 0xE66B,0x9B6F,\r\n 0xE66C,0x9DFA, 0xE66D,0x9E75, 0xE66E,0x788C, 0xE66F,0x797F, 0xE670,0x7DA0, 0xE671,0x83C9, 0xE672,0x9304, 0xE673,0x9E7F,\r\n 0xE674,0x9E93, 0xE675,0x8AD6, 0xE676,0x58DF, 0xE677,0x5F04, 0xE678,0x6727, 0xE679,0x7027, 0xE67A,0x74CF, 0xE67B,0x7C60,\r\n 0xE67C,0x807E, 0xE67D,0x5121, 0xE67E,0x7028, 0xE691,0x7262, 0xE692,0x78CA, 0xE693,0x8CC2, 0xE694,0x8CDA, 0xE695,0x8CF4,\r\n 0xE696,0x96F7, 0xE697,0x4E86, 0xE698,0x50DA, 0xE699,0x5BEE, 0xE69A,0x5ED6, 0xE69B,0x6599, 0xE69C,0x71CE, 0xE69D,0x7642,\r\n 0xE69E,0x77AD, 0xE69F,0x804A, 0xE6A0,0x84FC, 0xE6A1,0x907C, 0xE6A2,0x9B27, 0xE6A3,0x9F8D, 0xE6A4,0x58D8, 0xE6A5,0x5A41,\r\n 0xE6A6,0x5C62, 0xE6A7,0x6A13, 0xE6A8,0x6DDA, 0xE6A9,0x6F0F, 0xE6AA,0x763B, 0xE6AB,0x7D2F, 0xE6AC,0x7E37, 0xE6AD,0x851E,\r\n 0xE6AE,0x8938, 0xE6AF,0x93E4, 0xE6B0,0x964B, 0xE6B1,0x5289, 0xE6B2,0x65D2, 0xE6B3,0x67F3, 0xE6B4,0x69B4, 0xE6B5,0x6D41,\r\n 0xE6B6,0x6E9C, 0xE6B7,0x700F, 0xE6B8,0x7409, 0xE6B9,0x7460, 0xE6BA,0x7559, 0xE6BB,0x7624, 0xE6BC,0x786B, 0xE6BD,0x8B2C,\r\n 0xE6BE,0x985E, 0xE6BF,0x516D, 0xE6C0,0x622E, 0xE6C1,0x9678, 0xE6C2,0x4F96, 0xE6C3,0x502B, 0xE6C4,0x5D19, 0xE6C5,0x6DEA,\r\n 0xE6C6,0x7DB8, 0xE6C7,0x8F2A, 0xE6C8,0x5F8B, 0xE6C9,0x6144, 0xE6CA,0x6817, 0xE6CB,0xF961, 0xE6CC,0x9686, 0xE6CD,0x52D2,\r\n 0xE6CE,0x808B, 0xE6CF,0x51DC, 0xE6D0,0x51CC, 0xE6D1,0x695E, 0xE6D2,0x7A1C, 0xE6D3,0x7DBE, 0xE6D4,0x83F1, 0xE6D5,0x9675,\r\n 0xE6D6,0x4FDA, 0xE6D7,0x5229, 0xE6D8,0x5398, 0xE6D9,0x540F, 0xE6DA,0x550E, 0xE6DB,0x5C65, 0xE6DC,0x60A7, 0xE6DD,0x674E,\r\n 0xE6DE,0x68A8, 0xE6DF,0x6D6C, 0xE6E0,0x7281, 0xE6E1,0x72F8, 0xE6E2,0x7406, 0xE6E3,0x7483, 0xE6E4,0xF962, 0xE6E5,0x75E2,\r\n 0xE6E6,0x7C6C, 0xE6E7,0x7F79, 0xE6E8,0x7FB8, 0xE6E9,0x8389, 0xE6EA,0x88CF, 0xE6EB,0x88E1, 0xE6EC,0x91CC, 0xE6ED,0x91D0,\r\n 0xE6EE,0x96E2, 0xE6EF,0x9BC9, 0xE6F0,0x541D, 0xE6F1,0x6F7E, 0xE6F2,0x71D0, 0xE6F3,0x7498, 0xE6F4,0x85FA, 0xE6F5,0x8EAA,\r\n 0xE6F6,0x96A3, 0xE6F7,0x9C57, 0xE6F8,0x9E9F, 0xE6F9,0x6797, 0xE6FA,0x6DCB, 0xE6FB,0x7433, 0xE6FC,0x81E8, 0xE6FD,0x9716,\r\n 0xE6FE,0x782C, 0xE731,0x7ACB, 0xE732,0x7B20, 0xE733,0x7C92, 0xE734,0x6469, 0xE735,0x746A, 0xE736,0x75F2, 0xE737,0x78BC,\r\n 0xE738,0x78E8, 0xE739,0x99AC, 0xE73A,0x9B54, 0xE73B,0x9EBB, 0xE73C,0x5BDE, 0xE73D,0x5E55, 0xE73E,0x6F20, 0xE73F,0x819C,\r\n 0xE740,0x83AB, 0xE741,0x9088, 0xE742,0x4E07, 0xE743,0x534D, 0xE744,0x5A29, 0xE745,0x5DD2, 0xE746,0x5F4E, 0xE747,0x6162,\r\n 0xE748,0x633D, 0xE749,0x6669, 0xE74A,0x66FC, 0xE74B,0x6EFF, 0xE74C,0x6F2B, 0xE74D,0x7063, 0xE74E,0x779E, 0xE74F,0x842C,\r\n 0xE750,0x8513, 0xE751,0x883B, 0xE752,0x8F13, 0xE753,0x9945, 0xE754,0x9C3B, 0xE755,0x551C, 0xE756,0x62B9, 0xE757,0x672B,\r\n 0xE758,0x6CAB, 0xE759,0x8309, 0xE75A,0x896A, 0xE75B,0x977A, 0xE75C,0x4EA1, 0xE75D,0x5984, 0xE75E,0x5FD8, 0xE75F,0x5FD9,\r\n 0xE760,0x671B, 0xE761,0x7DB2, 0xE762,0x7F54, 0xE763,0x8292, 0xE764,0x832B, 0xE765,0x83BD, 0xE766,0x8F1E, 0xE767,0x9099,\r\n 0xE768,0x57CB, 0xE769,0x59B9, 0xE76A,0x5A92, 0xE76B,0x5BD0, 0xE76C,0x6627, 0xE76D,0x679A, 0xE76E,0x6885, 0xE76F,0x6BCF,\r\n 0xE770,0x7164, 0xE771,0x7F75, 0xE772,0x8CB7, 0xE773,0x8CE3, 0xE774,0x9081, 0xE775,0x9B45, 0xE776,0x8108, 0xE777,0x8C8A,\r\n 0xE778,0x964C, 0xE779,0x9A40, 0xE77A,0x9EA5, 0xE77B,0x5B5F, 0xE77C,0x6C13, 0xE77D,0x731B, 0xE77E,0x76F2, 0xE791,0x76DF,\r\n 0xE792,0x840C, 0xE793,0x51AA, 0xE794,0x8993, 0xE795,0x514D, 0xE796,0x5195, 0xE797,0x52C9, 0xE798,0x68C9, 0xE799,0x6C94,\r\n 0xE79A,0x7704, 0xE79B,0x7720, 0xE79C,0x7DBF, 0xE79D,0x7DEC, 0xE79E,0x9762, 0xE79F,0x9EB5, 0xE7A0,0x6EC5, 0xE7A1,0x8511,\r\n 0xE7A2,0x51A5, 0xE7A3,0x540D, 0xE7A4,0x547D, 0xE7A5,0x660E, 0xE7A6,0x669D, 0xE7A7,0x6927, 0xE7A8,0x6E9F, 0xE7A9,0x76BF,\r\n 0xE7AA,0x7791, 0xE7AB,0x8317, 0xE7AC,0x84C2, 0xE7AD,0x879F, 0xE7AE,0x9169, 0xE7AF,0x9298, 0xE7B0,0x9CF4, 0xE7B1,0x8882,\r\n 0xE7B2,0x4FAE, 0xE7B3,0x5192, 0xE7B4,0x52DF, 0xE7B5,0x59C6, 0xE7B6,0x5E3D, 0xE7B7,0x6155, 0xE7B8,0x6478, 0xE7B9,0x6479,\r\n 0xE7BA,0x66AE, 0xE7BB,0x67D0, 0xE7BC,0x6A21, 0xE7BD,0x6BCD, 0xE7BE,0x6BDB, 0xE7BF,0x725F, 0xE7C0,0x7261, 0xE7C1,0x7441,\r\n 0xE7C2,0x7738, 0xE7C3,0x77DB, 0xE7C4,0x8017, 0xE7C5,0x82BC, 0xE7C6,0x8305, 0xE7C7,0x8B00, 0xE7C8,0x8B28, 0xE7C9,0x8C8C,\r\n 0xE7CA,0x6728, 0xE7CB,0x6C90, 0xE7CC,0x7267, 0xE7CD,0x76EE, 0xE7CE,0x7766, 0xE7CF,0x7A46, 0xE7D0,0x9DA9, 0xE7D1,0x6B7F,\r\n 0xE7D2,0x6C92, 0xE7D3,0x5922, 0xE7D4,0x6726, 0xE7D5,0x8499, 0xE7D6,0x536F, 0xE7D7,0x5893, 0xE7D8,0x5999, 0xE7D9,0x5EDF,\r\n 0xE7DA,0x63CF, 0xE7DB,0x6634, 0xE7DC,0x6773, 0xE7DD,0x6E3A, 0xE7DE,0x732B, 0xE7DF,0x7AD7, 0xE7E0,0x82D7, 0xE7E1,0x9328,\r\n 0xE7E2,0x52D9, 0xE7E3,0x5DEB, 0xE7E4,0x61AE, 0xE7E5,0x61CB, 0xE7E6,0x620A, 0xE7E7,0x62C7, 0xE7E8,0x64AB, 0xE7E9,0x65E0,\r\n 0xE7EA,0x6959, 0xE7EB,0x6B66, 0xE7EC,0x6BCB, 0xE7ED,0x7121, 0xE7EE,0x73F7, 0xE7EF,0x755D, 0xE7F0,0x7E46, 0xE7F1,0x821E,\r\n 0xE7F2,0x8302, 0xE7F3,0x856A, 0xE7F4,0x8AA3, 0xE7F5,0x8CBF, 0xE7F6,0x9727, 0xE7F7,0x9D61, 0xE7F8,0x58A8, 0xE7F9,0x9ED8,\r\n 0xE7FA,0x5011, 0xE7FB,0x520E, 0xE7FC,0x543B, 0xE7FD,0x554F, 0xE7FE,0x6587, 0xE831,0x6C76, 0xE832,0x7D0A, 0xE833,0x7D0B,\r\n 0xE834,0x805E, 0xE835,0x868A, 0xE836,0x9580, 0xE837,0x96EF, 0xE838,0x52FF, 0xE839,0x6C95, 0xE83A,0x7269, 0xE83B,0x5473,\r\n 0xE83C,0x5A9A, 0xE83D,0x5C3E, 0xE83E,0x5D4B, 0xE83F,0x5F4C, 0xE840,0x5FAE, 0xE841,0x672A, 0xE842,0x68B6, 0xE843,0x6963,\r\n 0xE844,0x6E3C, 0xE845,0x6E44, 0xE846,0x7709, 0xE847,0x7C73, 0xE848,0x7F8E, 0xE849,0x8587, 0xE84A,0x8B0E, 0xE84B,0x8FF7,\r\n 0xE84C,0x9761, 0xE84D,0x9EF4, 0xE84E,0x5CB7, 0xE84F,0x60B6, 0xE850,0x610D, 0xE851,0x61AB, 0xE852,0x654F, 0xE853,0x65FB,\r\n 0xE854,0x65FC, 0xE855,0x6C11, 0xE856,0x6CEF, 0xE857,0x739F, 0xE858,0x73C9, 0xE859,0x7DE1, 0xE85A,0x9594, 0xE85B,0x5BC6,\r\n 0xE85C,0x871C, 0xE85D,0x8B10, 0xE85E,0x525D, 0xE85F,0x535A, 0xE860,0x62CD, 0xE861,0x640F, 0xE862,0x64B2, 0xE863,0x6734,\r\n 0xE864,0x6A38, 0xE865,0x6CCA, 0xE866,0x73C0, 0xE867,0x749E, 0xE868,0x7B94, 0xE869,0x7C95, 0xE86A,0x7E1B, 0xE86B,0x818A,\r\n 0xE86C,0x8236, 0xE86D,0x8584, 0xE86E,0x8FEB, 0xE86F,0x96F9, 0xE870,0x99C1, 0xE871,0x4F34, 0xE872,0x534A, 0xE873,0x53CD,\r\n 0xE874,0x53DB, 0xE875,0x62CC, 0xE876,0x642C, 0xE877,0x6500, 0xE878,0x6591, 0xE879,0x69C3, 0xE87A,0x6CEE, 0xE87B,0x6F58,\r\n 0xE87C,0x73ED, 0xE87D,0x7554, 0xE87E,0x7622, 0xE891,0x76E4, 0xE892,0x76FC, 0xE893,0x78D0, 0xE894,0x78FB, 0xE895,0x792C,\r\n 0xE896,0x7D46, 0xE897,0x822C, 0xE898,0x87E0, 0xE899,0x8FD4, 0xE89A,0x9812, 0xE89B,0x98EF, 0xE89C,0x52C3, 0xE89D,0x62D4,\r\n 0xE89E,0x64A5, 0xE89F,0x6E24, 0xE8A0,0x6F51, 0xE8A1,0x767C, 0xE8A2,0x8DCB, 0xE8A3,0x91B1, 0xE8A4,0x9262, 0xE8A5,0x9AEE,\r\n 0xE8A6,0x9B43, 0xE8A7,0x5023, 0xE8A8,0x508D, 0xE8A9,0x574A, 0xE8AA,0x59A8, 0xE8AB,0x5C28, 0xE8AC,0x5E47, 0xE8AD,0x5F77,\r\n 0xE8AE,0x623F, 0xE8AF,0x653E, 0xE8B0,0x65B9, 0xE8B1,0x65C1, 0xE8B2,0x6609, 0xE8B3,0x678B, 0xE8B4,0x699C, 0xE8B5,0x6EC2,\r\n 0xE8B6,0x78C5, 0xE8B7,0x7D21, 0xE8B8,0x80AA, 0xE8B9,0x8180, 0xE8BA,0x822B, 0xE8BB,0x82B3, 0xE8BC,0x84A1, 0xE8BD,0x868C,\r\n 0xE8BE,0x8A2A, 0xE8BF,0x8B17, 0xE8C0,0x90A6, 0xE8C1,0x9632, 0xE8C2,0x9F90, 0xE8C3,0x500D, 0xE8C4,0x4FF3, 0xE8C5,0xF963,\r\n 0xE8C6,0x57F9, 0xE8C7,0x5F98, 0xE8C8,0x62DC, 0xE8C9,0x6392, 0xE8CA,0x676F, 0xE8CB,0x6E43, 0xE8CC,0x7119, 0xE8CD,0x76C3,\r\n 0xE8CE,0x80CC, 0xE8CF,0x80DA, 0xE8D0,0x88F4, 0xE8D1,0x88F5, 0xE8D2,0x8919, 0xE8D3,0x8CE0, 0xE8D4,0x8F29, 0xE8D5,0x914D,\r\n 0xE8D6,0x966A, 0xE8D7,0x4F2F, 0xE8D8,0x4F70, 0xE8D9,0x5E1B, 0xE8DA,0x67CF, 0xE8DB,0x6822, 0xE8DC,0x767D, 0xE8DD,0x767E,\r\n 0xE8DE,0x9B44, 0xE8DF,0x5E61, 0xE8E0,0x6A0A, 0xE8E1,0x7169, 0xE8E2,0x71D4, 0xE8E3,0x756A, 0xE8E4,0xF964, 0xE8E5,0x7E41,\r\n 0xE8E6,0x8543, 0xE8E7,0x85E9, 0xE8E8,0x98DC, 0xE8E9,0x4F10, 0xE8EA,0x7B4F, 0xE8EB,0x7F70, 0xE8EC,0x95A5, 0xE8ED,0x51E1,\r\n 0xE8EE,0x5E06, 0xE8EF,0x68B5, 0xE8F0,0x6C3E, 0xE8F1,0x6C4E, 0xE8F2,0x6CDB, 0xE8F3,0x72AF, 0xE8F4,0x7BC4, 0xE8F5,0x8303,\r\n 0xE8F6,0x6CD5, 0xE8F7,0x743A, 0xE8F8,0x50FB, 0xE8F9,0x5288, 0xE8FA,0x58C1, 0xE8FB,0x64D8, 0xE8FC,0x6A97, 0xE8FD,0x74A7,\r\n 0xE8FE,0x7656, 0xE931,0x78A7, 0xE932,0x8617, 0xE933,0x95E2, 0xE934,0x9739, 0xE935,0xF965, 0xE936,0x535E, 0xE937,0x5F01,\r\n 0xE938,0x8B8A, 0xE939,0x8FA8, 0xE93A,0x8FAF, 0xE93B,0x908A, 0xE93C,0x5225, 0xE93D,0x77A5, 0xE93E,0x9C49, 0xE93F,0x9F08,\r\n 0xE940,0x4E19, 0xE941,0x5002, 0xE942,0x5175, 0xE943,0x5C5B, 0xE944,0x5E77, 0xE945,0x661E, 0xE946,0x663A, 0xE947,0x67C4,\r\n 0xE948,0x68C5, 0xE949,0x70B3, 0xE94A,0x7501, 0xE94B,0x75C5, 0xE94C,0x79C9, 0xE94D,0x7ADD, 0xE94E,0x8F27, 0xE94F,0x9920,\r\n 0xE950,0x9A08, 0xE951,0x4FDD, 0xE952,0x5821, 0xE953,0x5831, 0xE954,0x5BF6, 0xE955,0x666E, 0xE956,0x6B65, 0xE957,0x6D11,\r\n 0xE958,0x6E7A, 0xE959,0x6F7D, 0xE95A,0x73E4, 0xE95B,0x752B, 0xE95C,0x83E9, 0xE95D,0x88DC, 0xE95E,0x8913, 0xE95F,0x8B5C,\r\n 0xE960,0x8F14, 0xE961,0x4F0F, 0xE962,0x50D5, 0xE963,0x5310, 0xE964,0x535C, 0xE965,0x5B93, 0xE966,0x5FA9, 0xE967,0x670D,\r\n 0xE968,0x798F, 0xE969,0x8179, 0xE96A,0x832F, 0xE96B,0x8514, 0xE96C,0x8907, 0xE96D,0x8986, 0xE96E,0x8F39, 0xE96F,0x8F3B,\r\n 0xE970,0x99A5, 0xE971,0x9C12, 0xE972,0x672C, 0xE973,0x4E76, 0xE974,0x4FF8, 0xE975,0x5949, 0xE976,0x5C01, 0xE977,0x5CEF,\r\n 0xE978,0x5CF0, 0xE979,0x6367, 0xE97A,0x68D2, 0xE97B,0x70FD, 0xE97C,0x71A2, 0xE97D,0x742B, 0xE97E,0x7E2B, 0xE991,0x84EC,\r\n 0xE992,0x8702, 0xE993,0x9022, 0xE994,0x92D2, 0xE995,0x9CF3, 0xE996,0x4E0D, 0xE997,0x4ED8, 0xE998,0x4FEF, 0xE999,0x5085,\r\n 0xE99A,0x5256, 0xE99B,0x526F, 0xE99C,0x5426, 0xE99D,0x5490, 0xE99E,0x57E0, 0xE99F,0x592B, 0xE9A0,0x5A66, 0xE9A1,0x5B5A,\r\n 0xE9A2,0x5B75, 0xE9A3,0x5BCC, 0xE9A4,0x5E9C, 0xE9A5,0xF966, 0xE9A6,0x6276, 0xE9A7,0x6577, 0xE9A8,0x65A7, 0xE9A9,0x6D6E,\r\n 0xE9AA,0x6EA5, 0xE9AB,0x7236, 0xE9AC,0x7B26, 0xE9AD,0x7C3F, 0xE9AE,0x7F36, 0xE9AF,0x8150, 0xE9B0,0x8151, 0xE9B1,0x819A,\r\n 0xE9B2,0x8240, 0xE9B3,0x8299, 0xE9B4,0x83A9, 0xE9B5,0x8A03, 0xE9B6,0x8CA0, 0xE9B7,0x8CE6, 0xE9B8,0x8CFB, 0xE9B9,0x8D74,\r\n 0xE9BA,0x8DBA, 0xE9BB,0x90E8, 0xE9BC,0x91DC, 0xE9BD,0x961C, 0xE9BE,0x9644, 0xE9BF,0x99D9, 0xE9C0,0x9CE7, 0xE9C1,0x5317,\r\n 0xE9C2,0x5206, 0xE9C3,0x5429, 0xE9C4,0x5674, 0xE9C5,0x58B3, 0xE9C6,0x5954, 0xE9C7,0x596E, 0xE9C8,0x5FFF, 0xE9C9,0x61A4,\r\n 0xE9CA,0x626E, 0xE9CB,0x6610, 0xE9CC,0x6C7E, 0xE9CD,0x711A, 0xE9CE,0x76C6, 0xE9CF,0x7C89, 0xE9D0,0x7CDE, 0xE9D1,0x7D1B,\r\n 0xE9D2,0x82AC, 0xE9D3,0x8CC1, 0xE9D4,0x96F0, 0xE9D5,0xF967, 0xE9D6,0x4F5B, 0xE9D7,0x5F17, 0xE9D8,0x5F7F, 0xE9D9,0x62C2,\r\n 0xE9DA,0x5D29, 0xE9DB,0x670B, 0xE9DC,0x68DA, 0xE9DD,0x787C, 0xE9DE,0x7E43, 0xE9DF,0x9D6C, 0xE9E0,0x4E15, 0xE9E1,0x5099,\r\n 0xE9E2,0x5315, 0xE9E3,0x532A, 0xE9E4,0x5351, 0xE9E5,0x5983, 0xE9E6,0x5A62, 0xE9E7,0x5E87, 0xE9E8,0x60B2, 0xE9E9,0x618A,\r\n 0xE9EA,0x6249, 0xE9EB,0x6279, 0xE9EC,0x6590, 0xE9ED,0x6787, 0xE9EE,0x69A7, 0xE9EF,0x6BD4, 0xE9F0,0x6BD6, 0xE9F1,0x6BD7,\r\n 0xE9F2,0x6BD8, 0xE9F3,0x6CB8, 0xE9F4,0xF968, 0xE9F5,0x7435, 0xE9F6,0x75FA, 0xE9F7,0x7812, 0xE9F8,0x7891, 0xE9F9,0x79D5,\r\n 0xE9FA,0x79D8, 0xE9FB,0x7C83, 0xE9FC,0x7DCB, 0xE9FD,0x7FE1, 0xE9FE,0x80A5, 0xEA31,0x813E, 0xEA32,0x81C2, 0xEA33,0x83F2,\r\n 0xEA34,0x871A, 0xEA35,0x88E8, 0xEA36,0x8AB9, 0xEA37,0x8B6C, 0xEA38,0x8CBB, 0xEA39,0x9119, 0xEA3A,0x975E, 0xEA3B,0x98DB,\r\n 0xEA3C,0x9F3B, 0xEA3D,0x56AC, 0xEA3E,0x5B2A, 0xEA3F,0x5F6C, 0xEA40,0x658C, 0xEA41,0x6AB3, 0xEA42,0x6BAF, 0xEA43,0x6D5C,\r\n 0xEA44,0x6FF1, 0xEA45,0x7015, 0xEA46,0x725D, 0xEA47,0x73AD, 0xEA48,0x8CA7, 0xEA49,0x8CD3, 0xEA4A,0x983B, 0xEA4B,0x6191,\r\n 0xEA4C,0x6C37, 0xEA4D,0x8058, 0xEA4E,0x9A01, 0xEA4F,0x4E4D, 0xEA50,0x4E8B, 0xEA51,0x4E9B, 0xEA52,0x4ED5, 0xEA53,0x4F3A,\r\n 0xEA54,0x4F3C, 0xEA55,0x4F7F, 0xEA56,0x4FDF, 0xEA57,0x50FF, 0xEA58,0x53F2, 0xEA59,0x53F8, 0xEA5A,0x5506, 0xEA5B,0x55E3,\r\n 0xEA5C,0x56DB, 0xEA5D,0x58EB, 0xEA5E,0x5962, 0xEA5F,0x5A11, 0xEA60,0x5BEB, 0xEA61,0x5BFA, 0xEA62,0x5C04, 0xEA63,0x5DF3,\r\n 0xEA64,0x5E2B, 0xEA65,0x5F99, 0xEA66,0x601D, 0xEA67,0x6368, 0xEA68,0x659C, 0xEA69,0x65AF, 0xEA6A,0x67F6, 0xEA6B,0x67FB,\r\n 0xEA6C,0x68AD, 0xEA6D,0x6B7B, 0xEA6E,0x6C99, 0xEA6F,0x6CD7, 0xEA70,0x6E23, 0xEA71,0x7009, 0xEA72,0x7345, 0xEA73,0x7802,\r\n 0xEA74,0x793E, 0xEA75,0x7940, 0xEA76,0x7960, 0xEA77,0x79C1, 0xEA78,0x7BE9, 0xEA79,0x7D17, 0xEA7A,0x7D72, 0xEA7B,0x8086,\r\n 0xEA7C,0x820D, 0xEA7D,0x838E, 0xEA7E,0x84D1, 0xEA91,0x86C7, 0xEA92,0x88DF, 0xEA93,0x8A50, 0xEA94,0x8A5E, 0xEA95,0x8B1D,\r\n 0xEA96,0x8CDC, 0xEA97,0x8D66, 0xEA98,0x8FAD, 0xEA99,0x90AA, 0xEA9A,0x98FC, 0xEA9B,0x99DF, 0xEA9C,0x9E9D, 0xEA9D,0x524A,\r\n 0xEA9E,0xF969, 0xEA9F,0x6714, 0xEAA0,0xF96A, 0xEAA1,0x5098, 0xEAA2,0x522A, 0xEAA3,0x5C71, 0xEAA4,0x6563, 0xEAA5,0x6C55,\r\n 0xEAA6,0x73CA, 0xEAA7,0x7523, 0xEAA8,0x759D, 0xEAA9,0x7B97, 0xEAAA,0x849C, 0xEAAB,0x9178, 0xEAAC,0x9730, 0xEAAD,0x4E77,\r\n 0xEAAE,0x6492, 0xEAAF,0x6BBA, 0xEAB0,0x715E, 0xEAB1,0x85A9, 0xEAB2,0x4E09, 0xEAB3,0xF96B, 0xEAB4,0x6749, 0xEAB5,0x68EE,\r\n 0xEAB6,0x6E17, 0xEAB7,0x829F, 0xEAB8,0x8518, 0xEAB9,0x886B, 0xEABA,0x63F7, 0xEABB,0x6F81, 0xEABC,0x9212, 0xEABD,0x98AF,\r\n 0xEABE,0x4E0A, 0xEABF,0x50B7, 0xEAC0,0x50CF, 0xEAC1,0x511F, 0xEAC2,0x5546, 0xEAC3,0x55AA, 0xEAC4,0x5617, 0xEAC5,0x5B40,\r\n 0xEAC6,0x5C19, 0xEAC7,0x5CE0, 0xEAC8,0x5E38, 0xEAC9,0x5E8A, 0xEACA,0x5EA0, 0xEACB,0x5EC2, 0xEACC,0x60F3, 0xEACD,0x6851,\r\n 0xEACE,0x6A61, 0xEACF,0x6E58, 0xEAD0,0x723D, 0xEAD1,0x7240, 0xEAD2,0x72C0, 0xEAD3,0x76F8, 0xEAD4,0x7965, 0xEAD5,0x7BB1,\r\n 0xEAD6,0x7FD4, 0xEAD7,0x88F3, 0xEAD8,0x89F4, 0xEAD9,0x8A73, 0xEADA,0x8C61, 0xEADB,0x8CDE, 0xEADC,0x971C, 0xEADD,0x585E,\r\n 0xEADE,0x74BD, 0xEADF,0x8CFD, 0xEAE0,0x55C7, 0xEAE1,0xF96C, 0xEAE2,0x7A61, 0xEAE3,0x7D22, 0xEAE4,0x8272, 0xEAE5,0x7272,\r\n 0xEAE6,0x751F, 0xEAE7,0x7525, 0xEAE8,0xF96D, 0xEAE9,0x7B19, 0xEAEA,0x5885, 0xEAEB,0x58FB, 0xEAEC,0x5DBC, 0xEAED,0x5E8F,\r\n 0xEAEE,0x5EB6, 0xEAEF,0x5F90, 0xEAF0,0x6055, 0xEAF1,0x6292, 0xEAF2,0x637F, 0xEAF3,0x654D, 0xEAF4,0x6691, 0xEAF5,0x66D9,\r\n 0xEAF6,0x66F8, 0xEAF7,0x6816, 0xEAF8,0x68F2, 0xEAF9,0x7280, 0xEAFA,0x745E, 0xEAFB,0x7B6E, 0xEAFC,0x7D6E, 0xEAFD,0x7DD6,\r\n 0xEAFE,0x7F72, 0xEB31,0x80E5, 0xEB32,0x8212, 0xEB33,0x85AF, 0xEB34,0x897F, 0xEB35,0x8A93, 0xEB36,0x901D, 0xEB37,0x92E4,\r\n 0xEB38,0x9ECD, 0xEB39,0x9F20, 0xEB3A,0x5915, 0xEB3B,0x596D, 0xEB3C,0x5E2D, 0xEB3D,0x60DC, 0xEB3E,0x6614, 0xEB3F,0x6673,\r\n 0xEB40,0x6790, 0xEB41,0x6C50, 0xEB42,0x6DC5, 0xEB43,0x6F5F, 0xEB44,0x77F3, 0xEB45,0x78A9, 0xEB46,0x84C6, 0xEB47,0x91CB,\r\n 0xEB48,0x932B, 0xEB49,0x4ED9, 0xEB4A,0x50CA, 0xEB4B,0x5148, 0xEB4C,0x5584, 0xEB4D,0x5B0B, 0xEB4E,0x5BA3, 0xEB4F,0x6247,\r\n 0xEB50,0x657E, 0xEB51,0x65CB, 0xEB52,0x6E32, 0xEB53,0x717D, 0xEB54,0x7401, 0xEB55,0x7444, 0xEB56,0x7487, 0xEB57,0x74BF,\r\n 0xEB58,0x766C, 0xEB59,0x79AA, 0xEB5A,0x7DDA, 0xEB5B,0x7E55, 0xEB5C,0x7FA8, 0xEB5D,0x817A, 0xEB5E,0x81B3, 0xEB5F,0x8239,\r\n 0xEB60,0x861A, 0xEB61,0x87EC, 0xEB62,0x8A75, 0xEB63,0x8DE3, 0xEB64,0x9078, 0xEB65,0x9291, 0xEB66,0x9425, 0xEB67,0x994D,\r\n 0xEB68,0x9BAE, 0xEB69,0x5368, 0xEB6A,0x5C51, 0xEB6B,0x6954, 0xEB6C,0x6CC4, 0xEB6D,0x6D29, 0xEB6E,0x6E2B, 0xEB6F,0x820C,\r\n 0xEB70,0x859B, 0xEB71,0x893B, 0xEB72,0x8A2D, 0xEB73,0x8AAA, 0xEB74,0x96EA, 0xEB75,0x9F67, 0xEB76,0x5261, 0xEB77,0x66B9,\r\n 0xEB78,0x6BB2, 0xEB79,0x7E96, 0xEB7A,0x87FE, 0xEB7B,0x8D0D, 0xEB7C,0x9583, 0xEB7D,0x965D, 0xEB7E,0x651D, 0xEB91,0x6D89,\r\n 0xEB92,0x71EE, 0xEB93,0xF96E, 0xEB94,0x57CE, 0xEB95,0x59D3, 0xEB96,0x5BAC, 0xEB97,0x6027, 0xEB98,0x60FA, 0xEB99,0x6210,\r\n 0xEB9A,0x661F, 0xEB9B,0x665F, 0xEB9C,0x7329, 0xEB9D,0x73F9, 0xEB9E,0x76DB, 0xEB9F,0x7701, 0xEBA0,0x7B6C, 0xEBA1,0x8056,\r\n 0xEBA2,0x8072, 0xEBA3,0x8165, 0xEBA4,0x8AA0, 0xEBA5,0x9192, 0xEBA6,0x4E16, 0xEBA7,0x52E2, 0xEBA8,0x6B72, 0xEBA9,0x6D17,\r\n 0xEBAA,0x7A05, 0xEBAB,0x7B39, 0xEBAC,0x7D30, 0xEBAD,0xF96F, 0xEBAE,0x8CB0, 0xEBAF,0x53EC, 0xEBB0,0x562F, 0xEBB1,0x5851,\r\n 0xEBB2,0x5BB5, 0xEBB3,0x5C0F, 0xEBB4,0x5C11, 0xEBB5,0x5DE2, 0xEBB6,0x6240, 0xEBB7,0x6383, 0xEBB8,0x6414, 0xEBB9,0x662D,\r\n 0xEBBA,0x68B3, 0xEBBB,0x6CBC, 0xEBBC,0x6D88, 0xEBBD,0x6EAF, 0xEBBE,0x701F, 0xEBBF,0x70A4, 0xEBC0,0x71D2, 0xEBC1,0x7526,\r\n 0xEBC2,0x758F, 0xEBC3,0x758E, 0xEBC4,0x7619, 0xEBC5,0x7B11, 0xEBC6,0x7BE0, 0xEBC7,0x7C2B, 0xEBC8,0x7D20, 0xEBC9,0x7D39,\r\n 0xEBCA,0x852C, 0xEBCB,0x856D, 0xEBCC,0x8607, 0xEBCD,0x8A34, 0xEBCE,0x900D, 0xEBCF,0x9061, 0xEBD0,0x90B5, 0xEBD1,0x92B7,\r\n 0xEBD2,0x97F6, 0xEBD3,0x9A37, 0xEBD4,0x4FD7, 0xEBD5,0x5C6C, 0xEBD6,0x675F, 0xEBD7,0x6D91, 0xEBD8,0x7C9F, 0xEBD9,0x7E8C,\r\n 0xEBDA,0x8B16, 0xEBDB,0x8D16, 0xEBDC,0x901F, 0xEBDD,0x5B6B, 0xEBDE,0x5DFD, 0xEBDF,0x640D, 0xEBE0,0x84C0, 0xEBE1,0x905C,\r\n 0xEBE2,0x98E1, 0xEBE3,0x7387, 0xEBE4,0x5B8B, 0xEBE5,0x609A, 0xEBE6,0x677E, 0xEBE7,0x6DDE, 0xEBE8,0x8A1F, 0xEBE9,0x8AA6,\r\n 0xEBEA,0x9001, 0xEBEB,0x980C, 0xEBEC,0x5237, 0xEBED,0xF970, 0xEBEE,0x7051, 0xEBEF,0x788E, 0xEBF0,0x9396, 0xEBF1,0x8870,\r\n 0xEBF2,0x91D7, 0xEBF3,0x4FEE, 0xEBF4,0x53D7, 0xEBF5,0x55FD, 0xEBF6,0x56DA, 0xEBF7,0x5782, 0xEBF8,0x58FD, 0xEBF9,0x5AC2,\r\n 0xEBFA,0x5B88, 0xEBFB,0x5CAB, 0xEBFC,0x5CC0, 0xEBFD,0x5E25, 0xEBFE,0x6101, 0xEC31,0x620D, 0xEC32,0x624B, 0xEC33,0x6388,\r\n 0xEC34,0x641C, 0xEC35,0x6536, 0xEC36,0x6578, 0xEC37,0x6A39, 0xEC38,0x6B8A, 0xEC39,0x6C34, 0xEC3A,0x6D19, 0xEC3B,0x6F31,\r\n 0xEC3C,0x71E7, 0xEC3D,0x72E9, 0xEC3E,0x7378, 0xEC3F,0x7407, 0xEC40,0x74B2, 0xEC41,0x7626, 0xEC42,0x7761, 0xEC43,0x79C0,\r\n 0xEC44,0x7A57, 0xEC45,0x7AEA, 0xEC46,0x7CB9, 0xEC47,0x7D8F, 0xEC48,0x7DAC, 0xEC49,0x7E61, 0xEC4A,0x7F9E, 0xEC4B,0x8129,\r\n 0xEC4C,0x8331, 0xEC4D,0x8490, 0xEC4E,0x84DA, 0xEC4F,0x85EA, 0xEC50,0x8896, 0xEC51,0x8AB0, 0xEC52,0x8B90, 0xEC53,0x8F38,\r\n 0xEC54,0x9042, 0xEC55,0x9083, 0xEC56,0x916C, 0xEC57,0x9296, 0xEC58,0x92B9, 0xEC59,0x968B, 0xEC5A,0x96A7, 0xEC5B,0x96A8,\r\n 0xEC5C,0x96D6, 0xEC5D,0x9700, 0xEC5E,0x9808, 0xEC5F,0x9996, 0xEC60,0x9AD3, 0xEC61,0x9B1A, 0xEC62,0x53D4, 0xEC63,0x587E,\r\n 0xEC64,0x5919, 0xEC65,0x5B70, 0xEC66,0x5BBF, 0xEC67,0x6DD1, 0xEC68,0x6F5A, 0xEC69,0x719F, 0xEC6A,0x7421, 0xEC6B,0x74B9,\r\n 0xEC6C,0x8085, 0xEC6D,0x83FD, 0xEC6E,0x5DE1, 0xEC6F,0x5F87, 0xEC70,0x5FAA, 0xEC71,0x6042, 0xEC72,0x65EC, 0xEC73,0x6812,\r\n 0xEC74,0x696F, 0xEC75,0x6A53, 0xEC76,0x6B89, 0xEC77,0x6D35, 0xEC78,0x6DF3, 0xEC79,0x73E3, 0xEC7A,0x76FE, 0xEC7B,0x77AC,\r\n 0xEC7C,0x7B4D, 0xEC7D,0x7D14, 0xEC7E,0x8123, 0xEC91,0x821C, 0xEC92,0x8340, 0xEC93,0x84F4, 0xEC94,0x8563, 0xEC95,0x8A62,\r\n 0xEC96,0x8AC4, 0xEC97,0x9187, 0xEC98,0x931E, 0xEC99,0x9806, 0xEC9A,0x99B4, 0xEC9B,0x620C, 0xEC9C,0x8853, 0xEC9D,0x8FF0,\r\n 0xEC9E,0x9265, 0xEC9F,0x5D07, 0xECA0,0x5D27, 0xECA1,0x5D69, 0xECA2,0x745F, 0xECA3,0x819D, 0xECA4,0x8768, 0xECA5,0x6FD5,\r\n 0xECA6,0x62FE, 0xECA7,0x7FD2, 0xECA8,0x8936, 0xECA9,0x8972, 0xECAA,0x4E1E, 0xECAB,0x4E58, 0xECAC,0x50E7, 0xECAD,0x52DD,\r\n 0xECAE,0x5347, 0xECAF,0x627F, 0xECB0,0x6607, 0xECB1,0x7E69, 0xECB2,0x8805, 0xECB3,0x965E, 0xECB4,0x4F8D, 0xECB5,0x5319,\r\n 0xECB6,0x5636, 0xECB7,0x59CB, 0xECB8,0x5AA4, 0xECB9,0x5C38, 0xECBA,0x5C4E, 0xECBB,0x5C4D, 0xECBC,0x5E02, 0xECBD,0x5F11,\r\n 0xECBE,0x6043, 0xECBF,0x65BD, 0xECC0,0x662F, 0xECC1,0x6642, 0xECC2,0x67BE, 0xECC3,0x67F4, 0xECC4,0x731C, 0xECC5,0x77E2,\r\n 0xECC6,0x793A, 0xECC7,0x7FC5, 0xECC8,0x8494, 0xECC9,0x84CD, 0xECCA,0x8996, 0xECCB,0x8A66, 0xECCC,0x8A69, 0xECCD,0x8AE1,\r\n 0xECCE,0x8C55, 0xECCF,0x8C7A, 0xECD0,0x57F4, 0xECD1,0x5BD4, 0xECD2,0x5F0F, 0xECD3,0x606F, 0xECD4,0x62ED, 0xECD5,0x690D,\r\n 0xECD6,0x6B96, 0xECD7,0x6E5C, 0xECD8,0x7184, 0xECD9,0x7BD2, 0xECDA,0x8755, 0xECDB,0x8B58, 0xECDC,0x8EFE, 0xECDD,0x98DF,\r\n 0xECDE,0x98FE, 0xECDF,0x4F38, 0xECE0,0x4F81, 0xECE1,0x4FE1, 0xECE2,0x547B, 0xECE3,0x5A20, 0xECE4,0x5BB8, 0xECE5,0x613C,\r\n 0xECE6,0x65B0, 0xECE7,0x6668, 0xECE8,0x71FC, 0xECE9,0x7533, 0xECEA,0x795E, 0xECEB,0x7D33, 0xECEC,0x814E, 0xECED,0x81E3,\r\n 0xECEE,0x8398, 0xECEF,0x85AA, 0xECF0,0x85CE, 0xECF1,0x8703, 0xECF2,0x8A0A, 0xECF3,0x8EAB, 0xECF4,0x8F9B, 0xECF5,0xF971,\r\n 0xECF6,0x8FC5, 0xECF7,0x5931, 0xECF8,0x5BA4, 0xECF9,0x5BE6, 0xECFA,0x6089, 0xECFB,0x5BE9, 0xECFC,0x5C0B, 0xECFD,0x5FC3,\r\n 0xECFE,0x6C81, 0xED31,0xF972, 0xED32,0x6DF1, 0xED33,0x700B, 0xED34,0x751A, 0xED35,0x82AF, 0xED36,0x8AF6, 0xED37,0x4EC0,\r\n 0xED38,0x5341, 0xED39,0xF973, 0xED3A,0x96D9, 0xED3B,0x6C0F, 0xED3C,0x4E9E, 0xED3D,0x4FC4, 0xED3E,0x5152, 0xED3F,0x555E,\r\n 0xED40,0x5A25, 0xED41,0x5CE8, 0xED42,0x6211, 0xED43,0x7259, 0xED44,0x82BD, 0xED45,0x83AA, 0xED46,0x86FE, 0xED47,0x8859,\r\n 0xED48,0x8A1D, 0xED49,0x963F, 0xED4A,0x96C5, 0xED4B,0x9913, 0xED4C,0x9D09, 0xED4D,0x9D5D, 0xED4E,0x580A, 0xED4F,0x5CB3,\r\n 0xED50,0x5DBD, 0xED51,0x5E44, 0xED52,0x60E1, 0xED53,0x6115, 0xED54,0x63E1, 0xED55,0x6A02, 0xED56,0x6E25, 0xED57,0x9102,\r\n 0xED58,0x9354, 0xED59,0x984E, 0xED5A,0x9C10, 0xED5B,0x9F77, 0xED5C,0x5B89, 0xED5D,0x5CB8, 0xED5E,0x6309, 0xED5F,0x664F,\r\n 0xED60,0x6848, 0xED61,0x773C, 0xED62,0x96C1, 0xED63,0x978D, 0xED64,0x9854, 0xED65,0x9B9F, 0xED66,0x65A1, 0xED67,0x8B01,\r\n 0xED68,0x8ECB, 0xED69,0x95BC, 0xED6A,0x5535, 0xED6B,0x5CA9, 0xED6C,0x5DD6, 0xED6D,0x5EB5, 0xED6E,0x6697, 0xED6F,0x764C,\r\n 0xED70,0x83F4, 0xED71,0x95C7, 0xED72,0x58D3, 0xED73,0x62BC, 0xED74,0x72CE, 0xED75,0x9D28, 0xED76,0x4EF0, 0xED77,0x592E,\r\n 0xED78,0x600F, 0xED79,0x663B, 0xED7A,0x6B83, 0xED7B,0x79E7, 0xED7C,0x9D26, 0xED7D,0x5393, 0xED7E,0x54C0, 0xED91,0x57C3,\r\n 0xED92,0x5D16, 0xED93,0x611B, 0xED94,0x66D6, 0xED95,0x6DAF, 0xED96,0x788D, 0xED97,0x827E, 0xED98,0x9698, 0xED99,0x9744,\r\n 0xED9A,0x5384, 0xED9B,0x627C, 0xED9C,0x6396, 0xED9D,0x6DB2, 0xED9E,0x7E0A, 0xED9F,0x814B, 0xEDA0,0x984D, 0xEDA1,0x6AFB,\r\n 0xEDA2,0x7F4C, 0xEDA3,0x9DAF, 0xEDA4,0x9E1A, 0xEDA5,0x4E5F, 0xEDA6,0x503B, 0xEDA7,0x51B6, 0xEDA8,0x591C, 0xEDA9,0x60F9,\r\n 0xEDAA,0x63F6, 0xEDAB,0x6930, 0xEDAC,0x723A, 0xEDAD,0x8036, 0xEDAE,0xF974, 0xEDAF,0x91CE, 0xEDB0,0x5F31, 0xEDB1,0xF975,\r\n 0xEDB2,0xF976, 0xEDB3,0x7D04, 0xEDB4,0x82E5, 0xEDB5,0x846F, 0xEDB6,0x84BB, 0xEDB7,0x85E5, 0xEDB8,0x8E8D, 0xEDB9,0xF977,\r\n 0xEDBA,0x4F6F, 0xEDBB,0xF978, 0xEDBC,0xF979, 0xEDBD,0x58E4, 0xEDBE,0x5B43, 0xEDBF,0x6059, 0xEDC0,0x63DA, 0xEDC1,0x6518,\r\n 0xEDC2,0x656D, 0xEDC3,0x6698, 0xEDC4,0xF97A, 0xEDC5,0x694A, 0xEDC6,0x6A23, 0xEDC7,0x6D0B, 0xEDC8,0x7001, 0xEDC9,0x716C,\r\n 0xEDCA,0x75D2, 0xEDCB,0x760D, 0xEDCC,0x79B3, 0xEDCD,0x7A70, 0xEDCE,0xF97B, 0xEDCF,0x7F8A, 0xEDD0,0xF97C, 0xEDD1,0x8944,\r\n 0xEDD2,0xF97D, 0xEDD3,0x8B93, 0xEDD4,0x91C0, 0xEDD5,0x967D, 0xEDD6,0xF97E, 0xEDD7,0x990A, 0xEDD8,0x5704, 0xEDD9,0x5FA1,\r\n 0xEDDA,0x65BC, 0xEDDB,0x6F01, 0xEDDC,0x7600, 0xEDDD,0x79A6, 0xEDDE,0x8A9E, 0xEDDF,0x99AD, 0xEDE0,0x9B5A, 0xEDE1,0x9F6C,\r\n 0xEDE2,0x5104, 0xEDE3,0x61B6, 0xEDE4,0x6291, 0xEDE5,0x6A8D, 0xEDE6,0x81C6, 0xEDE7,0x5043, 0xEDE8,0x5830, 0xEDE9,0x5F66,\r\n 0xEDEA,0x7109, 0xEDEB,0x8A00, 0xEDEC,0x8AFA, 0xEDED,0x5B7C, 0xEDEE,0x8616, 0xEDEF,0x4FFA, 0xEDF0,0x513C, 0xEDF1,0x56B4,\r\n 0xEDF2,0x5944, 0xEDF3,0x63A9, 0xEDF4,0x6DF9, 0xEDF5,0x5DAA, 0xEDF6,0x696D, 0xEDF7,0x5186, 0xEDF8,0x4E88, 0xEDF9,0x4F59,\r\n 0xEDFA,0xF97F, 0xEDFB,0xF980, 0xEDFC,0xF981, 0xEDFD,0x5982, 0xEDFE,0xF982, 0xEE31,0xF983, 0xEE32,0x6B5F, 0xEE33,0x6C5D,\r\n 0xEE34,0xF984, 0xEE35,0x74B5, 0xEE36,0x7916, 0xEE37,0xF985, 0xEE38,0x8207, 0xEE39,0x8245, 0xEE3A,0x8339, 0xEE3B,0x8F3F,\r\n 0xEE3C,0x8F5D, 0xEE3D,0xF986, 0xEE3E,0x9918, 0xEE3F,0xF987, 0xEE40,0xF988, 0xEE41,0xF989, 0xEE42,0x4EA6, 0xEE43,0xF98A,\r\n 0xEE44,0x57DF, 0xEE45,0x5F79, 0xEE46,0x6613, 0xEE47,0xF98B, 0xEE48,0xF98C, 0xEE49,0x75AB, 0xEE4A,0x7E79, 0xEE4B,0x8B6F,\r\n 0xEE4C,0xF98D, 0xEE4D,0x9006, 0xEE4E,0x9A5B, 0xEE4F,0x56A5, 0xEE50,0x5827, 0xEE51,0x59F8, 0xEE52,0x5A1F, 0xEE53,0x5BB4,\r\n 0xEE54,0xF98E, 0xEE55,0x5EF6, 0xEE56,0xF98F, 0xEE57,0xF990, 0xEE58,0x6350, 0xEE59,0x633B, 0xEE5A,0xF991, 0xEE5B,0x693D,\r\n 0xEE5C,0x6C87, 0xEE5D,0x6CBF, 0xEE5E,0x6D8E, 0xEE5F,0x6D93, 0xEE60,0x6DF5, 0xEE61,0x6F14, 0xEE62,0xF992, 0xEE63,0x70DF,\r\n 0xEE64,0x7136, 0xEE65,0x7159, 0xEE66,0xF993, 0xEE67,0x71C3, 0xEE68,0x71D5, 0xEE69,0xF994, 0xEE6A,0x784F, 0xEE6B,0x786F,\r\n 0xEE6C,0xF995, 0xEE6D,0x7B75, 0xEE6E,0x7DE3, 0xEE6F,0xF996, 0xEE70,0x7E2F, 0xEE71,0xF997, 0xEE72,0x884D, 0xEE73,0x8EDF,\r\n 0xEE74,0xF998, 0xEE75,0xF999, 0xEE76,0xF99A, 0xEE77,0x925B, 0xEE78,0xF99B, 0xEE79,0x9CF6, 0xEE7A,0xF99C, 0xEE7B,0xF99D,\r\n 0xEE7C,0xF99E, 0xEE7D,0x6085, 0xEE7E,0x6D85, 0xEE91,0xF99F, 0xEE92,0x71B1, 0xEE93,0xF9A0, 0xEE94,0xF9A1, 0xEE95,0x95B1,\r\n 0xEE96,0x53AD, 0xEE97,0xF9A2, 0xEE98,0xF9A3, 0xEE99,0xF9A4, 0xEE9A,0x67D3, 0xEE9B,0xF9A5, 0xEE9C,0x708E, 0xEE9D,0x7130,\r\n 0xEE9E,0x7430, 0xEE9F,0x8276, 0xEEA0,0x82D2, 0xEEA1,0xF9A6, 0xEEA2,0x95BB, 0xEEA3,0x9AE5, 0xEEA4,0x9E7D, 0xEEA5,0x66C4,\r\n 0xEEA6,0xF9A7, 0xEEA7,0x71C1, 0xEEA8,0x8449, 0xEEA9,0xF9A8, 0xEEAA,0xF9A9, 0xEEAB,0x584B, 0xEEAC,0xF9AA, 0xEEAD,0xF9AB,\r\n 0xEEAE,0x5DB8, 0xEEAF,0x5F71, 0xEEB0,0xF9AC, 0xEEB1,0x6620, 0xEEB2,0x668E, 0xEEB3,0x6979, 0xEEB4,0x69AE, 0xEEB5,0x6C38,\r\n 0xEEB6,0x6CF3, 0xEEB7,0x6E36, 0xEEB8,0x6F41, 0xEEB9,0x6FDA, 0xEEBA,0x701B, 0xEEBB,0x702F, 0xEEBC,0x7150, 0xEEBD,0x71DF,\r\n 0xEEBE,0x7370, 0xEEBF,0xF9AD, 0xEEC0,0x745B, 0xEEC1,0xF9AE, 0xEEC2,0x74D4, 0xEEC3,0x76C8, 0xEEC4,0x7A4E, 0xEEC5,0x7E93,\r\n 0xEEC6,0xF9AF, 0xEEC7,0xF9B0, 0xEEC8,0x82F1, 0xEEC9,0x8A60, 0xEECA,0x8FCE, 0xEECB,0xF9B1, 0xEECC,0x9348, 0xEECD,0xF9B2,\r\n 0xEECE,0x9719, 0xEECF,0xF9B3, 0xEED0,0xF9B4, 0xEED1,0x4E42, 0xEED2,0x502A, 0xEED3,0xF9B5, 0xEED4,0x5208, 0xEED5,0x53E1,\r\n 0xEED6,0x66F3, 0xEED7,0x6C6D, 0xEED8,0x6FCA, 0xEED9,0x730A, 0xEEDA,0x777F, 0xEEDB,0x7A62, 0xEEDC,0x82AE, 0xEEDD,0x85DD,\r\n 0xEEDE,0x8602, 0xEEDF,0xF9B6, 0xEEE0,0x88D4, 0xEEE1,0x8A63, 0xEEE2,0x8B7D, 0xEEE3,0x8C6B, 0xEEE4,0xF9B7, 0xEEE5,0x92B3,\r\n 0xEEE6,0xF9B8, 0xEEE7,0x9713, 0xEEE8,0x9810, 0xEEE9,0x4E94, 0xEEEA,0x4F0D, 0xEEEB,0x4FC9, 0xEEEC,0x50B2, 0xEEED,0x5348,\r\n 0xEEEE,0x543E, 0xEEEF,0x5433, 0xEEF0,0x55DA, 0xEEF1,0x5862, 0xEEF2,0x58BA, 0xEEF3,0x5967, 0xEEF4,0x5A1B, 0xEEF5,0x5BE4,\r\n 0xEEF6,0x609F, 0xEEF7,0xF9B9, 0xEEF8,0x61CA, 0xEEF9,0x6556, 0xEEFA,0x65FF, 0xEEFB,0x6664, 0xEEFC,0x68A7, 0xEEFD,0x6C5A,\r\n 0xEEFE,0x6FB3, 0xEF31,0x70CF, 0xEF32,0x71AC, 0xEF33,0x7352, 0xEF34,0x7B7D, 0xEF35,0x8708, 0xEF36,0x8AA4, 0xEF37,0x9C32,\r\n 0xEF38,0x9F07, 0xEF39,0x5C4B, 0xEF3A,0x6C83, 0xEF3B,0x7344, 0xEF3C,0x7389, 0xEF3D,0x923A, 0xEF3E,0x6EAB, 0xEF3F,0x7465,\r\n 0xEF40,0x761F, 0xEF41,0x7A69, 0xEF42,0x7E15, 0xEF43,0x860A, 0xEF44,0x5140, 0xEF45,0x58C5, 0xEF46,0x64C1, 0xEF47,0x74EE,\r\n 0xEF48,0x7515, 0xEF49,0x7670, 0xEF4A,0x7FC1, 0xEF4B,0x9095, 0xEF4C,0x96CD, 0xEF4D,0x9954, 0xEF4E,0x6E26, 0xEF4F,0x74E6,\r\n 0xEF50,0x7AA9, 0xEF51,0x7AAA, 0xEF52,0x81E5, 0xEF53,0x86D9, 0xEF54,0x8778, 0xEF55,0x8A1B, 0xEF56,0x5A49, 0xEF57,0x5B8C,\r\n 0xEF58,0x5B9B, 0xEF59,0x68A1, 0xEF5A,0x6900, 0xEF5B,0x6D63, 0xEF5C,0x73A9, 0xEF5D,0x7413, 0xEF5E,0x742C, 0xEF5F,0x7897,\r\n 0xEF60,0x7DE9, 0xEF61,0x7FEB, 0xEF62,0x8118, 0xEF63,0x8155, 0xEF64,0x839E, 0xEF65,0x8C4C, 0xEF66,0x962E, 0xEF67,0x9811,\r\n 0xEF68,0x66F0, 0xEF69,0x5F80, 0xEF6A,0x65FA, 0xEF6B,0x6789, 0xEF6C,0x6C6A, 0xEF6D,0x738B, 0xEF6E,0x502D, 0xEF6F,0x5A03,\r\n 0xEF70,0x6B6A, 0xEF71,0x77EE, 0xEF72,0x5916, 0xEF73,0x5D6C, 0xEF74,0x5DCD, 0xEF75,0x7325, 0xEF76,0x754F, 0xEF77,0xF9BA,\r\n 0xEF78,0xF9BB, 0xEF79,0x50E5, 0xEF7A,0x51F9, 0xEF7B,0x582F, 0xEF7C,0x592D, 0xEF7D,0x5996, 0xEF7E,0x59DA, 0xEF91,0x5BE5,\r\n 0xEF92,0xF9BC, 0xEF93,0xF9BD, 0xEF94,0x5DA2, 0xEF95,0x62D7, 0xEF96,0x6416, 0xEF97,0x6493, 0xEF98,0x64FE, 0xEF99,0xF9BE,\r\n 0xEF9A,0x66DC, 0xEF9B,0xF9BF, 0xEF9C,0x6A48, 0xEF9D,0xF9C0, 0xEF9E,0x71FF, 0xEF9F,0x7464, 0xEFA0,0xF9C1, 0xEFA1,0x7A88,\r\n 0xEFA2,0x7AAF, 0xEFA3,0x7E47, 0xEFA4,0x7E5E, 0xEFA5,0x8000, 0xEFA6,0x8170, 0xEFA7,0xF9C2, 0xEFA8,0x87EF, 0xEFA9,0x8981,\r\n 0xEFAA,0x8B20, 0xEFAB,0x9059, 0xEFAC,0xF9C3, 0xEFAD,0x9080, 0xEFAE,0x9952, 0xEFAF,0x617E, 0xEFB0,0x6B32, 0xEFB1,0x6D74,\r\n 0xEFB2,0x7E1F, 0xEFB3,0x8925, 0xEFB4,0x8FB1, 0xEFB5,0x4FD1, 0xEFB6,0x50AD, 0xEFB7,0x5197, 0xEFB8,0x52C7, 0xEFB9,0x57C7,\r\n 0xEFBA,0x5889, 0xEFBB,0x5BB9, 0xEFBC,0x5EB8, 0xEFBD,0x6142, 0xEFBE,0x6995, 0xEFBF,0x6D8C, 0xEFC0,0x6E67, 0xEFC1,0x6EB6,\r\n 0xEFC2,0x7194, 0xEFC3,0x7462, 0xEFC4,0x7528, 0xEFC5,0x752C, 0xEFC6,0x8073, 0xEFC7,0x8338, 0xEFC8,0x84C9, 0xEFC9,0x8E0A,\r\n 0xEFCA,0x9394, 0xEFCB,0x93DE, 0xEFCC,0xF9C4, 0xEFCD,0x4E8E, 0xEFCE,0x4F51, 0xEFCF,0x5076, 0xEFD0,0x512A, 0xEFD1,0x53C8,\r\n 0xEFD2,0x53CB, 0xEFD3,0x53F3, 0xEFD4,0x5B87, 0xEFD5,0x5BD3, 0xEFD6,0x5C24, 0xEFD7,0x611A, 0xEFD8,0x6182, 0xEFD9,0x65F4,\r\n 0xEFDA,0x725B, 0xEFDB,0x7397, 0xEFDC,0x7440, 0xEFDD,0x76C2, 0xEFDE,0x7950, 0xEFDF,0x7991, 0xEFE0,0x79B9, 0xEFE1,0x7D06,\r\n 0xEFE2,0x7FBD, 0xEFE3,0x828B, 0xEFE4,0x85D5, 0xEFE5,0x865E, 0xEFE6,0x8FC2, 0xEFE7,0x9047, 0xEFE8,0x90F5, 0xEFE9,0x91EA,\r\n 0xEFEA,0x9685, 0xEFEB,0x96E8, 0xEFEC,0x96E9, 0xEFED,0x52D6, 0xEFEE,0x5F67, 0xEFEF,0x65ED, 0xEFF0,0x6631, 0xEFF1,0x682F,\r\n 0xEFF2,0x715C, 0xEFF3,0x7A36, 0xEFF4,0x90C1, 0xEFF5,0x980A, 0xEFF6,0x4E91, 0xEFF7,0xF9C5, 0xEFF8,0x6A52, 0xEFF9,0x6B9E,\r\n 0xEFFA,0x6F90, 0xEFFB,0x7189, 0xEFFC,0x8018, 0xEFFD,0x82B8, 0xEFFE,0x8553, 0xF031,0x904B, 0xF032,0x9695, 0xF033,0x96F2,\r\n 0xF034,0x97FB, 0xF035,0x851A, 0xF036,0x9B31, 0xF037,0x4E90, 0xF038,0x718A, 0xF039,0x96C4, 0xF03A,0x5143, 0xF03B,0x539F,\r\n 0xF03C,0x54E1, 0xF03D,0x5713, 0xF03E,0x5712, 0xF03F,0x57A3, 0xF040,0x5A9B, 0xF041,0x5AC4, 0xF042,0x5BC3, 0xF043,0x6028,\r\n 0xF044,0x613F, 0xF045,0x63F4, 0xF046,0x6C85, 0xF047,0x6D39, 0xF048,0x6E72, 0xF049,0x6E90, 0xF04A,0x7230, 0xF04B,0x733F,\r\n 0xF04C,0x7457, 0xF04D,0x82D1, 0xF04E,0x8881, 0xF04F,0x8F45, 0xF050,0x9060, 0xF051,0xF9C6, 0xF052,0x9662, 0xF053,0x9858,\r\n 0xF054,0x9D1B, 0xF055,0x6708, 0xF056,0x8D8A, 0xF057,0x925E, 0xF058,0x4F4D, 0xF059,0x5049, 0xF05A,0x50DE, 0xF05B,0x5371,\r\n 0xF05C,0x570D, 0xF05D,0x59D4, 0xF05E,0x5A01, 0xF05F,0x5C09, 0xF060,0x6170, 0xF061,0x6690, 0xF062,0x6E2D, 0xF063,0x7232,\r\n 0xF064,0x744B, 0xF065,0x7DEF, 0xF066,0x80C3, 0xF067,0x840E, 0xF068,0x8466, 0xF069,0x853F, 0xF06A,0x875F, 0xF06B,0x885B,\r\n 0xF06C,0x8918, 0xF06D,0x8B02, 0xF06E,0x9055, 0xF06F,0x97CB, 0xF070,0x9B4F, 0xF071,0x4E73, 0xF072,0x4F91, 0xF073,0x5112,\r\n 0xF074,0x516A, 0xF075,0xF9C7, 0xF076,0x552F, 0xF077,0x55A9, 0xF078,0x5B7A, 0xF079,0x5BA5, 0xF07A,0x5E7C, 0xF07B,0x5E7D,\r\n 0xF07C,0x5EBE, 0xF07D,0x60A0, 0xF07E,0x60DF, 0xF091,0x6108, 0xF092,0x6109, 0xF093,0x63C4, 0xF094,0x6538, 0xF095,0x6709,\r\n 0xF096,0xF9C8, 0xF097,0x67D4, 0xF098,0x67DA, 0xF099,0xF9C9, 0xF09A,0x6961, 0xF09B,0x6962, 0xF09C,0x6CB9, 0xF09D,0x6D27,\r\n 0xF09E,0xF9CA, 0xF09F,0x6E38, 0xF0A0,0xF9CB, 0xF0A1,0x6FE1, 0xF0A2,0x7336, 0xF0A3,0x7337, 0xF0A4,0xF9CC, 0xF0A5,0x745C,\r\n 0xF0A6,0x7531, 0xF0A7,0xF9CD, 0xF0A8,0x7652, 0xF0A9,0xF9CE, 0xF0AA,0xF9CF, 0xF0AB,0x7DAD, 0xF0AC,0x81FE, 0xF0AD,0x8438,\r\n 0xF0AE,0x88D5, 0xF0AF,0x8A98, 0xF0B0,0x8ADB, 0xF0B1,0x8AED, 0xF0B2,0x8E30, 0xF0B3,0x8E42, 0xF0B4,0x904A, 0xF0B5,0x903E,\r\n 0xF0B6,0x907A, 0xF0B7,0x9149, 0xF0B8,0x91C9, 0xF0B9,0x936E, 0xF0BA,0xF9D0, 0xF0BB,0xF9D1, 0xF0BC,0x5809, 0xF0BD,0xF9D2,\r\n 0xF0BE,0x6BD3, 0xF0BF,0x8089, 0xF0C0,0x80B2, 0xF0C1,0xF9D3, 0xF0C2,0xF9D4, 0xF0C3,0x5141, 0xF0C4,0x596B, 0xF0C5,0x5C39,\r\n 0xF0C6,0xF9D5, 0xF0C7,0xF9D6, 0xF0C8,0x6F64, 0xF0C9,0x73A7, 0xF0CA,0x80E4, 0xF0CB,0x8D07, 0xF0CC,0xF9D7, 0xF0CD,0x9217,\r\n 0xF0CE,0x958F, 0xF0CF,0xF9D8, 0xF0D0,0xF9D9, 0xF0D1,0xF9DA, 0xF0D2,0xF9DB, 0xF0D3,0x807F, 0xF0D4,0x620E, 0xF0D5,0x701C,\r\n 0xF0D6,0x7D68, 0xF0D7,0x878D, 0xF0D8,0xF9DC, 0xF0D9,0x57A0, 0xF0DA,0x6069, 0xF0DB,0x6147, 0xF0DC,0x6BB7, 0xF0DD,0x8ABE,\r\n 0xF0DE,0x9280, 0xF0DF,0x96B1, 0xF0E0,0x4E59, 0xF0E1,0x541F, 0xF0E2,0x6DEB, 0xF0E3,0x852D, 0xF0E4,0x9670, 0xF0E5,0x97F3,\r\n 0xF0E6,0x98EE, 0xF0E7,0x63D6, 0xF0E8,0x6CE3, 0xF0E9,0x9091, 0xF0EA,0x51DD, 0xF0EB,0x61C9, 0xF0EC,0x81BA, 0xF0ED,0x9DF9,\r\n 0xF0EE,0x4F9D, 0xF0EF,0x501A, 0xF0F0,0x5100, 0xF0F1,0x5B9C, 0xF0F2,0x610F, 0xF0F3,0x61FF, 0xF0F4,0x64EC, 0xF0F5,0x6905,\r\n 0xF0F6,0x6BC5, 0xF0F7,0x7591, 0xF0F8,0x77E3, 0xF0F9,0x7FA9, 0xF0FA,0x8264, 0xF0FB,0x858F, 0xF0FC,0x87FB, 0xF0FD,0x8863,\r\n 0xF0FE,0x8ABC, 0xF131,0x8B70, 0xF132,0x91AB, 0xF133,0x4E8C, 0xF134,0x4EE5, 0xF135,0x4F0A, 0xF136,0xF9DD, 0xF137,0xF9DE,\r\n 0xF138,0x5937, 0xF139,0x59E8, 0xF13A,0xF9DF, 0xF13B,0x5DF2, 0xF13C,0x5F1B, 0xF13D,0x5F5B, 0xF13E,0x6021, 0xF13F,0xF9E0,\r\n 0xF140,0xF9E1, 0xF141,0xF9E2, 0xF142,0xF9E3, 0xF143,0x723E, 0xF144,0x73E5, 0xF145,0xF9E4, 0xF146,0x7570, 0xF147,0x75CD,\r\n 0xF148,0xF9E5, 0xF149,0x79FB, 0xF14A,0xF9E6, 0xF14B,0x800C, 0xF14C,0x8033, 0xF14D,0x8084, 0xF14E,0x82E1, 0xF14F,0x8351,\r\n 0xF150,0xF9E7, 0xF151,0xF9E8, 0xF152,0x8CBD, 0xF153,0x8CB3, 0xF154,0x9087, 0xF155,0xF9E9, 0xF156,0xF9EA, 0xF157,0x98F4,\r\n 0xF158,0x990C, 0xF159,0xF9EB, 0xF15A,0xF9EC, 0xF15B,0x7037, 0xF15C,0x76CA, 0xF15D,0x7FCA, 0xF15E,0x7FCC, 0xF15F,0x7FFC,\r\n 0xF160,0x8B1A, 0xF161,0x4EBA, 0xF162,0x4EC1, 0xF163,0x5203, 0xF164,0x5370, 0xF165,0xF9ED, 0xF166,0x54BD, 0xF167,0x56E0,\r\n 0xF168,0x59FB, 0xF169,0x5BC5, 0xF16A,0x5F15, 0xF16B,0x5FCD, 0xF16C,0x6E6E, 0xF16D,0xF9EE, 0xF16E,0xF9EF, 0xF16F,0x7D6A,\r\n 0xF170,0x8335, 0xF171,0xF9F0, 0xF172,0x8693, 0xF173,0x8A8D, 0xF174,0xF9F1, 0xF175,0x976D, 0xF176,0x9777, 0xF177,0xF9F2,\r\n 0xF178,0xF9F3, 0xF179,0x4E00, 0xF17A,0x4F5A, 0xF17B,0x4F7E, 0xF17C,0x58F9, 0xF17D,0x65E5, 0xF17E,0x6EA2, 0xF191,0x9038,\r\n 0xF192,0x93B0, 0xF193,0x99B9, 0xF194,0x4EFB, 0xF195,0x58EC, 0xF196,0x598A, 0xF197,0x59D9, 0xF198,0x6041, 0xF199,0xF9F4,\r\n 0xF19A,0xF9F5, 0xF19B,0x7A14, 0xF19C,0xF9F6, 0xF19D,0x834F, 0xF19E,0x8CC3, 0xF19F,0x5165, 0xF1A0,0x5344, 0xF1A1,0xF9F7,\r\n 0xF1A2,0xF9F8, 0xF1A3,0xF9F9, 0xF1A4,0x4ECD, 0xF1A5,0x5269, 0xF1A6,0x5B55, 0xF1A7,0x82BF, 0xF1A8,0x4ED4, 0xF1A9,0x523A,\r\n 0xF1AA,0x54A8, 0xF1AB,0x59C9, 0xF1AC,0x59FF, 0xF1AD,0x5B50, 0xF1AE,0x5B57, 0xF1AF,0x5B5C, 0xF1B0,0x6063, 0xF1B1,0x6148,\r\n 0xF1B2,0x6ECB, 0xF1B3,0x7099, 0xF1B4,0x716E, 0xF1B5,0x7386, 0xF1B6,0x74F7, 0xF1B7,0x75B5, 0xF1B8,0x78C1, 0xF1B9,0x7D2B,\r\n 0xF1BA,0x8005, 0xF1BB,0x81EA, 0xF1BC,0x8328, 0xF1BD,0x8517, 0xF1BE,0x85C9, 0xF1BF,0x8AEE, 0xF1C0,0x8CC7, 0xF1C1,0x96CC,\r\n 0xF1C2,0x4F5C, 0xF1C3,0x52FA, 0xF1C4,0x56BC, 0xF1C5,0x65AB, 0xF1C6,0x6628, 0xF1C7,0x707C, 0xF1C8,0x70B8, 0xF1C9,0x7235,\r\n 0xF1CA,0x7DBD, 0xF1CB,0x828D, 0xF1CC,0x914C, 0xF1CD,0x96C0, 0xF1CE,0x9D72, 0xF1CF,0x5B71, 0xF1D0,0x68E7, 0xF1D1,0x6B98,\r\n 0xF1D2,0x6F7A, 0xF1D3,0x76DE, 0xF1D4,0x5C91, 0xF1D5,0x66AB, 0xF1D6,0x6F5B, 0xF1D7,0x7BB4, 0xF1D8,0x7C2A, 0xF1D9,0x8836,\r\n 0xF1DA,0x96DC, 0xF1DB,0x4E08, 0xF1DC,0x4ED7, 0xF1DD,0x5320, 0xF1DE,0x5834, 0xF1DF,0x58BB, 0xF1E0,0x58EF, 0xF1E1,0x596C,\r\n 0xF1E2,0x5C07, 0xF1E3,0x5E33, 0xF1E4,0x5E84, 0xF1E5,0x5F35, 0xF1E6,0x638C, 0xF1E7,0x66B2, 0xF1E8,0x6756, 0xF1E9,0x6A1F,\r\n 0xF1EA,0x6AA3, 0xF1EB,0x6B0C, 0xF1EC,0x6F3F, 0xF1ED,0x7246, 0xF1EE,0xF9FA, 0xF1EF,0x7350, 0xF1F0,0x748B, 0xF1F1,0x7AE0,\r\n 0xF1F2,0x7CA7, 0xF1F3,0x8178, 0xF1F4,0x81DF, 0xF1F5,0x81E7, 0xF1F6,0x838A, 0xF1F7,0x846C, 0xF1F8,0x8523, 0xF1F9,0x8594,\r\n 0xF1FA,0x85CF, 0xF1FB,0x88DD, 0xF1FC,0x8D13, 0xF1FD,0x91AC, 0xF1FE,0x9577, 0xF231,0x969C, 0xF232,0x518D, 0xF233,0x54C9,\r\n 0xF234,0x5728, 0xF235,0x5BB0, 0xF236,0x624D, 0xF237,0x6750, 0xF238,0x683D, 0xF239,0x6893, 0xF23A,0x6E3D, 0xF23B,0x6ED3,\r\n 0xF23C,0x707D, 0xF23D,0x7E21, 0xF23E,0x88C1, 0xF23F,0x8CA1, 0xF240,0x8F09, 0xF241,0x9F4B, 0xF242,0x9F4E, 0xF243,0x722D,\r\n 0xF244,0x7B8F, 0xF245,0x8ACD, 0xF246,0x931A, 0xF247,0x4F47, 0xF248,0x4F4E, 0xF249,0x5132, 0xF24A,0x5480, 0xF24B,0x59D0,\r\n 0xF24C,0x5E95, 0xF24D,0x62B5, 0xF24E,0x6775, 0xF24F,0x696E, 0xF250,0x6A17, 0xF251,0x6CAE, 0xF252,0x6E1A, 0xF253,0x72D9,\r\n 0xF254,0x732A, 0xF255,0x75BD, 0xF256,0x7BB8, 0xF257,0x7D35, 0xF258,0x82E7, 0xF259,0x83F9, 0xF25A,0x8457, 0xF25B,0x85F7,\r\n 0xF25C,0x8A5B, 0xF25D,0x8CAF, 0xF25E,0x8E87, 0xF25F,0x9019, 0xF260,0x90B8, 0xF261,0x96CE, 0xF262,0x9F5F, 0xF263,0x52E3,\r\n 0xF264,0x540A, 0xF265,0x5AE1, 0xF266,0x5BC2, 0xF267,0x6458, 0xF268,0x6575, 0xF269,0x6EF4, 0xF26A,0x72C4, 0xF26B,0xF9FB,\r\n 0xF26C,0x7684, 0xF26D,0x7A4D, 0xF26E,0x7B1B, 0xF26F,0x7C4D, 0xF270,0x7E3E, 0xF271,0x7FDF, 0xF272,0x837B, 0xF273,0x8B2B,\r\n 0xF274,0x8CCA, 0xF275,0x8D64, 0xF276,0x8DE1, 0xF277,0x8E5F, 0xF278,0x8FEA, 0xF279,0x8FF9, 0xF27A,0x9069, 0xF27B,0x93D1,\r\n 0xF27C,0x4F43, 0xF27D,0x4F7A, 0xF27E,0x50B3, 0xF291,0x5168, 0xF292,0x5178, 0xF293,0x524D, 0xF294,0x526A, 0xF295,0x5861,\r\n 0xF296,0x587C, 0xF297,0x5960, 0xF298,0x5C08, 0xF299,0x5C55, 0xF29A,0x5EDB, 0xF29B,0x609B, 0xF29C,0x6230, 0xF29D,0x6813,\r\n 0xF29E,0x6BBF, 0xF29F,0x6C08, 0xF2A0,0x6FB1, 0xF2A1,0x714E, 0xF2A2,0x7420, 0xF2A3,0x7530, 0xF2A4,0x7538, 0xF2A5,0x7551,\r\n 0xF2A6,0x7672, 0xF2A7,0x7B4C, 0xF2A8,0x7B8B, 0xF2A9,0x7BAD, 0xF2AA,0x7BC6, 0xF2AB,0x7E8F, 0xF2AC,0x8A6E, 0xF2AD,0x8F3E,\r\n 0xF2AE,0x8F49, 0xF2AF,0x923F, 0xF2B0,0x9293, 0xF2B1,0x9322, 0xF2B2,0x942B, 0xF2B3,0x96FB, 0xF2B4,0x985A, 0xF2B5,0x986B,\r\n 0xF2B6,0x991E, 0xF2B7,0x5207, 0xF2B8,0x622A, 0xF2B9,0x6298, 0xF2BA,0x6D59, 0xF2BB,0x7664, 0xF2BC,0x7ACA, 0xF2BD,0x7BC0,\r\n 0xF2BE,0x7D76, 0xF2BF,0x5360, 0xF2C0,0x5CBE, 0xF2C1,0x5E97, 0xF2C2,0x6F38, 0xF2C3,0x70B9, 0xF2C4,0x7C98, 0xF2C5,0x9711,\r\n 0xF2C6,0x9B8E, 0xF2C7,0x9EDE, 0xF2C8,0x63A5, 0xF2C9,0x647A, 0xF2CA,0x8776, 0xF2CB,0x4E01, 0xF2CC,0x4E95, 0xF2CD,0x4EAD,\r\n 0xF2CE,0x505C, 0xF2CF,0x5075, 0xF2D0,0x5448, 0xF2D1,0x59C3, 0xF2D2,0x5B9A, 0xF2D3,0x5E40, 0xF2D4,0x5EAD, 0xF2D5,0x5EF7,\r\n 0xF2D6,0x5F81, 0xF2D7,0x60C5, 0xF2D8,0x633A, 0xF2D9,0x653F, 0xF2DA,0x6574, 0xF2DB,0x65CC, 0xF2DC,0x6676, 0xF2DD,0x6678,\r\n 0xF2DE,0x67FE, 0xF2DF,0x6968, 0xF2E0,0x6A89, 0xF2E1,0x6B63, 0xF2E2,0x6C40, 0xF2E3,0x6DC0, 0xF2E4,0x6DE8, 0xF2E5,0x6E1F,\r\n 0xF2E6,0x6E5E, 0xF2E7,0x701E, 0xF2E8,0x70A1, 0xF2E9,0x738E, 0xF2EA,0x73FD, 0xF2EB,0x753A, 0xF2EC,0x775B, 0xF2ED,0x7887,\r\n 0xF2EE,0x798E, 0xF2EF,0x7A0B, 0xF2F0,0x7A7D, 0xF2F1,0x7CBE, 0xF2F2,0x7D8E, 0xF2F3,0x8247, 0xF2F4,0x8A02, 0xF2F5,0x8AEA,\r\n 0xF2F6,0x8C9E, 0xF2F7,0x912D, 0xF2F8,0x914A, 0xF2F9,0x91D8, 0xF2FA,0x9266, 0xF2FB,0x92CC, 0xF2FC,0x9320, 0xF2FD,0x9706,\r\n 0xF2FE,0x9756, 0xF331,0x975C, 0xF332,0x9802, 0xF333,0x9F0E, 0xF334,0x5236, 0xF335,0x5291, 0xF336,0x557C, 0xF337,0x5824,\r\n 0xF338,0x5E1D, 0xF339,0x5F1F, 0xF33A,0x608C, 0xF33B,0x63D0, 0xF33C,0x68AF, 0xF33D,0x6FDF, 0xF33E,0x796D, 0xF33F,0x7B2C,\r\n 0xF340,0x81CD, 0xF341,0x85BA, 0xF342,0x88FD, 0xF343,0x8AF8, 0xF344,0x8E44, 0xF345,0x918D, 0xF346,0x9664, 0xF347,0x969B,\r\n 0xF348,0x973D, 0xF349,0x984C, 0xF34A,0x9F4A, 0xF34B,0x4FCE, 0xF34C,0x5146, 0xF34D,0x51CB, 0xF34E,0x52A9, 0xF34F,0x5632,\r\n 0xF350,0x5F14, 0xF351,0x5F6B, 0xF352,0x63AA, 0xF353,0x64CD, 0xF354,0x65E9, 0xF355,0x6641, 0xF356,0x66FA, 0xF357,0x66F9,\r\n 0xF358,0x671D, 0xF359,0x689D, 0xF35A,0x68D7, 0xF35B,0x69FD, 0xF35C,0x6F15, 0xF35D,0x6F6E, 0xF35E,0x7167, 0xF35F,0x71E5,\r\n 0xF360,0x722A, 0xF361,0x74AA, 0xF362,0x773A, 0xF363,0x7956, 0xF364,0x795A, 0xF365,0x79DF, 0xF366,0x7A20, 0xF367,0x7A95,\r\n 0xF368,0x7C97, 0xF369,0x7CDF, 0xF36A,0x7D44, 0xF36B,0x7E70, 0xF36C,0x8087, 0xF36D,0x85FB, 0xF36E,0x86A4, 0xF36F,0x8A54,\r\n 0xF370,0x8ABF, 0xF371,0x8D99, 0xF372,0x8E81, 0xF373,0x9020, 0xF374,0x906D, 0xF375,0x91E3, 0xF376,0x963B, 0xF377,0x96D5,\r\n 0xF378,0x9CE5, 0xF379,0x65CF, 0xF37A,0x7C07, 0xF37B,0x8DB3, 0xF37C,0x93C3, 0xF37D,0x5B58, 0xF37E,0x5C0A, 0xF391,0x5352,\r\n 0xF392,0x62D9, 0xF393,0x731D, 0xF394,0x5027, 0xF395,0x5B97, 0xF396,0x5F9E, 0xF397,0x60B0, 0xF398,0x616B, 0xF399,0x68D5,\r\n 0xF39A,0x6DD9, 0xF39B,0x742E, 0xF39C,0x7A2E, 0xF39D,0x7D42, 0xF39E,0x7D9C, 0xF39F,0x7E31, 0xF3A0,0x816B, 0xF3A1,0x8E2A,\r\n 0xF3A2,0x8E35, 0xF3A3,0x937E, 0xF3A4,0x9418, 0xF3A5,0x4F50, 0xF3A6,0x5750, 0xF3A7,0x5DE6, 0xF3A8,0x5EA7, 0xF3A9,0x632B,\r\n 0xF3AA,0x7F6A, 0xF3AB,0x4E3B, 0xF3AC,0x4F4F, 0xF3AD,0x4F8F, 0xF3AE,0x505A, 0xF3AF,0x59DD, 0xF3B0,0x80C4, 0xF3B1,0x546A,\r\n 0xF3B2,0x5468, 0xF3B3,0x55FE, 0xF3B4,0x594F, 0xF3B5,0x5B99, 0xF3B6,0x5DDE, 0xF3B7,0x5EDA, 0xF3B8,0x665D, 0xF3B9,0x6731,\r\n 0xF3BA,0x67F1, 0xF3BB,0x682A, 0xF3BC,0x6CE8, 0xF3BD,0x6D32, 0xF3BE,0x6E4A, 0xF3BF,0x6F8D, 0xF3C0,0x70B7, 0xF3C1,0x73E0,\r\n 0xF3C2,0x7587, 0xF3C3,0x7C4C, 0xF3C4,0x7D02, 0xF3C5,0x7D2C, 0xF3C6,0x7DA2, 0xF3C7,0x821F, 0xF3C8,0x86DB, 0xF3C9,0x8A3B,\r\n 0xF3CA,0x8A85, 0xF3CB,0x8D70, 0xF3CC,0x8E8A, 0xF3CD,0x8F33, 0xF3CE,0x9031, 0xF3CF,0x914E, 0xF3D0,0x9152, 0xF3D1,0x9444,\r\n 0xF3D2,0x99D0, 0xF3D3,0x7AF9, 0xF3D4,0x7CA5, 0xF3D5,0x4FCA, 0xF3D6,0x5101, 0xF3D7,0x51C6, 0xF3D8,0x57C8, 0xF3D9,0x5BEF,\r\n 0xF3DA,0x5CFB, 0xF3DB,0x6659, 0xF3DC,0x6A3D, 0xF3DD,0x6D5A, 0xF3DE,0x6E96, 0xF3DF,0x6FEC, 0xF3E0,0x710C, 0xF3E1,0x756F,\r\n 0xF3E2,0x7AE3, 0xF3E3,0x8822, 0xF3E4,0x9021, 0xF3E5,0x9075, 0xF3E6,0x96CB, 0xF3E7,0x99FF, 0xF3E8,0x8301, 0xF3E9,0x4E2D,\r\n 0xF3EA,0x4EF2, 0xF3EB,0x8846, 0xF3EC,0x91CD, 0xF3ED,0x537D, 0xF3EE,0x6ADB, 0xF3EF,0x696B, 0xF3F0,0x6C41, 0xF3F1,0x847A,\r\n 0xF3F2,0x589E, 0xF3F3,0x618E, 0xF3F4,0x66FE, 0xF3F5,0x62EF, 0xF3F6,0x70DD, 0xF3F7,0x7511, 0xF3F8,0x75C7, 0xF3F9,0x7E52,\r\n 0xF3FA,0x84B8, 0xF3FB,0x8B49, 0xF3FC,0x8D08, 0xF3FD,0x4E4B, 0xF3FE,0x53EA, 0xF431,0x54AB, 0xF432,0x5730, 0xF433,0x5740,\r\n 0xF434,0x5FD7, 0xF435,0x6301, 0xF436,0x6307, 0xF437,0x646F, 0xF438,0x652F, 0xF439,0x65E8, 0xF43A,0x667A, 0xF43B,0x679D,\r\n 0xF43C,0x67B3, 0xF43D,0x6B62, 0xF43E,0x6C60, 0xF43F,0x6C9A, 0xF440,0x6F2C, 0xF441,0x77E5, 0xF442,0x7825, 0xF443,0x7949,\r\n 0xF444,0x7957, 0xF445,0x7D19, 0xF446,0x80A2, 0xF447,0x8102, 0xF448,0x81F3, 0xF449,0x829D, 0xF44A,0x82B7, 0xF44B,0x8718,\r\n 0xF44C,0x8A8C, 0xF44D,0xF9FC, 0xF44E,0x8D04, 0xF44F,0x8DBE, 0xF450,0x9072, 0xF451,0x76F4, 0xF452,0x7A19, 0xF453,0x7A37,\r\n 0xF454,0x7E54, 0xF455,0x8077, 0xF456,0x5507, 0xF457,0x55D4, 0xF458,0x5875, 0xF459,0x632F, 0xF45A,0x6422, 0xF45B,0x6649,\r\n 0xF45C,0x664B, 0xF45D,0x686D, 0xF45E,0x699B, 0xF45F,0x6B84, 0xF460,0x6D25, 0xF461,0x6EB1, 0xF462,0x73CD, 0xF463,0x7468,\r\n 0xF464,0x74A1, 0xF465,0x755B, 0xF466,0x75B9, 0xF467,0x76E1, 0xF468,0x771E, 0xF469,0x778B, 0xF46A,0x79E6, 0xF46B,0x7E09,\r\n 0xF46C,0x7E1D, 0xF46D,0x81FB, 0xF46E,0x852F, 0xF46F,0x8897, 0xF470,0x8A3A, 0xF471,0x8CD1, 0xF472,0x8EEB, 0xF473,0x8FB0,\r\n 0xF474,0x9032, 0xF475,0x93AD, 0xF476,0x9663, 0xF477,0x9673, 0xF478,0x9707, 0xF479,0x4F84, 0xF47A,0x53F1, 0xF47B,0x59EA,\r\n 0xF47C,0x5AC9, 0xF47D,0x5E19, 0xF47E,0x684E, 0xF491,0x74C6, 0xF492,0x75BE, 0xF493,0x79E9, 0xF494,0x7A92, 0xF495,0x81A3,\r\n 0xF496,0x86ED, 0xF497,0x8CEA, 0xF498,0x8DCC, 0xF499,0x8FED, 0xF49A,0x659F, 0xF49B,0x6715, 0xF49C,0xF9FD, 0xF49D,0x57F7,\r\n 0xF49E,0x6F57, 0xF49F,0x7DDD, 0xF4A0,0x8F2F, 0xF4A1,0x93F6, 0xF4A2,0x96C6, 0xF4A3,0x5FB5, 0xF4A4,0x61F2, 0xF4A5,0x6F84,\r\n 0xF4A6,0x4E14, 0xF4A7,0x4F98, 0xF4A8,0x501F, 0xF4A9,0x53C9, 0xF4AA,0x55DF, 0xF4AB,0x5D6F, 0xF4AC,0x5DEE, 0xF4AD,0x6B21,\r\n 0xF4AE,0x6B64, 0xF4AF,0x78CB, 0xF4B0,0x7B9A, 0xF4B1,0xF9FE, 0xF4B2,0x8E49, 0xF4B3,0x8ECA, 0xF4B4,0x906E, 0xF4B5,0x6349,\r\n 0xF4B6,0x643E, 0xF4B7,0x7740, 0xF4B8,0x7A84, 0xF4B9,0x932F, 0xF4BA,0x947F, 0xF4BB,0x9F6A, 0xF4BC,0x64B0, 0xF4BD,0x6FAF,\r\n 0xF4BE,0x71E6, 0xF4BF,0x74A8, 0xF4C0,0x74DA, 0xF4C1,0x7AC4, 0xF4C2,0x7C12, 0xF4C3,0x7E82, 0xF4C4,0x7CB2, 0xF4C5,0x7E98,\r\n 0xF4C6,0x8B9A, 0xF4C7,0x8D0A, 0xF4C8,0x947D, 0xF4C9,0x9910, 0xF4CA,0x994C, 0xF4CB,0x5239, 0xF4CC,0x5BDF, 0xF4CD,0x64E6,\r\n 0xF4CE,0x672D, 0xF4CF,0x7D2E, 0xF4D0,0x50ED, 0xF4D1,0x53C3, 0xF4D2,0x5879, 0xF4D3,0x6158, 0xF4D4,0x6159, 0xF4D5,0x61FA,\r\n 0xF4D6,0x65AC, 0xF4D7,0x7AD9, 0xF4D8,0x8B92, 0xF4D9,0x8B96, 0xF4DA,0x5009, 0xF4DB,0x5021, 0xF4DC,0x5275, 0xF4DD,0x5531,\r\n 0xF4DE,0x5A3C, 0xF4DF,0x5EE0, 0xF4E0,0x5F70, 0xF4E1,0x6134, 0xF4E2,0x655E, 0xF4E3,0x660C, 0xF4E4,0x6636, 0xF4E5,0x66A2,\r\n 0xF4E6,0x69CD, 0xF4E7,0x6EC4, 0xF4E8,0x6F32, 0xF4E9,0x7316, 0xF4EA,0x7621, 0xF4EB,0x7A93, 0xF4EC,0x8139, 0xF4ED,0x8259,\r\n 0xF4EE,0x83D6, 0xF4EF,0x84BC, 0xF4F0,0x50B5, 0xF4F1,0x57F0, 0xF4F2,0x5BC0, 0xF4F3,0x5BE8, 0xF4F4,0x5F69, 0xF4F5,0x63A1,\r\n 0xF4F6,0x7826, 0xF4F7,0x7DB5, 0xF4F8,0x83DC, 0xF4F9,0x8521, 0xF4FA,0x91C7, 0xF4FB,0x91F5, 0xF4FC,0x518A, 0xF4FD,0x67F5,\r\n 0xF4FE,0x7B56, 0xF531,0x8CAC, 0xF532,0x51C4, 0xF533,0x59BB, 0xF534,0x60BD, 0xF535,0x8655, 0xF536,0x501C, 0xF537,0xF9FF,\r\n 0xF538,0x5254, 0xF539,0x5C3A, 0xF53A,0x617D, 0xF53B,0x621A, 0xF53C,0x62D3, 0xF53D,0x64F2, 0xF53E,0x65A5, 0xF53F,0x6ECC,\r\n 0xF540,0x7620, 0xF541,0x810A, 0xF542,0x8E60, 0xF543,0x965F, 0xF544,0x96BB, 0xF545,0x4EDF, 0xF546,0x5343, 0xF547,0x5598,\r\n 0xF548,0x5929, 0xF549,0x5DDD, 0xF54A,0x64C5, 0xF54B,0x6CC9, 0xF54C,0x6DFA, 0xF54D,0x7394, 0xF54E,0x7A7F, 0xF54F,0x821B,\r\n 0xF550,0x85A6, 0xF551,0x8CE4, 0xF552,0x8E10, 0xF553,0x9077, 0xF554,0x91E7, 0xF555,0x95E1, 0xF556,0x9621, 0xF557,0x97C6,\r\n 0xF558,0x51F8, 0xF559,0x54F2, 0xF55A,0x5586, 0xF55B,0x5FB9, 0xF55C,0x64A4, 0xF55D,0x6F88, 0xF55E,0x7DB4, 0xF55F,0x8F1F,\r\n 0xF560,0x8F4D, 0xF561,0x9435, 0xF562,0x50C9, 0xF563,0x5C16, 0xF564,0x6CBE, 0xF565,0x6DFB, 0xF566,0x751B, 0xF567,0x77BB,\r\n 0xF568,0x7C3D, 0xF569,0x7C64, 0xF56A,0x8A79, 0xF56B,0x8AC2, 0xF56C,0x581E, 0xF56D,0x59BE, 0xF56E,0x5E16, 0xF56F,0x6377,\r\n 0xF570,0x7252, 0xF571,0x758A, 0xF572,0x776B, 0xF573,0x8ADC, 0xF574,0x8CBC, 0xF575,0x8F12, 0xF576,0x5EF3, 0xF577,0x6674,\r\n 0xF578,0x6DF8, 0xF579,0x807D, 0xF57A,0x83C1, 0xF57B,0x8ACB, 0xF57C,0x9751, 0xF57D,0x9BD6, 0xF57E,0xFA00, 0xF591,0x5243,\r\n 0xF592,0x66FF, 0xF593,0x6D95, 0xF594,0x6EEF, 0xF595,0x7DE0, 0xF596,0x8AE6, 0xF597,0x902E, 0xF598,0x905E, 0xF599,0x9AD4,\r\n 0xF59A,0x521D, 0xF59B,0x527F, 0xF59C,0x54E8, 0xF59D,0x6194, 0xF59E,0x6284, 0xF59F,0x62DB, 0xF5A0,0x68A2, 0xF5A1,0x6912,\r\n 0xF5A2,0x695A, 0xF5A3,0x6A35, 0xF5A4,0x7092, 0xF5A5,0x7126, 0xF5A6,0x785D, 0xF5A7,0x7901, 0xF5A8,0x790E, 0xF5A9,0x79D2,\r\n 0xF5AA,0x7A0D, 0xF5AB,0x8096, 0xF5AC,0x8278, 0xF5AD,0x82D5, 0xF5AE,0x8349, 0xF5AF,0x8549, 0xF5B0,0x8C82, 0xF5B1,0x8D85,\r\n 0xF5B2,0x9162, 0xF5B3,0x918B, 0xF5B4,0x91AE, 0xF5B5,0x4FC3, 0xF5B6,0x56D1, 0xF5B7,0x71ED, 0xF5B8,0x77D7, 0xF5B9,0x8700,\r\n 0xF5BA,0x89F8, 0xF5BB,0x5BF8, 0xF5BC,0x5FD6, 0xF5BD,0x6751, 0xF5BE,0x90A8, 0xF5BF,0x53E2, 0xF5C0,0x585A, 0xF5C1,0x5BF5,\r\n 0xF5C2,0x60A4, 0xF5C3,0x6181, 0xF5C4,0x6460, 0xF5C5,0x7E3D, 0xF5C6,0x8070, 0xF5C7,0x8525, 0xF5C8,0x9283, 0xF5C9,0x64AE,\r\n 0xF5CA,0x50AC, 0xF5CB,0x5D14, 0xF5CC,0x6700, 0xF5CD,0x589C, 0xF5CE,0x62BD, 0xF5CF,0x63A8, 0xF5D0,0x690E, 0xF5D1,0x6978,\r\n 0xF5D2,0x6A1E, 0xF5D3,0x6E6B, 0xF5D4,0x76BA, 0xF5D5,0x79CB, 0xF5D6,0x82BB, 0xF5D7,0x8429, 0xF5D8,0x8ACF, 0xF5D9,0x8DA8,\r\n 0xF5DA,0x8FFD, 0xF5DB,0x9112, 0xF5DC,0x914B, 0xF5DD,0x919C, 0xF5DE,0x9310, 0xF5DF,0x9318, 0xF5E0,0x939A, 0xF5E1,0x96DB,\r\n 0xF5E2,0x9A36, 0xF5E3,0x9C0D, 0xF5E4,0x4E11, 0xF5E5,0x755C, 0xF5E6,0x795D, 0xF5E7,0x7AFA, 0xF5E8,0x7B51, 0xF5E9,0x7BC9,\r\n 0xF5EA,0x7E2E, 0xF5EB,0x84C4, 0xF5EC,0x8E59, 0xF5ED,0x8E74, 0xF5EE,0x8EF8, 0xF5EF,0x9010, 0xF5F0,0x6625, 0xF5F1,0x693F,\r\n 0xF5F2,0x7443, 0xF5F3,0x51FA, 0xF5F4,0x672E, 0xF5F5,0x9EDC, 0xF5F6,0x5145, 0xF5F7,0x5FE0, 0xF5F8,0x6C96, 0xF5F9,0x87F2,\r\n 0xF5FA,0x885D, 0xF5FB,0x8877, 0xF5FC,0x60B4, 0xF5FD,0x81B5, 0xF5FE,0x8403, 0xF631,0x8D05, 0xF632,0x53D6, 0xF633,0x5439,\r\n 0xF634,0x5634, 0xF635,0x5A36, 0xF636,0x5C31, 0xF637,0x708A, 0xF638,0x7FE0, 0xF639,0x805A, 0xF63A,0x8106, 0xF63B,0x81ED,\r\n 0xF63C,0x8DA3, 0xF63D,0x9189, 0xF63E,0x9A5F, 0xF63F,0x9DF2, 0xF640,0x5074, 0xF641,0x4EC4, 0xF642,0x53A0, 0xF643,0x60FB,\r\n 0xF644,0x6E2C, 0xF645,0x5C64, 0xF646,0x4F88, 0xF647,0x5024, 0xF648,0x55E4, 0xF649,0x5CD9, 0xF64A,0x5E5F, 0xF64B,0x6065,\r\n 0xF64C,0x6894, 0xF64D,0x6CBB, 0xF64E,0x6DC4, 0xF64F,0x71BE, 0xF650,0x75D4, 0xF651,0x75F4, 0xF652,0x7661, 0xF653,0x7A1A,\r\n 0xF654,0x7A49, 0xF655,0x7DC7, 0xF656,0x7DFB, 0xF657,0x7F6E, 0xF658,0x81F4, 0xF659,0x86A9, 0xF65A,0x8F1C, 0xF65B,0x96C9,\r\n 0xF65C,0x99B3, 0xF65D,0x9F52, 0xF65E,0x5247, 0xF65F,0x52C5, 0xF660,0x98ED, 0xF661,0x89AA, 0xF662,0x4E03, 0xF663,0x67D2,\r\n 0xF664,0x6F06, 0xF665,0x4FB5, 0xF666,0x5BE2, 0xF667,0x6795, 0xF668,0x6C88, 0xF669,0x6D78, 0xF66A,0x741B, 0xF66B,0x7827,\r\n 0xF66C,0x91DD, 0xF66D,0x937C, 0xF66E,0x87C4, 0xF66F,0x79E4, 0xF670,0x7A31, 0xF671,0x5FEB, 0xF672,0x4ED6, 0xF673,0x54A4,\r\n 0xF674,0x553E, 0xF675,0x58AE, 0xF676,0x59A5, 0xF677,0x60F0, 0xF678,0x6253, 0xF679,0x62D6, 0xF67A,0x6736, 0xF67B,0x6955,\r\n 0xF67C,0x8235, 0xF67D,0x9640, 0xF67E,0x99B1, 0xF691,0x99DD, 0xF692,0x502C, 0xF693,0x5353, 0xF694,0x5544, 0xF695,0x577C,\r\n 0xF696,0xFA01, 0xF697,0x6258, 0xF698,0xFA02, 0xF699,0x64E2, 0xF69A,0x666B, 0xF69B,0x67DD, 0xF69C,0x6FC1, 0xF69D,0x6FEF,\r\n 0xF69E,0x7422, 0xF69F,0x7438, 0xF6A0,0x8A17, 0xF6A1,0x9438, 0xF6A2,0x5451, 0xF6A3,0x5606, 0xF6A4,0x5766, 0xF6A5,0x5F48,\r\n 0xF6A6,0x619A, 0xF6A7,0x6B4E, 0xF6A8,0x7058, 0xF6A9,0x70AD, 0xF6AA,0x7DBB, 0xF6AB,0x8A95, 0xF6AC,0x596A, 0xF6AD,0x812B,\r\n 0xF6AE,0x63A2, 0xF6AF,0x7708, 0xF6B0,0x803D, 0xF6B1,0x8CAA, 0xF6B2,0x5854, 0xF6B3,0x642D, 0xF6B4,0x69BB, 0xF6B5,0x5B95,\r\n 0xF6B6,0x5E11, 0xF6B7,0x6E6F, 0xF6B8,0xFA03, 0xF6B9,0x8569, 0xF6BA,0x514C, 0xF6BB,0x53F0, 0xF6BC,0x592A, 0xF6BD,0x6020,\r\n 0xF6BE,0x614B, 0xF6BF,0x6B86, 0xF6C0,0x6C70, 0xF6C1,0x6CF0, 0xF6C2,0x7B1E, 0xF6C3,0x80CE, 0xF6C4,0x82D4, 0xF6C5,0x8DC6,\r\n 0xF6C6,0x90B0, 0xF6C7,0x98B1, 0xF6C8,0xFA04, 0xF6C9,0x64C7, 0xF6CA,0x6FA4, 0xF6CB,0x6491, 0xF6CC,0x6504, 0xF6CD,0x514E,\r\n 0xF6CE,0x5410, 0xF6CF,0x571F, 0xF6D0,0x8A0E, 0xF6D1,0x615F, 0xF6D2,0x6876, 0xF6D3,0xFA05, 0xF6D4,0x75DB, 0xF6D5,0x7B52,\r\n 0xF6D6,0x7D71, 0xF6D7,0x901A, 0xF6D8,0x5806, 0xF6D9,0x69CC, 0xF6DA,0x817F, 0xF6DB,0x892A, 0xF6DC,0x9000, 0xF6DD,0x9839,\r\n 0xF6DE,0x5078, 0xF6DF,0x5957, 0xF6E0,0x59AC, 0xF6E1,0x6295, 0xF6E2,0x900F, 0xF6E3,0x9B2A, 0xF6E4,0x615D, 0xF6E5,0x7279,\r\n 0xF6E6,0x95D6, 0xF6E7,0x5761, 0xF6E8,0x5A46, 0xF6E9,0x5DF4, 0xF6EA,0x628A, 0xF6EB,0x64AD, 0xF6EC,0x64FA, 0xF6ED,0x6777,\r\n 0xF6EE,0x6CE2, 0xF6EF,0x6D3E, 0xF6F0,0x722C, 0xF6F1,0x7436, 0xF6F2,0x7834, 0xF6F3,0x7F77, 0xF6F4,0x82AD, 0xF6F5,0x8DDB,\r\n 0xF6F6,0x9817, 0xF6F7,0x5224, 0xF6F8,0x5742, 0xF6F9,0x677F, 0xF6FA,0x7248, 0xF6FB,0x74E3, 0xF6FC,0x8CA9, 0xF6FD,0x8FA6,\r\n 0xF6FE,0x9211, 0xF731,0x962A, 0xF732,0x516B, 0xF733,0x53ED, 0xF734,0x634C, 0xF735,0x4F69, 0xF736,0x5504, 0xF737,0x6096,\r\n 0xF738,0x6557, 0xF739,0x6C9B, 0xF73A,0x6D7F, 0xF73B,0x724C, 0xF73C,0x72FD, 0xF73D,0x7A17, 0xF73E,0x8987, 0xF73F,0x8C9D,\r\n 0xF740,0x5F6D, 0xF741,0x6F8E, 0xF742,0x70F9, 0xF743,0x81A8, 0xF744,0x610E, 0xF745,0x4FBF, 0xF746,0x504F, 0xF747,0x6241,\r\n 0xF748,0x7247, 0xF749,0x7BC7, 0xF74A,0x7DE8, 0xF74B,0x7FE9, 0xF74C,0x904D, 0xF74D,0x97AD, 0xF74E,0x9A19, 0xF74F,0x8CB6,\r\n 0xF750,0x576A, 0xF751,0x5E73, 0xF752,0x67B0, 0xF753,0x840D, 0xF754,0x8A55, 0xF755,0x5420, 0xF756,0x5B16, 0xF757,0x5E63,\r\n 0xF758,0x5EE2, 0xF759,0x5F0A, 0xF75A,0x6583, 0xF75B,0x80BA, 0xF75C,0x853D, 0xF75D,0x9589, 0xF75E,0x965B, 0xF75F,0x4F48,\r\n 0xF760,0x5305, 0xF761,0x530D, 0xF762,0x530F, 0xF763,0x5486, 0xF764,0x54FA, 0xF765,0x5703, 0xF766,0x5E03, 0xF767,0x6016,\r\n 0xF768,0x629B, 0xF769,0x62B1, 0xF76A,0x6355, 0xF76B,0xFA06, 0xF76C,0x6CE1, 0xF76D,0x6D66, 0xF76E,0x75B1, 0xF76F,0x7832,\r\n 0xF770,0x80DE, 0xF771,0x812F, 0xF772,0x82DE, 0xF773,0x8461, 0xF774,0x84B2, 0xF775,0x888D, 0xF776,0x8912, 0xF777,0x900B,\r\n 0xF778,0x92EA, 0xF779,0x98FD, 0xF77A,0x9B91, 0xF77B,0x5E45, 0xF77C,0x66B4, 0xF77D,0x66DD, 0xF77E,0x7011, 0xF791,0x7206,\r\n 0xF792,0xFA07, 0xF793,0x4FF5, 0xF794,0x527D, 0xF795,0x5F6A, 0xF796,0x6153, 0xF797,0x6753, 0xF798,0x6A19, 0xF799,0x6F02,\r\n 0xF79A,0x74E2, 0xF79B,0x7968, 0xF79C,0x8868, 0xF79D,0x8C79, 0xF79E,0x98C7, 0xF79F,0x98C4, 0xF7A0,0x9A43, 0xF7A1,0x54C1,\r\n 0xF7A2,0x7A1F, 0xF7A3,0x6953, 0xF7A4,0x8AF7, 0xF7A5,0x8C4A, 0xF7A6,0x98A8, 0xF7A7,0x99AE, 0xF7A8,0x5F7C, 0xF7A9,0x62AB,\r\n 0xF7AA,0x75B2, 0xF7AB,0x76AE, 0xF7AC,0x88AB, 0xF7AD,0x907F, 0xF7AE,0x9642, 0xF7AF,0x5339, 0xF7B0,0x5F3C, 0xF7B1,0x5FC5,\r\n 0xF7B2,0x6CCC, 0xF7B3,0x73CC, 0xF7B4,0x7562, 0xF7B5,0x758B, 0xF7B6,0x7B46, 0xF7B7,0x82FE, 0xF7B8,0x999D, 0xF7B9,0x4E4F,\r\n 0xF7BA,0x903C, 0xF7BB,0x4E0B, 0xF7BC,0x4F55, 0xF7BD,0x53A6, 0xF7BE,0x590F, 0xF7BF,0x5EC8, 0xF7C0,0x6630, 0xF7C1,0x6CB3,\r\n 0xF7C2,0x7455, 0xF7C3,0x8377, 0xF7C4,0x8766, 0xF7C5,0x8CC0, 0xF7C6,0x9050, 0xF7C7,0x971E, 0xF7C8,0x9C15, 0xF7C9,0x58D1,\r\n 0xF7CA,0x5B78, 0xF7CB,0x8650, 0xF7CC,0x8B14, 0xF7CD,0x9DB4, 0xF7CE,0x5BD2, 0xF7CF,0x6068, 0xF7D0,0x608D, 0xF7D1,0x65F1,\r\n 0xF7D2,0x6C57, 0xF7D3,0x6F22, 0xF7D4,0x6FA3, 0xF7D5,0x701A, 0xF7D6,0x7F55, 0xF7D7,0x7FF0, 0xF7D8,0x9591, 0xF7D9,0x9592,\r\n 0xF7DA,0x9650, 0xF7DB,0x97D3, 0xF7DC,0x5272, 0xF7DD,0x8F44, 0xF7DE,0x51FD, 0xF7DF,0x542B, 0xF7E0,0x54B8, 0xF7E1,0x5563,\r\n 0xF7E2,0x558A, 0xF7E3,0x6ABB, 0xF7E4,0x6DB5, 0xF7E5,0x7DD8, 0xF7E6,0x8266, 0xF7E7,0x929C, 0xF7E8,0x9677, 0xF7E9,0x9E79,\r\n 0xF7EA,0x5408, 0xF7EB,0x54C8, 0xF7EC,0x76D2, 0xF7ED,0x86E4, 0xF7EE,0x95A4, 0xF7EF,0x95D4, 0xF7F0,0x965C, 0xF7F1,0x4EA2,\r\n 0xF7F2,0x4F09, 0xF7F3,0x59EE, 0xF7F4,0x5AE6, 0xF7F5,0x5DF7, 0xF7F6,0x6052, 0xF7F7,0x6297, 0xF7F8,0x676D, 0xF7F9,0x6841,\r\n 0xF7FA,0x6C86, 0xF7FB,0x6E2F, 0xF7FC,0x7F38, 0xF7FD,0x809B, 0xF7FE,0x822A, 0xF831,0xFA08, 0xF832,0xFA09, 0xF833,0x9805,\r\n 0xF834,0x4EA5, 0xF835,0x5055, 0xF836,0x54B3, 0xF837,0x5793, 0xF838,0x595A, 0xF839,0x5B69, 0xF83A,0x5BB3, 0xF83B,0x61C8,\r\n 0xF83C,0x6977, 0xF83D,0x6D77, 0xF83E,0x7023, 0xF83F,0x87F9, 0xF840,0x89E3, 0xF841,0x8A72, 0xF842,0x8AE7, 0xF843,0x9082,\r\n 0xF844,0x99ED, 0xF845,0x9AB8, 0xF846,0x52BE, 0xF847,0x6838, 0xF848,0x5016, 0xF849,0x5E78, 0xF84A,0x674F, 0xF84B,0x8347,\r\n 0xF84C,0x884C, 0xF84D,0x4EAB, 0xF84E,0x5411, 0xF84F,0x56AE, 0xF850,0x73E6, 0xF851,0x9115, 0xF852,0x97FF, 0xF853,0x9909,\r\n 0xF854,0x9957, 0xF855,0x9999, 0xF856,0x5653, 0xF857,0x589F, 0xF858,0x865B, 0xF859,0x8A31, 0xF85A,0x61B2, 0xF85B,0x6AF6,\r\n 0xF85C,0x737B, 0xF85D,0x8ED2, 0xF85E,0x6B47, 0xF85F,0x96AA, 0xF860,0x9A57, 0xF861,0x5955, 0xF862,0x7200, 0xF863,0x8D6B,\r\n 0xF864,0x9769, 0xF865,0x4FD4, 0xF866,0x5CF4, 0xF867,0x5F26, 0xF868,0x61F8, 0xF869,0x665B, 0xF86A,0x6CEB, 0xF86B,0x70AB,\r\n 0xF86C,0x7384, 0xF86D,0x73B9, 0xF86E,0x73FE, 0xF86F,0x7729, 0xF870,0x774D, 0xF871,0x7D43, 0xF872,0x7D62, 0xF873,0x7E23,\r\n 0xF874,0x8237, 0xF875,0x8852, 0xF876,0xFA0A, 0xF877,0x8CE2, 0xF878,0x9249, 0xF879,0x986F, 0xF87A,0x5B51, 0xF87B,0x7A74,\r\n 0xF87C,0x8840, 0xF87D,0x9801, 0xF87E,0x5ACC, 0xF891,0x4FE0, 0xF892,0x5354, 0xF893,0x593E, 0xF894,0x5CFD, 0xF895,0x633E,\r\n 0xF896,0x6D79, 0xF897,0x72F9, 0xF898,0x8105, 0xF899,0x8107, 0xF89A,0x83A2, 0xF89B,0x92CF, 0xF89C,0x9830, 0xF89D,0x4EA8,\r\n 0xF89E,0x5144, 0xF89F,0x5211, 0xF8A0,0x578B, 0xF8A1,0x5F62, 0xF8A2,0x6CC2, 0xF8A3,0x6ECE, 0xF8A4,0x7005, 0xF8A5,0x7050,\r\n 0xF8A6,0x70AF, 0xF8A7,0x7192, 0xF8A8,0x73E9, 0xF8A9,0x7469, 0xF8AA,0x834A, 0xF8AB,0x87A2, 0xF8AC,0x8861, 0xF8AD,0x9008,\r\n 0xF8AE,0x90A2, 0xF8AF,0x93A3, 0xF8B0,0x99A8, 0xF8B1,0x516E, 0xF8B2,0x5F57, 0xF8B3,0x60E0, 0xF8B4,0x6167, 0xF8B5,0x66B3,\r\n 0xF8B6,0x8559, 0xF8B7,0x8E4A, 0xF8B8,0x91AF, 0xF8B9,0x978B, 0xF8BA,0x4E4E, 0xF8BB,0x4E92, 0xF8BC,0x547C, 0xF8BD,0x58D5,\r\n 0xF8BE,0x58FA, 0xF8BF,0x597D, 0xF8C0,0x5CB5, 0xF8C1,0x5F27, 0xF8C2,0x6236, 0xF8C3,0x6248, 0xF8C4,0x660A, 0xF8C5,0x6667,\r\n 0xF8C6,0x6BEB, 0xF8C7,0x6D69, 0xF8C8,0x6DCF, 0xF8C9,0x6E56, 0xF8CA,0x6EF8, 0xF8CB,0x6F94, 0xF8CC,0x6FE0, 0xF8CD,0x6FE9,\r\n 0xF8CE,0x705D, 0xF8CF,0x72D0, 0xF8D0,0x7425, 0xF8D1,0x745A, 0xF8D2,0x74E0, 0xF8D3,0x7693, 0xF8D4,0x795C, 0xF8D5,0x7CCA,\r\n 0xF8D6,0x7E1E, 0xF8D7,0x80E1, 0xF8D8,0x82A6, 0xF8D9,0x846B, 0xF8DA,0x84BF, 0xF8DB,0x864E, 0xF8DC,0x865F, 0xF8DD,0x8774,\r\n 0xF8DE,0x8B77, 0xF8DF,0x8C6A, 0xF8E0,0x93AC, 0xF8E1,0x9800, 0xF8E2,0x9865, 0xF8E3,0x60D1, 0xF8E4,0x6216, 0xF8E5,0x9177,\r\n 0xF8E6,0x5A5A, 0xF8E7,0x660F, 0xF8E8,0x6DF7, 0xF8E9,0x6E3E, 0xF8EA,0x743F, 0xF8EB,0x9B42, 0xF8EC,0x5FFD, 0xF8ED,0x60DA,\r\n 0xF8EE,0x7B0F, 0xF8EF,0x54C4, 0xF8F0,0x5F18, 0xF8F1,0x6C5E, 0xF8F2,0x6CD3, 0xF8F3,0x6D2A, 0xF8F4,0x70D8, 0xF8F5,0x7D05,\r\n 0xF8F6,0x8679, 0xF8F7,0x8A0C, 0xF8F8,0x9D3B, 0xF8F9,0x5316, 0xF8FA,0x548C, 0xF8FB,0x5B05, 0xF8FC,0x6A3A, 0xF8FD,0x706B,\r\n 0xF8FE,0x7575, 0xF931,0x798D, 0xF932,0x79BE, 0xF933,0x82B1, 0xF934,0x83EF, 0xF935,0x8A71, 0xF936,0x8B41, 0xF937,0x8CA8,\r\n 0xF938,0x9774, 0xF939,0xFA0B, 0xF93A,0x64F4, 0xF93B,0x652B, 0xF93C,0x78BA, 0xF93D,0x78BB, 0xF93E,0x7A6B, 0xF93F,0x4E38,\r\n 0xF940,0x559A, 0xF941,0x5950, 0xF942,0x5BA6, 0xF943,0x5E7B, 0xF944,0x60A3, 0xF945,0x63DB, 0xF946,0x6B61, 0xF947,0x6665,\r\n 0xF948,0x6853, 0xF949,0x6E19, 0xF94A,0x7165, 0xF94B,0x74B0, 0xF94C,0x7D08, 0xF94D,0x9084, 0xF94E,0x9A69, 0xF94F,0x9C25,\r\n 0xF950,0x6D3B, 0xF951,0x6ED1, 0xF952,0x733E, 0xF953,0x8C41, 0xF954,0x95CA, 0xF955,0x51F0, 0xF956,0x5E4C, 0xF957,0x5FA8,\r\n 0xF958,0x604D, 0xF959,0x60F6, 0xF95A,0x6130, 0xF95B,0x614C, 0xF95C,0x6643, 0xF95D,0x6644, 0xF95E,0x69A5, 0xF95F,0x6CC1,\r\n 0xF960,0x6E5F, 0xF961,0x6EC9, 0xF962,0x6F62, 0xF963,0x714C, 0xF964,0x749C, 0xF965,0x7687, 0xF966,0x7BC1, 0xF967,0x7C27,\r\n 0xF968,0x8352, 0xF969,0x8757, 0xF96A,0x9051, 0xF96B,0x968D, 0xF96C,0x9EC3, 0xF96D,0x532F, 0xF96E,0x56DE, 0xF96F,0x5EFB,\r\n 0xF970,0x5F8A, 0xF971,0x6062, 0xF972,0x6094, 0xF973,0x61F7, 0xF974,0x6666, 0xF975,0x6703, 0xF976,0x6A9C, 0xF977,0x6DEE,\r\n 0xF978,0x6FAE, 0xF979,0x7070, 0xF97A,0x736A, 0xF97B,0x7E6A, 0xF97C,0x81BE, 0xF97D,0x8334, 0xF97E,0x86D4, 0xF991,0x8AA8,\r\n 0xF992,0x8CC4, 0xF993,0x5283, 0xF994,0x7372, 0xF995,0x5B96, 0xF996,0x6A6B, 0xF997,0x9404, 0xF998,0x54EE, 0xF999,0x5686,\r\n 0xF99A,0x5B5D, 0xF99B,0x6548, 0xF99C,0x6585, 0xF99D,0x66C9, 0xF99E,0x689F, 0xF99F,0x6D8D, 0xF9A0,0x6DC6, 0xF9A1,0x723B,\r\n 0xF9A2,0x80B4, 0xF9A3,0x9175, 0xF9A4,0x9A4D, 0xF9A5,0x4FAF, 0xF9A6,0x5019, 0xF9A7,0x539A, 0xF9A8,0x540E, 0xF9A9,0x543C,\r\n 0xF9AA,0x5589, 0xF9AB,0x55C5, 0xF9AC,0x5E3F, 0xF9AD,0x5F8C, 0xF9AE,0x673D, 0xF9AF,0x7166, 0xF9B0,0x73DD, 0xF9B1,0x9005,\r\n 0xF9B2,0x52DB, 0xF9B3,0x52F3, 0xF9B4,0x5864, 0xF9B5,0x58CE, 0xF9B6,0x7104, 0xF9B7,0x718F, 0xF9B8,0x71FB, 0xF9B9,0x85B0,\r\n 0xF9BA,0x8A13, 0xF9BB,0x6688, 0xF9BC,0x85A8, 0xF9BD,0x55A7, 0xF9BE,0x6684, 0xF9BF,0x714A, 0xF9C0,0x8431, 0xF9C1,0x5349,\r\n 0xF9C2,0x5599, 0xF9C3,0x6BC1, 0xF9C4,0x5F59, 0xF9C5,0x5FBD, 0xF9C6,0x63EE, 0xF9C7,0x6689, 0xF9C8,0x7147, 0xF9C9,0x8AF1,\r\n 0xF9CA,0x8F1D, 0xF9CB,0x9EBE, 0xF9CC,0x4F11, 0xF9CD,0x643A, 0xF9CE,0x70CB, 0xF9CF,0x7566, 0xF9D0,0x8667, 0xF9D1,0x6064,\r\n 0xF9D2,0x8B4E, 0xF9D3,0x9DF8, 0xF9D4,0x5147, 0xF9D5,0x51F6, 0xF9D6,0x5308, 0xF9D7,0x6D36, 0xF9D8,0x80F8, 0xF9D9,0x9ED1,\r\n 0xF9DA,0x6615, 0xF9DB,0x6B23, 0xF9DC,0x7098, 0xF9DD,0x75D5, 0xF9DE,0x5403, 0xF9DF,0x5C79, 0xF9E0,0x7D07, 0xF9E1,0x8A16,\r\n 0xF9E2,0x6B20, 0xF9E3,0x6B3D, 0xF9E4,0x6B46, 0xF9E5,0x5438, 0xF9E6,0x6070, 0xF9E7,0x6D3D, 0xF9E8,0x7FD5, 0xF9E9,0x8208,\r\n 0xF9EA,0x50D6, 0xF9EB,0x51DE, 0xF9EC,0x559C, 0xF9ED,0x566B, 0xF9EE,0x56CD, 0xF9EF,0x59EC, 0xF9F0,0x5B09, 0xF9F1,0x5E0C,\r\n 0xF9F2,0x6199, 0xF9F3,0x6198, 0xF9F4,0x6231, 0xF9F5,0x665E, 0xF9F6,0x66E6, 0xF9F7,0x7199, 0xF9F8,0x71B9, 0xF9F9,0x71BA,\r\n 0xF9FA,0x72A7, 0xF9FB,0x79A7, 0xF9FC,0x7A00, 0xF9FD,0x7FB2, 0xF9FE,0x8A70,\r\n])\r\n","/**\r\n * HWP 3.0 상용 조합형 → 유니코드 디코더.\r\n *\r\n * 한국어 한글은 cho/jung/jong 비트 분해로 0xAC00 한글 음절 영역에 직접 매핑되고,\r\n * 한자/기호 등 그 외 영역은 johab-symbols.ts 의 lookup table 로 처리한다.\r\n * 매핑되지 않는 코드는 '?' 로 fallback 한다.\r\n *\r\n * 출처: rhwp/src/parser/hwp3/johab.rs (Apache-2.0). 알고리즘 동일.\r\n */\r\n\r\nimport { JOHAB_SYMBOLS } from \"./johab-symbols.js\"\r\n\r\n// 인덱스 → 자모 위치. -1 은 invalid (KS X 1001 johab 정의).\r\nconst CHO_MAP: ReadonlyArray<number> = Object.freeze([\r\n -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,\r\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n])\r\nconst JUNG_MAP: ReadonlyArray<number> = Object.freeze([\r\n -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, 5, 6, 7, 8, 9, 10, -1, -1, 11, 12, 13, 14,\r\n 15, 16, -1, -1, 17, 18, 19, 20, -1, -1,\r\n])\r\nconst JONG_MAP: ReadonlyArray<number> = Object.freeze([\r\n -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19,\r\n 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,\r\n])\r\n\r\n/** JOHAB_SYMBOLS flat array (key,val,key,val…) 에서 key 이진 탐색. */\r\nfunction lookupSymbol(ch: number): number | null {\r\n let lo = 0\r\n let hi = JOHAB_SYMBOLS.length / 2 - 1\r\n while (lo <= hi) {\r\n const mid = (lo + hi) >>> 1\r\n const k = JOHAB_SYMBOLS[mid * 2]\r\n if (k === ch) return JOHAB_SYMBOLS[mid * 2 + 1]\r\n if (k < ch) lo = mid + 1\r\n else hi = mid - 1\r\n }\r\n return null\r\n}\r\n\r\n/** 매핑 실패를 명확히 알리기 위한 sentinel. 호출자가 string 에 추가하지 않도록 skip. */\r\nexport const JOHAB_UNMAPPED = -1\r\n\r\n/**\r\n * HWP3 hchar (u16) → 유니코드 코드포인트. 매핑 실패 시 JOHAB_UNMAPPED.\r\n *\r\n * 매핑 실패 케이스를 '?' 로 fallback 시키면 검색 인덱스에 noise 가 누적된다 (특히\r\n * 메타 컨트롤이 가득한 paragraph 가 ??? 시퀀스를 생산). 호출자가 unmapped 를\r\n * 식별해서 silently skip 할 수 있도록 sentinel 을 반환한다.\r\n */\r\nexport function decodeJohab(ch: number): number {\r\n // ASCII 영역 — 1바이트 직접 사용\r\n if (ch < 0x80) return ch\r\n\r\n // 조합형 한글 (상위 비트 1): cho 5b | jung 5b | jong 5b\r\n if (ch >= 0x8000) {\r\n const choIdx = (ch >> 10) & 0x1f\r\n const jungIdx = (ch >> 5) & 0x1f\r\n const jongIdx = ch & 0x1f\r\n\r\n const cho = CHO_MAP[choIdx]\r\n const jung = JUNG_MAP[jungIdx]\r\n let jong = JONG_MAP[jongIdx]\r\n\r\n if (cho !== -1 && jung !== -1) {\r\n if (jong === -1) jong = 0\r\n // 0xAC00 + (cho * 21 * 28) + (jung * 28) + jong\r\n return 0xac00 + cho * 588 + jung * 28 + jong\r\n }\r\n\r\n // 한자/기호: lookup table\r\n const hit = lookupSymbol(ch)\r\n if (hit !== null) return hit\r\n }\r\n\r\n return JOHAB_UNMAPPED\r\n}\r\n\r\n/**\r\n * HWP3 hchar stream (u16 LE 순서) 를 string 으로 디코딩.\r\n *\r\n * DocSummary 의 56 hchar (112 byte) 영역에 사용. 본문 char stream 과 같은 단위인데\r\n * 그 영역은 ASCII 도 high byte 0 으로 padding 되어 있다 (\"C\\x00r\\x00...\"). byte 단위\r\n * 디코딩으로 처리하면 NUL 에서 break 되어 첫 글자만 남으므로, hchar 단위 LE u16 로\r\n * 읽고 그 값이 0 이면 종료한다.\r\n */\r\nexport function decodeHcharString(bytes: Uint8Array): string {\r\n let out = \"\"\r\n let i = 0\r\n while (i + 1 < bytes.length) {\r\n const ch = bytes[i] | (bytes[i + 1] << 8) // LE u16\r\n if (ch === 0) break\r\n const cp = decodeJohab(ch)\r\n if (cp !== JOHAB_UNMAPPED) out += String.fromCodePoint(cp)\r\n i += 2\r\n }\r\n return out\r\n}\r\n\r\n/**\r\n * HWP3 byte sequence (1바이트 ASCII < 0x80, 2바이트 johab >= 0x80) 를 string 으로 디코딩.\r\n * NUL byte 만나면 종료. link_print_file/description 같은 짧은 byte string 영역에 사용.\r\n */\r\nexport function decodeHwp3String(bytes: Uint8Array): string {\r\n let out = \"\"\r\n let i = 0\r\n while (i < bytes.length) {\r\n const b1 = bytes[i]\r\n if (b1 === 0) break\r\n if (b1 < 0x80) {\r\n out += String.fromCharCode(b1)\r\n i += 1\r\n } else if (i + 1 < bytes.length) {\r\n const ch = (b1 << 8) | bytes[i + 1]\r\n const cp = decodeJohab(ch)\r\n if (cp !== JOHAB_UNMAPPED) out += String.fromCodePoint(cp)\r\n i += 2\r\n } else {\r\n i += 1\r\n }\r\n }\r\n return out\r\n}\r\n","/**\r\n * HWP3 binary stream reader.\r\n * Buffer 기반 cursor 로 little-endian primitive 를 순차 read 한다.\r\n * 부족한 데이터에선 InsufficientData 를 throw 해서 상위 try/catch 가 partial-parse 모드로 전환할 수 있게 한다.\r\n */\r\n\r\nexport class InsufficientDataError extends Error {\r\n constructor(public requested: number, public available: number) {\r\n super(`HWP3: insufficient data (need ${requested}, have ${available})`)\r\n this.name = \"InsufficientDataError\"\r\n }\r\n}\r\n\r\nexport class Reader {\r\n private pos: number\r\n\r\n constructor(private readonly buf: Buffer, start = 0) {\r\n this.pos = start\r\n }\r\n\r\n position(): number {\r\n return this.pos\r\n }\r\n\r\n remaining(): number {\r\n return this.buf.length - this.pos\r\n }\r\n\r\n eof(): boolean {\r\n return this.pos >= this.buf.length\r\n }\r\n\r\n skip(n: number): void {\r\n this.ensure(n)\r\n this.pos += n\r\n }\r\n\r\n private ensure(n: number) {\r\n if (this.pos + n > this.buf.length) {\r\n throw new InsufficientDataError(n, this.buf.length - this.pos)\r\n }\r\n }\r\n\r\n readU8(): number {\r\n this.ensure(1)\r\n const v = this.buf[this.pos]\r\n this.pos += 1\r\n return v\r\n }\r\n\r\n readU16(): number {\r\n this.ensure(2)\r\n const v = this.buf.readUInt16LE(this.pos)\r\n this.pos += 2\r\n return v\r\n }\r\n\r\n readU32(): number {\r\n this.ensure(4)\r\n const v = this.buf.readUInt32LE(this.pos)\r\n this.pos += 4\r\n return v\r\n }\r\n\r\n readBytes(n: number): Buffer {\r\n this.ensure(n)\r\n const slice = this.buf.subarray(this.pos, this.pos + n)\r\n this.pos += n\r\n return slice\r\n }\r\n\r\n /** 남은 모든 바이트를 새 Buffer 로 반환 (커서를 끝으로 이동). */\r\n readToEnd(): Buffer {\r\n const slice = this.buf.subarray(this.pos)\r\n this.pos = this.buf.length\r\n return slice\r\n }\r\n}\r\n","/**\r\n * HWP3 fixed-size record definitions.\r\n *\r\n * 모두 little-endian. 구조는 rhwp/src/parser/hwp3/records.rs 와 1:1 대응.\r\n * 텍스트 추출에 필요한 필드만 명시적으로 노출하고, 레이아웃 전용 필드 (margins,\r\n * tab stops 등) 는 단순 skip 한다.\r\n */\r\n\r\nimport { Reader } from \"./reader.js\"\r\nimport { decodeHcharString } from \"./johab.js\"\r\n\r\n// HWP3 file signature: \"HWP Document File V3.00 \" (24 bytes) + 6-byte tail (\\x1A\\x01\\x02\\x03\\x04\\x05)\r\n// 총 30 byte. 일부 실제 파일은 첫 30 byte 이내에 NUL pad 가 끼어있는 경우가 있어\r\n// 앞 23 byte 의 ASCII signature 만 strict 비교하고 나머지 7 byte 는 advisory.\r\nexport const SIGNATURE_PREFIX = Buffer.from(\"HWP Document File V3.00\", \"ascii\")\r\nexport const SIGNATURE_LEN = 30\r\n\r\n/** rhwp 와 같은 고정 byte size. cursor 가 정확히 이 만큼 advance 한다. */\r\nexport const DOC_INFO_SIZE = 128\r\nexport const DOC_SUMMARY_SIZE = 9 * 112 // 9 fields × 112 bytes (56 hchar each)\r\n\r\nexport interface Hwp3Header {\r\n /** DocInfo의 압축 플래그 (0이 아니면 InfoBlock 이후 raw deflate 압축). */\r\n compressed: number\r\n /** DocInfo 의 encrypted 플래그 (0 이 아니면 본문 암호화 → 복호화 못함). */\r\n encrypted: number\r\n /** InfoBlock 길이 (DocSummary 뒤 가변 길이 metadata). */\r\n infoBlockLength: number\r\n /** DocSummary 에서 추출한 메타데이터. */\r\n title: string\r\n subject: string\r\n author: string\r\n date: string\r\n}\r\n\r\n/**\r\n * 헤더 파싱: 30 byte signature + 128 byte DocInfo + 1008 byte DocSummary.\r\n * 호출 시 reader 위치는 0 이어야 하고, 반환 후엔 InfoBlock 시작점.\r\n */\r\nexport function readHeader(reader: Reader): Hwp3Header {\r\n // signature 30 byte — strict prefix check\r\n const sig = reader.readBytes(SIGNATURE_LEN)\r\n if (!sig.subarray(0, SIGNATURE_PREFIX.length).equals(SIGNATURE_PREFIX)) {\r\n throw new Error(\"HWP3: invalid file signature\")\r\n }\r\n\r\n // DocInfo 128 byte — 텍스트 추출에 필요한 3개 필드 외엔 skip.\r\n // 절대 offset 기준 (DocInfo 시작점 = docInfoStart):\r\n // encrypted : offset 96..97 (u16) — 0 이 아니면 본문 암호 보호\r\n // compressed : offset 124 (u8) — 0 이 아니면 InfoBlock 이후 raw deflate\r\n // info_block_length : offset 126..127 (u16) — 가변 InfoBlock 길이\r\n const docInfoStart = reader.position()\r\n reader.skip(96)\r\n const encrypted = reader.readU16() // 96..97\r\n reader.skip(124 - 98) // → 124\r\n const compressed = reader.readU8() // 124\r\n reader.skip(1) // sub_revision (125)\r\n const infoBlockLength = reader.readU16() // 126..127\r\n // DocInfo 끝까지 정확히 advance — sanity\r\n if (reader.position() !== docInfoStart + DOC_INFO_SIZE) {\r\n throw new Error(\r\n `HWP3: DocInfo size mismatch (got ${reader.position() - docInfoStart}, expected ${DOC_INFO_SIZE})`,\r\n )\r\n }\r\n\r\n // DocSummary 1008 byte — title/subject/author/date 만 추출, 나머지 (keywords, etc) skip.\r\n // DocSummary 의 string 은 56 hchar × 2 byte 로 구성 — byte 단위가 아닌 u16 hchar 단위로\r\n // 디코딩해야 ASCII 문자가 high byte 0 padding 으로 인해 잘리지 않는다.\r\n const summaryStart = reader.position()\r\n const title = decodeHcharString(reader.readBytes(112))\r\n const subject = decodeHcharString(reader.readBytes(112))\r\n const author = decodeHcharString(reader.readBytes(112))\r\n const date = decodeHcharString(reader.readBytes(112))\r\n // 나머지 (keywords ×2 + etc ×3 = 5 × 112 = 560 byte) skip\r\n reader.skip(5 * 112)\r\n if (reader.position() !== summaryStart + DOC_SUMMARY_SIZE) {\r\n throw new Error(\"HWP3: DocSummary size mismatch\")\r\n }\r\n\r\n return { compressed, encrypted, infoBlockLength, title, subject, author, date }\r\n}\r\n","/**\n * HWP 5.x 배포용 문서 \"상위 버전\" 경고 플레이스홀더 감지.\n *\n * 배포용(열람 제한) HWP 파일은 본문을 암호화하고, 복호화 실패 시 한컴에서 삽입한\n * 고정 경고 문자열이 노출된다. 이 문자열이 파싱 결과의 대부분을 차지하면 COM API\n * fallback으로 전환해야 한다.\n *\n * 이슈 #25 참고.\n */\n\n// 배포용 HWP의 고정 경고 문구 (버전·지역에 따라 미세 차이 가능 → 핵심 키만 매칭)\nconst SENTINEL_PATTERNS: RegExp[] = [\n /상위\\s*버전의\\s*배포용\\s*문서/,\n /최신\\s*버전의\\s*한글.*뷰어/,\n /문서를\\s*읽으려면/,\n]\n\n/**\n * 본문이 배포용 플레이스홀더로만 채워졌는지 판정.\n *\n * 기준:\n * - 패턴이 한 번 이상 매치\n * - 패턴을 제거한 나머지 의미 있는 텍스트가 매우 짧음 (공백·개행 제외 120자 미만)\n *\n * → 정상 본문이 섞여 있으면 false (COM fallback 불필요)\n */\nexport function isDistributionSentinel(markdown: string): boolean {\n if (!markdown) return false\n const hit = SENTINEL_PATTERNS.some(p => p.test(markdown))\n if (!hit) return false\n\n // 경고 문구 라인 제거 후 실질 내용이 짧은지\n const stripped = markdown\n .split(/\\r?\\n/)\n .filter(line => !SENTINEL_PATTERNS.some(p => p.test(line)))\n .join(\"\")\n .replace(/\\s+/g, \"\")\n\n return stripped.length < 120\n}\n","/**\n * XLSX (Office Open XML Spreadsheet) 파서\n *\n * ZIP + XML 구조를 jszip + xmldom으로 파싱하여 IRBlock[]로 변환.\n * 각 시트 → heading(시트명) + table(데이터) 블록.\n */\n\nimport JSZip from \"jszip\"\nimport { DOMParser } from \"@xmldom/xmldom\"\nimport type {\n IRBlock, IRTable, IRCell, CellContext, DocumentMetadata, InternalParseResult,\n ParseOptions, ParseWarning, ExtractedImage,\n} from \"../types.js\"\nimport { KordocError, precheckZipSize, stripDtd } from \"../utils.js\"\nimport { buildTable, blocksToMarkdown } from \"../table/builder.js\"\n\n// ─── 상수 ────────────────────────────────────────────\n\nconst MAX_SHEETS = 100\n/** ZIP 압축 해제 누적 최대 크기 (100MB) — ZIP bomb 방지 */\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\nconst MAX_ROWS = 10000\nconst MAX_COLS = 200\n\n// ─── 숫자값 정리 ──────────────────────────────────────\n\n/** 부동소수점 아티팩트 정리 (132.30000000000001 → 132.3) */\nfunction cleanNumericValue(raw: string): string {\n if (!/^-?\\d+\\.\\d+$/.test(raw)) return raw\n const num = parseFloat(raw)\n if (!isFinite(num)) return raw\n // toPrecision(15)로 IEEE 754 오차 제거 후 불필요한 후행 0 제거\n const cleaned = parseFloat(num.toPrecision(15)).toString()\n return cleaned\n}\n\n// ─── 셀 참조 파싱 ──────────────────────────────────────\n\n/** \"A1\" → { col: 0, row: 0 }, \"AB123\" → { col: 27, row: 122 } */\nfunction parseCellRef(ref: string): { col: number; row: number } | null {\n const m = ref.match(/^([A-Z]+)(\\d+)$/)\n if (!m) return null\n let col = 0\n for (const ch of m[1]) col = col * 26 + (ch.charCodeAt(0) - 64)\n return { col: col - 1, row: parseInt(m[2], 10) - 1 }\n}\n\n/** \"A1:C3\" → { startCol, startRow, endCol, endRow } */\nfunction parseMergeRef(ref: string): { startCol: number; startRow: number; endCol: number; endRow: number } | null {\n const parts = ref.split(\":\")\n if (parts.length !== 2) return null\n const start = parseCellRef(parts[0])\n const end = parseCellRef(parts[1])\n if (!start || !end) return null\n return { startCol: start.col, startRow: start.row, endCol: end.col, endRow: end.row }\n}\n\n// ─── XML 헬퍼 ──────────────────────────────────────────\n\nfunction getElements(parent: Element, tagName: string): Element[] {\n const nodes = parent.getElementsByTagName(tagName)\n const result: Element[] = []\n for (let i = 0; i < nodes.length; i++) result.push(nodes[i] as Element)\n return result\n}\n\nfunction getTextContent(el: Element): string {\n return el.textContent?.trim() ?? \"\"\n}\n\nfunction parseXml(text: string): Document {\n return new DOMParser().parseFromString(stripDtd(text), \"text/xml\")\n}\n\n// ─── 공유 문자열 파싱 ──────────────────────────────────\n\nfunction parseSharedStrings(xml: string): string[] {\n const doc = parseXml(xml)\n const strings: string[] = []\n const siList = getElements(doc.documentElement, \"si\")\n for (const si of siList) {\n // <si><t>text</t></si> 또는 <si><r><t>text</t></r>...</si>\n const tElements = getElements(si, \"t\")\n strings.push(tElements.map(t => t.textContent ?? \"\").join(\"\"))\n }\n return strings\n}\n\n// ─── 시트 목록 파싱 ─────────────────────────────────────\n\ninterface SheetInfo {\n name: string\n sheetId: string\n rId: string\n}\n\nfunction parseWorkbook(xml: string): SheetInfo[] {\n const doc = parseXml(xml)\n const sheets: SheetInfo[] = []\n const sheetElements = getElements(doc.documentElement, \"sheet\")\n for (const el of sheetElements) {\n sheets.push({\n name: el.getAttribute(\"name\") ?? `Sheet${sheets.length + 1}`,\n sheetId: el.getAttribute(\"sheetId\") ?? \"\",\n rId: el.getAttribute(\"r:id\") ?? \"\",\n })\n }\n return sheets\n}\n\n/** workbook.xml.rels 파싱 → rId → target 매핑 */\nfunction parseRels(xml: string): Map<string, string> {\n const doc = parseXml(xml)\n const map = new Map<string, string>()\n const rels = getElements(doc.documentElement, \"Relationship\")\n for (const rel of rels) {\n const id = rel.getAttribute(\"Id\")\n const target = rel.getAttribute(\"Target\")\n if (id && target) map.set(id, target)\n }\n return map\n}\n\n// ─── 워크시트 파싱 ──────────────────────────────────────\n\ninterface MergeInfo {\n startCol: number\n startRow: number\n endCol: number\n endRow: number\n}\n\nfunction parseWorksheet(\n xml: string,\n sharedStrings: string[],\n): { grid: string[][]; merges: MergeInfo[]; maxRow: number; maxCol: number } {\n const doc = parseXml(xml)\n const grid: string[][] = []\n let maxRow = 0\n let maxCol = 0\n\n // 데이터 행 파싱\n const rows = getElements(doc.documentElement, \"row\")\n for (const rowEl of rows) {\n const rowNum = parseInt(rowEl.getAttribute(\"r\") ?? \"0\", 10) - 1\n if (rowNum < 0 || rowNum >= MAX_ROWS) continue\n\n const cells = getElements(rowEl, \"c\")\n for (const cellEl of cells) {\n const ref = cellEl.getAttribute(\"r\")\n if (!ref) continue\n const pos = parseCellRef(ref)\n if (!pos || pos.col >= MAX_COLS) continue\n\n // 값 추출\n const type = cellEl.getAttribute(\"t\")\n const vElements = getElements(cellEl, \"v\")\n const fElements = getElements(cellEl, \"f\")\n let value = \"\"\n\n if (vElements.length > 0) {\n const raw = getTextContent(vElements[0])\n if (type === \"s\") {\n // shared string\n const idx = parseInt(raw, 10)\n value = sharedStrings[idx] ?? \"\"\n } else if (type === \"b\") {\n value = raw === \"1\" ? \"TRUE\" : \"FALSE\"\n } else {\n // 숫자값 부동소수점 아티팩트 정리 (9895607.8000000007 → 9895607.8)\n value = cleanNumericValue(raw)\n }\n } else if (type === \"inlineStr\") {\n // <is><t>text</t></is>\n const isEl = getElements(cellEl, \"is\")\n if (isEl.length > 0) {\n const tElements = getElements(isEl[0], \"t\")\n value = tElements.map(t => t.textContent ?? \"\").join(\"\")\n }\n }\n\n // 수식이 있고 값이 없으면 수식 표시\n if (!value && fElements.length > 0) {\n value = `=${getTextContent(fElements[0])}`\n }\n\n // 그리드 확장\n while (grid.length <= pos.row) grid.push([])\n while (grid[pos.row].length <= pos.col) grid[pos.row].push(\"\")\n grid[pos.row][pos.col] = value\n\n if (pos.row > maxRow) maxRow = pos.row\n if (pos.col > maxCol) maxCol = pos.col\n }\n }\n\n // 병합 셀 파싱\n const merges: MergeInfo[] = []\n const mergeCellElements = getElements(doc.documentElement, \"mergeCell\")\n for (const el of mergeCellElements) {\n const ref = el.getAttribute(\"ref\")\n if (!ref) continue\n const m = parseMergeRef(ref)\n if (m) merges.push(m)\n }\n\n return { grid, merges, maxRow, maxCol }\n}\n\n// ─── 시트 → IRBlock[] 변환 ────────────────────────────\n\nfunction sheetToBlocks(\n sheetName: string,\n grid: string[][],\n merges: MergeInfo[],\n maxRow: number,\n maxCol: number,\n sheetIndex: number,\n): IRBlock[] {\n const blocks: IRBlock[] = []\n\n // 시트명 = heading\n if (sheetName) {\n blocks.push({\n type: \"heading\",\n text: sheetName,\n level: 2,\n pageNumber: sheetIndex + 1,\n })\n }\n\n // 빈 시트\n if (maxRow < 0 || maxCol < 0 || grid.length === 0) return blocks\n\n // 병합 맵: \"row,col\" → { colSpan, rowSpan }\n const mergeMap = new Map<string, { colSpan: number; rowSpan: number }>()\n const mergeSkip = new Set<string>()\n for (const m of merges) {\n const colSpan = m.endCol - m.startCol + 1\n const rowSpan = m.endRow - m.startRow + 1\n mergeMap.set(`${m.startRow},${m.startCol}`, { colSpan, rowSpan })\n for (let r = m.startRow; r <= m.endRow; r++) {\n for (let c = m.startCol; c <= m.endCol; c++) {\n if (r !== m.startRow || c !== m.startCol) {\n mergeSkip.add(`${r},${c}`)\n }\n }\n }\n }\n\n // 유효 행 범위 감지 (앞뒤 빈 행 제거)\n let firstRow = -1\n let lastRow = -1\n for (let r = 0; r <= maxRow; r++) {\n const row = grid[r]\n if (row && row.some(cell => cell !== \"\")) {\n if (firstRow === -1) firstRow = r\n lastRow = r\n }\n }\n if (firstRow === -1) return blocks\n\n // CellContext[][] → buildTable로 IRTable 생성 (2-pass 알고리즘 재사용)\n const cellRows: CellContext[][] = []\n\n for (let r = firstRow; r <= lastRow; r++) {\n const row: CellContext[] = []\n for (let c = 0; c <= maxCol; c++) {\n const key = `${r},${c}`\n if (mergeSkip.has(key)) continue\n\n const text = (grid[r] && grid[r][c]) ?? \"\"\n const merge = mergeMap.get(key)\n row.push({\n text,\n colSpan: merge?.colSpan ?? 1,\n rowSpan: merge?.rowSpan ?? 1,\n })\n }\n cellRows.push(row)\n }\n\n if (cellRows.length > 0) {\n const table = buildTable(cellRows)\n if (table.rows > 0) {\n blocks.push({ type: \"table\", table, pageNumber: sheetIndex + 1 })\n }\n }\n\n return blocks\n}\n\n// ─── 메인 파서 ─────────────────────────────────────────\n\nexport async function parseXlsxDocument(\n buffer: ArrayBuffer,\n options?: ParseOptions,\n): Promise<InternalParseResult> {\n // ZIP bomb 사전 검사\n precheckZipSize(buffer, MAX_DECOMPRESS_SIZE)\n\n const zip = await JSZip.loadAsync(buffer)\n const warnings: ParseWarning[] = []\n\n // XLSX 구조 검증\n const workbookFile = zip.file(\"xl/workbook.xml\")\n if (!workbookFile) {\n throw new KordocError(\"유효하지 않은 XLSX 파일: xl/workbook.xml이 없습니다\")\n }\n\n // 1. 공유 문자열 로드\n let sharedStrings: string[] = []\n const ssFile = zip.file(\"xl/sharedStrings.xml\")\n if (ssFile) {\n sharedStrings = parseSharedStrings(await ssFile.async(\"text\"))\n }\n\n // 2. 시트 목록 로드\n const sheets = parseWorkbook(await workbookFile.async(\"text\"))\n if (sheets.length === 0) {\n throw new KordocError(\"XLSX 파일에 시트가 없습니다\")\n }\n\n // 3. 관계 매핑 (rId → 파일 경로)\n let relsMap = new Map<string, string>()\n const relsFile = zip.file(\"xl/_rels/workbook.xml.rels\")\n if (relsFile) {\n relsMap = parseRels(await relsFile.async(\"text\"))\n }\n\n // 4. 페이지 필터\n let pageFilter: Set<number> | null = null\n if (options?.pages) {\n const { parsePageRange } = await import(\"../page-range.js\")\n pageFilter = parsePageRange(options.pages, sheets.length)\n }\n\n // 5. 각 시트 파싱\n const blocks: IRBlock[] = []\n const processedSheets = Math.min(sheets.length, MAX_SHEETS)\n\n for (let i = 0; i < processedSheets; i++) {\n if (pageFilter && !pageFilter.has(i + 1)) continue\n\n const sheet = sheets[i]\n options?.onProgress?.(i + 1, processedSheets)\n\n // 시트 파일 경로 결정\n let sheetPath = relsMap.get(sheet.rId)\n if (sheetPath) {\n // 상대 경로 → 절대 경로\n if (!sheetPath.startsWith(\"xl/\") && !sheetPath.startsWith(\"/\")) {\n sheetPath = `xl/${sheetPath}`\n } else if (sheetPath.startsWith(\"/\")) {\n sheetPath = sheetPath.slice(1)\n }\n } else {\n sheetPath = `xl/worksheets/sheet${i + 1}.xml`\n }\n\n const sheetFile = zip.file(sheetPath)\n if (!sheetFile) {\n warnings.push({\n page: i + 1,\n message: `시트 \"${sheet.name}\" 파일을 찾을 수 없습니다: ${sheetPath}`,\n code: \"PARTIAL_PARSE\",\n })\n continue\n }\n\n try {\n const sheetXml = await sheetFile.async(\"text\")\n const { grid, merges, maxRow, maxCol } = parseWorksheet(sheetXml, sharedStrings)\n const sheetBlocks = sheetToBlocks(sheet.name, grid, merges, maxRow, maxCol, i)\n blocks.push(...sheetBlocks)\n } catch (err) {\n warnings.push({\n page: i + 1,\n message: `시트 \"${sheet.name}\" 파싱 실패: ${err instanceof Error ? err.message : \"알 수 없는 오류\"}`,\n code: \"PARTIAL_PARSE\",\n })\n }\n }\n\n // 6. 메타데이터 추출\n const metadata: DocumentMetadata = {\n pageCount: processedSheets,\n }\n const coreFile = zip.file(\"docProps/core.xml\")\n if (coreFile) {\n try {\n const coreXml = await coreFile.async(\"text\")\n const doc = parseXml(coreXml)\n const getFirst = (tag: string) => {\n const els = doc.getElementsByTagName(tag)\n return els.length > 0 ? (els[0].textContent ?? \"\").trim() : undefined\n }\n metadata.title = getFirst(\"dc:title\") || getFirst(\"dcterms:title\")\n metadata.author = getFirst(\"dc:creator\")\n metadata.description = getFirst(\"dc:description\")\n const created = getFirst(\"dcterms:created\")\n if (created) metadata.createdAt = created\n const modified = getFirst(\"dcterms:modified\")\n if (modified) metadata.modifiedAt = modified\n } catch { /* 메타데이터 실패는 무시 */ }\n }\n\n const markdown = blocksToMarkdown(blocks)\n\n return { markdown, blocks, metadata, warnings: warnings.length > 0 ? warnings : undefined }\n}\n","/**\r\n * BIFF8 (Excel 97-2003) 레코드 리더.\r\n *\r\n * Workbook 스트림(OLE2 → cfb-lenient로 추출)에서 4바이트 헤더(opcode u16 + length u16)\r\n * 기반 레코드를 순차 읽어들인다. 길이가 8224를 초과하는 데이터는 직후 CONTINUE\r\n * 레코드로 분할되며, 본 모듈은 호출자가 원할 때 자동 결합 옵션을 제공한다.\r\n *\r\n * 참조: docs/biff8-spec.md §2~§3, [MS-XLS] §2.4\r\n */\r\n\r\n// ─── Opcode 상수 ─────────────────────────────────────\r\n\r\nexport const OP_BOF = 0x0809\r\nexport const OP_EOF = 0x000a\r\nexport const OP_CONTINUE = 0x003c\r\n\r\n// Globals 서브스트림\r\nexport const OP_BOUNDSHEET8 = 0x0085\r\nexport const OP_SST = 0x00fc\r\nexport const OP_EXTSST = 0x00ff\r\nexport const OP_CODEPAGE = 0x0042\r\nexport const OP_DATE1904 = 0x0022\r\nexport const OP_FILEPASS = 0x002f\r\n\r\n// Worksheet 서브스트림 — 셀\r\nexport const OP_NUMBER = 0x0203\r\nexport const OP_RK = 0x027e\r\nexport const OP_MULRK = 0x00bd\r\nexport const OP_LABELSST = 0x00fd\r\nexport const OP_LABEL = 0x0204\r\nexport const OP_FORMULA = 0x0006\r\nexport const OP_STRING = 0x0207\r\nexport const OP_BOOLERR = 0x0205\r\nexport const OP_BLANK = 0x0201\r\nexport const OP_MULBLANK = 0x00be\r\nexport const OP_MERGECELLS = 0x00e5\r\nexport const OP_ROW = 0x0208\r\n\r\n// BOF dt 필드 값\r\nexport const DT_GLOBALS = 0x0005\r\nexport const DT_WORKSHEET = 0x0010\r\nexport const DT_CHART = 0x0020\r\nexport const DT_MACRO = 0x0040\r\n\r\n// ─── 타입 ──────────────────────────────────────────\r\n\r\nexport interface BiffRecord {\r\n opcode: number\r\n /** 본 레코드의 데이터 (CONTINUE 결합 안 한 raw) */\r\n data: Buffer\r\n /** Workbook 스트림 내 절대 오프셋 (헤더 시작 위치) — BoundSheet8 lbPlyPos 매칭용 */\r\n offset: number\r\n}\r\n\r\n// ─── 리더 ──────────────────────────────────────────\r\n\r\n/** 비정상 파일에 의한 메모리 폭주 방지 */\r\nconst MAX_RECORDS = 1_000_000\r\n\r\n/**\r\n * Workbook 스트림 전체에서 BIFF 레코드를 순차 읽는다.\r\n * CONTINUE 결합은 호출자 책임 (SST 디코딩 시점에서 처리).\r\n */\r\nexport function readRecords(stream: Buffer): BiffRecord[] {\r\n const out: BiffRecord[] = []\r\n let offset = 0\r\n\r\n while (offset + 4 <= stream.length && out.length < MAX_RECORDS) {\r\n const recOffset = offset\r\n const opcode = stream.readUInt16LE(offset)\r\n const length = stream.readUInt16LE(offset + 2)\r\n offset += 4\r\n\r\n if (offset + length > stream.length) {\r\n // 잘린 레코드 — lenient: 부분 데이터로 끊고 종료\r\n const data = stream.subarray(offset, stream.length)\r\n out.push({ opcode, data, offset: recOffset })\r\n break\r\n }\r\n\r\n const data = stream.subarray(offset, offset + length)\r\n out.push({ opcode, data, offset: recOffset })\r\n offset += length\r\n }\r\n\r\n return out\r\n}\r\n\r\n/**\r\n * 특정 레코드부터 직후 연속된 CONTINUE 레코드 데이터를 결합.\r\n * SST처럼 8224바이트를 초과해 분할되는 레코드 처리용.\r\n *\r\n * 반환: { combined: Buffer, segments: number[] }\r\n * - combined: 결합된 데이터\r\n * - segments: 각 CONTINUE 경계의 결합 후 오프셋 (디코딩 시 flags 재해석에 사용)\r\n */\r\nexport function combineWithContinue(\r\n records: BiffRecord[],\r\n startIndex: number,\r\n): { combined: Buffer; segments: number[]; nextIndex: number } {\r\n const first = records[startIndex]\r\n const chunks: Buffer[] = [first.data]\r\n const segments: number[] = [first.data.length] // 첫 CONTINUE 경계\r\n let i = startIndex + 1\r\n let total = first.data.length\r\n\r\n while (i < records.length && records[i].opcode === OP_CONTINUE) {\r\n chunks.push(records[i].data)\r\n total += records[i].data.length\r\n segments.push(total)\r\n i++\r\n }\r\n\r\n return {\r\n combined: Buffer.concat(chunks),\r\n segments,\r\n nextIndex: i,\r\n }\r\n}\r\n\r\n// ─── BOF 헬퍼 ──────────────────────────────────────\r\n\r\nexport interface BofInfo {\r\n vers: number\r\n /** 서브스트림 타입 (DT_*) */\r\n dt: number\r\n}\r\n\r\nexport function decodeBof(data: Buffer): BofInfo | null {\r\n if (data.length < 4) return null\r\n return {\r\n vers: data.readUInt16LE(0),\r\n dt: data.readUInt16LE(2),\r\n }\r\n}\r\n\r\n// ─── RK / MulRk 디코더 ─────────────────────────────\r\n\r\n/**\r\n * RK 32bit 압축 숫자 디코딩.\r\n *\r\n * 비트 0 (fDiv100): 1이면 결과를 100으로 나눔\r\n * 비트 1 (fInt): 1이면 정수, 0이면 double\r\n * 비트 2~31: 30비트 값\r\n *\r\n * 정수: 30비트 부호확장.\r\n * double: 30비트를 double의 상위 30비트(63..34)에 배치, 하위 34비트는 0.\r\n */\r\nexport function decodeRk(rk: number): number {\r\n const fDiv100 = (rk & 0x01) !== 0\r\n const fInt = (rk & 0x02) !== 0\r\n const val30 = rk >> 2 // signed 31-bit shift, 그러나 30bit 부호확장 별도 처리\r\n\r\n let num: number\r\n if (fInt) {\r\n // 30bit signed → 부호확장\r\n num = val30 // JS의 >> 2는 산술시프트라 부호 유지됨\r\n } else {\r\n // double 복원: 30bit가 double의 상위 30bit (63..34)\r\n // 하위 34bit는 0. JS bitwise는 32bit이므로 BigInt 사용.\r\n const high32 = (rk & 0xfffffffc) >>> 0 // 상위 30bit + 하위 2bit(0)\r\n // double 비트 패턴: high32 << 32 | 0\r\n const buf = Buffer.alloc(8)\r\n buf.writeUInt32LE(0, 0)\r\n buf.writeUInt32LE(high32, 4)\r\n num = buf.readDoubleLE(0)\r\n }\r\n\r\n return fDiv100 ? num / 100 : num\r\n}\r\n\r\nexport interface MulRkCell {\r\n col: number\r\n ixfe: number\r\n value: number\r\n}\r\n\r\n/**\r\n * MulRk 레코드 디코딩.\r\n * data 구조: [row u16][colFirst u16][rkrec_0]...[rkrec_n][colLast u16]\r\n * rkrec = [ixfe u16][rk u32] = 6바이트\r\n *\r\n * 반환: { row, cells: [{col, ixfe, value}, ...] }\r\n */\r\nexport function decodeMulRk(data: Buffer): { row: number; cells: MulRkCell[] } | null {\r\n if (data.length < 6) return null\r\n const row = data.readUInt16LE(0)\r\n const colFirst = data.readUInt16LE(2)\r\n const colLast = data.readUInt16LE(data.length - 2)\r\n const count = colLast - colFirst + 1\r\n if (count <= 0) return { row, cells: [] }\r\n\r\n const cells: MulRkCell[] = []\r\n let off = 4\r\n for (let i = 0; i < count && off + 6 <= data.length - 2; i++) {\r\n const ixfe = data.readUInt16LE(off)\r\n const rk = data.readUInt32LE(off + 2)\r\n cells.push({ col: colFirst + i, ixfe, value: decodeRk(rk) })\r\n off += 6\r\n }\r\n\r\n return { row, cells }\r\n}\r\n\r\n// ─── 일반 셀 헤더 (row, col, ixfe) ────────────────\r\n\r\nexport interface CellHeader {\r\n row: number\r\n col: number\r\n ixfe: number\r\n}\r\n\r\nexport function readCellHeader(data: Buffer): CellHeader | null {\r\n if (data.length < 6) return null\r\n return {\r\n row: data.readUInt16LE(0),\r\n col: data.readUInt16LE(2),\r\n ixfe: data.readUInt16LE(4),\r\n }\r\n}\r\n","/**\r\n * XLS 문자열 인코딩 디코더.\r\n *\r\n * BIFF8의 문자열은 다음 인코딩 중 하나:\r\n * - UTF-16LE (fHighByte=1)\r\n * - Compressed Unicode (fHighByte=0): 1바이트/문자, 상위 바이트는 0\r\n * - 구형 Label 레코드: CodePage 의존 (보통 CP949 또는 CP1200)\r\n *\r\n * 한국 공문서 .xls 우선 순위: UTF-16LE → Compressed → CP949\r\n *\r\n * 참조: docs/biff8-spec.md §3.3, §5\r\n */\r\n\r\n/**\r\n * UTF-16LE 디코딩 (Buffer.toString('utf16le')는 LE 가정으로 안전).\r\n */\r\nexport function decodeUtf16Le(buf: Buffer): string {\r\n return buf.toString(\"utf16le\")\r\n}\r\n\r\n/**\r\n * Compressed Unicode 디코딩.\r\n * 1바이트당 1문자, 각 바이트가 UTF-16 코드 포인트의 하위 바이트(상위 바이트=0).\r\n * 즉 ISO-8859-1 (Latin-1)과 동일.\r\n */\r\nexport function decodeCompressed(buf: Buffer): string {\r\n // Buffer.toString('latin1') == ISO-8859-1\r\n return buf.toString(\"latin1\")\r\n}\r\n\r\n/**\r\n * CP949 (EUC-KR 확장) 디코딩.\r\n * Node.js TextDecoder가 ICU 빌드일 때만 'euc-kr' 지원.\r\n * 미지원 환경에서는 latin1 폴백 (한글 깨짐, 영숫자만 보존).\r\n */\r\nexport function decodeCp949(buf: Buffer): string {\r\n try {\r\n // Node 18+ ICU 빌드: 'euc-kr', 'cp949' 모두 지원\r\n return new TextDecoder(\"euc-kr\", { fatal: false }).decode(buf)\r\n } catch {\r\n return buf.toString(\"latin1\")\r\n }\r\n}\r\n\r\n/**\r\n * 코드페이지 번호로 디코딩 (CodePage 레코드 0x0042 값).\r\n * 1200 = UTF-16LE\r\n * 949 = CP949\r\n * 1252 = Windows-1252\r\n * 기타 = latin1 폴백\r\n */\r\nexport function decodeByCodePage(buf: Buffer, codePage: number): string {\r\n if (codePage === 1200) return decodeUtf16Le(buf)\r\n if (codePage === 949) return decodeCp949(buf)\r\n if (codePage === 1252 || codePage === 65001) {\r\n try {\r\n return new TextDecoder(codePage === 65001 ? \"utf-8\" : \"windows-1252\", {\r\n fatal: false,\r\n }).decode(buf)\r\n } catch {\r\n return buf.toString(\"latin1\")\r\n }\r\n }\r\n return buf.toString(\"latin1\")\r\n}\r\n","/**\r\n * BIFF8 Shared String Table 디코더.\r\n *\r\n * SST 레코드(0x00FC)는 데이터가 8224B를 초과하면 직후 CONTINUE(0x003C) 레코드로 분할됨.\r\n * 단순히 데이터를 이어붙이는 게 아니라, **각 CONTINUE 경계의 첫 바이트는 새 flags\r\n * 바이트로 재해석**해야 한다 (MS-XLS §2.4.265 ~ §2.4.272).\r\n *\r\n * 본 모듈은 SST + 후속 CONTINUE를 통합 버퍼로 만든 후, segments 경계를 활용해\r\n * XLUnicodeRichExtendedString을 순차 디코딩한다.\r\n *\r\n * 참조: docs/biff8-spec.md §3.3\r\n */\r\n\r\nimport { decodeCompressed, decodeUtf16Le } from \"./encoding.js\"\r\nimport { combineWithContinue, type BiffRecord, OP_SST } from \"./record.js\"\r\n\r\ninterface ParseStringResult {\r\n text: string\r\n consumed: number\r\n}\r\n\r\n/**\r\n * 단일 XLUnicodeRichExtendedString 디코딩.\r\n *\r\n * 구조 (가변):\r\n * cch u16 문자 수\r\n * flags u8 bit 0 fHighByte (1=UTF-16LE, 0=compressed)\r\n * bit 2 fExtSt\r\n * bit 3 fRichSt\r\n * [cRun u16] rich text run 수 (fRichSt=1일 때만)\r\n * [cbExtRst u32] 확장 데이터 길이 (fExtSt=1일 때만)\r\n * rgb 가변 문자 데이터 (compressed: cch바이트, uncompressed: 2*cch바이트)\r\n * [richRuns 4*cRun] (fRichSt=1)\r\n * [extRst cbExtRst] (fExtSt=1)\r\n *\r\n * **CONTINUE 경계 처리**: 본 함수는 segments 정보를 받아 문자 데이터(rgb)가 경계를\r\n * 가로지르면 경계 직후 1바이트(새 flags)를 스킵하고 인코딩이 바뀌면 재해석한다.\r\n */\r\nfunction parseString(\r\n buf: Buffer,\r\n offset: number,\r\n segments: number[],\r\n): ParseStringResult | null {\r\n if (offset + 3 > buf.length) return null\r\n\r\n const cch = buf.readUInt16LE(offset)\r\n let flags = buf.readUInt8(offset + 2)\r\n let off = offset + 3\r\n\r\n let highByte = (flags & 0x01) !== 0\r\n const extSt = (flags & 0x04) !== 0\r\n const richSt = (flags & 0x08) !== 0\r\n\r\n let cRun = 0\r\n let cbExtRst = 0\r\n if (richSt) {\r\n if (off + 2 > buf.length) return null\r\n cRun = buf.readUInt16LE(off)\r\n off += 2\r\n }\r\n if (extSt) {\r\n if (off + 4 > buf.length) return null\r\n cbExtRst = buf.readUInt32LE(off)\r\n off += 4\r\n }\r\n\r\n // 문자 데이터 읽기 — CONTINUE 경계마다 새 flags 재해석\r\n // segments는 결합 버퍼 기준 경계 오프셋들. 첫 segment는 SST의 끝, 그 다음부터 CONTINUE 경계.\r\n const charBytes: Buffer[] = []\r\n let charsRead = 0\r\n\r\n while (charsRead < cch) {\r\n // 다음 경계 찾기\r\n const nextBoundary = segments.find(s => s > off) ?? buf.length\r\n\r\n const remainChars = cch - charsRead\r\n const bytesPerChar = highByte ? 2 : 1\r\n const bytesAvail = nextBoundary - off\r\n const charsInThisRun = Math.min(remainChars, Math.floor(bytesAvail / bytesPerChar))\r\n const bytesToRead = charsInThisRun * bytesPerChar\r\n\r\n if (bytesToRead > 0) {\r\n const slice = buf.subarray(off, off + bytesToRead)\r\n // highByte=0 (compressed) 처리: utf16le 통일을 위해 0x00 패딩 후 합칠 수도 있으나\r\n // 디코딩은 latin1로 따로 처리 후 string concat이 명확.\r\n charBytes.push(highByte ? slice : padToUtf16(slice))\r\n off += bytesToRead\r\n charsRead += charsInThisRun\r\n }\r\n\r\n if (charsRead < cch) {\r\n // 경계 진입 — 새 flags 1바이트\r\n if (off >= buf.length) return null\r\n flags = buf.readUInt8(off)\r\n highByte = (flags & 0x01) !== 0\r\n off += 1\r\n }\r\n }\r\n\r\n // 모든 charBytes는 utf16le로 통일된 상태 → 합쳐서 디코딩\r\n const text = decodeUtf16Le(Buffer.concat(charBytes))\r\n\r\n // rich runs 스킵\r\n if (richSt) off += 4 * cRun\r\n // extRst 스킵\r\n if (extSt) off += cbExtRst\r\n\r\n // 안전장치: 경계 넘침 방지\r\n if (off > buf.length) off = buf.length\r\n\r\n return { text, consumed: off - offset }\r\n}\r\n\r\n/** compressed (1바이트/문자) → utf16le (2바이트/문자) 패딩. */\r\nfunction padToUtf16(compressed: Buffer): Buffer {\r\n const out = Buffer.alloc(compressed.length * 2)\r\n for (let i = 0; i < compressed.length; i++) {\r\n out[i * 2] = compressed[i]\r\n out[i * 2 + 1] = 0\r\n }\r\n return out\r\n}\r\n\r\n/**\r\n * 레코드 배열에서 SST를 찾아 디코딩한다.\r\n * SST가 없으면 빈 배열 반환.\r\n */\r\nexport function decodeSST(records: BiffRecord[]): string[] {\r\n const sstIndex = records.findIndex(r => r.opcode === OP_SST)\r\n if (sstIndex < 0) return []\r\n\r\n const { combined, segments } = combineWithContinue(records, sstIndex)\r\n if (combined.length < 8) return []\r\n\r\n // const cstTotal = combined.readUInt32LE(0) // 참조 횟수 (사용 안 함)\r\n const cstUnique = combined.readUInt32LE(4)\r\n\r\n const strings: string[] = []\r\n let off = 8\r\n for (let i = 0; i < cstUnique && off < combined.length; i++) {\r\n const r = parseString(combined, off, segments)\r\n if (!r) break\r\n strings.push(r.text)\r\n off += r.consumed\r\n }\r\n\r\n return strings\r\n}\r\n\r\n// _ unused export silencer\r\nvoid decodeCompressed\r\n","/**\r\n * BIFF8 Worksheet 서브스트림의 셀 레코드 → RawCell 변환.\r\n *\r\n * 처리 대상: Number, RK, MulRk, LabelSst, BoolErr, Formula(+String), Label, Blank, MulBlank, MergeCells\r\n * 무시: Row 메타, GUTS, Header/Footer, Window 등\r\n *\r\n * 참조: docs/biff8-spec.md §3.4, §3.5\r\n */\r\n\r\nimport {\r\n OP_NUMBER,\r\n OP_RK,\r\n OP_MULRK,\r\n OP_LABELSST,\r\n OP_LABEL,\r\n OP_FORMULA,\r\n OP_STRING,\r\n OP_BOOLERR,\r\n OP_BLANK,\r\n OP_MULBLANK,\r\n OP_MERGECELLS,\r\n OP_BOF,\r\n OP_EOF,\r\n decodeMulRk,\r\n decodeRk,\r\n readCellHeader,\r\n type BiffRecord,\r\n} from \"./record.js\"\r\nimport { decodeUtf16Le } from \"./encoding.js\"\r\n\r\nexport type CellValue = string | number | boolean | null\r\n\r\nexport interface RawCell {\r\n row: number\r\n col: number\r\n value: CellValue\r\n}\r\n\r\nexport interface MergeRange {\r\n r1: number\r\n c1: number\r\n r2: number\r\n c2: number\r\n}\r\n\r\nexport interface RawSheet {\r\n /** 시트 시작 BOF의 절대 오프셋 */\r\n bofOffset: number\r\n cells: RawCell[]\r\n merges: MergeRange[]\r\n}\r\n\r\n/** BIFF8 표준 에러 코드 → 표시 문자열 */\r\nfunction errorCodeToText(code: number): string {\r\n switch (code) {\r\n case 0x00:\r\n return \"#NULL!\"\r\n case 0x07:\r\n return \"#DIV/0!\"\r\n case 0x0f:\r\n return \"#VALUE!\"\r\n case 0x17:\r\n return \"#REF!\"\r\n case 0x1d:\r\n return \"#NAME?\"\r\n case 0x24:\r\n return \"#NUM!\"\r\n case 0x2a:\r\n return \"#N/A\"\r\n default:\r\n return `#ERR${code}`\r\n }\r\n}\r\n\r\n/**\r\n * BIFF8 Label 레코드의 단순 문자열 디코딩.\r\n * 구조: row(2) col(2) ixfe(2) cch(2) flags(1) rgb(...)\r\n * - flags bit 0: 1=UTF-16LE, 0=compressed\r\n */\r\nfunction decodeLabelString(data: Buffer): string {\r\n if (data.length < 9) return \"\"\r\n const cch = data.readUInt16LE(6)\r\n const flags = data.readUInt8(8)\r\n const highByte = (flags & 0x01) !== 0\r\n const start = 9\r\n\r\n if (highByte) {\r\n const end = Math.min(start + cch * 2, data.length)\r\n return decodeUtf16Le(data.subarray(start, end))\r\n } else {\r\n const end = Math.min(start + cch, data.length)\r\n // compressed → utf16 패딩 후 디코딩\r\n const slice = data.subarray(start, end)\r\n const padded = Buffer.alloc(slice.length * 2)\r\n for (let i = 0; i < slice.length; i++) padded[i * 2] = slice[i]\r\n return decodeUtf16Le(padded)\r\n }\r\n}\r\n\r\n/**\r\n * Formula 레코드의 결과값 디코딩.\r\n * val 8바이트:\r\n * val[6..8] == 0xFFFF 이고:\r\n * val[0]=0x00: 결과가 문자열 → 직후 String 레코드 참조\r\n * val[0]=0x01: boolean → val[2] (0/1)\r\n * val[0]=0x02: error → val[2]\r\n * val[0]=0x03: empty\r\n * 그 외: double로 해석\r\n *\r\n * 반환:\r\n * - 문자열 결과 신호: { kind: 'stringRef' }\r\n * - 그 외: { kind: 'value', value: ... }\r\n */\r\ntype FormulaResult =\r\n | { kind: \"stringRef\" }\r\n | { kind: \"value\"; value: CellValue }\r\n\r\nfunction decodeFormulaResult(val: Buffer): FormulaResult {\r\n if (val.length < 8) return { kind: \"value\", value: null }\r\n const tail = val.readUInt16LE(6)\r\n if (tail === 0xffff) {\r\n const code = val.readUInt8(0)\r\n if (code === 0x00) return { kind: \"stringRef\" }\r\n if (code === 0x01) return { kind: \"value\", value: val.readUInt8(2) === 1 }\r\n if (code === 0x02) return { kind: \"value\", value: errorCodeToText(val.readUInt8(2)) }\r\n return { kind: \"value\", value: null } // empty\r\n }\r\n return { kind: \"value\", value: val.readDoubleLE(0) }\r\n}\r\n\r\n/**\r\n * Formula 직후의 String 레코드에서 결과 문자열 디코딩.\r\n * 구조: cch(2) flags(1) rgb(...)\r\n */\r\nfunction decodeFormulaStringRecord(data: Buffer): string {\r\n if (data.length < 3) return \"\"\r\n const cch = data.readUInt16LE(0)\r\n const flags = data.readUInt8(2)\r\n const highByte = (flags & 0x01) !== 0\r\n const start = 3\r\n\r\n if (highByte) {\r\n const end = Math.min(start + cch * 2, data.length)\r\n return decodeUtf16Le(data.subarray(start, end))\r\n } else {\r\n const end = Math.min(start + cch, data.length)\r\n const slice = data.subarray(start, end)\r\n const padded = Buffer.alloc(slice.length * 2)\r\n for (let i = 0; i < slice.length; i++) padded[i * 2] = slice[i]\r\n return decodeUtf16Le(padded)\r\n }\r\n}\r\n\r\n/**\r\n * 단일 Worksheet 서브스트림 (BOF~EOF) 의 셀 레코드 추출.\r\n * @param records 전체 레코드 배열\r\n * @param bofIndex 본 시트 BOF의 records 인덱스\r\n * @param sst 디코딩된 SST\r\n * @returns RawSheet — 다음 시트로 넘어갈 수 있는 endIndex 포함\r\n */\r\nexport function extractSheetCells(\r\n records: BiffRecord[],\r\n bofIndex: number,\r\n sst: string[],\r\n): { sheet: RawSheet; endIndex: number } {\r\n const cells: RawCell[] = []\r\n const merges: MergeRange[] = []\r\n const bofOffset = records[bofIndex].offset\r\n\r\n let i = bofIndex + 1\r\n while (i < records.length) {\r\n const rec = records[i]\r\n if (rec.opcode === OP_EOF) {\r\n i++\r\n break\r\n }\r\n if (rec.opcode === OP_BOF) {\r\n // 새 서브스트림 시작 — 안전장치\r\n break\r\n }\r\n\r\n switch (rec.opcode) {\r\n case OP_NUMBER: {\r\n const h = readCellHeader(rec.data)\r\n if (h && rec.data.length >= 14) {\r\n cells.push({ row: h.row, col: h.col, value: rec.data.readDoubleLE(6) })\r\n }\r\n break\r\n }\r\n case OP_RK: {\r\n const h = readCellHeader(rec.data)\r\n if (h && rec.data.length >= 10) {\r\n cells.push({ row: h.row, col: h.col, value: decodeRk(rec.data.readInt32LE(6)) })\r\n }\r\n break\r\n }\r\n case OP_MULRK: {\r\n const m = decodeMulRk(rec.data)\r\n if (m) {\r\n for (const c of m.cells) {\r\n cells.push({ row: m.row, col: c.col, value: c.value })\r\n }\r\n }\r\n break\r\n }\r\n case OP_LABELSST: {\r\n const h = readCellHeader(rec.data)\r\n if (h && rec.data.length >= 10) {\r\n const isst = rec.data.readUInt32LE(6)\r\n cells.push({ row: h.row, col: h.col, value: sst[isst] ?? \"\" })\r\n }\r\n break\r\n }\r\n case OP_LABEL: {\r\n const h = readCellHeader(rec.data)\r\n if (h) {\r\n cells.push({ row: h.row, col: h.col, value: decodeLabelString(rec.data) })\r\n }\r\n break\r\n }\r\n case OP_FORMULA: {\r\n const h = readCellHeader(rec.data)\r\n if (h && rec.data.length >= 14) {\r\n const result = decodeFormulaResult(rec.data.subarray(6, 14))\r\n if (result.kind === \"stringRef\") {\r\n // 직후 String 레코드 찾기\r\n const next = records[i + 1]\r\n if (next && next.opcode === OP_STRING) {\r\n cells.push({\r\n row: h.row,\r\n col: h.col,\r\n value: decodeFormulaStringRecord(next.data),\r\n })\r\n i++ // String 레코드 건너뛰기\r\n } else {\r\n cells.push({ row: h.row, col: h.col, value: \"\" })\r\n }\r\n } else {\r\n cells.push({ row: h.row, col: h.col, value: result.value })\r\n }\r\n }\r\n break\r\n }\r\n case OP_BOOLERR: {\r\n const h = readCellHeader(rec.data)\r\n if (h && rec.data.length >= 8) {\r\n const v = rec.data.readUInt8(6)\r\n const isErr = rec.data.readUInt8(7) === 1\r\n if (isErr) {\r\n cells.push({ row: h.row, col: h.col, value: errorCodeToText(v) })\r\n } else {\r\n cells.push({ row: h.row, col: h.col, value: v === 1 })\r\n }\r\n }\r\n break\r\n }\r\n case OP_BLANK:\r\n case OP_MULBLANK: {\r\n // 빈 셀은 결과 그리드에서 자연 처리됨 — 명시적 추가 안 함\r\n break\r\n }\r\n case OP_MERGECELLS: {\r\n // [cmcs u16][Ref8U[cmcs] (각 8바이트: rwFirst rwLast colFirst colLast)]\r\n if (rec.data.length >= 2) {\r\n const cmcs = rec.data.readUInt16LE(0)\r\n let off = 2\r\n for (let k = 0; k < cmcs && off + 8 <= rec.data.length; k++) {\r\n const r1 = rec.data.readUInt16LE(off)\r\n const r2 = rec.data.readUInt16LE(off + 2)\r\n const c1 = rec.data.readUInt16LE(off + 4)\r\n const c2 = rec.data.readUInt16LE(off + 6)\r\n merges.push({ r1, c1, r2, c2 })\r\n off += 8\r\n }\r\n }\r\n break\r\n }\r\n default:\r\n // 무시 (Row, Window, GUTS, etc)\r\n break\r\n }\r\n\r\n i++\r\n }\r\n\r\n return {\r\n sheet: { bofOffset, cells, merges },\r\n endIndex: i,\r\n }\r\n}\r\n","/**\r\n * XLS (BIFF8) 파서 — Workbook 스트림 → IRBlock[].\r\n *\r\n * 흐름:\r\n * 1. cfb-lenient로 OLE2 컨테이너 → \"Workbook\" 스트림 추출\r\n * 2. readRecords로 BIFF 레코드 시퀀스 파싱\r\n * 3. Globals 서브스트림: BoundSheet8 수집 + SST 디코딩\r\n * 4. 각 시트 BOF 인덱스 찾기 → extractSheetCells\r\n * 5. RawSheet → heading + IRTable 블록 변환\r\n *\r\n * 참조: docs/biff8-spec.md\r\n */\r\n\r\nimport type {\r\n IRBlock,\r\n CellContext,\r\n DocumentMetadata,\r\n InternalParseResult,\r\n ParseOptions,\r\n ParseWarning,\r\n} from \"../types.js\"\r\nimport { KordocError } from \"../utils.js\"\r\nimport { buildTable, blocksToMarkdown } from \"../table/builder.js\"\r\nimport { parseLenientCfb } from \"../hwp5/cfb-lenient.js\"\r\nimport {\r\n readRecords,\r\n decodeBof,\r\n OP_BOF,\r\n OP_EOF,\r\n OP_BOUNDSHEET8,\r\n OP_FILEPASS,\r\n OP_CODEPAGE,\r\n DT_GLOBALS,\r\n DT_WORKSHEET,\r\n type BiffRecord,\r\n} from \"./record.js\"\r\nimport { decodeSST } from \"./sst.js\"\r\nimport { extractSheetCells, type RawSheet, type CellValue } from \"./cell.js\"\r\nimport { decodeUtf16Le } from \"./encoding.js\"\r\n\r\n// ─── 상수 ─────────────────────────────────────────\r\n\r\nconst MAX_SHEETS = 100\r\nconst MAX_ROWS = 100_000\r\nconst MAX_COLS = 1_000\r\n\r\n// ─── BoundSheet8 ─────────────────────────────────\r\n\r\ninterface BoundSheet {\r\n name: string\r\n /** Workbook 스트림 절대 오프셋 — 본 시트 BOF 위치 */\r\n lbPlyPos: number\r\n /** 0=Worksheet, 1=Chart, 2=Macro */\r\n dt: number\r\n}\r\n\r\n/**\r\n * BoundSheet8 레코드 디코딩.\r\n * 구조: lbPlyPos(4) hsState(1) dt(1) stName(ShortXLUnicodeString)\r\n * ShortXLUnicodeString: cch(1) flags(1) chars(...)\r\n * flags bit 0: 1=UTF-16LE, 0=compressed\r\n */\r\nfunction decodeBoundSheet(data: Buffer): BoundSheet | null {\r\n if (data.length < 8) return null\r\n const lbPlyPos = data.readUInt32LE(0)\r\n const dt = data.readUInt8(5)\r\n const cch = data.readUInt8(6)\r\n const flags = data.readUInt8(7)\r\n const highByte = (flags & 0x01) !== 0\r\n const start = 8\r\n\r\n let name: string\r\n if (highByte) {\r\n const end = Math.min(start + cch * 2, data.length)\r\n name = decodeUtf16Le(data.subarray(start, end))\r\n } else {\r\n const end = Math.min(start + cch, data.length)\r\n const slice = data.subarray(start, end)\r\n const padded = Buffer.alloc(slice.length * 2)\r\n for (let i = 0; i < slice.length; i++) padded[i * 2] = slice[i]\r\n name = decodeUtf16Le(padded)\r\n }\r\n\r\n return { name, lbPlyPos, dt }\r\n}\r\n\r\n// ─── Globals 처리 ────────────────────────────────\r\n\r\ninterface GlobalsResult {\r\n sheets: BoundSheet[]\r\n sst: string[]\r\n codePage: number\r\n encrypted: boolean\r\n /** Globals 서브스트림이 끝난 records 인덱스 */\r\n endIndex: number\r\n}\r\n\r\nfunction processGlobals(records: BiffRecord[]): GlobalsResult {\r\n const sheets: BoundSheet[] = []\r\n let codePage = 1200\r\n let encrypted = false\r\n\r\n // 첫 BOF는 records[0]이어야 함\r\n const firstBof = records[0]\r\n if (!firstBof || firstBof.opcode !== OP_BOF) {\r\n throw new KordocError(\"XLS: 첫 레코드가 BOF가 아님\")\r\n }\r\n const bof = decodeBof(firstBof.data)\r\n if (!bof || bof.dt !== DT_GLOBALS) {\r\n throw new KordocError(\"XLS: Globals 서브스트림 BOF 누락\")\r\n }\r\n\r\n let i = 1\r\n while (i < records.length) {\r\n const r = records[i]\r\n if (r.opcode === OP_EOF) {\r\n i++\r\n break\r\n }\r\n if (r.opcode === OP_BOUNDSHEET8) {\r\n const bs = decodeBoundSheet(r.data)\r\n if (bs) sheets.push(bs)\r\n } else if (r.opcode === OP_CODEPAGE && r.data.length >= 2) {\r\n codePage = r.data.readUInt16LE(0)\r\n } else if (r.opcode === OP_FILEPASS) {\r\n encrypted = true\r\n }\r\n i++\r\n }\r\n\r\n // SST는 Globals 내부 어딘가 — 전체 records 검색하되 첫 EOF 이전만\r\n const globalsRecords = records.slice(0, i)\r\n const sst = decodeSST(globalsRecords)\r\n\r\n return { sheets, sst, codePage, encrypted, endIndex: i }\r\n}\r\n\r\n// ─── 시트 BOF 인덱스 찾기 ─────────────────────────\r\n\r\nfunction findSheetBofIndex(records: BiffRecord[], lbPlyPos: number): number {\r\n // 정확한 매칭 우선\r\n const exact = records.findIndex(\r\n r => r.opcode === OP_BOF && r.offset === lbPlyPos,\r\n )\r\n if (exact >= 0) return exact\r\n\r\n // 못 찾으면 가장 가까운 BOF (관용)\r\n const bofIndices = records\r\n .map((r, idx) => (r.opcode === OP_BOF ? idx : -1))\r\n .filter(idx => idx >= 0)\r\n if (bofIndices.length === 0) return -1\r\n // 첫 BOF는 Globals → 두 번째부터 시트\r\n return bofIndices.length > 1 ? bofIndices[1] : -1\r\n}\r\n\r\n// ─── RawSheet → IRBlock[] ────────────────────────\r\n\r\nfunction cellValueToText(v: CellValue): string {\r\n if (v === null || v === undefined) return \"\"\r\n if (typeof v === \"number\") {\r\n // 부동소수점 아티팩트 정리\r\n if (Number.isInteger(v)) return v.toString()\r\n const cleaned = parseFloat(v.toPrecision(15)).toString()\r\n return cleaned\r\n }\r\n if (typeof v === \"boolean\") return v ? \"TRUE\" : \"FALSE\"\r\n return v\r\n}\r\n\r\nfunction sheetToBlocks(\r\n sheetName: string,\r\n sheet: RawSheet,\r\n sheetIndex: number,\r\n): IRBlock[] {\r\n const blocks: IRBlock[] = []\r\n\r\n if (sheetName) {\r\n blocks.push({\r\n type: \"heading\",\r\n text: sheetName,\r\n level: 2,\r\n pageNumber: sheetIndex + 1,\r\n })\r\n }\r\n\r\n if (sheet.cells.length === 0) return blocks\r\n\r\n // 그리드 크기 계산\r\n let maxRow = -1\r\n let maxCol = -1\r\n for (const c of sheet.cells) {\r\n if (c.row > maxRow) maxRow = c.row\r\n if (c.col > maxCol) maxCol = c.col\r\n }\r\n for (const m of sheet.merges) {\r\n if (m.r2 > maxRow) maxRow = m.r2\r\n if (m.c2 > maxCol) maxCol = m.c2\r\n }\r\n if (maxRow < 0 || maxCol < 0) return blocks\r\n\r\n // DOS 방어\r\n if (maxRow >= MAX_ROWS || maxCol >= MAX_COLS) {\r\n maxRow = Math.min(maxRow, MAX_ROWS - 1)\r\n maxCol = Math.min(maxCol, MAX_COLS - 1)\r\n }\r\n\r\n // 그리드 채우기\r\n const grid: string[][] = Array.from({ length: maxRow + 1 }, () =>\r\n Array(maxCol + 1).fill(\"\"),\r\n )\r\n for (const c of sheet.cells) {\r\n if (c.row > maxRow || c.col > maxCol) continue\r\n grid[c.row][c.col] = cellValueToText(c.value)\r\n }\r\n\r\n // 병합 맵\r\n const mergeMap = new Map<string, { colSpan: number; rowSpan: number }>()\r\n const mergeSkip = new Set<string>()\r\n for (const m of sheet.merges) {\r\n const r1 = Math.min(m.r1, maxRow)\r\n const c1 = Math.min(m.c1, maxCol)\r\n const r2 = Math.min(m.r2, maxRow)\r\n const c2 = Math.min(m.c2, maxCol)\r\n mergeMap.set(`${r1},${c1}`, { colSpan: c2 - c1 + 1, rowSpan: r2 - r1 + 1 })\r\n for (let r = r1; r <= r2; r++) {\r\n for (let c = c1; c <= c2; c++) {\r\n if (r !== r1 || c !== c1) mergeSkip.add(`${r},${c}`)\r\n }\r\n }\r\n }\r\n\r\n // 유효 행 트리밍\r\n let firstRow = -1\r\n let lastRow = -1\r\n for (let r = 0; r <= maxRow; r++) {\r\n if (grid[r].some(v => v !== \"\")) {\r\n if (firstRow === -1) firstRow = r\r\n lastRow = r\r\n }\r\n }\r\n if (firstRow === -1) return blocks\r\n\r\n // CellContext[][] 빌드\r\n const cellRows: CellContext[][] = []\r\n for (let r = firstRow; r <= lastRow; r++) {\r\n const row: CellContext[] = []\r\n for (let c = 0; c <= maxCol; c++) {\r\n const key = `${r},${c}`\r\n if (mergeSkip.has(key)) continue\r\n const merge = mergeMap.get(key)\r\n row.push({\r\n text: grid[r][c],\r\n colSpan: merge?.colSpan ?? 1,\r\n rowSpan: merge?.rowSpan ?? 1,\r\n })\r\n }\r\n cellRows.push(row)\r\n }\r\n\r\n if (cellRows.length > 0) {\r\n const table = buildTable(cellRows)\r\n if (table.rows > 0) {\r\n blocks.push({ type: \"table\", table, pageNumber: sheetIndex + 1 })\r\n }\r\n }\r\n\r\n return blocks\r\n}\r\n\r\n// ─── 메인 ─────────────────────────────────────────\r\n\r\nexport async function parseXlsDocument(\r\n buffer: ArrayBuffer,\r\n options?: ParseOptions,\r\n): Promise<InternalParseResult> {\r\n const buf = Buffer.from(buffer)\r\n\r\n // 1. OLE2 컨테이너 → Workbook 스트림\r\n let cfb\r\n try {\r\n cfb = parseLenientCfb(buf)\r\n } catch (e) {\r\n throw new KordocError(\r\n `XLS: OLE2 시그니처 검증 실패 — ${e instanceof Error ? e.message : \"알 수 없는 오류\"}`,\r\n )\r\n }\r\n\r\n const wb = cfb.findStream(\"/Workbook\") ?? cfb.findStream(\"/Book\")\r\n if (!wb) {\r\n throw new KordocError(\"XLS: Workbook 스트림이 없음 (BIFF5 또는 비표준 파일)\")\r\n }\r\n\r\n // 2. BIFF 레코드 시퀀스\r\n const records = readRecords(wb)\r\n if (records.length === 0) {\r\n throw new KordocError(\"XLS: 시그니처 레코드가 없음 (Workbook 스트림 손상)\")\r\n }\r\n\r\n // 3. BIFF 버전 체크\r\n const firstBof = decodeBof(records[0].data)\r\n if (firstBof && firstBof.vers !== 0x0600) {\r\n throw new KordocError(\r\n `XLS: BIFF8(0x0600)만 지원 — 본 파일은 0x${firstBof.vers.toString(16)}`,\r\n )\r\n }\r\n\r\n // 4. Globals 처리\r\n const globals = processGlobals(records)\r\n const warnings: ParseWarning[] = []\r\n\r\n if (globals.encrypted) {\r\n return {\r\n markdown: \"\",\r\n blocks: [],\r\n metadata: { pageCount: globals.sheets.length },\r\n warnings: [\r\n {\r\n message: \"XLS 파일이 암호화되어 있어 파싱할 수 없습니다\",\r\n code: \"PARTIAL_PARSE\",\r\n },\r\n ],\r\n }\r\n }\r\n\r\n // 5. 페이지/시트 필터\r\n const totalSheets = Math.min(globals.sheets.length, MAX_SHEETS)\r\n let pageFilter: Set<number> | null = null\r\n if (options?.pages) {\r\n const { parsePageRange } = await import(\"../page-range.js\")\r\n pageFilter = parsePageRange(options.pages, totalSheets)\r\n }\r\n\r\n // 6. 각 시트 처리\r\n const allBlocks: IRBlock[] = []\r\n for (let i = 0; i < totalSheets; i++) {\r\n if (pageFilter && !pageFilter.has(i + 1)) continue\r\n const meta = globals.sheets[i]\r\n // BoundSheet8.dt: 0=Worksheet, 1=Macro, 2=Chart — 워크시트만 처리\r\n if (meta.dt !== 0) continue\r\n\r\n options?.onProgress?.(i + 1, totalSheets)\r\n\r\n const bofIdx = findSheetBofIndex(records, meta.lbPlyPos)\r\n if (bofIdx < 0) {\r\n warnings.push({\r\n page: i + 1,\r\n message: `시트 \"${meta.name}\" BOF를 찾을 수 없음 (lbPlyPos=${meta.lbPlyPos})`,\r\n code: \"PARTIAL_PARSE\",\r\n })\r\n continue\r\n }\r\n\r\n // 시트 BOF 검증\r\n const sheetBof = decodeBof(records[bofIdx].data)\r\n if (sheetBof && sheetBof.dt !== DT_WORKSHEET) {\r\n // 차트/매크로 등은 스킵\r\n continue\r\n }\r\n\r\n try {\r\n const { sheet } = extractSheetCells(records, bofIdx, globals.sst)\r\n const blocks = sheetToBlocks(meta.name, sheet, i)\r\n allBlocks.push(...blocks)\r\n } catch (e) {\r\n warnings.push({\r\n page: i + 1,\r\n message: `시트 \"${meta.name}\" 파싱 실패: ${e instanceof Error ? e.message : \"알 수 없는 오류\"}`,\r\n code: \"PARTIAL_PARSE\",\r\n })\r\n }\r\n }\r\n\r\n // 7. 메타데이터\r\n const metadata: DocumentMetadata = {\r\n pageCount: totalSheets,\r\n }\r\n\r\n return {\r\n markdown: blocksToMarkdown(allBlocks),\r\n blocks: allBlocks,\r\n metadata,\r\n warnings: warnings.length > 0 ? warnings : undefined,\r\n }\r\n}\r\n","/**\n * DOCX (Office Open XML Document) 파서\n *\n * ZIP + XML 구조를 jszip + xmldom으로 파싱하여 IRBlock[]로 변환.\n * w:p → paragraph/heading, w:tbl → table, w:drawing → image.\n */\n\nimport JSZip from \"jszip\"\nimport { DOMParser } from \"@xmldom/xmldom\"\nimport type {\n IRBlock, IRTable, IRCell, DocumentMetadata, InternalParseResult,\n ParseOptions, ParseWarning, ExtractedImage, InlineStyle,\n} from \"../types.js\"\nimport { KordocError, precheckZipSize, stripDtd } from \"../utils.js\"\nimport { blocksToMarkdown } from \"../table/builder.js\"\nimport { ommlElementToLatex, isDisplayMath } from \"./equation.js\"\n\n/** ZIP 압축 해제 누적 최대 크기 (100MB) — ZIP bomb 방지 */\nconst MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024\n\n// ─── XML 헬퍼 ──────────────────────────────────────────\n\n/** 네임스페이스 무시 태그 검색 — DOCX는 네임스페이스가 많음 */\nfunction getChildElements(parent: Element | Document, localName: string): Element[] {\n const result: Element[] = []\n const children = parent.childNodes\n for (let i = 0; i < children.length; i++) {\n const node = children[i]\n if (node.nodeType === 1) {\n const el = node as Element\n if (el.localName === localName || el.tagName?.endsWith(`:${localName}`)) {\n result.push(el)\n }\n }\n }\n return result\n}\n\n/** 재귀적으로 localName 매칭 — getElementsByTagName 대안 */\nfunction findElements(parent: Element | Document, localName: string): Element[] {\n const result: Element[] = []\n const walk = (node: Element | Document) => {\n const children = node.childNodes\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (child.nodeType === 1) {\n const el = child as Element\n if (el.localName === localName || el.tagName?.endsWith(`:${localName}`)) {\n result.push(el)\n }\n walk(el)\n }\n }\n }\n walk(parent)\n return result\n}\n\nfunction getAttr(el: Element, localName: string): string | null {\n // w:val, r:id 등 네임스페이스 포함 속성\n const attrs = el.attributes\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs[i]\n if (attr.localName === localName || attr.name === localName) return attr.value\n }\n return null\n}\n\nfunction parseXml(text: string): Document {\n return new DOMParser().parseFromString(stripDtd(text), \"text/xml\")\n}\n\n// ─── 스타일 파싱 ────────────────────────────────────────\n\ninterface StyleInfo {\n name: string\n basedOn?: string\n outlineLevel?: number\n}\n\nfunction parseStyles(xml: string): Map<string, StyleInfo> {\n const doc = parseXml(xml)\n const styles = new Map<string, StyleInfo>()\n const styleElements = findElements(doc, \"style\")\n\n for (const el of styleElements) {\n const styleId = getAttr(el, \"styleId\")\n if (!styleId) continue\n\n const nameEls = getChildElements(el, \"name\")\n const name = nameEls.length > 0 ? (getAttr(nameEls[0], \"val\") ?? \"\") : \"\"\n const basedOnEls = getChildElements(el, \"basedOn\")\n const basedOn = basedOnEls.length > 0 ? (getAttr(basedOnEls[0], \"val\") ?? undefined) : undefined\n\n // outlineLevel으로 heading 감지\n const pPrEls = getChildElements(el, \"pPr\")\n let outlineLevel: number | undefined\n if (pPrEls.length > 0) {\n const outlineEls = getChildElements(pPrEls[0], \"outlineLvl\")\n if (outlineEls.length > 0) {\n const val = getAttr(outlineEls[0], \"val\")\n if (val !== null) outlineLevel = parseInt(val, 10)\n }\n }\n\n // Heading 패턴 매칭\n if (outlineLevel === undefined) {\n const headingMatch = name.match(/^(?:heading|Heading)\\s*(\\d+)$/i)\n if (headingMatch) outlineLevel = parseInt(headingMatch[1], 10) - 1\n }\n\n styles.set(styleId, { name, basedOn, outlineLevel })\n }\n return styles\n}\n\n// ─── 번호 매기기 파싱 ──────────────────────────────────\n\ninterface NumberingInfo {\n numFmt: string // \"decimal\", \"bullet\", etc.\n level: number\n}\n\nfunction parseNumbering(xml: string): Map<string, Map<number, NumberingInfo>> {\n const doc = parseXml(xml)\n const abstractNums = new Map<string, Map<number, NumberingInfo>>()\n\n // abstractNum 파싱\n const abstractElements = findElements(doc, \"abstractNum\")\n for (const el of abstractElements) {\n const abstractNumId = getAttr(el, \"abstractNumId\")\n if (!abstractNumId) continue\n const levels = new Map<number, NumberingInfo>()\n const lvlElements = getChildElements(el, \"lvl\")\n for (const lvl of lvlElements) {\n const ilvl = parseInt(getAttr(lvl, \"ilvl\") ?? \"0\", 10)\n const numFmtEls = getChildElements(lvl, \"numFmt\")\n const numFmt = numFmtEls.length > 0 ? (getAttr(numFmtEls[0], \"val\") ?? \"bullet\") : \"bullet\"\n levels.set(ilvl, { numFmt, level: ilvl })\n }\n abstractNums.set(abstractNumId, levels)\n }\n\n // num → abstractNum 매핑\n const nums = new Map<string, Map<number, NumberingInfo>>()\n const numElements = findElements(doc, \"num\")\n for (const el of numElements) {\n const numId = getAttr(el, \"numId\")\n if (!numId) continue\n const abstractRefs = getChildElements(el, \"abstractNumId\")\n if (abstractRefs.length > 0) {\n const ref = getAttr(abstractRefs[0], \"val\")\n if (ref && abstractNums.has(ref)) {\n nums.set(numId, abstractNums.get(ref)!)\n }\n }\n }\n return nums\n}\n\n// ─── 관계 파싱 ─────────────────────────────────────────\n\nfunction parseRels(xml: string): Map<string, string> {\n const doc = parseXml(xml)\n const map = new Map<string, string>()\n const rels = findElements(doc, \"Relationship\")\n for (const rel of rels) {\n const id = getAttr(rel, \"Id\")\n const target = getAttr(rel, \"Target\")\n if (id && target) map.set(id, target)\n }\n return map\n}\n\n// ─── 각주 파싱 ─────────────────────────────────────────\n\nfunction parseFootnotes(xml: string): Map<string, string> {\n const doc = parseXml(xml)\n const notes = new Map<string, string>()\n const fnElements = findElements(doc, \"footnote\")\n for (const fn of fnElements) {\n const id = getAttr(fn, \"id\")\n if (!id || id === \"0\" || id === \"-1\") continue // 0=separator, -1=continuation\n const texts: string[] = []\n const pElements = findElements(fn, \"p\")\n for (const p of pElements) {\n const runs = findElements(p, \"r\")\n for (const r of runs) {\n const tElements = getChildElements(r, \"t\")\n for (const t of tElements) texts.push(t.textContent ?? \"\")\n }\n }\n notes.set(id, texts.join(\"\").trim())\n }\n return notes\n}\n\n// ─── OMML 수집 ────────────────────────────────────────\n\n/**\n * paragraph 내부의 최상위 OMML 엘리먼트(`<m:oMath>` / `<m:oMathPara>`) 수집.\n * `<m:oMathPara>` 안의 중첩 `<m:oMath>` 는 중복 제외.\n */\nfunction collectOmmlRoots(p: Element): Element[] {\n const out: Element[] = []\n const walk = (node: Element) => {\n const children = node.childNodes\n if (!children) return\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (child.nodeType !== 1) continue\n const el = child as Element\n const tag = el.localName || el.tagName?.replace(/^[^:]+:/, \"\") || \"\"\n if (tag === \"oMath\" || tag === \"oMathPara\") {\n out.push(el)\n // 내부는 재귀하지 않음 (oMathPara 안의 oMath 중복 방지)\n } else {\n walk(el)\n }\n }\n }\n walk(p)\n return out\n}\n\n// ─── Run 텍스트 추출 ──────────────────────────────────\n\ninterface RunResult {\n text: string\n bold: boolean\n italic: boolean\n}\n\nfunction extractRun(r: Element): RunResult {\n const tElements = getChildElements(r, \"t\")\n const text = tElements.map(t => t.textContent ?? \"\").join(\"\")\n\n let bold = false\n let italic = false\n const rPrEls = getChildElements(r, \"rPr\")\n if (rPrEls.length > 0) {\n bold = getChildElements(rPrEls[0], \"b\").length > 0\n italic = getChildElements(rPrEls[0], \"i\").length > 0\n }\n\n return { text, bold, italic }\n}\n\n// ─── 단락 파싱 ─────────────────────────────────────────\n\nfunction parseParagraph(\n p: Element,\n styles: Map<string, StyleInfo>,\n numbering: Map<string, Map<number, NumberingInfo>>,\n footnotes: Map<string, string>,\n rels: Map<string, string>,\n): IRBlock | null {\n // 스타일 확인\n const pPrEls = getChildElements(p, \"pPr\")\n let styleId = \"\"\n let numId = \"\"\n let ilvl = 0\n\n if (pPrEls.length > 0) {\n const pStyleEls = getChildElements(pPrEls[0], \"pStyle\")\n if (pStyleEls.length > 0) styleId = getAttr(pStyleEls[0], \"val\") ?? \"\"\n\n const numPrEls = getChildElements(pPrEls[0], \"numPr\")\n if (numPrEls.length > 0) {\n const numIdEls = getChildElements(numPrEls[0], \"numId\")\n const ilvlEls = getChildElements(numPrEls[0], \"ilvl\")\n numId = numIdEls.length > 0 ? (getAttr(numIdEls[0], \"val\") ?? \"\") : \"\"\n ilvl = ilvlEls.length > 0 ? parseInt(getAttr(ilvlEls[0], \"val\") ?? \"0\", 10) : 0\n }\n }\n\n // 텍스트 수집\n const parts: string[] = []\n let hasBold = false\n let hasItalic = false\n let href: string | undefined\n let footnoteText: string | undefined\n\n // 하이퍼링크 처리\n const hyperlinks = getChildElements(p, \"hyperlink\")\n const hyperlinkTexts = new Set<string>()\n\n for (const hl of hyperlinks) {\n const rId = getAttr(hl, \"id\")\n const hlText: string[] = []\n const runs = findElements(hl, \"r\")\n for (const r of runs) {\n const result = extractRun(r)\n hlText.push(result.text)\n }\n const text = hlText.join(\"\")\n if (text) {\n hyperlinkTexts.add(text)\n if (rId && rels.has(rId)) {\n href = rels.get(rId)\n parts.push(text)\n } else {\n parts.push(text)\n }\n }\n }\n\n // 일반 run 처리\n const runs = getChildElements(p, \"r\")\n for (const r of runs) {\n // 하이퍼링크 내부 run은 이미 처리됨 — 부모가 hyperlink이면 스킵\n if (r.parentNode && (r.parentNode as Element).localName === \"hyperlink\") continue\n\n const result = extractRun(r)\n if (result.bold) hasBold = true\n if (result.italic) hasItalic = true\n\n // 각주 참조 확인\n const fnRefEls = getChildElements(r, \"footnoteReference\")\n if (fnRefEls.length > 0) {\n const fnId = getAttr(fnRefEls[0], \"id\")\n if (fnId && footnotes.has(fnId)) {\n footnoteText = footnotes.get(fnId)\n }\n }\n\n if (result.text) parts.push(result.text)\n }\n\n // OMML 수식 — <m:oMath> / <m:oMathPara> 를 LaTeX 로 변환해 덧붙임.\n // 인라인 수식은 `$...$`, display 는 `$$...$$`. 순서는 run 뒤로 몰리지만\n // 대부분 한 단락 내 수식/텍스트가 분리돼 있어 실용상 무해.\n for (const om of collectOmmlRoots(p)) {\n const latex = ommlElementToLatex(om)\n if (!latex) continue\n if (isDisplayMath(om)) parts.push(\" $$\" + latex + \"$$ \")\n else parts.push(\" $\" + latex + \"$ \")\n }\n\n const text = parts.join(\"\").replace(/[ \\t]{2,}/g, \" \").trim()\n if (!text) return null\n\n // Heading 판별\n const style = styles.get(styleId)\n if (style?.outlineLevel !== undefined && style.outlineLevel >= 0 && style.outlineLevel <= 5) {\n return {\n type: \"heading\",\n text,\n level: style.outlineLevel + 1,\n }\n }\n\n // 리스트 판별\n if (numId && numId !== \"0\") {\n const numDef = numbering.get(numId)\n const levelInfo = numDef?.get(ilvl)\n const listType = levelInfo?.numFmt === \"bullet\" ? \"unordered\" : \"ordered\"\n return { type: \"list\", text, listType }\n }\n\n // 일반 단락\n const block: IRBlock = { type: \"paragraph\", text }\n if (hasBold || hasItalic) {\n block.style = { bold: hasBold || undefined, italic: hasItalic || undefined }\n }\n if (href) block.href = href\n if (footnoteText) block.footnoteText = footnoteText\n return block\n}\n\n// ─── 테이블 파싱 ────────────────────────────────────────\n\nfunction parseTable(\n tbl: Element,\n styles: Map<string, StyleInfo>,\n numbering: Map<string, Map<number, NumberingInfo>>,\n footnotes: Map<string, string>,\n rels: Map<string, string>,\n): IRBlock | null {\n const trElements = getChildElements(tbl, \"tr\")\n if (trElements.length === 0) return null\n\n const rows: IRCell[][] = []\n let maxCols = 0\n\n for (const tr of trElements) {\n const tcElements = getChildElements(tr, \"tc\")\n const row: IRCell[] = []\n\n for (const tc of tcElements) {\n // 셀 속성\n let colSpan = 1\n let rowSpan = 1\n const tcPrEls = getChildElements(tc, \"tcPr\")\n if (tcPrEls.length > 0) {\n const gridSpanEls = getChildElements(tcPrEls[0], \"gridSpan\")\n if (gridSpanEls.length > 0) {\n colSpan = parseInt(getAttr(gridSpanEls[0], \"val\") ?? \"1\", 10)\n }\n const vMergeEls = getChildElements(tcPrEls[0], \"vMerge\")\n if (vMergeEls.length > 0) {\n const val = getAttr(vMergeEls[0], \"val\")\n if (val !== \"restart\" && val !== null) {\n // 병합 계속 셀 — 스킵 마커\n row.push({ text: \"\", colSpan, rowSpan: 0 })\n continue\n }\n }\n }\n\n // 셀 텍스트\n const cellTexts: string[] = []\n const pElements = getChildElements(tc, \"p\")\n for (const p of pElements) {\n const block = parseParagraph(p, styles, numbering, footnotes, rels)\n if (block?.text) cellTexts.push(block.text)\n }\n\n row.push({ text: cellTexts.join(\"\\n\"), colSpan, rowSpan })\n }\n rows.push(row)\n if (row.length > maxCols) maxCols = row.length\n }\n\n // vMerge rowSpan 후처리: restart에서 아래로 연속되는 rowSpan=0 카운트\n for (let c = 0; c < maxCols; c++) {\n for (let r = 0; r < rows.length; r++) {\n const cell = rows[r][c]\n if (!cell || cell.rowSpan === 0) continue\n let span = 1\n for (let nr = r + 1; nr < rows.length; nr++) {\n if (rows[nr][c]?.rowSpan === 0) span++\n else break\n }\n cell.rowSpan = span\n }\n }\n\n // rowSpan=0인 placeholder 제거\n const cleanRows: IRCell[][] = []\n for (const row of rows) {\n const clean = row.filter(cell => cell.rowSpan !== 0)\n cleanRows.push(clean)\n }\n\n // 빈 테이블 체크\n if (cleanRows.length === 0) return null\n\n // 컬럼 수 재계산\n let cols = 0\n for (const row of cleanRows) {\n let c = 0\n for (const cell of row) c += cell.colSpan\n if (c > cols) cols = c\n }\n\n const table: IRTable = {\n rows: cleanRows.length,\n cols,\n cells: cleanRows,\n hasHeader: cleanRows.length > 1,\n }\n return { type: \"table\", table }\n}\n\n// ─── 이미지 추출 ────────────────────────────────────────\n\nasync function extractImages(\n zip: JSZip,\n rels: Map<string, string>,\n doc: Document,\n): Promise<{ blocks: IRBlock[]; images: ExtractedImage[] }> {\n const blocks: IRBlock[] = []\n const images: ExtractedImage[] = []\n\n const drawingElements = findElements(doc.documentElement, \"drawing\")\n let imgIdx = 0\n\n for (const drawing of drawingElements) {\n // a:blip → r:embed\n const blips = findElements(drawing, \"blip\")\n for (const blip of blips) {\n const embedId = getAttr(blip, \"embed\")\n if (!embedId) continue\n const target = rels.get(embedId)\n if (!target) continue\n\n const imgPath = target.startsWith(\"/\") ? target.slice(1)\n : target.startsWith(\"word/\") ? target\n : `word/${target}`\n\n const imgFile = zip.file(imgPath)\n if (!imgFile) continue\n\n try {\n const data = await imgFile.async(\"uint8array\")\n imgIdx++\n const ext = imgPath.split(\".\").pop()?.toLowerCase() ?? \"png\"\n const mimeMap: Record<string, string> = {\n png: \"image/png\", jpg: \"image/jpeg\", jpeg: \"image/jpeg\",\n gif: \"image/gif\", bmp: \"image/bmp\", wmf: \"image/wmf\", emf: \"image/emf\",\n }\n const filename = `image_${String(imgIdx).padStart(3, \"0\")}.${ext}`\n images.push({ filename, data, mimeType: mimeMap[ext] ?? \"image/png\" })\n blocks.push({ type: \"image\", text: filename })\n } catch { /* 이미지 실패 무시 */ }\n }\n }\n return { blocks, images }\n}\n\n// ─── 메인 파서 ─────────────────────────────────────────\n\nexport async function parseDocxDocument(\n buffer: ArrayBuffer,\n options?: ParseOptions,\n): Promise<InternalParseResult> {\n // ZIP bomb 사전 검사\n precheckZipSize(buffer, MAX_DECOMPRESS_SIZE)\n\n const zip = await JSZip.loadAsync(buffer)\n const warnings: ParseWarning[] = []\n\n // DOCX 구조 검증\n const docFile = zip.file(\"word/document.xml\")\n if (!docFile) {\n throw new KordocError(\"유효하지 않은 DOCX 파일: word/document.xml이 없습니다\")\n }\n\n // 1. 관계 로드\n let rels = new Map<string, string>()\n const relsFile = zip.file(\"word/_rels/document.xml.rels\")\n if (relsFile) {\n rels = parseRels(await relsFile.async(\"text\"))\n }\n\n // 2. 스타일 로드\n let styles = new Map<string, StyleInfo>()\n const stylesFile = zip.file(\"word/styles.xml\")\n if (stylesFile) {\n try {\n styles = parseStyles(await stylesFile.async(\"text\"))\n } catch { /* 스타일 실패 무시 */ }\n }\n\n // 3. 번호 매기기 로드\n let numbering = new Map<string, Map<number, NumberingInfo>>()\n const numFile = zip.file(\"word/numbering.xml\")\n if (numFile) {\n try {\n numbering = parseNumbering(await numFile.async(\"text\"))\n } catch { /* 번호 매기기 실패 무시 */ }\n }\n\n // 4. 각주 로드\n let footnotes = new Map<string, string>()\n const fnFile = zip.file(\"word/footnotes.xml\")\n if (fnFile) {\n try {\n footnotes = parseFootnotes(await fnFile.async(\"text\"))\n } catch { /* 각주 실패 무시 */ }\n }\n\n // 5. 본문 파싱\n const docXml = await docFile.async(\"text\")\n const doc = parseXml(docXml)\n const body = findElements(doc, \"body\")\n if (body.length === 0) {\n throw new KordocError(\"DOCX 본문(w:body)을 찾을 수 없습니다\")\n }\n\n const blocks: IRBlock[] = []\n const bodyEl = body[0]\n const children = bodyEl.childNodes\n\n for (let i = 0; i < children.length; i++) {\n const node = children[i]\n if (node.nodeType !== 1) continue\n const el = node as Element\n const localName = el.localName ?? el.tagName?.split(\":\").pop()\n\n if (localName === \"p\") {\n const block = parseParagraph(el, styles, numbering, footnotes, rels)\n if (block) blocks.push(block)\n } else if (localName === \"tbl\") {\n const block = parseTable(el, styles, numbering, footnotes, rels)\n if (block) blocks.push(block)\n }\n }\n\n // 6. 이미지 추출\n const { blocks: imgBlocks, images } = await extractImages(zip, rels, doc)\n // 이미지 블록은 본문에 이미 포함되어야 하지만, 누락된 것 추가\n // (drawing이 paragraph 내에 있으므로 대부분 이미 포함됨)\n\n // 7. 메타데이터\n const metadata: DocumentMetadata = {}\n const coreFile = zip.file(\"docProps/core.xml\")\n if (coreFile) {\n try {\n const coreXml = await coreFile.async(\"text\")\n const coreDoc = parseXml(coreXml)\n const getFirst = (tag: string) => {\n const els = coreDoc.getElementsByTagName(tag)\n return els.length > 0 ? (els[0].textContent ?? \"\").trim() : undefined\n }\n metadata.title = getFirst(\"dc:title\") || getFirst(\"dcterms:title\")\n metadata.author = getFirst(\"dc:creator\")\n metadata.description = getFirst(\"dc:description\")\n const created = getFirst(\"dcterms:created\")\n if (created) metadata.createdAt = created\n const modified = getFirst(\"dcterms:modified\")\n if (modified) metadata.modifiedAt = modified\n } catch { /* 메타데이터 실패 무시 */ }\n }\n\n // 8. 아웃라인\n const outline = blocks\n .filter(b => b.type === \"heading\")\n .map(b => ({ level: b.level ?? 2, text: b.text ?? \"\" }))\n\n const markdown = blocksToMarkdown(blocks)\n\n return {\n markdown,\n blocks,\n metadata,\n outline: outline.length > 0 ? outline : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n images: images.length > 0 ? images : undefined,\n }\n}\n","/**\n * DOCX OMML (Office Math ML) → LaTeX\n *\n * OMML 루트 엘리먼트(`<m:oMath>`, `<m:oMathPara>`) 를 재귀적으로 훑어 LaTeX\n * 문자열을 생성한다. `<m:r>/<m:t>` 텍스트, 분수/근호/첨자/행렬/괄호/함수\n * /적분 등 실무에서 가장 흔한 OMML 18종 태그를 지원.\n *\n * 레퍼런스:\n * - Microsoft OMML2MML.xsl (Office 공식 XSLT 매핑)\n * - Pandoc texmath (Text.TeXMath.Readers.OMML)\n * 매핑 테이블은 CLAUDE plan `.claude/plans/auto-update-and-math.md` 참조.\n *\n * Entry points:\n * - ommlElementToLatex(el) — 하나의 <m:oMath> 또는 <m:oMathPara> 엘리먼트를\n * LaTeX 로 변환 (delim 은 호출자가 씌움).\n * - isOmmlRoot(el) — 엘리먼트가 OMML 최상위인지 판별.\n */\n\n/** localName 비교 — 네임스페이스 prefix 제거 */\nfunction lname(el: Element): string {\n return el.localName || el.tagName?.replace(/^[^:]+:/, \"\") || \"\"\n}\n\n/** 자식 중 localName 매칭 엘리먼트들 (직계만) */\nfunction kids(parent: Element, name: string): Element[] {\n const out: Element[] = []\n const nodes = parent.childNodes\n if (!nodes) return out\n for (let i = 0; i < nodes.length; i++) {\n const n = nodes[i]\n if (n.nodeType !== 1) continue\n const el = n as Element\n if (lname(el) === name) out.push(el)\n }\n return out\n}\n\n/** 직계 자식 첫 매칭 또는 null */\nfunction firstKid(parent: Element, name: string): Element | null {\n const list = kids(parent, name)\n return list[0] ?? null\n}\n\n/** 자식 엘리먼트 순회 (직계만, Element only) */\nfunction eachChild(parent: Element): Element[] {\n const out: Element[] = []\n const nodes = parent.childNodes\n if (!nodes) return out\n for (let i = 0; i < nodes.length; i++) {\n if (nodes[i].nodeType === 1) out.push(nodes[i] as Element)\n }\n return out\n}\n\n/** <m:r> 내부 <m:t> 텍스트 집계. 특수 연산자에 백슬래시 매핑. */\nfunction runToLatex(r: Element): string {\n let out = \"\"\n for (const t of kids(r, \"t\")) out += t.textContent ?? \"\"\n return out\n}\n\n/** 함수 이름(sin/cos/log/ln/exp/tan/…) → `\\sin` 식 매핑 */\nconst FUNC_NAMES = new Set([\n \"sin\", \"cos\", \"tan\", \"cot\", \"sec\", \"csc\",\n \"sinh\", \"cosh\", \"tanh\", \"coth\",\n \"arcsin\", \"arccos\", \"arctan\",\n \"log\", \"ln\", \"lg\", \"exp\",\n \"det\", \"dim\", \"gcd\", \"inf\", \"sup\", \"lim\", \"max\", \"min\",\n \"Pr\", \"arg\",\n])\n\n/** acc/char → LaTeX accent */\nconst ACCENT_MAP: Record<string, string> = {\n \"̂\": \"\\\\hat\", // U+0302 COMBINING CIRCUMFLEX\n \"̃\": \"\\\\tilde\", // U+0303\n \"̄\": \"\\\\bar\", // U+0304\n \"̇\": \"\\\\dot\", // U+0307\n \"̈\": \"\\\\ddot\", // U+0308\n \"́\": \"\\\\acute\", // U+0301\n \"̀\": \"\\\\grave\", // U+0300\n \"̆\": \"\\\\breve\", // U+0306\n \"̌\": \"\\\\check\", // U+030C\n \"⃗\": \"\\\\vec\", // U+20D7 COMBINING RIGHT ARROW ABOVE\n \"→\": \"\\\\vec\",\n}\n\n/** n-ary 연산자 (m:nary) chr → LaTeX */\nconst NARY_MAP: Record<string, string> = {\n \"∑\": \"\\\\sum\",\n \"∏\": \"\\\\prod\",\n \"∐\": \"\\\\coprod\",\n \"∫\": \"\\\\int\",\n \"∬\": \"\\\\iint\",\n \"∭\": \"\\\\iiint\",\n \"∮\": \"\\\\oint\",\n \"∯\": \"\\\\oiint\",\n \"∰\": \"\\\\oiiint\",\n \"⋃\": \"\\\\bigcup\",\n \"⋂\": \"\\\\bigcap\",\n \"⨁\": \"\\\\bigoplus\",\n \"⨂\": \"\\\\bigotimes\",\n \"⨀\": \"\\\\bigodot\",\n}\n\n/** 괄호 문자 → LaTeX (좌/우) */\nfunction mapDelim(ch: string, isLeft: boolean): string {\n const l: Record<string, string> = {\n \"(\": \"(\", \"[\": \"[\", \"{\": \"\\\\{\", \"⟨\": \"\\\\langle\",\n \"|\": \"|\", \"‖\": \"\\\\|\", \"⌊\": \"\\\\lfloor\", \"⌈\": \"\\\\lceil\",\n \"\": \".\",\n }\n const r: Record<string, string> = {\n \")\": \")\", \"]\": \"]\", \"}\": \"\\\\}\", \"⟩\": \"\\\\rangle\",\n \"|\": \"|\", \"‖\": \"\\\\|\", \"⌋\": \"\\\\rfloor\", \"⌉\": \"\\\\rceil\",\n \"\": \".\",\n }\n const map = isLeft ? l : r\n return map[ch] ?? ch\n}\n\n/** 내용이 단일 문자거나 단순 원자면 `{}` 없이, 아니면 감싸서 반환 */\nfunction grp(body: string): string {\n const s = body.trim()\n if (s.length === 0) return \"{}\"\n // 이미 `{...}` 로 감싸진 경우 그대로\n if (s.startsWith(\"{\") && s.endsWith(\"}\")) return s\n return \"{\" + s + \"}\"\n}\n\n/** 엘리먼트 리스트를 연결한 LaTeX 문자열로 변환 */\nfunction childrenToLatex(parent: Element): string {\n let out = \"\"\n for (const ch of eachChild(parent)) {\n out += nodeToLatex(ch)\n }\n return out\n}\n\n/** 노드(Element) 하나 → LaTeX */\nfunction nodeToLatex(el: Element): string {\n const tag = lname(el)\n switch (tag) {\n case \"r\": return runToLatex(el)\n\n case \"e\": // generic container (인자로 쓰임) — 자식 연결\n case \"num\":\n case \"den\":\n case \"sub\":\n case \"sup\":\n case \"deg\":\n case \"lim\":\n case \"fName\":\n return childrenToLatex(el)\n\n // 분수\n case \"f\": {\n const n = firstKid(el, \"num\")\n const d = firstKid(el, \"den\")\n const num = n ? childrenToLatex(n) : \"\"\n const den = d ? childrenToLatex(d) : \"\"\n return \"\\\\frac\" + grp(num) + grp(den)\n }\n\n // 첨자\n case \"sSup\": {\n const e = firstKid(el, \"e\")\n const sup = firstKid(el, \"sup\")\n return grp(e ? childrenToLatex(e) : \"\") + \"^\" + grp(sup ? childrenToLatex(sup) : \"\")\n }\n case \"sSub\": {\n const e = firstKid(el, \"e\")\n const sub = firstKid(el, \"sub\")\n return grp(e ? childrenToLatex(e) : \"\") + \"_\" + grp(sub ? childrenToLatex(sub) : \"\")\n }\n case \"sSubSup\": {\n const e = firstKid(el, \"e\")\n const sub = firstKid(el, \"sub\")\n const sup = firstKid(el, \"sup\")\n return grp(e ? childrenToLatex(e) : \"\") +\n \"_\" + grp(sub ? childrenToLatex(sub) : \"\") +\n \"^\" + grp(sup ? childrenToLatex(sup) : \"\")\n }\n case \"sPre\": {\n // pre-superscript/subscript\n const sub = firstKid(el, \"sub\")\n const sup = firstKid(el, \"sup\")\n const e = firstKid(el, \"e\")\n const preSub = sub ? grp(childrenToLatex(sub)) : \"{}\"\n const preSup = sup ? grp(childrenToLatex(sup)) : \"{}\"\n const body = e ? childrenToLatex(e) : \"\"\n return \"{}_\" + preSub + \"^\" + preSup + grp(body)\n }\n\n // 근호\n case \"rad\": {\n const deg = firstKid(el, \"deg\")\n const e = firstKid(el, \"e\")\n const body = e ? childrenToLatex(e) : \"\"\n // degHide 속성이 있으면 degree 생략\n const radPr = firstKid(el, \"radPr\")\n let hide = false\n if (radPr) {\n const degHide = firstKid(radPr, \"degHide\")\n if (degHide) {\n const val = degHide.getAttribute(\"m:val\") ?? degHide.getAttribute(\"val\")\n hide = val === \"1\" || val === \"on\" || val === \"true\"\n }\n }\n const degStr = (!hide && deg) ? childrenToLatex(deg).trim() : \"\"\n return degStr ? \"\\\\sqrt[\" + degStr + \"]\" + grp(body) : \"\\\\sqrt\" + grp(body)\n }\n\n // n-ary 연산자 (sum, prod, int, …)\n case \"nary\": {\n const naryPr = firstKid(el, \"naryPr\")\n let op = \"\\\\int\"\n let subHide = false\n let supHide = false\n let limLoc = \"\"\n if (naryPr) {\n const chr = firstKid(naryPr, \"chr\")\n if (chr) {\n const v = chr.getAttribute(\"m:val\") ?? chr.getAttribute(\"val\") ?? \"\"\n if (v && NARY_MAP[v]) op = NARY_MAP[v]\n else if (v) op = v\n } else {\n // chr 생략 시 기본값은 integral (OMML 스펙)\n op = \"\\\\int\"\n }\n const sh = firstKid(naryPr, \"subHide\")\n const ph = firstKid(naryPr, \"supHide\")\n if (sh) subHide = (sh.getAttribute(\"m:val\") ?? sh.getAttribute(\"val\")) !== \"0\"\n if (ph) supHide = (ph.getAttribute(\"m:val\") ?? ph.getAttribute(\"val\")) !== \"0\"\n const ll = firstKid(naryPr, \"limLoc\")\n if (ll) limLoc = ll.getAttribute(\"m:val\") ?? ll.getAttribute(\"val\") ?? \"\"\n }\n const sub = firstKid(el, \"sub\")\n const sup = firstKid(el, \"sup\")\n const e = firstKid(el, \"e\")\n const subStr = (!subHide && sub) ? childrenToLatex(sub) : \"\"\n const supStr = (!supHide && sup) ? childrenToLatex(sup) : \"\"\n const body = e ? childrenToLatex(e) : \"\"\n\n let head = op\n if (limLoc === \"undOvr\") {\n // limit 위치를 연산자 아래/위 (sum/prod 기본)\n if (subStr) head += \"_\" + grp(subStr)\n if (supStr) head += \"^\" + grp(supStr)\n } else {\n if (subStr) head += \"_\" + grp(subStr)\n if (supStr) head += \"^\" + grp(supStr)\n }\n return head + \" \" + body\n }\n\n // 괄호 (delimiter)\n case \"d\": {\n const dPr = firstKid(el, \"dPr\")\n let beg = \"(\"\n let end = \")\"\n let sep = \",\"\n if (dPr) {\n const begChr = firstKid(dPr, \"begChr\")\n const endChr = firstKid(dPr, \"endChr\")\n const sepChr = firstKid(dPr, \"sepChr\")\n if (begChr) beg = begChr.getAttribute(\"m:val\") ?? begChr.getAttribute(\"val\") ?? beg\n if (endChr) end = endChr.getAttribute(\"m:val\") ?? endChr.getAttribute(\"val\") ?? end\n if (sepChr) sep = sepChr.getAttribute(\"m:val\") ?? sepChr.getAttribute(\"val\") ?? sep\n }\n const items = kids(el, \"e\").map(childrenToLatex)\n const body = items.join(sep)\n return \"\\\\left\" + mapDelim(beg, true) + body + \"\\\\right\" + mapDelim(end, false)\n }\n\n // 행렬\n case \"m\": {\n const rows: string[] = []\n for (const mr of kids(el, \"mr\")) {\n const cells = kids(mr, \"e\").map(childrenToLatex)\n rows.push(cells.join(\" & \"))\n }\n return \"\\\\begin{matrix}\" + rows.join(\" \\\\\\\\ \") + \"\\\\end{matrix}\"\n }\n\n // 상자/박스 (acc 와 유사하지만 bar 가 아닌 box)\n case \"box\":\n return childrenToLatex(el)\n\n // 함수 적용 (sin, cos, log …)\n case \"func\": {\n const fn = firstKid(el, \"fName\")\n const e = firstKid(el, \"e\")\n const fnStr = fn ? childrenToLatex(fn).trim() : \"\"\n const body = e ? childrenToLatex(e) : \"\"\n const fnLatex = FUNC_NAMES.has(fnStr) ? \"\\\\\" + fnStr : fnStr\n return fnLatex + grp(body)\n }\n\n // 악센트 (hat/bar/vec/…)\n case \"acc\": {\n const accPr = firstKid(el, \"accPr\")\n let chr = \"\"\n if (accPr) {\n const chrEl = firstKid(accPr, \"chr\")\n if (chrEl) chr = chrEl.getAttribute(\"m:val\") ?? chrEl.getAttribute(\"val\") ?? \"\"\n }\n // default accent = U+0302 (circumflex)\n if (!chr) chr = \"̂\"\n const e = firstKid(el, \"e\")\n const body = e ? childrenToLatex(e) : \"\"\n const cmd = ACCENT_MAP[chr] ?? \"\\\\hat\"\n return cmd + grp(body)\n }\n\n // bar (위/아래 줄)\n case \"bar\": {\n const barPr = firstKid(el, \"barPr\")\n let pos = \"top\"\n if (barPr) {\n const posEl = firstKid(barPr, \"pos\")\n if (posEl) pos = posEl.getAttribute(\"m:val\") ?? posEl.getAttribute(\"val\") ?? pos\n }\n const e = firstKid(el, \"e\")\n const body = e ? childrenToLatex(e) : \"\"\n return (pos === \"bot\" ? \"\\\\underline\" : \"\\\\overline\") + grp(body)\n }\n\n // lim 위/아래\n case \"limLow\": {\n const e = firstKid(el, \"e\")\n const lim = firstKid(el, \"lim\")\n const base = e ? childrenToLatex(e).trim() : \"\"\n const below = lim ? childrenToLatex(lim) : \"\"\n // 만약 base 가 \"lim\"/\"max\"/\"min\" 이면 \\lim_{...} 식으로\n if (FUNC_NAMES.has(base)) return \"\\\\\" + base + \"_\" + grp(below)\n return base + \"_\" + grp(below)\n }\n case \"limUpp\": {\n const e = firstKid(el, \"e\")\n const lim = firstKid(el, \"lim\")\n const base = e ? childrenToLatex(e).trim() : \"\"\n const above = lim ? childrenToLatex(lim) : \"\"\n if (FUNC_NAMES.has(base)) return \"\\\\\" + base + \"^\" + grp(above)\n return base + \"^\" + grp(above)\n }\n\n // group character (over/underset 비슷)\n case \"groupChr\":\n return childrenToLatex(firstKid(el, \"e\") ?? el)\n\n // box/borderBox/phantom/eqArr/… 는 자식 본문만 유지\n case \"borderBox\":\n case \"phant\":\n case \"eqArr\":\n return childrenToLatex(el)\n\n // 최상위 컨테이너\n case \"oMath\":\n case \"oMathPara\":\n return childrenToLatex(el)\n\n // 메타 — 속성만 들어있으므로 출력 제외\n case \"rPr\":\n case \"fPr\":\n case \"sSubPr\":\n case \"sSupPr\":\n case \"sSubSupPr\":\n case \"radPr\":\n case \"naryPr\":\n case \"dPr\":\n case \"accPr\":\n case \"barPr\":\n case \"funcPr\":\n case \"mPr\":\n case \"ctrlPr\":\n return \"\"\n\n default:\n // 자식 연결로 폴백 (모르면 재귀)\n return childrenToLatex(el)\n }\n}\n\n/** 최상위 OMML 엘리먼트인지 */\nexport function isOmmlRoot(el: Element): boolean {\n const t = lname(el)\n return t === \"oMath\" || t === \"oMathPara\"\n}\n\n/**\n * OMML 엘리먼트(`<m:oMath>` 또는 `<m:oMathPara>`) 를 LaTeX 로 변환.\n * 공백은 정규화(중복 제거 + trim)만 하고 delim($/$$)은 호출자가 추가.\n */\nexport function ommlElementToLatex(el: Element): string {\n if (!isOmmlRoot(el)) return \"\"\n const raw = childrenToLatex(el)\n return raw.replace(/\\s+/g, \" \").trim()\n}\n\n/** `<m:oMathPara>` 는 display mode */\nexport function isDisplayMath(el: Element): boolean {\n return lname(el) === \"oMathPara\"\n}\n","/** HWPML 2.x 파서 — XML 기반 한컴 문서 (.hwp with XML content) */\r\n\r\nimport { DOMParser } from \"@xmldom/xmldom\"\r\nimport type { IRBlock, InternalParseResult, ParseOptions, ParseWarning, DocumentMetadata, OutlineItem } from \"../types.js\"\r\nimport { blocksToMarkdown, buildTable } from \"../table/builder.js\"\r\nimport { parsePageRange } from \"../page-range.js\"\r\nimport { stripDtd } from \"../utils.js\"\r\nimport type { CellContext } from \"../types.js\"\r\n\r\nconst MAX_XML_DEPTH = 200\r\nconst MAX_TABLE_ROWS = 5000\r\nconst MAX_TABLE_COLS = 500\r\nconst MAX_HWPML_BYTES = 50 * 1024 * 1024 // 50MB 상한\r\n\r\n/** ParaShape 헤딩 정보 */\r\ninterface ParaShapeInfo {\r\n headingLevel: number | null // null = 일반 단락, 1-6 = 헤딩 레벨\r\n}\r\n\r\n/** HWPML 문서 파싱 진입점 */\r\nexport function parseHwpmlDocument(buffer: ArrayBuffer, options?: ParseOptions): InternalParseResult {\r\n if (buffer.byteLength > MAX_HWPML_BYTES) {\r\n throw new Error(`HWPML 파일 크기 초과 (${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB > 50MB)`)\r\n }\r\n const text = new TextDecoder(\"utf-8\").decode(buffer).replace(/^\\uFEFF/, \"\")\r\n\r\n // &nbsp; 엔티티 치환 (DOCTYPE 제거 전에 처리)\r\n const normalized = text.replace(/&nbsp;/g, \"&#160;\")\r\n const xml = stripDtd(normalized)\r\n\r\n const warnings: ParseWarning[] = []\r\n const parser = new DOMParser({\r\n onError: (_level: string, msg: string) => {\r\n warnings.push({ message: `HWPML XML 파싱 경고: ${msg}`, code: \"MALFORMED_XML\" })\r\n },\r\n } as ConstructorParameters<typeof DOMParser>[0])\r\n\r\n const doc = parser.parseFromString(xml, \"text/xml\")\r\n if (!doc.documentElement) {\r\n return { markdown: \"\", blocks: [], warnings }\r\n }\r\n\r\n const root = doc.documentElement\r\n\r\n // ─── 메타데이터 추출 ──────────────────────────────────\r\n const metadata: DocumentMetadata = {}\r\n const docSummary = findChild(root, \"DOCSUMMARY\")\r\n if (docSummary) {\r\n const title = findChild(docSummary, \"TITLE\")\r\n const author = findChild(docSummary, \"AUTHOR\")\r\n const date = findChild(docSummary, \"DATE\")\r\n if (title) metadata.title = textContent(title).trim()\r\n if (author) metadata.author = textContent(author).trim()\r\n if (date) metadata.createdAt = textContent(date).trim() || undefined\r\n }\r\n\r\n // ─── HEAD: ParaShape 맵 구축 ──────────────────────────\r\n const paraShapeMap = buildParaShapeMap(root)\r\n\r\n // ─── BODY 파싱 ────────────────────────────────────────\r\n const body = findChild(root, \"BODY\")\r\n if (!body) {\r\n return { markdown: \"\", blocks: [], metadata, warnings }\r\n }\r\n\r\n const blocks: IRBlock[] = []\r\n const pageFilter = options?.pages ? parsePageRange(options.pages, countSections(body)) : null\r\n let sectionIdx = 0\r\n\r\n const children = body.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType !== 1) continue\r\n if (localName(el) !== \"SECTION\") continue\r\n\r\n sectionIdx++\r\n if (pageFilter && !pageFilter.has(sectionIdx)) continue\r\n\r\n parseSection(el, blocks, paraShapeMap, sectionIdx, warnings)\r\n }\r\n\r\n // ─── 헤딩 트리(outline) 구성 ──────────────────────────\r\n const outline: OutlineItem[] = blocks\r\n .filter(b => b.type === \"heading\" && b.text)\r\n .map(b => ({ level: b.level ?? 1, text: b.text!, pageNumber: b.pageNumber }))\r\n\r\n const markdown = blocksToMarkdown(blocks)\r\n return {\r\n markdown,\r\n blocks,\r\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\r\n outline: outline.length > 0 ? outline : undefined,\r\n warnings: warnings.length > 0 ? warnings : undefined,\r\n }\r\n}\r\n\r\n// ─── ParaShape 맵 ────────────────────────────────────────\r\n\r\nfunction buildParaShapeMap(root: Element): Map<string, ParaShapeInfo> {\r\n const map = new Map<string, ParaShapeInfo>()\r\n const head = findChild(root, \"HEAD\")\r\n if (!head) return map\r\n\r\n const mappingTable = findChild(head, \"MAPPINGTABLE\")\r\n if (!mappingTable) return map\r\n\r\n const paraShapeList = findChild(mappingTable, \"PARASHAPELIST\")\r\n if (!paraShapeList) return map\r\n\r\n const children = paraShapeList.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType !== 1 || localName(el) !== \"PARASHAPE\") continue\r\n const id = el.getAttribute(\"Id\") ?? \"\"\r\n const headingType = el.getAttribute(\"HeadingType\") ?? \"None\"\r\n const level = parseInt(el.getAttribute(\"Level\") ?? \"0\", 10)\r\n let headingLevel: number | null = null\r\n if (headingType === \"Outline\") {\r\n const safeLevel = isNaN(level) ? 0 : Math.max(0, level)\r\n headingLevel = Math.min(safeLevel + 1, 6) // Level 0→H1, 1→H2, ..., 5→H6\r\n }\r\n map.set(id, { headingLevel })\r\n }\r\n\r\n return map\r\n}\r\n\r\n// ─── 섹션 파싱 ───────────────────────────────────────────\r\n\r\nfunction parseSection(\r\n section: Element,\r\n blocks: IRBlock[],\r\n paraShapeMap: Map<string, ParaShapeInfo>,\r\n sectionNum: number,\r\n warnings: ParseWarning[],\r\n): void {\r\n walkContent(section, blocks, paraShapeMap, sectionNum, warnings, false)\r\n}\r\n\r\n/**\r\n * 콘텐츠 노드를 재귀적으로 순회하여 IRBlock 생성.\r\n * inHeaderFooter=true일 때 단락/표 블록 출력 억제.\r\n */\r\nfunction walkContent(\r\n node: Element,\r\n blocks: IRBlock[],\r\n paraShapeMap: Map<string, ParaShapeInfo>,\r\n sectionNum: number,\r\n warnings: ParseWarning[],\r\n inHeaderFooter: boolean,\r\n depth: number = 0,\r\n): void {\r\n if (depth > MAX_XML_DEPTH) return\r\n const children = node.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType !== 1) continue\r\n const tag = localName(el)\r\n\r\n if (tag === \"HEADER\" || tag === \"FOOTER\") {\r\n // 머리글/바닥글 — 텍스트 콘텐츠 무시\r\n continue\r\n }\r\n\r\n if (tag === \"P\") {\r\n if (!inHeaderFooter) {\r\n parseParagraph(el, blocks, paraShapeMap, sectionNum)\r\n }\r\n continue\r\n }\r\n\r\n if (tag === \"TABLE\") {\r\n if (!inHeaderFooter) {\r\n parseTable(el, blocks, paraShapeMap, sectionNum, warnings)\r\n }\r\n continue\r\n }\r\n\r\n // PARALIST, SUBLIST, SECTION 내부 등 — 재귀\r\n if (tag === \"PARALIST\" || tag === \"SECTION\" || tag === \"COLDEF\") {\r\n walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, depth + 1)\r\n continue\r\n }\r\n\r\n // TEXT, SECDEF 등 내부에서도 P/TABLE이 중첩될 수 있음 — 재귀\r\n walkContent(el, blocks, paraShapeMap, sectionNum, warnings, inHeaderFooter, depth + 1)\r\n }\r\n}\r\n\r\n// ─── 단락 파싱 ───────────────────────────────────────────\r\n\r\nfunction parseParagraph(\r\n el: Element,\r\n blocks: IRBlock[],\r\n paraShapeMap: Map<string, ParaShapeInfo>,\r\n sectionNum: number,\r\n): void {\r\n const paraShapeId = el.getAttribute(\"ParaShape\") ?? \"\"\r\n const shapeInfo = paraShapeMap.get(paraShapeId)\r\n\r\n const text = extractParagraphText(el)\r\n if (!text) return\r\n\r\n if (shapeInfo?.headingLevel != null) {\r\n blocks.push({ type: \"heading\", text, level: shapeInfo.headingLevel, pageNumber: sectionNum })\r\n } else {\r\n blocks.push({ type: \"paragraph\", text, pageNumber: sectionNum })\r\n }\r\n}\r\n\r\n/** <P> 에서 텍스트 추출 — <TEXT><CHAR> 순회 */\r\nfunction extractParagraphText(p: Element): string {\r\n const parts: string[] = []\r\n collectCharText(p, parts)\r\n return parts.join(\"\").trim()\r\n}\r\n\r\nfunction collectCharText(node: Element, parts: string[], depth: number = 0): void {\r\n if (depth > MAX_XML_DEPTH) return\r\n const children = node.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType !== 1) continue\r\n const tag = localName(el)\r\n\r\n if (tag === \"CHAR\") {\r\n // textContent — 자식 텍스트 노드 직접 수집\r\n const t = textContent(el)\r\n if (t) parts.push(t)\r\n } else if (tag === \"TABLE\" || tag === \"PICTURE\" || tag === \"SHAPEOBJECT\") {\r\n // 단락 내 테이블/이미지는 별도 블록으로 처리되므로 스킵\r\n } else if (tag === \"AUTONUM\") {\r\n // 자동 번호 (페이지 번호 등) 스킵\r\n } else {\r\n collectCharText(el, parts, depth + 1)\r\n }\r\n }\r\n}\r\n\r\n// ─── 테이블 파싱 ─────────────────────────────────────────\r\n\r\nfunction parseTable(\r\n el: Element,\r\n blocks: IRBlock[],\r\n paraShapeMap: Map<string, ParaShapeInfo>,\r\n sectionNum: number,\r\n warnings: ParseWarning[],\r\n): void {\r\n const cells: CellContext[] = []\r\n const rowCount = parseInt(el.getAttribute(\"RowCount\") ?? \"0\", 10)\r\n const colCount = parseInt(el.getAttribute(\"ColCount\") ?? \"0\", 10)\r\n if (isNaN(rowCount) || isNaN(colCount) || rowCount === 0 || colCount === 0) return\r\n if (rowCount > MAX_TABLE_ROWS || colCount > MAX_TABLE_COLS) {\r\n warnings.push({ message: `테이블 크기 초과 (${rowCount}x${colCount}) — 스킵`, code: \"TRUNCATED_TABLE\" })\r\n return\r\n }\r\n\r\n // <ROW> → <CELL> 순회\r\n const children = el.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const rowEl = children[i] as Element\r\n if (rowEl.nodeType !== 1 || localName(rowEl) !== \"ROW\") continue\r\n\r\n const rowCells = rowEl.childNodes\r\n for (let j = 0; j < rowCells.length; j++) {\r\n const cellEl = rowCells[j] as Element\r\n if (cellEl.nodeType !== 1 || localName(cellEl) !== \"CELL\") continue\r\n\r\n const colAddr = parseInt(cellEl.getAttribute(\"ColAddr\") ?? \"0\", 10)\r\n const rowAddr = parseInt(cellEl.getAttribute(\"RowAddr\") ?? \"0\", 10)\r\n // colSpan/rowSpan 클램핑: NaN, 음수, 과대값 방어\r\n const colSpan = Math.min(Math.max(1, parseInt(cellEl.getAttribute(\"ColSpan\") ?? \"1\", 10) || 1), MAX_TABLE_COLS)\r\n const rowSpan = Math.min(Math.max(1, parseInt(cellEl.getAttribute(\"RowSpan\") ?? \"1\", 10) || 1), MAX_TABLE_ROWS)\r\n\r\n // 셀 텍스트: PARALIST > P 재귀 추출\r\n const cellText = extractCellText(cellEl)\r\n\r\n cells.push({ text: cellText, colSpan, rowSpan, colAddr, rowAddr })\r\n }\r\n }\r\n\r\n if (cells.length === 0) return\r\n\r\n // 그리드 배치 (HWP5와 동일한 방식 — colAddr/rowAddr 사용)\r\n const grid: (CellContext | null)[][] = Array.from({ length: rowCount }, () => Array(colCount).fill(null))\r\n for (const cell of cells) {\r\n const r = cell.rowAddr ?? 0\r\n const c = cell.colAddr ?? 0\r\n if (isNaN(r) || isNaN(c) || r >= rowCount || c >= colCount) continue\r\n grid[r][c] = cell\r\n for (let dr = 0; dr < cell.rowSpan; dr++) {\r\n for (let dc = 0; dc < cell.colSpan; dc++) {\r\n if (dr === 0 && dc === 0) continue\r\n if (r + dr < rowCount && c + dc < colCount) {\r\n grid[r + dr][c + dc] = { text: \"\", colSpan: 1, rowSpan: 1 }\r\n }\r\n }\r\n }\r\n }\r\n\r\n const cellRows: CellContext[][] = grid.map(row =>\r\n row.map(cell => cell ?? { text: \"\", colSpan: 1, rowSpan: 1 })\r\n )\r\n\r\n const table = buildTable(cellRows)\r\n blocks.push({ type: \"table\", table, pageNumber: sectionNum })\r\n}\r\n\r\n/** 셀 내부 텍스트 추출 — PARALIST > P 재귀, 중첩 테이블은 평탄화 */\r\nfunction extractCellText(cellEl: Element): string {\r\n const textParts: string[] = []\r\n collectCellText(cellEl, textParts, 0)\r\n return textParts.filter(Boolean).join(\"\\n\").trim()\r\n}\r\n\r\nfunction collectCellText(node: Element, parts: string[], depth: number): void {\r\n if (depth > 20) return\r\n const children = node.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType !== 1) continue\r\n const tag = localName(el)\r\n\r\n if (tag === \"P\") {\r\n const t = extractParagraphText(el)\r\n if (t) parts.push(t)\r\n } else if (tag === \"TABLE\") {\r\n // 중첩 테이블 — 텍스트로 평탄화\r\n parts.push(\"[중첩 테이블]\")\r\n } else {\r\n collectCellText(el, parts, depth + 1)\r\n }\r\n }\r\n}\r\n\r\n// ─── XML 유틸 ────────────────────────────────────────────\r\n\r\nfunction localName(el: Element): string {\r\n return (el.tagName || el.localName || \"\").replace(/^[^:]+:/, \"\")\r\n}\r\n\r\nfunction findChild(parent: Element, tag: string): Element | null {\r\n const children = parent.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType === 1 && localName(el) === tag) return el\r\n }\r\n return null\r\n}\r\n\r\nfunction textContent(el: Element): string {\r\n const children = el.childNodes\r\n const parts: string[] = []\r\n for (let i = 0; i < children.length; i++) {\r\n const node = children[i]\r\n if (node.nodeType === 3) { // TEXT_NODE\r\n parts.push(node.nodeValue || \"\")\r\n } else if (node.nodeType === 1) {\r\n parts.push(textContent(node as Element))\r\n }\r\n }\r\n return parts.join(\"\")\r\n}\r\n\r\nfunction countSections(body: Element): number {\r\n let count = 0\r\n const children = body.childNodes\r\n for (let i = 0; i < children.length; i++) {\r\n const el = children[i] as Element\r\n if (el.nodeType === 1 && localName(el) === \"SECTION\") count++\r\n }\r\n return count\r\n}\r\n","/** 양식(서식) 필드 인식 — 테이블 기반 label-value 패턴 매칭 */\r\n\r\nimport type { IRBlock, IRTable, FormField, FormResult } from \"../types.js\"\r\n\r\n/** 한국 공문서 필드 라벨 키워드 */\r\nexport const LABEL_KEYWORDS = new Set([\r\n \"성명\", \"이름\", \"주소\", \"전화\", \"전화번호\", \"휴대폰\", \"핸드폰\", \"연락처\",\r\n \"생년월일\", \"주민등록번호\", \"소속\", \"직위\", \"직급\", \"부서\",\r\n \"이메일\", \"팩스\", \"학교\", \"학년\", \"반\", \"번호\",\r\n \"신청인\", \"대표자\", \"담당자\", \"작성자\", \"확인자\", \"승인자\",\r\n \"일시\", \"날짜\", \"기간\", \"장소\", \"목적\", \"사유\", \"비고\",\r\n \"금액\", \"수량\", \"단가\", \"합계\", \"계\", \"소계\",\r\n \"등록기준지\", \"본적\", \"위임인\", \"청구사유\", \"소명자료\",\r\n])\r\n\r\n/** 라벨처럼 보이는 셀인지 판별 */\r\nexport function isLabelCell(text: string): boolean {\r\n // 각주 번호/특수문자 제거 후 판별 (예: \"등록기준지²\" → \"등록기준지\")\r\n const trimmed = text.trim().replace(/[¹²³⁴⁵⁶⁷⁸⁹⁰*※]+$/g, \"\").trim()\r\n if (!trimmed || trimmed.length > 30) return false\r\n // 키워드 매칭\r\n for (const kw of LABEL_KEYWORDS) {\r\n if (trimmed.includes(kw)) return true\r\n }\r\n // 짧은 한글 텍스트 (2-8자) + 숫자 없음 (공백/괄호/특수기호 허용)\r\n if (/^[가-힣\\s()()·::]+$/.test(trimmed) && trimmed.replace(/\\s/g, \"\").length >= 2 && trimmed.replace(/\\s/g, \"\").length <= 8 && !/\\d/.test(trimmed)) return true\r\n // \"라벨:\" 패턴\r\n if (/^[가-힣A-Za-z\\s]+[::]$/.test(trimmed)) return true\r\n return false\r\n}\r\n\r\n/**\r\n * IRBlock[]에서 양식 필드를 인식하여 추출.\r\n * 테이블의 label-value 패턴을 감지.\r\n */\r\nexport function extractFormFields(blocks: IRBlock[]): FormResult {\r\n const fields: FormField[] = []\r\n let totalTables = 0\r\n let formTables = 0\r\n\r\n for (const block of blocks) {\r\n if (block.type !== \"table\" || !block.table) continue\r\n totalTables++\r\n\r\n const tableFields = extractFromTable(block.table)\r\n if (tableFields.length > 0) {\r\n formTables++\r\n fields.push(...tableFields)\r\n }\r\n }\r\n\r\n // 인라인 \"라벨: 값\" 패턴도 검사 (paragraph만 — heading/list는 양식 필드가 아님)\r\n for (const block of blocks) {\r\n if (block.type === \"paragraph\" && block.text) {\r\n const inlineFields = extractInlineFields(block.text)\r\n fields.push(...inlineFields)\r\n }\r\n }\r\n\r\n const confidence = totalTables > 0 ? formTables / totalTables : (fields.length > 0 ? 0.3 : 0)\r\n return { fields, confidence: Math.min(confidence, 1) }\r\n}\r\n\r\nfunction extractFromTable(table: IRTable): FormField[] {\r\n const fields: FormField[] = []\r\n\r\n // 전략 1: 인접셀 label-value (2열 이상 테이블)\r\n if (table.cols >= 2) {\r\n for (let r = 0; r < table.rows; r++) {\r\n for (let c = 0; c < table.cols - 1; c++) {\r\n const labelCell = table.cells[r][c]\r\n const valueCell = table.cells[r][c + 1]\r\n if (isLabelCell(labelCell.text)) {\r\n fields.push({\r\n label: labelCell.text.trim().replace(/[::]\\s*$/, \"\"),\r\n value: valueCell.text.trim(),\r\n row: r,\r\n col: c,\r\n })\r\n }\r\n }\r\n }\r\n }\r\n\r\n // 전략 2: 헤더+데이터 행 (첫 행이 전부 라벨이면)\r\n if (fields.length === 0 && table.rows >= 2 && table.cols >= 2) {\r\n const headerRow = table.cells[0]\r\n const allLabels = headerRow.every(cell => {\r\n const t = cell.text.trim()\r\n return t.length > 0 && t.length <= 20\r\n })\r\n if (allLabels) {\r\n for (let r = 1; r < table.rows; r++) {\r\n for (let c = 0; c < table.cols; c++) {\r\n const label = headerRow[c].text.trim()\r\n const value = table.cells[r][c].text.trim()\r\n if (label && value) {\r\n fields.push({ label, value, row: r, col: c })\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return fields\r\n}\r\n\r\nfunction extractInlineFields(text: string): FormField[] {\r\n const fields: FormField[] = []\r\n // \"라벨: 값\" 또는 \"라벨 : 값\" 패턴\r\n const pattern = /([가-힣A-Za-z]{2,10})\\s*[::]\\s*([^\\n,;]{1,100})/g\r\n let match\r\n while ((match = pattern.exec(text)) !== null) {\r\n const label = match[1].trim()\r\n const value = match[2].trim()\r\n if (value) {\r\n fields.push({ label, value, row: -1, col: -1 })\r\n }\r\n }\r\n return fields\r\n}\r\n","/** 양식 필드 매칭 공용 유틸 — filler.ts, filler-hwpx.ts에서 공유 */\n\nimport { LABEL_KEYWORDS } from \"./recognize.js\"\n\n/** 라벨 정규화 — 콜론/공백/특수문자 제거, 비교용 */\nexport function normalizeLabel(label: string): string {\n return label.trim().replace(/[::\\s()()·]/g, \"\")\n}\n\n/**\n * 정규화된 셀 라벨과 입력 값 맵에서 최적 매칭 키를 찾음.\n *\n * 매칭 우선순위:\n * 1. 정확 매칭 (normalizedCellLabel === key)\n * 2. 접두사 기반 매칭 (60% 이상 겹침 필요)\n */\nexport function findMatchingKey(\n cellLabel: string,\n values: Map<string, string>,\n): string | undefined {\n // 1) 정확 매칭\n if (values.has(cellLabel)) return cellLabel\n\n // 2) 접두사 기반 매칭 — 가장 긴 매칭 우선 (= 가장 구체적)\n // 단, 길이 비율 60% 이상 겹쳐야 매칭 (오탐 방지)\n let bestKey: string | undefined\n let bestLen = 0\n\n for (const key of values.keys()) {\n if (cellLabel.startsWith(key)) {\n if (key.length >= cellLabel.length * 0.6 && key.length > bestLen) {\n bestLen = key.length\n bestKey = key\n }\n } else if (key.startsWith(cellLabel)) {\n if (cellLabel.length >= key.length * 0.6 && cellLabel.length > bestLen) {\n bestLen = cellLabel.length\n bestKey = key\n }\n }\n }\n\n return bestKey\n}\n\n/**\n * 값 셀이 키워드 라벨(섹션 헤더의 하위 라벨)인지 판별.\n * \"성명\", \"주소\" 같은 키워드 라벨이면 true → 스킵 대상.\n * \"(한자:)\" 같은 어노테이션이면 false → 채울 수 있음.\n */\nexport function isKeywordLabel(text: string): boolean {\n const trimmed = text.trim().replace(/[¹²³⁴⁵⁶⁷⁸⁹⁰*※]+$/g, \"\").trim()\n if (!trimmed || trimmed.length > 15) return false\n for (const kw of LABEL_KEYWORDS) {\n if (trimmed.includes(kw)) return true\n }\n return false\n}\n\n/**\n * 셀 텍스트에서 인셀 패턴을 찾아 교체 — 체크박스 + 괄호 빈칸.\n *\n * 지원 패턴:\n * 1. 괄호 빈칸: `일반( )통` → 키 \"일반통\" 또는 \"일반\" 매칭 시 → `일반(값)통`\n * 2. 체크박스: `□부` → 키 \"부\" 매칭 시 → `☑부` (값이 \"☑\",\"✓\",\"v\",\"V\",\"true\",\"1\" 등)\n *\n * @returns 교체된 텍스트 + 매칭된 키 목록. null이면 교체 없음.\n */\nexport function fillInCellPatterns(\n cellText: string,\n values: Map<string, string>,\n matchedLabels: Set<string>,\n): { text: string; matches: Array<{ key: string; label: string; value: string }> } | null {\n let text = cellText\n const matches: Array<{ key: string; label: string; value: string }> = []\n\n // 1) 괄호 빈칸: keyword(\\s+)suffix → keyword(value)suffix\n text = text.replace(\n /([가-힣A-Za-z]+)\\(\\s{1,}\\)([가-힣A-Za-z]*)/g,\n (match, prefix: string, suffix: string) => {\n const label = prefix + suffix // \"일반\" + \"통\" = \"일반통\"\n const normalizedLabel = normalizeLabel(label)\n // 정확 매칭 → 접두사만 매칭 순\n const matchKey = values.has(normalizedLabel)\n ? normalizedLabel\n : values.has(normalizeLabel(prefix))\n ? normalizeLabel(prefix)\n : undefined\n if (matchKey === undefined) return match\n\n const newValue = values.get(matchKey)!\n matchedLabels.add(matchKey)\n matches.push({ key: matchKey, label, value: newValue })\n return `${prefix}(${newValue})${suffix}`\n },\n )\n\n // 2) 체크박스: □keyword → ☑keyword (값이 truthy)\n text = text.replace(\n /□([가-힣A-Za-z]+)/g,\n (match, keyword: string) => {\n const normalizedKw = normalizeLabel(keyword)\n const matchKey = values.has(normalizedKw) ? normalizedKw : undefined\n if (matchKey === undefined) return match\n\n const val = values.get(matchKey)!\n const isTruthy = [\"☑\", \"✓\", \"✔\", \"v\", \"V\", \"true\", \"1\", \"yes\", \"o\", \"O\"].includes(val.trim()) || val.trim() === \"\"\n if (!isTruthy) return match\n\n matchedLabels.add(matchKey)\n matches.push({ key: matchKey, label: `□${keyword}`, value: \"☑\" })\n return `☑${keyword}`\n },\n )\n\n // 3) 어노테이션 빈칸: (keyword:\\s+) → (keyword:value)\n // 예: \"(한자: )\" → \"(한자:金民秀)\"\n // 예: \"(성명: )\" → \"(성명: 홍길동)\"\n text = text.replace(\n /\\(([가-힣A-Za-z]+)[::]\\s{1,}\\)/g,\n (match, keyword: string) => {\n const normalizedKw = normalizeLabel(keyword)\n const matchKey = values.has(normalizedKw) ? normalizedKw : undefined\n if (matchKey === undefined) return match\n\n const newValue = values.get(matchKey)!\n matchedLabels.add(matchKey)\n matches.push({ key: matchKey, label: keyword, value: newValue })\n return `(${keyword}:${newValue})`\n },\n )\n\n return matches.length > 0 ? { text, matches } : null\n}\n\n/** 입력 values 맵을 정규화된 키로 변환 */\nexport function normalizeValues(values: Record<string, string>): Map<string, string> {\n const map = new Map<string, string>()\n for (const [label, value] of Object.entries(values)) {\n map.set(normalizeLabel(label), value)\n }\n return map\n}\n\n/** 매칭 안 된 라벨을 원본 키로 복원 */\nexport function resolveUnmatched(\n normalizedValues: Map<string, string>,\n matchedLabels: Set<string>,\n originalValues: Record<string, string>,\n): string[] {\n return [...normalizedValues.keys()]\n .filter(k => !matchedLabels.has(k))\n .map(k => {\n for (const orig of Object.keys(originalValues)) {\n if (normalizeLabel(orig) === k) return orig\n }\n return k\n })\n}\n","/** 양식 서식 필드 값 채우기 — IRBlock[] 기반 in-place 교체 */\n\nimport type { IRBlock, IRTable, FormField } from \"../types.js\"\nimport { isLabelCell } from \"./recognize.js\"\nimport { normalizeLabel, findMatchingKey, normalizeValues, resolveUnmatched, isKeywordLabel, fillInCellPatterns } from \"./match.js\"\n\n/** 필드 채우기 결과 */\nexport interface FillResult {\n /** 값이 교체된 IRBlock[] */\n blocks: IRBlock[]\n /** 실제 채워진 필드 목록 */\n filled: FormField[]\n /** 매칭 실패한 라벨 (입력에는 있지만 서식에서 못 찾은 것) */\n unmatched: string[]\n}\n\n/**\n * IRBlock[]에서 양식 필드를 찾아 값을 교체.\n *\n * @param blocks 원본 IRBlock[] (변경하지 않음 — deep clone)\n * @param values 채울 값 맵 (라벨 → 새 값). 라벨은 접두사 매칭 지원.\n * @returns FillResult\n *\n * @example\n * ```ts\n * const result = await parse(\"신청서.hwp\")\n * if (!result.success) throw new Error(result.error)\n * const { blocks, filled } = fillFormFields(result.blocks, {\n * \"성명\": \"홍길동\",\n * \"전화번호\": \"010-1234-5678\",\n * \"주소\": \"서울시 강남구\",\n * })\n * ```\n */\nexport function fillFormFields(\n blocks: IRBlock[],\n values: Record<string, string>,\n): FillResult {\n // deep clone — 원본 불변\n const cloned = structuredClone(blocks)\n const filled: FormField[] = []\n const matchedLabels = new Set<string>()\n\n const normalizedValues = normalizeValues(values)\n\n // 1) 인셀 패턴 먼저 (체크박스, 괄호 빈칸, 어노테이션) — 전략 2가 덮어쓰기 전에\n const patternFilledCells = new Set<string>() // \"r,c\" 키\n for (const block of cloned) {\n if (block.type !== \"table\" || !block.table) continue\n for (let r = 0; r < block.table.rows; r++) {\n for (let c = 0; c < block.table.cols; c++) {\n const cell = block.table.cells[r]?.[c]\n if (!cell) continue\n const result = fillInCellPatterns(cell.text, normalizedValues, matchedLabels)\n if (result) {\n cell.text = result.text\n patternFilledCells.add(`${r},${c}`)\n for (const m of result.matches) {\n filled.push({ label: m.label, value: m.value, row: r, col: c })\n }\n }\n }\n }\n }\n\n // 2) 테이블 기반 필드 교체 (라벨-값 셀 패턴)\n for (const block of cloned) {\n if (block.type !== \"table\" || !block.table) continue\n fillTable(block.table, normalizedValues, filled, matchedLabels, patternFilledCells)\n }\n\n // 3) 인라인 \"라벨: 값\" 패턴 교체\n for (const block of cloned) {\n if (block.type !== \"paragraph\" || !block.text) continue\n const newText = fillInlineFields(block.text, normalizedValues, filled, matchedLabels)\n if (newText !== block.text) block.text = newText\n }\n\n const unmatched = resolveUnmatched(normalizedValues, matchedLabels, values)\n return { blocks: cloned, filled, unmatched }\n}\n\n/** 테이블 셀에서 라벨-값 패턴을 찾아 값 교체 */\nfunction fillTable(\n table: IRTable,\n values: Map<string, string>,\n filled: FormField[],\n matchedLabels: Set<string>,\n patternFilledCells?: Set<string>,\n): void {\n if (table.cols < 2) return\n\n // 전략 1: 인접 라벨-값 셀 패턴\n for (let r = 0; r < table.rows; r++) {\n for (let c = 0; c < table.cols - 1; c++) {\n const labelCell = table.cells[r][c]\n const valueCell = table.cells[r][c + 1]\n if (!labelCell || !valueCell) continue\n\n if (!isLabelCell(labelCell.text)) continue\n\n if (isKeywordLabel(valueCell.text)) continue\n\n const normalizedCellLabel = normalizeLabel(labelCell.text)\n if (!normalizedCellLabel) continue\n\n const matchKey = findMatchingKey(normalizedCellLabel, values)\n if (matchKey === undefined) continue\n\n const newValue = values.get(matchKey)!\n // 이미 인셀 패턴이 처리된 셀이면 앞에 삽입 (어노테이션 보존)\n if (patternFilledCells?.has(`${r},${c + 1}`)) {\n valueCell.text = newValue + \" \" + valueCell.text\n } else {\n valueCell.text = newValue\n }\n matchedLabels.add(matchKey)\n filled.push({\n label: labelCell.text.trim().replace(/[::]\\s*$/, \"\"),\n value: newValue,\n row: r,\n col: c,\n })\n }\n }\n\n // 전략 2: 헤더+데이터 행 패턴 (첫 행이 전부 라벨이면)\n // 전략 1에서 이미 채운 필드는 스킵 (matchedLabels 검사)\n if (table.rows >= 2 && table.cols >= 2) {\n const headerRow = table.cells[0]\n const allLabels = headerRow.every(cell => {\n const t = cell.text.trim()\n return t.length > 0 && t.length <= 20 && isLabelCell(t)\n })\n if (!allLabels) return\n\n for (let r = 1; r < table.rows; r++) {\n for (let c = 0; c < table.cols; c++) {\n const headerLabel = normalizeLabel(headerRow[c].text)\n const matchKey = findMatchingKey(headerLabel, values)\n if (matchKey === undefined) continue\n if (matchedLabels.has(matchKey)) continue\n\n const newValue = values.get(matchKey)!\n table.cells[r][c].text = newValue\n matchedLabels.add(matchKey)\n filled.push({\n label: headerRow[c].text.trim(),\n value: newValue,\n row: r,\n col: c,\n })\n }\n }\n }\n}\n\n/** 인라인 \"라벨: 값\" 패턴 교체 */\nfunction fillInlineFields(\n text: string,\n values: Map<string, string>,\n filled: FormField[],\n matchedLabels: Set<string>,\n): string {\n return text.replace(\n /([가-힣A-Za-z]{2,10})\\s*[::]\\s*([^\\n,;]{0,100})/g,\n (match, rawLabel: string, _oldValue: string) => {\n const normalized = normalizeLabel(rawLabel)\n const matchKey = findMatchingKey(normalized, values)\n if (matchKey === undefined) return match\n\n const newValue = values.get(matchKey)!\n matchedLabels.add(matchKey)\n filled.push({\n label: rawLabel.trim(),\n value: newValue,\n row: -1,\n col: -1,\n })\n return `${rawLabel}: ${newValue}`\n },\n )\n}\n","/**\r\n * HWPX 원본 서식 유지 채우기 — ZIP 내 section XML 직접 수정\r\n *\r\n * IRBlock 중간 표현을 거치지 않고, 원본 HWPX ZIP의 section XML에서\r\n * 테이블 셀 텍스트(<hp:t>)만 교체하여 모든 스타일을 보존합니다.\r\n */\r\n\r\nimport JSZip from \"jszip\"\r\nimport { DOMParser, XMLSerializer } from \"@xmldom/xmldom\"\r\nimport { isLabelCell } from \"../form/recognize.js\"\r\nimport { KordocError, stripDtd } from \"../utils.js\"\r\nimport { normalizeLabel, findMatchingKey, normalizeValues, resolveUnmatched, isKeywordLabel, fillInCellPatterns } from \"./match.js\"\r\nimport type { FormField } from \"../types.js\"\r\n\r\n/** 채우기 결과 */\r\nexport interface HwpxFillResult {\r\n /** 채워진 HWPX 바이너리 */\r\n buffer: ArrayBuffer\r\n /** 실제 채워진 필드 목록 */\r\n filled: FormField[]\r\n /** 매칭 실패한 라벨 */\r\n unmatched: string[]\r\n}\r\n\r\n/**\r\n * HWPX 원본을 직접 수정하여 서식 필드를 채움 — 스타일 100% 보존.\r\n *\r\n * @param hwpxBuffer 원본 HWPX 파일 버퍼\r\n * @param values 채울 값 맵 (라벨 → 값)\r\n * @returns HwpxFillResult\r\n */\r\nexport async function fillHwpx(\r\n hwpxBuffer: ArrayBuffer,\r\n values: Record<string, string>,\r\n): Promise<HwpxFillResult> {\r\n const zip = await JSZip.loadAsync(hwpxBuffer)\r\n const filled: FormField[] = []\r\n const matchedLabels = new Set<string>()\r\n\r\n const normalizedValues = normalizeValues(values)\r\n\r\n // section XML 파일 찾기\r\n const sectionFiles = Object.keys(zip.files)\r\n .filter(name => /[Ss]ection\\d+\\.xml$/i.test(name))\r\n .sort()\r\n\r\n if (sectionFiles.length === 0) {\r\n throw new KordocError(\"HWPX에서 섹션 파일을 찾을 수 없습니다\")\r\n }\r\n\r\n const xmlParser = new DOMParser()\r\n const xmlSerializer = new XMLSerializer()\r\n\r\n for (const sectionPath of sectionFiles) {\r\n const zipEntry = zip.file(sectionPath)\r\n if (!zipEntry) continue // null 방어\r\n\r\n const rawXml = await zipEntry.async(\"text\")\r\n const doc = xmlParser.parseFromString(stripDtd(rawXml), \"text/xml\")\r\n if (!doc.documentElement) continue\r\n\r\n let modified = false\r\n\r\n // 모든 테이블 요소 탐색\r\n const tables = findAllElements(doc.documentElement as unknown as Node, \"tbl\")\r\n\r\n // 전략 0: 인셀 패턴 채우기 — 전략 1보다 먼저 실행\r\n // (체크박스 □→☑, 괄호 빈칸 ( )→(값), 어노테이션 (한자:)→(한자:값))\r\n // 이렇게 해야 전략 1이 셀을 덮어쓸 때 어노테이션이 보존됨\r\n const cellPatternApplied = new Set<Element>()\r\n for (const tblEl of tables) {\r\n const allCells = findAllElements(tblEl, \"tc\")\r\n for (const tcEl of allCells) {\r\n const tNodes = collectCellTextNodes(tcEl)\r\n const fullText = tNodes.map(n => n.text).join(\"\")\r\n const result = fillInCellPatterns(fullText, normalizedValues, matchedLabels)\r\n if (!result) continue\r\n\r\n applyTextReplacements(tNodes, fullText, result.text)\r\n cellPatternApplied.add(tcEl)\r\n for (const m of result.matches) {\r\n filled.push({ label: m.label, value: m.value, row: -1, col: -1 })\r\n }\r\n modified = true\r\n }\r\n }\r\n\r\n for (const tblEl of tables) {\r\n const rows = findDirectChildren(tblEl, \"tr\")\r\n\r\n // 전략 1: 인접 라벨-값 셀 (label | value 패턴)\r\n for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {\r\n const trEl = rows[rowIdx]\r\n const cells = findDirectChildren(trEl, \"tc\")\r\n\r\n for (let colIdx = 0; colIdx < cells.length - 1; colIdx++) {\r\n const labelText = extractCellText(cells[colIdx])\r\n if (!isLabelCell(labelText)) continue\r\n\r\n const valueCell = cells[colIdx + 1]\r\n const valueText = extractCellText(valueCell)\r\n if (isKeywordLabel(valueText)) continue\r\n\r\n const normalizedCellLabel = normalizeLabel(labelText)\r\n if (!normalizedCellLabel) continue\r\n\r\n const matchKey = findMatchingKey(normalizedCellLabel, normalizedValues)\r\n if (matchKey === undefined) continue\r\n\r\n const newValue = normalizedValues.get(matchKey)!\r\n\r\n // 전략 0이 이미 어노테이션을 채웠다면, 값을 앞에 삽입 (어노테이션 보존)\r\n if (cellPatternApplied.has(valueCell)) {\r\n prependCellText(valueCell, newValue)\r\n } else {\r\n replaceCellText(valueCell, newValue)\r\n }\r\n matchedLabels.add(matchKey)\r\n filled.push({\r\n label: labelText.trim().replace(/[::]\\s*$/, \"\"),\r\n value: newValue,\r\n row: rowIdx,\r\n col: colIdx,\r\n })\r\n modified = true\r\n }\r\n }\r\n\r\n // 전략 2: 헤더+데이터 행 패턴 (첫 행이 전부 라벨이면)\r\n if (rows.length >= 2) {\r\n const headerCells = findDirectChildren(rows[0], \"tc\")\r\n const allLabels = headerCells.every(cell => {\r\n const t = extractCellText(cell).trim()\r\n return t.length > 0 && t.length <= 20 && isLabelCell(t)\r\n })\r\n\r\n if (allLabels) {\r\n for (let rowIdx = 1; rowIdx < rows.length; rowIdx++) {\r\n const dataCells = findDirectChildren(rows[rowIdx], \"tc\")\r\n for (let colIdx = 0; colIdx < Math.min(headerCells.length, dataCells.length); colIdx++) {\r\n const headerLabel = normalizeLabel(extractCellText(headerCells[colIdx]))\r\n const matchKey = findMatchingKey(headerLabel, normalizedValues)\r\n if (matchKey === undefined) continue\r\n if (matchedLabels.has(matchKey)) continue\r\n\r\n const newValue = normalizedValues.get(matchKey)!\r\n replaceCellText(dataCells[colIdx], newValue)\r\n matchedLabels.add(matchKey)\r\n filled.push({\r\n label: extractCellText(headerCells[colIdx]).trim(),\r\n value: newValue,\r\n row: rowIdx,\r\n col: colIdx,\r\n })\r\n modified = true\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // 인라인 \"라벨: 값\" 패턴도 처리 (테이블 밖 paragraph)\r\n const allParagraphs = findAllElements(doc.documentElement as unknown as Node, \"p\")\r\n for (const pEl of allParagraphs) {\r\n if (isInsideTable(pEl)) continue\r\n\r\n // 모든 <hp:t> 텍스트를 위치 정보와 함께 수집\r\n const tNodes = collectTextNodes(pEl)\r\n const fullText = tNodes.map(n => n.text).join(\"\")\r\n\r\n const pattern = /([가-힣A-Za-z]{2,10})\\s*[::]\\s*([^\\n,;]{0,100})/g\r\n let match\r\n while ((match = pattern.exec(fullText)) !== null) {\r\n const rawLabel = match[1]\r\n const normalized = normalizeLabel(rawLabel)\r\n const matchKey = findMatchingKey(normalized, normalizedValues)\r\n if (matchKey === undefined) continue\r\n\r\n const newValue = normalizedValues.get(matchKey)!\r\n // 값 부분의 시작/끝 오프셋 계산\r\n const valueStart = match.index + match[0].length - match[2].length\r\n const valueEnd = match.index + match[0].length\r\n\r\n replaceTextRange(tNodes, valueStart, valueEnd, newValue)\r\n matchedLabels.add(matchKey)\r\n filled.push({ label: rawLabel.trim(), value: newValue, row: -1, col: -1 })\r\n modified = true\r\n // 교체 후 패턴 인덱스 조정 (텍스트 길이 변경됨) — 다음 매칭 건너뜀\r\n break\r\n }\r\n }\r\n\r\n if (modified) {\r\n const newXml = xmlSerializer.serializeToString(doc)\r\n zip.file(sectionPath, newXml)\r\n }\r\n }\r\n\r\n const unmatched = resolveUnmatched(normalizedValues, matchedLabels, values)\r\n const buffer = await zip.generateAsync({ type: \"arraybuffer\" })\r\n return { buffer, filled, unmatched }\r\n}\r\n\r\n// ─── XML 탐색 헬퍼 ──────────────────────────────────\r\n\r\n/** 로컬 태그명 추출 (네임스페이스 프리픽스 제거) */\r\nfunction localName(el: Element): string {\r\n return (el.tagName || el.localName || \"\").replace(/^[^:]+:/, \"\")\r\n}\r\n\r\n/** 문서 전체에서 특정 로컬 태그명의 요소를 재귀 탐색 */\r\nfunction findAllElements(node: Node, tagLocalName: string): Element[] {\r\n const result: Element[] = []\r\n const walk = (n: Node) => {\r\n const children = n.childNodes\r\n if (!children) return\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i] as Element\r\n if (child.nodeType !== 1) continue\r\n if (localName(child) === tagLocalName) result.push(child)\r\n walk(child)\r\n }\r\n }\r\n walk(node)\r\n return result\r\n}\r\n\r\n/** 직계 자식 중 특정 로컬 태그명 요소만 반환 */\r\nfunction findDirectChildren(parent: Node, tagLocalName: string): Element[] {\r\n const result: Element[] = []\r\n const children = parent.childNodes\r\n if (!children) return result\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i] as Element\r\n if (child.nodeType === 1 && localName(child) === tagLocalName) {\r\n result.push(child)\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/** 요소가 <tbl> 안에 있는지 확인 (부모 체인 탐색) */\r\nfunction isInsideTable(el: Element): boolean {\r\n let parent = el.parentNode as Element | null\r\n while (parent) {\r\n if (parent.nodeType === 1 && localName(parent) === \"tbl\") return true\r\n parent = parent.parentNode as Element | null\r\n }\r\n return false\r\n}\r\n\r\n// ─── 셀 텍스트 추출/교체 ────────────────────────────\r\n\r\n/** 셀(<hp:tc>) 내 모든 <hp:t> 텍스트를 합쳐 반환 */\r\nfunction extractCellText(tcEl: Element): string {\r\n const parts: string[] = []\r\n const walk = (node: Node) => {\r\n const children = node.childNodes\r\n if (!children) return\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i] as Element\r\n if (child.nodeType === 3) {\r\n parts.push(child.textContent || \"\")\r\n } else if (child.nodeType === 1) {\r\n const tag = localName(child)\r\n // subList는 tc 아래 p를 감싸는 컨테이너 — 반드시 순회\r\n if (tag === \"t\") walk(child)\r\n else if (tag === \"run\" || tag === \"r\" || tag === \"p\" || tag === \"subList\") walk(child)\r\n else if (tag === \"tab\") parts.push(\"\\t\")\r\n else if (tag === \"br\") parts.push(\"\\n\")\r\n }\r\n }\r\n }\r\n walk(tcEl)\r\n return parts.join(\"\")\r\n}\r\n\r\n/**\r\n * 셀(<hp:tc>)의 첫 번째 <hp:t> 앞에 텍스트를 삽입 — 어노테이션 보존.\r\n * 예: \"(한자:金民秀)\" → \"김민수 (한자:金民秀)\"\r\n */\r\nfunction prependCellText(tcEl: Element, text: string): void {\r\n const tElements = findAllElements(tcEl, \"t\")\r\n if (tElements.length === 0) return\r\n\r\n const firstT = tElements[0]\r\n const existing = firstT.textContent || \"\"\r\n clearChildren(firstT)\r\n firstT.appendChild(firstT.ownerDocument!.createTextNode(text + \" \" + existing))\r\n}\r\n\r\n/**\r\n * 셀(<hp:tc>) 내 텍스트를 새 값으로 교체 — 스타일 보존 전략:\r\n *\r\n * 1) 첫 번째 <hp:run>의 <hp:t>에 새 텍스트 설정\r\n * 2) 나머지 <hp:run>의 <hp:t>는 빈 문자열로\r\n * 3) 두 번째 이후 <hp:p>는 내용만 비움 (요소 유지 — HWPX 뷰어 호환)\r\n *\r\n * 이렇게 하면 첫 번째 run의 charPrIDRef(글꼴, 크기, 굵기 등)가 보존됨\r\n */\r\nfunction replaceCellText(tcEl: Element, newValue: string): void {\r\n const paragraphs = findAllElements(tcEl, \"p\")\r\n if (paragraphs.length === 0) return\r\n\r\n const firstP = paragraphs[0]\r\n const runs = findAllElements(firstP, \"run\").concat(findAllElements(firstP, \"r\"))\r\n\r\n if (runs.length > 0) {\r\n setRunText(runs[0], newValue)\r\n for (let i = 1; i < runs.length; i++) {\r\n setRunText(runs[i], \"\")\r\n }\r\n } else {\r\n const tElements = findAllElements(firstP, \"t\")\r\n if (tElements.length > 0) {\r\n clearChildren(tElements[0])\r\n tElements[0].appendChild(tElements[0].ownerDocument!.createTextNode(newValue))\r\n for (let i = 1; i < tElements.length; i++) {\r\n clearChildren(tElements[i])\r\n }\r\n }\r\n }\r\n\r\n // 두 번째 이후 paragraph — 내용만 비움\r\n for (let i = 1; i < paragraphs.length; i++) {\r\n const p = paragraphs[i]\r\n if (p.parentNode) {\r\n const pRuns = findAllElements(p, \"run\").concat(findAllElements(p, \"r\"))\r\n for (const run of pRuns) setRunText(run, \"\")\r\n const pTs = findAllElements(p, \"t\")\r\n for (const t of pTs) clearChildren(t)\r\n }\r\n }\r\n}\r\n\r\n/** <hp:run> 요소의 <hp:t> 텍스트를 교체 */\r\nfunction setRunText(runEl: Element, text: string): void {\r\n const tElements = findAllElements(runEl, \"t\")\r\n if (tElements.length > 0) {\r\n clearChildren(tElements[0])\r\n tElements[0].appendChild(tElements[0].ownerDocument!.createTextNode(text))\r\n for (let i = 1; i < tElements.length; i++) {\r\n clearChildren(tElements[i])\r\n }\r\n return\r\n }\r\n\r\n // <hp:t>가 없는 빈 run — 한컴오피스가 HWP→HWPX 변환 시 빈 셀의 run을\r\n // self-closing(<hp:run charPrIDRef=\"...\"/>)으로 만들면서 <hp:t>를 생략한다.\r\n // 이 경우 부모 run의 prefix/namespace를 따라 새로 생성해 추가한다.\r\n // 빈 문자열이면 굳이 노드를 만들지 않는다(다른 호출부에서 run을 비울 때 사용).\r\n if (!text) return\r\n\r\n const doc = runEl.ownerDocument!\r\n const ns = runEl.namespaceURI\r\n const qualifiedName = runEl.prefix ? `${runEl.prefix}:t` : \"t\"\r\n const tEl = ns\r\n ? doc.createElementNS(ns, qualifiedName)\r\n : doc.createElement(qualifiedName)\r\n tEl.appendChild(doc.createTextNode(text))\r\n runEl.appendChild(tEl)\r\n}\r\n\r\n/** 요소의 모든 자식 노드 제거 */\r\nfunction clearChildren(el: Element): void {\r\n while (el.firstChild) el.removeChild(el.firstChild)\r\n}\r\n\r\n// ─── 인라인 텍스트 교체 (분리된 <hp:t> 대응) ─────────\r\n\r\n/** <hp:t> 텍스트 노드와 글로벌 오프셋 정보 */\r\ninterface TextNodeInfo {\r\n /** <hp:t> 요소 */\r\n element: Element\r\n /** 이 요소의 텍스트 */\r\n text: string\r\n /** 전체 합산 텍스트에서의 시작 오프셋 */\r\n offset: number\r\n}\r\n\r\n/** paragraph 내 모든 <hp:t> 텍스트 노드를 오프셋과 함께 수집 */\r\nfunction collectTextNodes(pEl: Element): TextNodeInfo[] {\r\n const tElements = findAllElements(pEl, \"t\")\r\n const result: TextNodeInfo[] = []\r\n let offset = 0\r\n for (const t of tElements) {\r\n const text = t.textContent || \"\"\r\n result.push({ element: t, text, offset })\r\n offset += text.length\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 여러 <hp:t>에 걸친 텍스트 범위를 새 값으로 교체.\r\n * 첫 번째 걸리는 <hp:t>에 교체 텍스트를 넣고, 나머지는 해당 범위만큼 잘라냄.\r\n */\r\nfunction replaceTextRange(\r\n tNodes: TextNodeInfo[],\r\n globalStart: number,\r\n globalEnd: number,\r\n newValue: string,\r\n): void {\r\n let replaced = false\r\n for (const node of tNodes) {\r\n const nodeStart = node.offset\r\n const nodeEnd = node.offset + node.text.length\r\n\r\n if (nodeEnd <= globalStart || nodeStart >= globalEnd) continue\r\n\r\n const localStart = Math.max(0, globalStart - nodeStart)\r\n const localEnd = Math.min(node.text.length, globalEnd - nodeStart)\r\n\r\n if (!replaced) {\r\n const before = node.text.slice(0, localStart)\r\n const after = node.text.slice(localEnd)\r\n const newText = before + newValue + after\r\n clearChildren(node.element)\r\n node.element.appendChild(node.element.ownerDocument!.createTextNode(newText))\r\n replaced = true\r\n } else {\r\n const before = node.text.slice(0, localStart)\r\n const after = node.text.slice(localEnd)\r\n const newText = before + after\r\n clearChildren(node.element)\r\n node.element.appendChild(node.element.ownerDocument!.createTextNode(newText))\r\n }\r\n }\r\n}\r\n\r\n// ─── 인셀 패턴 교체 (체크박스/괄호 빈칸) ─────────\r\n\r\n/** 셀(<hp:tc>) 내 모든 <hp:t> 텍스트 노드를 오프셋과 함께 수집 (subList 순회 포함) */\r\nfunction collectCellTextNodes(tcEl: Element): TextNodeInfo[] {\r\n const tElements = findAllElements(tcEl, \"t\")\r\n const result: TextNodeInfo[] = []\r\n let offset = 0\r\n for (const t of tElements) {\r\n const text = t.textContent || \"\"\r\n result.push({ element: t, text, offset })\r\n offset += text.length\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 셀 내 <hp:t> 노드들의 텍스트를 원본→교체 결과에 맞춰 반영.\r\n * 각 노드가 원본 텍스트에서 차지하는 범위를 추적하고,\r\n * 교체된 텍스트에서 같은 비율의 영역을 할당.\r\n */\r\nfunction applyTextReplacements(\r\n tNodes: TextNodeInfo[],\r\n originalFull: string,\r\n replacedFull: string,\r\n): void {\r\n if (originalFull === replacedFull) return\r\n\r\n // 단일 <hp:t> 노드면 간단히 전체 교체\r\n if (tNodes.length === 1) {\r\n clearChildren(tNodes[0].element)\r\n tNodes[0].element.appendChild(\r\n tNodes[0].element.ownerDocument!.createTextNode(replacedFull),\r\n )\r\n return\r\n }\r\n\r\n // 여러 노드: diff를 노드 경계에 맞춰 적용\r\n // 변경된 부분의 시작 오프셋을 찾아서 해당 노드만 교체\r\n let diffStart = 0\r\n while (diffStart < originalFull.length && diffStart < replacedFull.length &&\r\n originalFull[diffStart] === replacedFull[diffStart]) {\r\n diffStart++\r\n }\r\n let diffEndOrig = originalFull.length\r\n let diffEndRepl = replacedFull.length\r\n while (diffEndOrig > diffStart && diffEndRepl > diffStart &&\r\n originalFull[diffEndOrig - 1] === replacedFull[diffEndRepl - 1]) {\r\n diffEndOrig--\r\n diffEndRepl--\r\n }\r\n\r\n // 변경된 범위를 포함하는 노드에 교체 적용\r\n const newPart = replacedFull.slice(diffStart, diffEndRepl)\r\n replaceTextRange(tNodes, diffStart, diffEndOrig, newPart)\r\n}\r\n","/**\r\n * Markdown → HWPX 역변환\r\n *\r\n * 지원: 헤딩(h1~h6), 단락, 볼드, 이탤릭, 인라인코드, 코드블록,\r\n * 순서/비순서 리스트, 수평선, 인용문, 테이블\r\n * jszip으로 HWPX ZIP 패키징.\r\n */\r\n\r\nimport JSZip from \"jszip\"\r\n\r\nconst NS_SECTION = \"http://www.hancom.co.kr/hwpml/2011/section\"\r\nconst NS_PARA = \"http://www.hancom.co.kr/hwpml/2011/paragraph\"\r\nconst NS_HEAD = \"http://www.hancom.co.kr/hwpml/2011/head\"\r\nconst NS_OPF = \"http://www.idpf.org/2007/opf/\"\r\nconst NS_HPF = \"http://www.hancom.co.kr/schema/2011/hpf\"\r\nconst NS_OCF = \"urn:oasis:names:tc:opendocument:xmlns:container\"\r\n\r\n// ─── 스타일 ID 매핑 ─────────────────────────────────\r\n// charPr: 0=본문, 1=볼드, 2=이탤릭, 3=볼드이탤릭, 4=인라인코드, 5=h1, 6=h2, 7=h3, 8=h4~h6, 9=표 헤더 셀, 10=인용문\r\n// paraPr: 0=본문, 1=h1, 2=h2, 3=h3, 4=h4~h6, 5=코드블록, 6=인용문, 7=리스트\r\n\r\nconst CHAR_NORMAL = 0\r\nconst CHAR_BOLD = 1\r\nconst CHAR_ITALIC = 2\r\nconst CHAR_BOLD_ITALIC = 3\r\nconst CHAR_CODE = 4\r\nconst CHAR_H1 = 5\r\nconst CHAR_H2 = 6\r\nconst CHAR_H3 = 7\r\nconst CHAR_H4 = 8\r\nconst CHAR_TABLE_HEADER = 9\r\nconst CHAR_QUOTE = 10\r\n\r\nconst PARA_NORMAL = 0\r\nconst PARA_H1 = 1\r\nconst PARA_H2 = 2\r\nconst PARA_H3 = 3\r\nconst PARA_H4 = 4\r\nconst PARA_CODE = 5\r\nconst PARA_QUOTE = 6\r\nconst PARA_LIST = 7\r\n\r\n/** HWPX 생성 시 적용할 시각 테마 (모두 선택) */\r\nexport interface HwpxTheme {\r\n /**\r\n * 헤딩 레벨별 텍스트 색상. 미지정 시 검정.\r\n * 현재 charPr 매핑은 h1/h2/h3/h4 4단계 (h5, h6은 h4와 같은 charPr 공유)이므로\r\n * 키는 1~4만 받는다.\r\n */\r\n headingColors?: Partial<Record<1 | 2 | 3 | 4, string>>\r\n /** 본문 단락 텍스트 색상. 미지정 시 검정 */\r\n bodyColor?: string\r\n /**\r\n * 인용문 텍스트 색상. 미지정 시 검정.\r\n *\r\n * 주의: 이 옵션을 지정하면 인용문이 별도 charPr(이탤릭)로 렌더링된다.\r\n * 미지정 시 기존 동작 그대로 본문 charPr로 렌더링 (이탤릭 아님).\r\n */\r\n quoteColor?: string\r\n /** 표 첫 행 텍스트 색상. 미지정 시 본문과 동일 */\r\n tableHeaderColor?: string\r\n /** 표 첫 행 텍스트를 굵게 표시 (기본 false) */\r\n tableHeaderBold?: boolean\r\n}\r\n\r\n/** markdownToHwpx 옵션 */\r\nexport interface MarkdownToHwpxOptions {\r\n theme?: HwpxTheme\r\n}\r\n\r\nconst DEFAULT_TEXT_COLOR = \"#000000\"\r\n\r\nfunction resolveTheme(theme?: HwpxTheme) {\r\n return {\r\n h1: theme?.headingColors?.[1] ?? DEFAULT_TEXT_COLOR,\r\n h2: theme?.headingColors?.[2] ?? DEFAULT_TEXT_COLOR,\r\n h3: theme?.headingColors?.[3] ?? DEFAULT_TEXT_COLOR,\r\n h4: theme?.headingColors?.[4] ?? theme?.headingColors?.[3] ?? DEFAULT_TEXT_COLOR,\r\n body: theme?.bodyColor ?? DEFAULT_TEXT_COLOR,\r\n quote: theme?.quoteColor ?? DEFAULT_TEXT_COLOR,\r\n /** quoteColor가 명시되었는지 — blockquote charPr 분기에 사용 (baseline 호환) */\r\n hasQuoteOption: theme?.quoteColor !== undefined,\r\n tableHeader: theme?.tableHeaderColor ?? theme?.bodyColor ?? DEFAULT_TEXT_COLOR,\r\n tableHeaderBold: !!theme?.tableHeaderBold,\r\n }\r\n}\r\n\r\ntype ResolvedTheme = ReturnType<typeof resolveTheme>\r\n\r\n/**\r\n * 마크다운 텍스트를 HWPX (ArrayBuffer)로 변환.\r\n */\r\nexport async function markdownToHwpx(\r\n markdown: string,\r\n options?: MarkdownToHwpxOptions,\r\n): Promise<ArrayBuffer> {\r\n const theme = resolveTheme(options?.theme)\r\n const blocks = parseMarkdownToBlocks(markdown)\r\n const sectionXml = blocksToSectionXml(blocks, theme)\r\n\r\n const zip = new JSZip()\r\n zip.file(\"mimetype\", \"application/hwp+zip\", { compression: \"STORE\" })\r\n zip.file(\"META-INF/container.xml\", generateContainerXml())\r\n zip.file(\"Contents/content.hpf\", generateManifest())\r\n zip.file(\"Contents/header.xml\", generateHeaderXml(theme))\r\n zip.file(\"Contents/section0.xml\", sectionXml)\r\n // Preview/ — 한글 프로그램의 일부 버전(특히 macOS)이 존재 여부를 확인함\r\n zip.file(\"Preview/PrvText.txt\", buildPrvText(blocks))\r\n\r\n return await zip.generateAsync({ type: \"arraybuffer\" })\r\n}\r\n\r\n/** Preview/PrvText.txt — 문서 앞부분 텍스트 스냅샷 (최대 1KB) */\r\nfunction buildPrvText(blocks: MdBlock[]): string {\r\n const lines: string[] = []\r\n let bytes = 0\r\n for (const b of blocks) {\r\n const text = b.text || (b.rows ? b.rows.map(r => r.join(\" \")).join(\"\\n\") : \"\")\r\n if (!text) continue\r\n lines.push(text)\r\n bytes += text.length * 3\r\n if (bytes > 1024) break\r\n }\r\n return lines.join(\"\\n\").slice(0, 1024)\r\n}\r\n\r\n// ─── 마크다운 파싱 ───────────────────────────────────\r\n\r\ninterface MdBlock {\r\n type: \"paragraph\" | \"heading\" | \"table\" | \"code_block\" | \"hr\" | \"blockquote\" | \"list_item\"\r\n text?: string\r\n level?: number\r\n rows?: string[][]\r\n lang?: string\r\n ordered?: boolean\r\n indent?: number\r\n}\r\n\r\nfunction parseMarkdownToBlocks(md: string): MdBlock[] {\r\n const lines = md.split(\"\\n\")\r\n const blocks: MdBlock[] = []\r\n let i = 0\r\n\r\n while (i < lines.length) {\r\n const line = lines[i]\r\n\r\n // 빈 줄 스킵\r\n if (!line.trim()) { i++; continue }\r\n\r\n // 코드블록\r\n const fenceMatch = line.match(/^(`{3,}|~{3,})(.*)$/)\r\n if (fenceMatch) {\r\n const fence = fenceMatch[1]\r\n const lang = fenceMatch[2].trim()\r\n const codeLines: string[] = []\r\n i++\r\n while (i < lines.length && !lines[i].startsWith(fence)) {\r\n codeLines.push(lines[i])\r\n i++\r\n }\r\n if (i < lines.length) i++ // 닫는 fence\r\n blocks.push({ type: \"code_block\", text: codeLines.join(\"\\n\"), lang })\r\n continue\r\n }\r\n\r\n // 수평선\r\n if (/^(\\*{3,}|-{3,}|_{3,})\\s*$/.test(line.trim())) {\r\n blocks.push({ type: \"hr\" })\r\n i++; continue\r\n }\r\n\r\n // 헤딩\r\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/)\r\n if (headingMatch) {\r\n blocks.push({ type: \"heading\", text: headingMatch[2].trim(), level: headingMatch[1].length })\r\n i++; continue\r\n }\r\n\r\n // 테이블\r\n if (line.trimStart().startsWith(\"|\")) {\r\n const tableRows: string[][] = []\r\n while (i < lines.length && lines[i].trimStart().startsWith(\"|\")) {\r\n const row = lines[i]\r\n if (/^[\\s|:\\-]+$/.test(row)) { i++; continue }\r\n const cells = row.split(\"|\").slice(1, -1).map(c => c.trim())\r\n if (cells.length > 0) tableRows.push(cells)\r\n i++\r\n }\r\n if (tableRows.length > 0) blocks.push({ type: \"table\", rows: tableRows })\r\n continue\r\n }\r\n\r\n // 인용문\r\n if (line.trimStart().startsWith(\"> \")) {\r\n const quoteLines: string[] = []\r\n while (i < lines.length && (lines[i].trimStart().startsWith(\"> \") || lines[i].trimStart().startsWith(\">\"))) {\r\n quoteLines.push(lines[i].replace(/^>\\s?/, \"\"))\r\n i++\r\n }\r\n for (const ql of quoteLines) {\r\n blocks.push({ type: \"blockquote\", text: ql.trim() || \"\" })\r\n }\r\n continue\r\n }\r\n\r\n // 리스트\r\n const listMatch = line.match(/^(\\s*)([-*+]|\\d+[.)]) (.+)$/)\r\n if (listMatch) {\r\n const indent = Math.floor(listMatch[1].length / 2)\r\n const ordered = /\\d/.test(listMatch[2])\r\n blocks.push({ type: \"list_item\", text: listMatch[3].trim(), ordered, indent })\r\n i++; continue\r\n }\r\n\r\n // 일반 단락\r\n blocks.push({ type: \"paragraph\", text: line.trim() })\r\n i++\r\n }\r\n\r\n return blocks\r\n}\r\n\r\n// ─── 인라인 마크다운 → 멀티 run ─────────────────────\r\n\r\ninterface InlineSpan {\r\n text: string\r\n bold: boolean\r\n italic: boolean\r\n code: boolean\r\n}\r\n\r\nfunction parseInlineMarkdown(text: string): InlineSpan[] {\r\n // 전처리: 마크다운 링크/이미지 → 텍스트만 추출\r\n text = text.replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, \"$1\") // ![alt](url) → alt\r\n text = text.replace(/\\[([^\\]]*)\\]\\(([^)]*)\\)/g, (_, t, u) => t || u) // [text](url) → text or url\r\n // 전처리: ~~취소선~~ → 텍스트만\r\n text = text.replace(/~~([^~]+)~~/g, \"$1\")\r\n\r\n const spans: InlineSpan[] = []\r\n // 패턴: `code`, ***bolditalic***, **bold**, *italic*, __bold__, _italic_\r\n const regex = /(`[^`]+`|\\*{3}[^*]+\\*{3}|\\*{2}[^*]+\\*{2}|\\*[^*]+\\*|_{2}[^_]+_{2}|_[^_]+_)/g\r\n let lastIdx = 0\r\n\r\n for (const match of text.matchAll(regex)) {\r\n const idx = match.index!\r\n if (idx > lastIdx) {\r\n spans.push({ text: text.slice(lastIdx, idx), bold: false, italic: false, code: false })\r\n }\r\n const raw = match[0]\r\n if (raw.startsWith(\"`\")) {\r\n spans.push({ text: raw.slice(1, -1), bold: false, italic: false, code: true })\r\n } else if (raw.startsWith(\"***\") || raw.startsWith(\"___\")) {\r\n spans.push({ text: raw.slice(3, -3), bold: true, italic: true, code: false })\r\n } else if (raw.startsWith(\"**\") || raw.startsWith(\"__\")) {\r\n spans.push({ text: raw.slice(2, -2), bold: true, italic: false, code: false })\r\n } else {\r\n spans.push({ text: raw.slice(1, -1), bold: false, italic: true, code: false })\r\n }\r\n lastIdx = idx + raw.length\r\n }\r\n if (lastIdx < text.length) {\r\n spans.push({ text: text.slice(lastIdx), bold: false, italic: false, code: false })\r\n }\r\n if (spans.length === 0) {\r\n spans.push({ text, bold: false, italic: false, code: false })\r\n }\r\n return spans\r\n}\r\n\r\nfunction spanToCharPrId(span: InlineSpan): number {\r\n if (span.code) return CHAR_CODE\r\n if (span.bold && span.italic) return CHAR_BOLD_ITALIC\r\n if (span.bold) return CHAR_BOLD\r\n if (span.italic) return CHAR_ITALIC\r\n return CHAR_NORMAL\r\n}\r\n\r\n// ─── XML 생성 헬퍼 ───────────────────────────────────\r\n\r\nfunction escapeXml(text: string): string {\r\n return text\r\n .replace(/&/g, \"&amp;\")\r\n .replace(/</g, \"&lt;\")\r\n .replace(/>/g, \"&gt;\")\r\n .replace(/\"/g, \"&quot;\")\r\n}\r\n\r\nfunction generateRuns(text: string, defaultCharPr: number = CHAR_NORMAL): string {\r\n const spans = parseInlineMarkdown(text)\r\n return spans.map(span => {\r\n const charId = span.code || span.bold || span.italic ? spanToCharPrId(span) : defaultCharPr\r\n return `<hp:run charPrIDRef=\"${charId}\"><hp:t>${escapeXml(span.text)}</hp:t></hp:run>`\r\n }).join(\"\")\r\n}\r\n\r\nfunction generateParagraph(text: string, paraPrId: number = PARA_NORMAL, charPrId: number = CHAR_NORMAL): string {\r\n if (paraPrId === PARA_CODE) {\r\n // 코드블록은 인라인 파싱 안 함\r\n return `<hp:p paraPrIDRef=\"${paraPrId}\" styleIDRef=\"0\"><hp:run charPrIDRef=\"${CHAR_CODE}\"><hp:t>${escapeXml(text)}</hp:t></hp:run></hp:p>`\r\n }\r\n const runs = generateRuns(text, charPrId)\r\n return `<hp:p paraPrIDRef=\"${paraPrId}\" styleIDRef=\"0\">${runs}</hp:p>`\r\n}\r\n\r\nfunction headingParaPrId(level: number): number {\r\n if (level === 1) return PARA_H1\r\n if (level === 2) return PARA_H2\r\n if (level === 3) return PARA_H3\r\n return PARA_H4\r\n}\r\n\r\nfunction headingCharPrId(level: number): number {\r\n if (level === 1) return CHAR_H1\r\n if (level === 2) return CHAR_H2\r\n if (level === 3) return CHAR_H3\r\n return CHAR_H4\r\n}\r\n\r\n// ─── HWPX 구조 파일 생성 ─────────────────────────────\r\n\r\nfunction generateContainerXml(): string {\r\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\r\n<ocf:container xmlns:ocf=\"${NS_OCF}\" xmlns:hpf=\"${NS_HPF}\">\r\n <ocf:rootfiles>\r\n <ocf:rootfile full-path=\"Contents/content.hpf\" media-type=\"application/hwpml-package+xml\"/>\r\n </ocf:rootfiles>\r\n</ocf:container>`\r\n}\r\n\r\nfunction generateManifest(): string {\r\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\r\n<opf:package xmlns:opf=\"${NS_OPF}\" xmlns:hpf=\"${NS_HPF}\" xmlns:hh=\"${NS_HEAD}\">\r\n <opf:manifest>\r\n <opf:item id=\"header\" href=\"Contents/header.xml\" media-type=\"application/xml\"/>\r\n <opf:item id=\"section0\" href=\"Contents/section0.xml\" media-type=\"application/xml\"/>\r\n </opf:manifest>\r\n <opf:spine>\r\n <opf:itemref idref=\"header\" linear=\"no\"/>\r\n <opf:itemref idref=\"section0\" linear=\"yes\"/>\r\n </opf:spine>\r\n</opf:package>`\r\n}\r\n\r\n// ─── charPr 생성 헬퍼 ───────────────────────────────\r\n\r\nfunction charPr(\r\n id: number,\r\n height: number,\r\n bold: boolean,\r\n italic: boolean,\r\n fontId: number = 0,\r\n textColor: string = DEFAULT_TEXT_COLOR,\r\n): string {\r\n const boldAttr = bold ? ` bold=\"1\"` : \"\"\r\n const italicAttr = italic ? ` italic=\"1\"` : \"\"\r\n // 볼드면 fontfaces의 bold variant(id=2: HY견고딕/Arial Black, weight=9) 참조해\r\n // macOS 한컴에서 합성 굵기 안 되는 케이스 커버. 코드(fontId=1)는 bold 아닌 경우에만\r\n // 원본 id 유지 (Consolas/함초롬돋움).\r\n const effFont = bold ? 2 : fontId\r\n return ` <hh:charPr id=\"${id}\" height=\"${height}\" textColor=\"${textColor}\" shadeColor=\"none\" useFontSpace=\"0\" useKerning=\"0\" symMark=\"NONE\" borderFillIDRef=\"0\"${boldAttr}${italicAttr}>\r\n <hh:fontRef hangul=\"${effFont}\" latin=\"${effFont}\" hanja=\"${effFont}\" japanese=\"${effFont}\" other=\"${effFont}\" symbol=\"${effFont}\" user=\"${effFont}\"/>\r\n <hh:ratio hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/>\r\n <hh:spacing hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>\r\n <hh:relSz hangul=\"100\" latin=\"100\" hanja=\"100\" japanese=\"100\" other=\"100\" symbol=\"100\" user=\"100\"/>\r\n <hh:offset hangul=\"0\" latin=\"0\" hanja=\"0\" japanese=\"0\" other=\"0\" symbol=\"0\" user=\"0\"/>\r\n </hh:charPr>`\r\n}\r\n\r\n// ─── paraPr 생성 헬퍼 ───────────────────────────────\r\n\r\nfunction paraPr(id: number, opts: { align?: string; spaceBefore?: number; spaceAfter?: number; lineSpacing?: number; indent?: number } = {}): string {\r\n const { align = \"JUSTIFY\", spaceBefore = 0, spaceAfter = 0, lineSpacing = 160, indent = 0 } = opts\r\n return ` <hh:paraPr id=\"${id}\" tabPrIDRef=\"0\" condense=\"0\" fontLineHeight=\"0\" snapToGrid=\"1\" suppressLineNumbers=\"0\" checked=\"0\" textDir=\"AUTO\">\r\n <hh:align horizontal=\"${align}\" vertical=\"BASELINE\"/>\r\n <hh:heading type=\"NONE\" idRef=\"0\" level=\"0\"/>\r\n <hh:breakSetting breakLatinWord=\"KEEP_WORD\" breakNonLatinWord=\"BREAK_WORD\" widowOrphan=\"0\" keepWithNext=\"0\" keepLines=\"0\" pageBreakBefore=\"0\" lineWrap=\"BREAK\"/>\r\n <hh:autoSpacing eAsianEng=\"0\" eAsianNum=\"0\"/>\r\n <hh:margin indent=\"${indent}\" left=\"0\" right=\"0\" prev=\"${spaceBefore}\" next=\"${spaceAfter}\"/>\r\n <hh:lineSpacing type=\"PERCENT\" value=\"${lineSpacing}\"/>\r\n <hh:border borderFillIDRef=\"0\" offsetLeft=\"0\" offsetRight=\"0\" offsetTop=\"0\" offsetBottom=\"0\" connect=\"0\" ignoreMargin=\"0\"/>\r\n </hh:paraPr>`\r\n}\r\n\r\nfunction generateHeaderXml(theme: ResolvedTheme): string {\r\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\r\n<hh:head xmlns:hh=\"${NS_HEAD}\" xmlns:hp=\"${NS_PARA}\" version=\"1.4\" secCnt=\"1\">\r\n <hh:beginNum page=\"1\" footnote=\"1\" endnote=\"1\" pic=\"1\" tbl=\"1\" equation=\"1\"/>\r\n <hh:refList>\r\n <hh:fontfaces itemCnt=\"7\">\r\n <hh:fontface lang=\"HANGUL\" fontCnt=\"3\">\r\n <hh:font id=\"0\" face=\"함초롬바탕\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"4\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n <hh:font id=\"1\" face=\"함초롬돋움\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"4\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n <hh:font id=\"2\" face=\"HY견고딕\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"9\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n </hh:fontface>\r\n <hh:fontface lang=\"LATIN\" fontCnt=\"3\">\r\n <hh:font id=\"0\" face=\"Times New Roman\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_OLDSTYLE\" weight=\"5\" proportion=\"4\" contrast=\"2\" strokeVariation=\"0\" armStyle=\"0\" letterform=\"0\" midline=\"0\" xHeight=\"4\"/>\r\n </hh:font>\r\n <hh:font id=\"1\" face=\"Consolas\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_MODERN\" weight=\"5\" proportion=\"0\" contrast=\"0\" strokeVariation=\"0\" armStyle=\"0\" letterform=\"0\" midline=\"0\" xHeight=\"0\"/>\r\n </hh:font>\r\n <hh:font id=\"2\" face=\"Arial Black\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"9\" proportion=\"0\" contrast=\"0\" strokeVariation=\"0\" armStyle=\"0\" letterform=\"0\" midline=\"0\" xHeight=\"0\"/>\r\n </hh:font>\r\n </hh:fontface>\r\n <hh:fontface lang=\"HANJA\" fontCnt=\"1\">\r\n <hh:font id=\"0\" face=\"함초롬바탕\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"4\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n </hh:fontface>\r\n <hh:fontface lang=\"JAPANESE\" fontCnt=\"1\">\r\n <hh:font id=\"0\" face=\"굴림\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n </hh:fontface>\r\n <hh:fontface lang=\"OTHER\" fontCnt=\"1\">\r\n <hh:font id=\"0\" face=\"굴림\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n </hh:fontface>\r\n <hh:fontface lang=\"SYMBOL\" fontCnt=\"1\">\r\n <hh:font id=\"0\" face=\"Symbol\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n </hh:fontface>\r\n <hh:fontface lang=\"USER\" fontCnt=\"1\">\r\n <hh:font id=\"0\" face=\"굴림\" type=\"TTF\" isEmbedded=\"0\">\r\n <hh:typeInfo familyType=\"FCAT_GOTHIC\" weight=\"6\" proportion=\"0\" contrast=\"0\" strokeVariation=\"1\" armStyle=\"1\" letterform=\"1\" midline=\"1\" xHeight=\"1\"/>\r\n </hh:font>\r\n </hh:fontface>\r\n </hh:fontfaces>\r\n <hh:borderFills itemCnt=\"2\">\r\n <hh:borderFill id=\"0\" threeD=\"0\" shadow=\"0\" centerLine=\"0\" breakCellSeparateLine=\"0\">\r\n <hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\r\n <hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\r\n <hh:leftBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\r\n <hh:rightBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\r\n <hh:topBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\r\n <hh:bottomBorder type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\r\n <hh:diagonal type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\r\n <hh:fillInfo/>\r\n </hh:borderFill>\r\n <hh:borderFill id=\"1\" threeD=\"0\" shadow=\"0\" centerLine=\"0\" breakCellSeparateLine=\"0\">\r\n <hh:slash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\r\n <hh:backSlash type=\"NONE\" Crooked=\"0\" isCounter=\"0\"/>\r\n <hh:leftBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\r\n <hh:rightBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\r\n <hh:topBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\r\n <hh:bottomBorder type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/>\r\n <hh:diagonal type=\"NONE\" width=\"0.1 mm\" color=\"#000000\"/>\r\n <hh:fillInfo/>\r\n </hh:borderFill>\r\n </hh:borderFills>\r\n <hh:charProperties itemCnt=\"11\">\r\n${charPr(0, 1000, false, false, 0, theme.body)}\r\n${charPr(1, 1000, true, false, 0, theme.body)}\r\n${charPr(2, 1000, false, true, 0, theme.body)}\r\n${charPr(3, 1000, true, true, 0, theme.body)}\r\n${charPr(4, 900, false, false, 1)}\r\n${charPr(5, 1800, true, false, 1, theme.h1)}\r\n${charPr(6, 1400, true, false, 1, theme.h2)}\r\n${charPr(7, 1200, true, false, 1, theme.h3)}\r\n${charPr(8, 1100, true, false, 1, theme.h4)}\r\n${charPr(CHAR_TABLE_HEADER, 1000, theme.tableHeaderBold, false, 0, theme.tableHeader)}\r\n${charPr(CHAR_QUOTE, 1000, false, true, 0, theme.quote)}\r\n </hh:charProperties>\r\n <hh:tabProperties itemCnt=\"0\"/>\r\n <hh:numberings itemCnt=\"0\"/>\r\n <hh:bullets itemCnt=\"0\"/>\r\n <hh:paraProperties itemCnt=\"8\">\r\n${paraPr(0)}\r\n${paraPr(1, { align: \"LEFT\", spaceBefore: 800, spaceAfter: 200, lineSpacing: 180 })}\r\n${paraPr(2, { align: \"LEFT\", spaceBefore: 600, spaceAfter: 150, lineSpacing: 170 })}\r\n${paraPr(3, { align: \"LEFT\", spaceBefore: 400, spaceAfter: 100, lineSpacing: 160 })}\r\n${paraPr(4, { align: \"LEFT\", spaceBefore: 300, spaceAfter: 100, lineSpacing: 160 })}\r\n${paraPr(5, { align: \"LEFT\", lineSpacing: 130, indent: 400 })}\r\n${paraPr(6, { align: \"LEFT\", lineSpacing: 150, indent: 600 })}\r\n${paraPr(7, { align: \"LEFT\", lineSpacing: 160, indent: 600 })}\r\n </hh:paraProperties>\r\n <hh:styles itemCnt=\"1\">\r\n <hh:style id=\"0\" type=\"PARA\" name=\"바탕글\" engName=\"Normal\" paraPrIDRef=\"0\" charPrIDRef=\"0\" nextStyleIDRef=\"0\" langIDRef=\"1042\" lockForm=\"0\"/>\r\n </hh:styles>\r\n </hh:refList>\r\n <hh:compatibleDocument targetProgram=\"HWP2018\"/>\r\n</hh:head>`\r\n}\r\n\r\n// ─── 섹션 속성 (공문서 표준 여백) ────────────────────\r\n\r\nfunction generateSecPr(): string {\r\n // A4: 210mm × 297mm → 59528 × 84188 HWPUNIT (1mm ≈ 283.46 HWPUNIT)\r\n // 공문서 표준: 위 30mm(8504), 아래 15mm(4252), 왼쪽 20mm(5670), 오른쪽 15mm(4252)\r\n // 머리말 10mm(2835), 꼬리말 10mm(2835)\r\n return `<hp:secPr textDirection=\"HORIZONTAL\" spaceColumns=\"1134\" tabStop=\"8000\" outlineShapeIDRef=\"0\" memoShapeIDRef=\"0\" textVerticalWidthHead=\"0\" masterPageCnt=\"0\">` +\r\n `<hp:grid lineGrid=\"0\" charGrid=\"0\" wonggojiFormat=\"0\"/>` +\r\n `<hp:startNum pageStartsOn=\"BOTH\" page=\"0\" pic=\"0\" tbl=\"0\" equation=\"0\"/>` +\r\n `<hp:visibility hideFirstHeader=\"0\" hideFirstFooter=\"0\" hideFirstMasterPage=\"0\" border=\"SHOW_ALL\" fill=\"SHOW_ALL\" hideFirstPageNum=\"0\" hideFirstEmptyLine=\"0\" showLineNumber=\"0\"/>` +\r\n `<hp:pagePr landscape=\"WIDELY\" width=\"59528\" height=\"84188\" gutterType=\"LEFT_ONLY\">` +\r\n `<hp:margin header=\"2835\" footer=\"2835\" gutter=\"0\" left=\"5670\" right=\"4252\" top=\"8504\" bottom=\"4252\"/>` +\r\n `</hp:pagePr>` +\r\n `<hp:footNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"-1\" type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"283\" belowLine=\"567\" aboveLine=\"850\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"EACH_COLUMN\" beneathText=\"0\"/></hp:footNotePr>` +\r\n `<hp:endNotePr><hp:autoNumFormat type=\"DIGIT\" userChar=\"\" prefixChar=\"\" suffixChar=\")\" supscript=\"0\"/><hp:noteLine length=\"14692344\" type=\"SOLID\" width=\"0.12 mm\" color=\"#000000\"/><hp:noteSpacing betweenNotes=\"0\" belowLine=\"567\" aboveLine=\"850\"/><hp:numbering type=\"CONTINUOUS\" newNum=\"1\"/><hp:placement place=\"END_OF_DOCUMENT\" beneathText=\"0\"/></hp:endNotePr>` +\r\n `</hp:secPr>`\r\n}\r\n\r\n// ─── 테이블 생성 ─────────────────────────────────────\r\n//\r\n// HWPX 스펙 완전 준수 버전 — 한글 프로그램(Windows/macOS)이 문서를 거부하지 않으려면\r\n// <hp:tbl> 필수 속성 + <hp:sz>/<hp:pos>/<hp:outMargin>/<hp:inMargin> + 각 cell의\r\n// <hp:subList> 래퍼, <hp:cellAddr>, <hp:cellSz>, <hp:cellMargin>이 전부 있어야 함.\r\n// 또한 테이블은 paragraph 안의 <hp:run><hp:ctrl>... 로 감싸야 한다.\r\n//\r\n// 이슈 #4 참고: v2.4.1 이전엔 최소 스켈레톤만 내서 macOS 한글이 \"파일이 깨졌다\"며 거부.\r\n\r\n// 기본 셀 크기 (HWPUnit) — A4 기준 적당한 기본값\r\nconst TABLE_ID_BASE = 1000\r\nlet tableIdCounter = TABLE_ID_BASE\r\nfunction nextTableId(): number { return ++tableIdCounter }\r\n\r\nfunction generateTable(rows: string[][], theme: ResolvedTheme): string {\r\n const rowCnt = rows.length\r\n const colCnt = Math.max(...rows.map(r => r.length), 1)\r\n // A4 portrait: 폭 약 44000 HWPUnit 사용 가능 → colCnt로 균등 분배\r\n const cellW = Math.floor(44000 / colCnt)\r\n const cellH = 1500 // 기본 행 높이\r\n const tblW = cellW * colCnt\r\n const tblH = cellH * rowCnt\r\n\r\n const tblId = nextTableId()\r\n\r\n // theme.tableHeaderColor 또는 tableHeaderBold가 설정되면 첫 행 셀에 별도 charPr 사용\r\n const useHeaderStyle =\r\n theme.tableHeader !== theme.body || theme.tableHeaderBold\r\n\r\n const trElements = rows.map((row, rowIdx) => {\r\n // 부족한 셀은 빈 문자열로 채워 colCnt 맞춤\r\n const cells = row.length < colCnt ? [...row, ...Array(colCnt - row.length).fill(\"\")] : row\r\n const isHeaderRow = rowIdx === 0\r\n const headerCharPr = isHeaderRow && useHeaderStyle ? CHAR_TABLE_HEADER : CHAR_NORMAL\r\n const tdElements = cells.map((cell, colIdx) => {\r\n const runs = generateRuns(cell, headerCharPr)\r\n const p = `<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\">${runs}</hp:p>`\r\n // <hp:tc> 필수 속성 + subList + cellAddr + cellSpan + cellSz + cellMargin\r\n return `<hp:tc name=\"\" header=\"${isHeaderRow ? 1 : 0}\" hasMargin=\"0\" protect=\"0\" editable=\"1\" dirty=\"0\" borderFillIDRef=\"1\">`\r\n + `<hp:subList id=\"\" textDirection=\"HORIZONTAL\" lineWrap=\"BREAK\" vertAlign=\"TOP\" linkListIDRef=\"0\" linkListNextIDRef=\"0\" textWidth=\"0\" textHeight=\"0\" hasTextRef=\"0\" hasNumRef=\"0\">${p}</hp:subList>`\r\n + `<hp:cellAddr colAddr=\"${colIdx}\" rowAddr=\"${rowIdx}\"/>`\r\n + `<hp:cellSpan colSpan=\"1\" rowSpan=\"1\"/>`\r\n + `<hp:cellSz width=\"${cellW}\" height=\"${cellH}\"/>`\r\n + `<hp:cellMargin left=\"141\" right=\"141\" top=\"141\" bottom=\"141\"/>`\r\n + `</hp:tc>`\r\n }).join(\"\")\r\n return `<hp:tr>${tdElements}</hp:tr>`\r\n }).join(\"\")\r\n\r\n // <hp:tbl>에 필수 속성 + <hp:sz>/<hp:outMargin>/<hp:inMargin> (pos는 inline-level 기준)\r\n const tblInner = `<hp:sz width=\"${tblW}\" widthRelTo=\"ABSOLUTE\" height=\"${tblH}\" heightRelTo=\"ABSOLUTE\" protect=\"0\"/>`\r\n + `<hp:pos treatAsChar=\"1\" affectLSpacing=\"0\" flowWithText=\"0\" allowOverlap=\"0\" holdAnchorAndSO=\"0\" vertRelTo=\"PARA\" horzRelTo=\"PARA\" vertAlign=\"TOP\" horzAlign=\"LEFT\" vertOffset=\"0\" horzOffset=\"0\"/>`\r\n + `<hp:outMargin left=\"0\" right=\"0\" top=\"0\" bottom=\"0\"/>`\r\n + `<hp:inMargin left=\"510\" right=\"510\" top=\"141\" bottom=\"141\"/>`\r\n + trElements\r\n\r\n const tbl = `<hp:tbl id=\"${tblId}\" zOrder=\"0\" numberingType=\"TABLE\" pageBreak=\"CELL\" repeatHeader=\"0\" rowCnt=\"${rowCnt}\" colCnt=\"${colCnt}\" cellSpacing=\"0\" borderFillIDRef=\"1\" noShading=\"0\">${tblInner}</hp:tbl>`\r\n\r\n // 테이블은 paragraph 안의 run → 가 아니라 별도 p로 감쌈 (block-level inline-anchored)\r\n return `<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\"><hp:run charPrIDRef=\"0\">${tbl}</hp:run></hp:p>`\r\n}\r\n\r\n// ─── 섹션 XML 생성 ──────────────────────────────────\r\n\r\nfunction blocksToSectionXml(blocks: MdBlock[], theme: ResolvedTheme): string {\r\n const paraXmls: string[] = []\r\n let isFirst = true\r\n // 순서 있는 목록 카운터 — indent 레벨별 별도 유지. 다른 블록 만나면 해당 레벨 리셋.\r\n const orderedCounters: Record<number, number> = {}\r\n let prevWasOrdered = false\r\n\r\n for (const block of blocks) {\r\n let xml = \"\"\r\n\r\n // 순서 있는 list_item이 아니면 카운터 전부 리셋 (연속되지 않은 목록은 다시 1부터)\r\n if (block.type !== \"list_item\" || !block.ordered) {\r\n if (prevWasOrdered) {\r\n for (const k of Object.keys(orderedCounters)) delete orderedCounters[+k]\r\n }\r\n prevWasOrdered = false\r\n }\r\n\r\n switch (block.type) {\r\n case \"heading\": {\r\n const pId = headingParaPrId(block.level || 1)\r\n const cId = headingCharPrId(block.level || 1)\r\n xml = generateParagraph(block.text || \"\", pId, cId)\r\n break\r\n }\r\n case \"paragraph\":\r\n xml = generateParagraph(block.text || \"\")\r\n break\r\n case \"code_block\": {\r\n const codeLines = (block.text || \"\").split(\"\\n\")\r\n xml = codeLines.map(line => generateParagraph(line || \" \", PARA_CODE)).join(\"\\n \")\r\n break\r\n }\r\n case \"blockquote\":\r\n // baseline 호환: quoteColor 옵션 없으면 기존처럼 CHAR_NORMAL (이탤릭 아님)\r\n xml = generateParagraph(\r\n block.text || \"\",\r\n PARA_QUOTE,\r\n theme.hasQuoteOption ? CHAR_QUOTE : CHAR_NORMAL,\r\n )\r\n break\r\n case \"list_item\": {\r\n const indent = block.indent || 0\r\n let marker: string\r\n if (block.ordered) {\r\n // 러닝 카운터: indent 레벨별로 증가. 하위 레벨(더 깊은 indent)은 별도 세퀀스.\r\n orderedCounters[indent] = (orderedCounters[indent] || 0) + 1\r\n // 상위 레벨 번호가 바뀌면 하위는 자동 리셋되어야 함 — 한 레벨 위로 올라갈 때 하위 카운터 초기화\r\n for (const k of Object.keys(orderedCounters)) {\r\n if (+k > indent) delete orderedCounters[+k]\r\n }\r\n marker = `${orderedCounters[indent]}. `\r\n prevWasOrdered = true\r\n } else {\r\n marker = \"· \"\r\n if (prevWasOrdered) {\r\n for (const k of Object.keys(orderedCounters)) delete orderedCounters[+k]\r\n }\r\n prevWasOrdered = false\r\n }\r\n const indentPrefix = \" \".repeat(indent)\r\n xml = generateParagraph(indentPrefix + marker + (block.text || \"\"), PARA_LIST)\r\n break\r\n }\r\n case \"hr\":\r\n // 수평선 — 긴 대시로 대체\r\n xml = `<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\"><hp:run charPrIDRef=\"0\"><hp:t>────────────────────────────────────────</hp:t></hp:run></hp:p>`\r\n break\r\n case \"table\":\r\n if (block.rows) {\r\n if (isFirst) {\r\n // 테이블이 첫 블록이면 빈 단락에 secPr\r\n const secRun = `<hp:run charPrIDRef=\"0\">${generateSecPr()}<hp:t></hp:t></hp:run>`\r\n paraXmls.push(`<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\">${secRun}</hp:p>`)\r\n isFirst = false\r\n }\r\n xml = generateTable(block.rows, theme)\r\n }\r\n break\r\n }\r\n\r\n if (!xml) continue\r\n\r\n // 첫 번째 단락에 secPr 주입\r\n if (isFirst && block.type !== \"table\") {\r\n xml = xml.replace(\r\n /<hp:run charPrIDRef=\"(\\d+)\">/,\r\n `<hp:run charPrIDRef=\"$1\">${generateSecPr()}`\r\n )\r\n isFirst = false\r\n }\r\n\r\n paraXmls.push(xml)\r\n }\r\n\r\n // 블록이 없으면 빈 단락\r\n if (paraXmls.length === 0) {\r\n paraXmls.push(`<hp:p paraPrIDRef=\"0\" styleIDRef=\"0\"><hp:run charPrIDRef=\"0\">${generateSecPr()}<hp:t></hp:t></hp:run></hp:p>`)\r\n }\r\n\r\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\r\n<hs:sec xmlns:hs=\"${NS_SECTION}\" xmlns:hp=\"${NS_PARA}\">\r\n ${paraXmls.join(\"\\n \")}\r\n</hs:sec>`\r\n}\r\n","/** 텍스트 유사도 및 diff 유틸리티 — 외부 의존성 없음 */\n\nexport interface TextChange {\n type: \"equal\" | \"insert\" | \"delete\"\n text: string\n}\n\n/** 두 문자열의 유사도 (0-1). 1 = 동일, 0 = 완전히 다름 */\nexport function similarity(a: string, b: string): number {\n if (a === b) return 1\n if (!a || !b) return 0\n const maxLen = Math.max(a.length, b.length)\n if (maxLen === 0) return 1\n return 1 - levenshtein(a, b) / maxLen\n}\n\n/** 공백 정규화 후 유사도 비교 (HWP/HWPX 포맷 차이 흡수) */\nexport function normalizedSimilarity(a: string, b: string): number {\n return similarity(normalize(a), normalize(b))\n}\n\nfunction normalize(s: string): string {\n return s.replace(/\\s+/g, \" \").trim()\n}\n\n/** 최대 입력 길이 합 — 초과 시 길이 차이 기반 빠른 추정 (O(m*n) CPU 폭발 방지) */\nconst MAX_LEVENSHTEIN_LEN = 10_000\n\n/** Levenshtein 편집 거리 — O(min(m,n)) 공간 최적화 */\nfunction levenshtein(a: string, b: string): number {\n if (a.length + b.length > MAX_LEVENSHTEIN_LEN) {\n // 길이 차이 + 앞 500자 샘플 비교로 근사 거리 추정\n const sampleLen = Math.min(500, a.length, b.length)\n let diffs = 0\n for (let i = 0; i < sampleLen; i++) if (a[i] !== b[i]) diffs++\n const sampleRate = sampleLen > 0 ? diffs / sampleLen : 1\n return Math.abs(a.length - b.length) + Math.round(Math.min(a.length, b.length) * sampleRate)\n }\n if (a.length > b.length) [a, b] = [b, a]\n const m = a.length\n const n = b.length\n let prev = Array.from({ length: m + 1 }, (_, i) => i)\n let curr = new Array(m + 1)\n\n for (let j = 1; j <= n; j++) {\n curr[0] = j\n for (let i = 1; i <= m; i++) {\n if (a[i - 1] === b[j - 1]) {\n curr[i] = prev[i - 1]\n } else {\n curr[i] = 1 + Math.min(prev[i - 1], prev[i], curr[i - 1])\n }\n }\n ;[prev, curr] = [curr, prev]\n }\n return prev[m]\n}\n\n/** 단어 단위 diff — LCS 기반 */\nexport function textDiff(a: string, b: string): TextChange[] {\n const wordsA = a.split(/(\\s+)/)\n const wordsB = b.split(/(\\s+)/)\n const lcs = lcsWords(wordsA, wordsB)\n\n const changes: TextChange[] = []\n let ia = 0, ib = 0, il = 0\n\n while (il < lcs.length) {\n // lcs 원소 이전에 있는 것들\n while (ia < wordsA.length && wordsA[ia] !== lcs[il]) {\n changes.push({ type: \"delete\", text: wordsA[ia++] })\n }\n while (ib < wordsB.length && wordsB[ib] !== lcs[il]) {\n changes.push({ type: \"insert\", text: wordsB[ib++] })\n }\n changes.push({ type: \"equal\", text: lcs[il] })\n ia++; ib++; il++\n }\n // 나머지\n while (ia < wordsA.length) changes.push({ type: \"delete\", text: wordsA[ia++] })\n while (ib < wordsB.length) changes.push({ type: \"insert\", text: wordsB[ib++] })\n\n return mergeChanges(changes)\n}\n\nfunction lcsWords(a: string[], b: string[]): string[] {\n const m = a.length, n = b.length\n // 대형 문서 보호: 5000 단어 초과 시 간이 비교\n if (m * n > 25_000_000) return simpleIntersect(a, b)\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0))\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1] + 1\n : Math.max(dp[i - 1][j], dp[i][j - 1])\n }\n }\n\n const result: string[] = []\n let i = m, j = n\n while (i > 0 && j > 0) {\n if (a[i - 1] === b[j - 1]) { result.push(a[i - 1]); i--; j-- }\n else if (dp[i - 1][j] >= dp[i][j - 1]) i--\n else j--\n }\n return result.reverse()\n}\n\nfunction simpleIntersect(a: string[], b: string[]): string[] {\n const setB = new Set(b)\n return a.filter(w => setB.has(w))\n}\n\nfunction mergeChanges(changes: TextChange[]): TextChange[] {\n if (changes.length === 0) return changes\n const merged: TextChange[] = [changes[0]]\n for (let i = 1; i < changes.length; i++) {\n const last = merged[merged.length - 1]\n if (last.type === changes[i].type) {\n last.text += changes[i].text\n } else {\n merged.push({ ...changes[i] })\n }\n }\n return merged\n}\n","/** 문서 비교 엔진 — IR 레벨 블록 비교로 신구대조표 생성 */\n\nimport { parse } from \"../index.js\"\nimport { normalizedSimilarity } from \"./text-diff.js\"\nimport type { IRBlock, IRTable, DiffResult, BlockDiff, CellDiff, DiffChangeType, ParseOptions } from \"../types.js\"\n\n/** 유사도 임계값 — 이 이상이면 modified, 미만이면 removed+added */\nconst SIMILARITY_THRESHOLD = 0.4\n\n/**\n * 두 문서를 비교하여 블록 단위 diff 생성.\n * 크로스 포맷 지원 — HWP vs HWPX 비교 가능 (IR 레벨).\n */\nexport async function compare(\n bufferA: ArrayBuffer,\n bufferB: ArrayBuffer,\n options?: ParseOptions\n): Promise<DiffResult> {\n const [resultA, resultB] = await Promise.all([\n parse(bufferA, options),\n parse(bufferB, options),\n ])\n\n if (!resultA.success) throw new Error(`문서A 파싱 실패: ${resultA.error}`)\n if (!resultB.success) throw new Error(`문서B 파싱 실패: ${resultB.error}`)\n\n return diffBlocks(resultA.blocks, resultB.blocks)\n}\n\n/** IRBlock[] 간 diff — LCS 기반 정렬 */\nexport function diffBlocks(blocksA: IRBlock[], blocksB: IRBlock[]): DiffResult {\n const aligned = alignBlocks(blocksA, blocksB)\n const stats = { added: 0, removed: 0, modified: 0, unchanged: 0 }\n const diffs: BlockDiff[] = []\n\n for (const [a, b] of aligned) {\n if (a && b) {\n const sim = blockSimilarity(a, b)\n if (sim >= 0.99) {\n diffs.push({ type: \"unchanged\", before: a, after: b, similarity: 1 })\n stats.unchanged++\n } else {\n const diff: BlockDiff = { type: \"modified\", before: a, after: b, similarity: sim }\n if (a.type === \"table\" && b.type === \"table\" && a.table && b.table) {\n diff.cellDiffs = diffTableCells(a.table, b.table)\n }\n diffs.push(diff)\n stats.modified++\n }\n } else if (a) {\n diffs.push({ type: \"removed\", before: a })\n stats.removed++\n } else if (b) {\n diffs.push({ type: \"added\", after: b })\n stats.added++\n }\n }\n\n return { stats, diffs }\n}\n\n// ─── 블록 정렬 (LCS 기반) ───────────────────────────\n\nfunction alignBlocks(a: IRBlock[], b: IRBlock[]): [IRBlock | null, IRBlock | null][] {\n const m = a.length, n = b.length\n\n // 대형 문서 보호\n if (m * n > 10_000_000) return fallbackAlign(a, b)\n\n // 유사도 매트릭스 캐시\n const simCache = new Map<string, number>()\n const getSim = (i: number, j: number): number => {\n const key = `${i},${j}`\n let v = simCache.get(key)\n if (v === undefined) { v = blockSimilarity(a[i], b[j]); simCache.set(key, v) }\n return v\n }\n\n // LCS with similarity threshold\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0))\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (getSim(i - 1, j - 1) >= SIMILARITY_THRESHOLD) {\n dp[i][j] = dp[i - 1][j - 1] + 1\n } else {\n dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1])\n }\n }\n }\n\n // 역추적\n const pairs: [number, number][] = []\n let i = m, j = n\n while (i > 0 && j > 0) {\n if (getSim(i - 1, j - 1) >= SIMILARITY_THRESHOLD && dp[i][j] === dp[i - 1][j - 1] + 1) {\n pairs.push([i - 1, j - 1]); i--; j--\n } else if (dp[i - 1][j] >= dp[i][j - 1]) {\n i--\n } else {\n j--\n }\n }\n pairs.reverse()\n\n // 정렬 결과 조립\n const result: [IRBlock | null, IRBlock | null][] = []\n let ai = 0, bi = 0\n for (const [pi, pj] of pairs) {\n while (ai < pi) result.push([a[ai++], null])\n while (bi < pj) result.push([null, b[bi++]])\n result.push([a[ai++], b[bi++]])\n }\n while (ai < m) result.push([a[ai++], null])\n while (bi < n) result.push([null, b[bi++]])\n\n return result\n}\n\nfunction fallbackAlign(a: IRBlock[], b: IRBlock[]): [IRBlock | null, IRBlock | null][] {\n const result: [IRBlock | null, IRBlock | null][] = []\n const len = Math.max(a.length, b.length)\n for (let i = 0; i < len; i++) {\n result.push([a[i] || null, b[i] || null])\n }\n return result\n}\n\n// ─── 블록 유사도 ────────────────────────────────────\n\nfunction blockSimilarity(a: IRBlock, b: IRBlock): number {\n if (a.type !== b.type) return 0\n\n // 텍스트 기반 블록: paragraph, heading, list, image(alt text)\n if (a.text !== undefined && b.text !== undefined) {\n return normalizedSimilarity(a.text || \"\", b.text || \"\")\n }\n\n if (a.type === \"table\" && a.table && b.table) {\n return tableSimilarity(a.table, b.table)\n }\n\n // separator 등 텍스트 없는 동일 타입 → 완전 일치\n if (a.type === b.type) return 1\n\n return 0\n}\n\nfunction tableSimilarity(a: IRTable, b: IRTable): number {\n // 구조 유사도 (차원)\n const dimSim = 1 - Math.abs(a.rows * a.cols - b.rows * b.cols) / Math.max(a.rows * a.cols, b.rows * b.cols, 1)\n\n // 내용 유사도 (셀 텍스트)\n const textsA = a.cells.flat().map(c => c.text).join(\" \")\n const textsB = b.cells.flat().map(c => c.text).join(\" \")\n const contentSim = normalizedSimilarity(textsA, textsB)\n\n return dimSim * 0.3 + contentSim * 0.7\n}\n\n// ─── 테이블 셀 diff ─────────────────────────────────\n\nfunction diffTableCells(a: IRTable, b: IRTable): CellDiff[][] {\n const maxRows = Math.max(a.rows, b.rows)\n const maxCols = Math.max(a.cols, b.cols)\n const result: CellDiff[][] = []\n\n for (let r = 0; r < maxRows; r++) {\n const row: CellDiff[] = []\n for (let c = 0; c < maxCols; c++) {\n const cellA = r < a.rows && c < a.cols ? a.cells[r][c].text : undefined\n const cellB = r < b.rows && c < b.cols ? b.cells[r][c].text : undefined\n\n let type: DiffChangeType\n if (cellA === undefined) type = \"added\"\n else if (cellB === undefined) type = \"removed\"\n else if (cellA === cellB) type = \"unchanged\"\n else type = \"modified\"\n\n row.push({ type, before: cellA, after: cellB })\n }\n result.push(row)\n }\n return result\n}\n","/**\r\n * Print Renderer — Markdown / IRBlock[] → PDF (puppeteer-core 기반).\r\n *\r\n * 흐름:\r\n * blocks → markdown (blocksToMarkdown)\r\n * markdown → HTML (markdown-it)\r\n * HTML + 프리셋 CSS → PDF (puppeteer-core)\r\n *\r\n * puppeteer-core는 optional peer dep. 미설치 시 markdownToPdf는 명확한 에러를 던지지만\r\n * `renderHtml()`은 항상 동작 (외부 PDF 엔진과 결합용).\r\n *\r\n * 참조: docs/SPEC.md §1.3\r\n */\r\n\r\nimport { existsSync } from \"fs\"\r\nimport MarkdownIt from \"markdown-it\"\r\nimport type { IRBlock } from \"../types.js\"\r\nimport { blocksToMarkdown } from \"../table/builder.js\"\r\nimport { KordocError } from \"../utils.js\"\r\n\r\n// ─── 타입 ─────────────────────────────────────────\r\n\r\nexport type PrintPreset = \"default\" | \"gov-formal\" | \"compact\"\r\n\r\nexport interface PageMargin {\r\n top: string | number // mm 또는 CSS string (\"20mm\", \"1in\")\r\n right: string | number\r\n bottom: string | number\r\n left: string | number\r\n}\r\n\r\nexport interface PrintOptions {\r\n preset?: PrintPreset\r\n pageSize?: \"A4\" | \"Letter\"\r\n orientation?: \"portrait\" | \"landscape\"\r\n margin?: PageMargin\r\n /** 페이지 머리글 (HTML 허용, gov-formal 프리셋에서 자동 표시) */\r\n header?: string\r\n /** 페이지 바닥글 (HTML 허용) */\r\n footer?: string\r\n /** 워터마크 텍스트 (대각선 회색) */\r\n watermark?: string\r\n /** 사용자 정의 추가 CSS */\r\n extraCss?: string\r\n}\r\n\r\n// ─── 프리셋 CSS ───────────────────────────────────\r\n\r\nconst PRESETS: Record<PrintPreset, string> = {\r\n default: `\r\n @page { size: A4; margin: 20mm; }\r\n body { font-family: 'Pretendard', 'Malgun Gothic', '맑은 고딕', sans-serif; font-size: 11pt; line-height: 1.6; color: #111; }\r\n h1 { font-size: 20pt; margin: 1em 0 0.5em; }\r\n h2 { font-size: 16pt; margin: 1em 0 0.4em; }\r\n h3 { font-size: 13pt; margin: 0.8em 0 0.3em; }\r\n p { margin: 0.4em 0; }\r\n table { border-collapse: collapse; margin: 0.6em 0; width: 100%; }\r\n th, td { border: 1px solid #555; padding: 4px 8px; text-align: left; vertical-align: top; }\r\n th { background: #f0f0f0; }\r\n code { background: #f5f5f5; padding: 1px 4px; border-radius: 2px; font-family: 'D2Coding', Consolas, monospace; }\r\n pre { background: #f5f5f5; padding: 8px; border-radius: 4px; overflow-x: auto; }\r\n blockquote { border-left: 3px solid #ccc; padding-left: 12px; color: #555; margin: 0.6em 0; }\r\n img { max-width: 100%; }\r\n `,\r\n \"gov-formal\": `\r\n @page { size: A4; margin: 25mm 20mm; }\r\n body { font-family: '함초롬바탕', 'HCR Batang', 'Batang', 'Malgun Gothic', serif; font-size: 11pt; line-height: 1.7; color: #000; }\r\n h1 { font-size: 18pt; text-align: center; margin: 0.5em 0 1em; letter-spacing: 0.05em; }\r\n h2 { font-size: 14pt; margin: 1em 0 0.4em; border-bottom: 1px solid #999; padding-bottom: 2px; }\r\n h3 { font-size: 12pt; margin: 0.8em 0 0.3em; }\r\n p { margin: 0.3em 0; text-indent: 1em; }\r\n table { border-collapse: collapse; margin: 0.8em 0; width: 100%; }\r\n th, td { border: 1px solid #000; padding: 5px 8px; vertical-align: top; }\r\n th { background: #e8e8e8; font-weight: normal; }\r\n blockquote { border-left: 2px solid #555; padding-left: 12px; margin: 0.6em 0; }\r\n `,\r\n compact: `\r\n @page { size: A4; margin: 10mm; }\r\n body { font-family: 'Pretendard', 'Malgun Gothic', sans-serif; font-size: 9pt; line-height: 1.4; color: #111; }\r\n h1 { font-size: 14pt; margin: 0.5em 0 0.3em; }\r\n h2 { font-size: 12pt; margin: 0.5em 0 0.3em; }\r\n h3 { font-size: 10pt; margin: 0.4em 0 0.2em; }\r\n p { margin: 0.2em 0; }\r\n table { border-collapse: collapse; margin: 0.3em 0; width: 100%; font-size: 8pt; }\r\n th, td { border: 1px solid #777; padding: 2px 4px; }\r\n th { background: #f0f0f0; }\r\n `,\r\n}\r\n\r\n// ─── HTML 생성 ─────────────────────────────────\r\n\r\nconst md = new MarkdownIt({\r\n html: true,\r\n linkify: true,\r\n breaks: false,\r\n})\r\n\r\n/**\r\n * Markdown 또는 IRBlock[] → HTML 문자열.\r\n * 외부 PDF 엔진(weasyprint, wkhtmltopdf 등)과 결합 가능.\r\n */\r\nexport function renderHtml(\r\n markdown: string,\r\n options?: PrintOptions,\r\n): string {\r\n const preset = options?.preset ?? \"default\"\r\n const css = PRESETS[preset] + (options?.extraCss ?? \"\")\r\n const body = md.render(markdown)\r\n\r\n const watermark = options?.watermark\r\n ? `<div class=\"watermark\">${escapeHtml(options.watermark)}</div>`\r\n : \"\"\r\n const watermarkCss = options?.watermark\r\n ? `\r\n .watermark {\r\n position: fixed;\r\n top: 50%; left: 50%;\r\n transform: translate(-50%, -50%) rotate(-30deg);\r\n font-size: 80pt;\r\n color: rgba(0,0,0,0.08);\r\n pointer-events: none;\r\n z-index: 9999;\r\n white-space: nowrap;\r\n }`\r\n : \"\"\r\n\r\n return `<!DOCTYPE html>\r\n<html lang=\"ko\">\r\n<head>\r\n<meta charset=\"utf-8\">\r\n<style>${css}${watermarkCss}</style>\r\n</head>\r\n<body>\r\n${watermark}\r\n${body}\r\n</body>\r\n</html>`\r\n}\r\n\r\nfunction escapeHtml(s: string): string {\r\n return s\r\n .replace(/&/g, \"&amp;\")\r\n .replace(/</g, \"&lt;\")\r\n .replace(/>/g, \"&gt;\")\r\n .replace(/\"/g, \"&quot;\")\r\n .replace(/'/g, \"&#39;\")\r\n}\r\n\r\n// ─── PDF 생성 ─────────────────────────────────\r\n\r\n/**\r\n * puppeteer-core로 HTML → PDF 변환.\r\n * 환경에 Chromium 실행 파일 필요 (PUPPETEER_EXECUTABLE_PATH 환경변수 또는 자동 감지).\r\n */\r\nasync function htmlToPdf(html: string, options?: PrintOptions): Promise<Buffer> {\r\n let puppeteer: typeof import(\"puppeteer-core\")\r\n try {\r\n puppeteer = await import(\"puppeteer-core\")\r\n } catch {\r\n throw new KordocError(\r\n \"PDF 생성에 puppeteer-core가 필요합니다. 설치: npm install puppeteer-core\",\r\n )\r\n }\r\n\r\n const executablePath =\r\n process.env.PUPPETEER_EXECUTABLE_PATH ?? findChromiumPath()\r\n if (!executablePath) {\r\n throw new KordocError(\r\n \"Chromium 실행 파일을 찾을 수 없습니다. PUPPETEER_EXECUTABLE_PATH 환경변수를 설정하세요.\",\r\n )\r\n }\r\n\r\n const browser = await puppeteer.default.launch({\r\n executablePath,\r\n headless: true,\r\n args: [\"--no-sandbox\", \"--disable-setuid-sandbox\"],\r\n })\r\n\r\n try {\r\n const page = await browser.newPage()\r\n await page.setContent(html, { waitUntil: \"networkidle0\" })\r\n\r\n const margin = options?.margin\r\n const pdf = await page.pdf({\r\n format: options?.pageSize ?? \"A4\",\r\n landscape: options?.orientation === \"landscape\",\r\n printBackground: true,\r\n margin: margin\r\n ? {\r\n top: toCss(margin.top),\r\n right: toCss(margin.right),\r\n bottom: toCss(margin.bottom),\r\n left: toCss(margin.left),\r\n }\r\n : undefined,\r\n displayHeaderFooter: !!(options?.header || options?.footer),\r\n headerTemplate: options?.header ?? \"<div></div>\",\r\n footerTemplate:\r\n options?.footer ??\r\n '<div style=\"font-size:8pt;width:100%;text-align:center;color:#777;\"><span class=\"pageNumber\"></span>/<span class=\"totalPages\"></span></div>',\r\n })\r\n return Buffer.from(pdf)\r\n } finally {\r\n await browser.close()\r\n }\r\n}\r\n\r\nfunction toCss(v: string | number): string {\r\n return typeof v === \"number\" ? `${v}mm` : v\r\n}\r\n\r\n/** Windows/Mac/Linux의 일반적 Chrome 경로 자동 감지 */\r\nfunction findChromiumPath(): string | null {\r\n // 사용자가 명시 안 했으면 OS 표준 경로 시도\r\n // Windows\r\n const win = [\r\n \"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\r\n \"C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\r\n process.env.LOCALAPPDATA + \"\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\r\n \"C:\\\\Program Files\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\",\r\n \"C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\",\r\n ]\r\n // Mac\r\n const mac = [\r\n \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\",\r\n \"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\",\r\n ]\r\n // Linux\r\n const linux = [\"/usr/bin/google-chrome\", \"/usr/bin/chromium-browser\", \"/usr/bin/chromium\"]\r\n\r\n const candidates =\r\n process.platform === \"win32\" ? win : process.platform === \"darwin\" ? mac : linux\r\n\r\n for (const p of candidates) {\r\n if (p && existsSync(p)) return p\r\n }\r\n return null\r\n}\r\n\r\n/** Markdown → PDF (Buffer). */\r\nexport async function markdownToPdf(\r\n markdown: string,\r\n options?: PrintOptions,\r\n): Promise<Buffer> {\r\n const html = renderHtml(markdown, options)\r\n return htmlToPdf(html, options)\r\n}\r\n\r\n/** IRBlock[] → PDF (Buffer). */\r\nexport async function blocksToPdf(\r\n blocks: IRBlock[],\r\n options?: PrintOptions,\r\n): Promise<Buffer> {\r\n const markdown = blocksToMarkdown(blocks)\r\n return markdownToPdf(markdown, options)\r\n}\r\n"],"mappings":"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,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAC7E,CAAC;AAED,IAAM,YAAY,IAAI,WAAW;AAAA,EAC/B;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,E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,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAChH;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA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","names":["JSZip","JSZip","warnings","kids","inflateRawSync","MAX_DECOMPRESS_SIZE","inflateRawSync","start","end","require","cellRows","inflateRawSync","inflateRawSync","JSZip","DOMParser","MAX_DECOMPRESS_SIZE","MAX_ROWS","MAX_COLS","DOMParser","JSZip","parsePageRange","MAX_RECORDS","readRecords","data","MAX_SHEETS","MAX_ROWS","MAX_COLS","sheetToBlocks","readRecords","parsePageRange","JSZip","DOMParser","MAX_DECOMPRESS_SIZE","localName","parseXml","DOMParser","parseRels","runs","text","JSZip","DOMParser","MAX_XML_DEPTH","DOMParser","parseSection","parseParagraph","parseTable","JSZip","DOMParser","JSZip","DOMParser","extractCellText","localName","JSZip","md","i","j"]}