diff --git a/Cargo.toml b/Cargo.toml index c3de5fb12..e1d59cec2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ cfb = "0.14" flate2 = "1.0" byteorder = "1.5" base64 = "0.22" -zip = { version = "8.5", default-features = false, features = ["deflate"] } +zip = { version = "2", default-features = false, features = ["deflate"] } quick-xml = "0.39" codepage = "0.1.2" embedded-io = "0.7.1" diff --git a/hwpkit-extension/index.d.mts b/hwpkit-extension/index.d.mts new file mode 100644 index 000000000..67f568e6a --- /dev/null +++ b/hwpkit-extension/index.d.mts @@ -0,0 +1,371 @@ +type Align = 'left' | 'center' | 'right' | 'justify'; +type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front' | 'topAndBottom'; +type ImgHorzAlign = 'left' | 'center' | 'right'; +type ImgVertAlign = 'top' | 'center' | 'bottom'; +type ImgHorzRelTo = 'margin' | 'column' | 'page' | 'para'; +type ImgVertRelTo = 'margin' | 'line' | 'page' | 'para'; +interface ImgLayout { + wrap: ImgWrap; + horzAlign?: ImgHorzAlign; + vertAlign?: ImgVertAlign; + horzRelTo?: ImgHorzRelTo; + vertRelTo?: ImgVertRelTo; + xPt?: number; + yPt?: number; + distT?: number; + distB?: number; + distL?: number; + distR?: number; + behindDoc?: boolean; + zOrder?: number; +} +type VAlign = 'top' | 'mid' | 'bot'; +type Heading = 1 | 2 | 3 | 4 | 5 | 6; +type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none' | 'dashDot' | 'dashDotDot' | 'wave'; +interface TextProps { + b?: boolean; + i?: boolean; + u?: boolean; + s?: boolean; + sup?: boolean; + sub?: boolean; + font?: string; + pt?: number; + color?: string; + bg?: string; +} +interface ParaProps { + align?: Align; + heading?: Heading; + styleId?: string; + indentPt?: number; + indentRightPt?: number; + firstLineIndentPt?: number; + leftMargin?: number; + spaceBefore?: number; + spaceAfter?: number; + lineHeight?: number; + lineHeightFixed?: number; + listLv?: number; + listOrd?: boolean; + listMark?: string; +} +interface Stroke { + kind: StrokeKind; + pt: number; + color: string; +} +interface CellProps { + top?: Stroke; + bot?: Stroke; + left?: Stroke; + right?: Stroke; + bg?: string; + padPt?: number; + padT?: number; + padB?: number; + padL?: number; + padR?: number; + align?: Align; + va?: VAlign; + isHeader?: boolean; +} +interface TableLook { + firstRow?: boolean; + lastRow?: boolean; + firstCol?: boolean; + lastCol?: boolean; + bandedRows?: boolean; + bandedCols?: boolean; +} +interface GridProps { + widthPct?: number; + colWidths?: number[]; + defaultStroke?: Stroke; + look?: TableLook; + headerRow?: boolean; + align?: Align; +} +interface PageDims { + wPt: number; + hPt: number; + mt: number; + mb: number; + ml: number; + mr: number; + orient?: 'portrait' | 'landscape'; + headerPt?: number; + footerPt?: number; +} +interface DocMeta { + title?: string; + author?: string; + subject?: string; + desc?: string; + keywords?: string; + created?: string; + modified?: string; + zoom?: number; + viewMode?: string; +} +declare const A4: PageDims; +declare const A4_LANDSCAPE: PageDims; +/** + * orient === 'landscape'일 때 wPt < hPt이면 swap, + * orient === 'portrait'일 때 wPt> hPt이면 swap하여 + * 방향과 치수가 항상 일치하도록 정규화합니다. + */ +declare function normalizeDims(dims: PageDims): PageDims; +declare const DEFAULT_STROKE: Stroke; + +type BlockTag = 'root' | 'sheet' | 'para' | 'span' | 'txt' | 'img' | 'link' | 'grid' | 'row' | 'cell' | 'br' | 'pb' | 'pagenum'; +interface TxtNode { + tag: 'txt'; + content: string; +} +interface BrNode { + tag: 'br'; +} +interface PbNode { + tag: 'pb'; +} +interface PageNumNode { + tag: 'pagenum'; + format?: 'decimal' | 'roman' | 'romanCaps'; +} +interface ImgNode { + tag: 'img'; + b64: string; + mime: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/bmp'; + w: number; + h: number; + alt?: string; + layout?: ImgLayout; +} +interface SpanNode { + tag: 'span'; + props: TextProps; + kids: (TxtNode | BrNode | PbNode | PageNumNode)[]; +} +interface LinkNode { + tag: 'link'; + href: string; + kids: SpanNode[]; +} +interface ParaNode { + tag: 'para'; + props: ParaProps; + kids: (SpanNode | ImgNode | LinkNode | GridNode)[]; +} +interface CellNode { + tag: 'cell'; + cs: number; + rs: number; + props: CellProps; + kids: (ParaNode | GridNode)[]; +} +interface RowNode { + tag: 'row'; + kids: CellNode[]; + heightPt?: number; +} +interface GridNode { + tag: 'grid'; + props: GridProps; + kids: RowNode[]; +} +type ContentNode = ParaNode | GridNode; +interface SheetNode { + tag: 'sheet'; + dims: PageDims; + kids: ContentNode[]; + headers?: { + default?: ParaNode[]; + first?: ParaNode[]; + even?: ParaNode[]; + }; + footers?: { + default?: ParaNode[]; + first?: ParaNode[]; + even?: ParaNode[]; + }; +} +interface DocRoot { + tag: 'root'; + meta: DocMeta; + kids: SheetNode[]; +} +type AnyNode = DocRoot | SheetNode | ParaNode | SpanNode | TxtNode | ImgNode | LinkNode | GridNode | RowNode | CellNode | BrNode | PbNode | PageNumNode; + +type Outcome = Ok | Fail; +interface Ok { + ok: true; + data: T; + warns: string[]; +} +interface Fail { + ok: false; + error: string; + warns: string[]; +} +declare function succeed(data: T, warns?: string[]): Ok; +declare function fail(error: string, warns?: string[]): Fail; + +interface EncoderOptions { + [key: string]: any; +} +interface Encoder { + readonly format: string; + readonly aliases?: string[]; + encode(doc: DocRoot, options?: EncoderOptions): Promise>; +} + +interface Decoder { + readonly format: string; + readonly aliases?: string[]; + decode(data: Uint8Array): Promise>; +} + +declare class Pipeline { + private raw; + private srcFmt; + private constructor(); + /** 파일을 열고 포맷을 자동 감지하거나 명시 */ + static open(input: Uint8Array | string, fmt?: string): Pipeline; + /** File/Blob 비동기 입력 */ + static openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise; + /** 목표 포맷으로 변환 */ + to(targetFmt: string, options?: EncoderOptions): Promise>; + /** DocRoot만 추출 (인코딩 없이) */ + inspect(): Promise>; +} + +declare class FormatRegistry { + private decoders; + private encoders; + registerDecoder(d: Decoder): void; + registerEncoder(e: Encoder): void; + getDecoder(fmt: string): Decoder | undefined; + getEncoder(fmt: string): Encoder | undefined; + supportedInputs(): string[]; + supportedOutputs(): string[]; +} +declare const registry: FormatRegistry; + +declare function buildRoot(meta?: DocMeta, kids?: SheetNode[]): DocRoot; +declare function buildSheet(kids?: ContentNode[], dims?: PageDims, opts?: { + headers?: SheetNode["headers"]; + footers?: SheetNode["footers"]; +}): SheetNode; +declare function buildPageNum(format?: PageNumNode['format']): PageNumNode; +declare function buildBr(): BrNode; +declare function buildPb(): PbNode; +declare function buildPara(kids?: ParaNode['kids'], props?: ParaProps): ParaNode; +declare function buildSpan(content: string, props?: TextProps): SpanNode; +declare function buildImg(b64: string, mime: ImgNode['mime'], w: number, h: number, alt?: string, layout?: ImgLayout): ImgNode; +declare function buildGrid(kids: RowNode[], props?: GridProps): GridNode; +declare function buildRow(kids: CellNode[], heightPt?: number): RowNode; +declare function buildCell(kids: (ParaNode | GridNode)[], opts?: { + cs?: number; + rs?: number; + props?: CellProps; +}): CellNode; + +declare class ShieldedParser { + private log; + /** 단일 요소 안전 파싱 */ + guard(fn: () => T, fallback: T, label: string): T; + /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */ + guardAll(items: I[], fn: (x: I, i: number) => O, fb: (x: I, i: number) => O, label: string): O[]; + /** + * 표 전용 4단계 폴백 + * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text + */ + guardGrid(node: unknown, lv1Full: (n: unknown) => T, lv2Grid: (n: unknown) => T, lv3Flat: (n: unknown) => T, lv4Text: (n: unknown) => T, label: string): { + value: T; + level: 1 | 2 | 3 | 4; + }; + /** 이미지 안전 파싱 */ + guardImg(node: unknown, fn: (n: unknown) => T, placeholder: (alt: string) => T, label: string): T; + private warn; + flush(): string[]; +} + +declare const Metric: { + readonly hwpToPt: (v: number) => number; + readonly ptToHwp: (v: number) => number; + readonly hwpToDxa: (v: number) => number; + readonly dxaToHwp: (v: number) => number; + readonly hwpToEmu: (v: number) => number; + readonly emuToHwp: (v: number) => number; + readonly dxaToPt: (v: number) => number; + readonly ptToDxa: (v: number) => number; + readonly dxaToEmu: (v: number) => number; + readonly emuToDxa: (v: number) => number; + readonly emuToPt: (v: number) => number; + readonly ptToEmu: (v: number) => number; + readonly hHeightToPt: (v: number) => number; + readonly ptToHHeight: (v: number) => number; + readonly halfPtToPt: (v: number) => number; + readonly ptToHalfPt: (v: number) => number; +}; +declare function safeHex(raw: string | number | null | undefined): string | undefined; +declare function safeAlign(raw?: string): Align; +declare function safeStrokeHwpx(type?: string, w?: number, c?: string): Stroke; +declare function safeStrokeDocx(val?: string, sz?: number, c?: string): Stroke; +declare function safeFont(raw?: string): string; +declare function safeFontToKr(raw?: string): string; + +type WalkCallback = (node: AnyNode, parent: AnyNode | null, depth: number) => void | 'stop'; +declare function walkNode(node: AnyNode, cb: WalkCallback, parent?: AnyNode | null, depth?: number): boolean; +declare class TreeWalker { + walk(root: DocRoot, cb: WalkCallback): void; + findAll(root: DocRoot, predicate: (n: AnyNode) => n is T): T[]; + extractText(root: DocRoot): string; +} + +declare function countNodes(root: DocRoot): Record; +declare function validateRoot(root: DocRoot): string[]; + +declare const XmlKit: { + /** @deprecated Use parseStrict instead */ + parse(xml: string): Promise; + parseStrict(xml: string): Promise; + attr(node: Record, key: string): string | undefined; + text(node: Record | string | undefined): string; +}; + +interface ZipEntry { + name: string; + data: Uint8Array; +} +declare const ArchiveKit: { + inflate(compressed: Uint8Array): Promise; + deflate(data: Uint8Array): Promise; + unzip(zipData: Uint8Array): Promise
    >; + zip(entries: ZipEntry[]): Promise; +}; + +/** + * OLE2 Compound File Binary Format (CFB) parser. + * Used for legacy HWP 5.0 files. + */ +declare const BinaryKit: { + readU16LE(buf: Uint8Array, offset: number): number; + readU32LE(buf: Uint8Array, offset: number): number; + isOle2(data: Uint8Array): boolean; + parseCfb(data: Uint8Array): Map; +}; + +declare const TextKit: { + decode(data: Uint8Array, encoding?: string): string; + encode(text: string): Uint8Array; + escapeXml(s: string): string; + unescapeXml(s: string): string; + normalizeWhitespace(s: string): string; + stripControl(s: string): string; + base64Encode(data: Uint8Array): string; + base64Decode(b64: string): Uint8Array; +}; + +export { A4, A4_LANDSCAPE, type Align, type AnyNode, ArchiveKit, BinaryKit, type BlockTag, type BrNode, type CellNode, type CellProps, type ContentNode, DEFAULT_STROKE, type Decoder, type DocMeta, type DocRoot, type Encoder, type Fail, type GridNode, type GridProps, type Heading, type ImgNode, type LinkNode, Metric, type Ok, type Outcome, type PageDims, type PageNumNode, type ParaNode, type ParaProps, type PbNode, Pipeline, type RowNode, type SheetNode, ShieldedParser, type SpanNode, type Stroke, type StrokeKind, type TableLook, TextKit, type TextProps, TreeWalker, type TxtNode, type VAlign, XmlKit, buildBr, buildCell, buildGrid, buildImg, buildPageNum, buildPara, buildPb, buildRoot, buildRow, buildSheet, buildSpan, countNodes, fail, normalizeDims, registry, safeAlign, safeFont, safeFontToKr, safeHex, safeStrokeDocx, safeStrokeHwpx, succeed, validateRoot, walkNode }; diff --git a/hwpkit-extension/index.d.ts b/hwpkit-extension/index.d.ts new file mode 100644 index 000000000..67f568e6a --- /dev/null +++ b/hwpkit-extension/index.d.ts @@ -0,0 +1,371 @@ +type Align = 'left' | 'center' | 'right' | 'justify'; +type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front' | 'topAndBottom'; +type ImgHorzAlign = 'left' | 'center' | 'right'; +type ImgVertAlign = 'top' | 'center' | 'bottom'; +type ImgHorzRelTo = 'margin' | 'column' | 'page' | 'para'; +type ImgVertRelTo = 'margin' | 'line' | 'page' | 'para'; +interface ImgLayout { + wrap: ImgWrap; + horzAlign?: ImgHorzAlign; + vertAlign?: ImgVertAlign; + horzRelTo?: ImgHorzRelTo; + vertRelTo?: ImgVertRelTo; + xPt?: number; + yPt?: number; + distT?: number; + distB?: number; + distL?: number; + distR?: number; + behindDoc?: boolean; + zOrder?: number; +} +type VAlign = 'top' | 'mid' | 'bot'; +type Heading = 1 | 2 | 3 | 4 | 5 | 6; +type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none' | 'dashDot' | 'dashDotDot' | 'wave'; +interface TextProps { + b?: boolean; + i?: boolean; + u?: boolean; + s?: boolean; + sup?: boolean; + sub?: boolean; + font?: string; + pt?: number; + color?: string; + bg?: string; +} +interface ParaProps { + align?: Align; + heading?: Heading; + styleId?: string; + indentPt?: number; + indentRightPt?: number; + firstLineIndentPt?: number; + leftMargin?: number; + spaceBefore?: number; + spaceAfter?: number; + lineHeight?: number; + lineHeightFixed?: number; + listLv?: number; + listOrd?: boolean; + listMark?: string; +} +interface Stroke { + kind: StrokeKind; + pt: number; + color: string; +} +interface CellProps { + top?: Stroke; + bot?: Stroke; + left?: Stroke; + right?: Stroke; + bg?: string; + padPt?: number; + padT?: number; + padB?: number; + padL?: number; + padR?: number; + align?: Align; + va?: VAlign; + isHeader?: boolean; +} +interface TableLook { + firstRow?: boolean; + lastRow?: boolean; + firstCol?: boolean; + lastCol?: boolean; + bandedRows?: boolean; + bandedCols?: boolean; +} +interface GridProps { + widthPct?: number; + colWidths?: number[]; + defaultStroke?: Stroke; + look?: TableLook; + headerRow?: boolean; + align?: Align; +} +interface PageDims { + wPt: number; + hPt: number; + mt: number; + mb: number; + ml: number; + mr: number; + orient?: 'portrait' | 'landscape'; + headerPt?: number; + footerPt?: number; +} +interface DocMeta { + title?: string; + author?: string; + subject?: string; + desc?: string; + keywords?: string; + created?: string; + modified?: string; + zoom?: number; + viewMode?: string; +} +declare const A4: PageDims; +declare const A4_LANDSCAPE: PageDims; +/** + * orient === 'landscape'일 때 wPt < hPt이면 swap, + * orient === 'portrait'일 때 wPt> hPt이면 swap하여 + * 방향과 치수가 항상 일치하도록 정규화합니다. + */ +declare function normalizeDims(dims: PageDims): PageDims; +declare const DEFAULT_STROKE: Stroke; + +type BlockTag = 'root' | 'sheet' | 'para' | 'span' | 'txt' | 'img' | 'link' | 'grid' | 'row' | 'cell' | 'br' | 'pb' | 'pagenum'; +interface TxtNode { + tag: 'txt'; + content: string; +} +interface BrNode { + tag: 'br'; +} +interface PbNode { + tag: 'pb'; +} +interface PageNumNode { + tag: 'pagenum'; + format?: 'decimal' | 'roman' | 'romanCaps'; +} +interface ImgNode { + tag: 'img'; + b64: string; + mime: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/bmp'; + w: number; + h: number; + alt?: string; + layout?: ImgLayout; +} +interface SpanNode { + tag: 'span'; + props: TextProps; + kids: (TxtNode | BrNode | PbNode | PageNumNode)[]; +} +interface LinkNode { + tag: 'link'; + href: string; + kids: SpanNode[]; +} +interface ParaNode { + tag: 'para'; + props: ParaProps; + kids: (SpanNode | ImgNode | LinkNode | GridNode)[]; +} +interface CellNode { + tag: 'cell'; + cs: number; + rs: number; + props: CellProps; + kids: (ParaNode | GridNode)[]; +} +interface RowNode { + tag: 'row'; + kids: CellNode[]; + heightPt?: number; +} +interface GridNode { + tag: 'grid'; + props: GridProps; + kids: RowNode[]; +} +type ContentNode = ParaNode | GridNode; +interface SheetNode { + tag: 'sheet'; + dims: PageDims; + kids: ContentNode[]; + headers?: { + default?: ParaNode[]; + first?: ParaNode[]; + even?: ParaNode[]; + }; + footers?: { + default?: ParaNode[]; + first?: ParaNode[]; + even?: ParaNode[]; + }; +} +interface DocRoot { + tag: 'root'; + meta: DocMeta; + kids: SheetNode[]; +} +type AnyNode = DocRoot | SheetNode | ParaNode | SpanNode | TxtNode | ImgNode | LinkNode | GridNode | RowNode | CellNode | BrNode | PbNode | PageNumNode; + +type Outcome = Ok | Fail; +interface Ok { + ok: true; + data: T; + warns: string[]; +} +interface Fail { + ok: false; + error: string; + warns: string[]; +} +declare function succeed(data: T, warns?: string[]): Ok; +declare function fail(error: string, warns?: string[]): Fail; + +interface EncoderOptions { + [key: string]: any; +} +interface Encoder { + readonly format: string; + readonly aliases?: string[]; + encode(doc: DocRoot, options?: EncoderOptions): Promise>; +} + +interface Decoder { + readonly format: string; + readonly aliases?: string[]; + decode(data: Uint8Array): Promise>; +} + +declare class Pipeline { + private raw; + private srcFmt; + private constructor(); + /** 파일을 열고 포맷을 자동 감지하거나 명시 */ + static open(input: Uint8Array | string, fmt?: string): Pipeline; + /** File/Blob 비동기 입력 */ + static openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise; + /** 목표 포맷으로 변환 */ + to(targetFmt: string, options?: EncoderOptions): Promise>; + /** DocRoot만 추출 (인코딩 없이) */ + inspect(): Promise>; +} + +declare class FormatRegistry { + private decoders; + private encoders; + registerDecoder(d: Decoder): void; + registerEncoder(e: Encoder): void; + getDecoder(fmt: string): Decoder | undefined; + getEncoder(fmt: string): Encoder | undefined; + supportedInputs(): string[]; + supportedOutputs(): string[]; +} +declare const registry: FormatRegistry; + +declare function buildRoot(meta?: DocMeta, kids?: SheetNode[]): DocRoot; +declare function buildSheet(kids?: ContentNode[], dims?: PageDims, opts?: { + headers?: SheetNode["headers"]; + footers?: SheetNode["footers"]; +}): SheetNode; +declare function buildPageNum(format?: PageNumNode['format']): PageNumNode; +declare function buildBr(): BrNode; +declare function buildPb(): PbNode; +declare function buildPara(kids?: ParaNode['kids'], props?: ParaProps): ParaNode; +declare function buildSpan(content: string, props?: TextProps): SpanNode; +declare function buildImg(b64: string, mime: ImgNode['mime'], w: number, h: number, alt?: string, layout?: ImgLayout): ImgNode; +declare function buildGrid(kids: RowNode[], props?: GridProps): GridNode; +declare function buildRow(kids: CellNode[], heightPt?: number): RowNode; +declare function buildCell(kids: (ParaNode | GridNode)[], opts?: { + cs?: number; + rs?: number; + props?: CellProps; +}): CellNode; + +declare class ShieldedParser { + private log; + /** 단일 요소 안전 파싱 */ + guard(fn: () => T, fallback: T, label: string): T; + /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */ + guardAll(items: I[], fn: (x: I, i: number) => O, fb: (x: I, i: number) => O, label: string): O[]; + /** + * 표 전용 4단계 폴백 + * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text + */ + guardGrid(node: unknown, lv1Full: (n: unknown) => T, lv2Grid: (n: unknown) => T, lv3Flat: (n: unknown) => T, lv4Text: (n: unknown) => T, label: string): { + value: T; + level: 1 | 2 | 3 | 4; + }; + /** 이미지 안전 파싱 */ + guardImg(node: unknown, fn: (n: unknown) => T, placeholder: (alt: string) => T, label: string): T; + private warn; + flush(): string[]; +} + +declare const Metric: { + readonly hwpToPt: (v: number) => number; + readonly ptToHwp: (v: number) => number; + readonly hwpToDxa: (v: number) => number; + readonly dxaToHwp: (v: number) => number; + readonly hwpToEmu: (v: number) => number; + readonly emuToHwp: (v: number) => number; + readonly dxaToPt: (v: number) => number; + readonly ptToDxa: (v: number) => number; + readonly dxaToEmu: (v: number) => number; + readonly emuToDxa: (v: number) => number; + readonly emuToPt: (v: number) => number; + readonly ptToEmu: (v: number) => number; + readonly hHeightToPt: (v: number) => number; + readonly ptToHHeight: (v: number) => number; + readonly halfPtToPt: (v: number) => number; + readonly ptToHalfPt: (v: number) => number; +}; +declare function safeHex(raw: string | number | null | undefined): string | undefined; +declare function safeAlign(raw?: string): Align; +declare function safeStrokeHwpx(type?: string, w?: number, c?: string): Stroke; +declare function safeStrokeDocx(val?: string, sz?: number, c?: string): Stroke; +declare function safeFont(raw?: string): string; +declare function safeFontToKr(raw?: string): string; + +type WalkCallback = (node: AnyNode, parent: AnyNode | null, depth: number) => void | 'stop'; +declare function walkNode(node: AnyNode, cb: WalkCallback, parent?: AnyNode | null, depth?: number): boolean; +declare class TreeWalker { + walk(root: DocRoot, cb: WalkCallback): void; + findAll(root: DocRoot, predicate: (n: AnyNode) => n is T): T[]; + extractText(root: DocRoot): string; +} + +declare function countNodes(root: DocRoot): Record; +declare function validateRoot(root: DocRoot): string[]; + +declare const XmlKit: { + /** @deprecated Use parseStrict instead */ + parse(xml: string): Promise; + parseStrict(xml: string): Promise; + attr(node: Record, key: string): string | undefined; + text(node: Record | string | undefined): string; +}; + +interface ZipEntry { + name: string; + data: Uint8Array; +} +declare const ArchiveKit: { + inflate(compressed: Uint8Array): Promise; + deflate(data: Uint8Array): Promise; + unzip(zipData: Uint8Array): Promise
      >; + zip(entries: ZipEntry[]): Promise; +}; + +/** + * OLE2 Compound File Binary Format (CFB) parser. + * Used for legacy HWP 5.0 files. + */ +declare const BinaryKit: { + readU16LE(buf: Uint8Array, offset: number): number; + readU32LE(buf: Uint8Array, offset: number): number; + isOle2(data: Uint8Array): boolean; + parseCfb(data: Uint8Array): Map; +}; + +declare const TextKit: { + decode(data: Uint8Array, encoding?: string): string; + encode(text: string): Uint8Array; + escapeXml(s: string): string; + unescapeXml(s: string): string; + normalizeWhitespace(s: string): string; + stripControl(s: string): string; + base64Encode(data: Uint8Array): string; + base64Decode(b64: string): Uint8Array; +}; + +export { A4, A4_LANDSCAPE, type Align, type AnyNode, ArchiveKit, BinaryKit, type BlockTag, type BrNode, type CellNode, type CellProps, type ContentNode, DEFAULT_STROKE, type Decoder, type DocMeta, type DocRoot, type Encoder, type Fail, type GridNode, type GridProps, type Heading, type ImgNode, type LinkNode, Metric, type Ok, type Outcome, type PageDims, type PageNumNode, type ParaNode, type ParaProps, type PbNode, Pipeline, type RowNode, type SheetNode, ShieldedParser, type SpanNode, type Stroke, type StrokeKind, type TableLook, TextKit, type TextProps, TreeWalker, type TxtNode, type VAlign, XmlKit, buildBr, buildCell, buildGrid, buildImg, buildPageNum, buildPara, buildPb, buildRoot, buildRow, buildSheet, buildSpan, countNodes, fail, normalizeDims, registry, safeAlign, safeFont, safeFontToKr, safeHex, safeStrokeDocx, safeStrokeHwpx, succeed, validateRoot, walkNode }; diff --git a/hwpkit-extension/index.js b/hwpkit-extension/index.js new file mode 100644 index 000000000..9384e76ab --- /dev/null +++ b/hwpkit-extension/index.js @@ -0,0 +1,7833 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var index_exports = {}; +__export(index_exports, { + A4: () => A4, + A4_LANDSCAPE: () => A4_LANDSCAPE, + ArchiveKit: () => ArchiveKit, + BinaryKit: () => BinaryKit, + DEFAULT_STROKE: () => DEFAULT_STROKE, + Metric: () => Metric, + Pipeline: () => Pipeline, + ShieldedParser: () => ShieldedParser, + TextKit: () => TextKit, + TreeWalker: () => TreeWalker, + XmlKit: () => XmlKit, + buildBr: () => buildBr, + buildCell: () => buildCell, + buildGrid: () => buildGrid, + buildImg: () => buildImg, + buildPageNum: () => buildPageNum, + buildPara: () => buildPara, + buildPb: () => buildPb, + buildRoot: () => buildRoot, + buildRow: () => buildRow, + buildSheet: () => buildSheet, + buildSpan: () => buildSpan, + countNodes: () => countNodes, + fail: () => fail, + normalizeDims: () => normalizeDims, + registry: () => registry, + safeAlign: () => safeAlign, + safeFont: () => safeFont, + safeFontToKr: () => safeFontToKr, + safeHex: () => safeHex, + safeStrokeDocx: () => safeStrokeDocx, + safeStrokeHwpx: () => safeStrokeHwpx, + succeed: () => succeed, + validateRoot: () => validateRoot, + walkNode: () => walkNode +}); +module.exports = __toCommonJS(index_exports); + +// src/contract/result.ts +function succeed(data, warns = []) { + return { ok: true, data, warns }; +} +function fail(error, warns = []) { + return { ok: false, error, warns }; +} + +// src/pipeline/registry.ts +var FormatRegistry = class { + constructor() { + this.decoders = /* @__PURE__ */ new Map(); + this.encoders = /* @__PURE__ */ new Map(); + } + registerDecoder(d) { + this.decoders.set(d.format, d); + if (d.aliases) { + for (const alias of d.aliases) this.decoders.set(alias, d); + } + } + registerEncoder(e) { + this.encoders.set(e.format, e); + if (e.aliases) { + for (const alias of e.aliases) this.encoders.set(alias, e); + } + } + getDecoder(fmt) { + return this.decoders.get(fmt); + } + getEncoder(fmt) { + return this.encoders.get(fmt); + } + supportedInputs() { + return [...this.decoders.keys()]; + } + supportedOutputs() { + return [...this.encoders.keys()]; + } +}; +var registry = new FormatRegistry(); + +// src/model/doc-props.ts +var A4 = { + wPt: 595.28, + hPt: 841.89, + mt: 56.69, + mb: 56.69, + ml: 70.87, + mr: 70.87, + orient: "portrait" +}; +var A4_LANDSCAPE = { + wPt: 841.89, + hPt: 595.28, + mt: 56.69, + mb: 56.69, + ml: 70.87, + mr: 70.87, + orient: "landscape" +}; +function normalizeDims(dims) { + const orient = dims.orient ?? "portrait"; + if (orient === "landscape" && dims.wPt < dims.hPt) { + return { ...dims, wPt: dims.hPt, hPt: dims.wPt }; + } + if (orient === "portrait" && dims.wPt> dims.hPt) { + return { ...dims, wPt: dims.hPt, hPt: dims.wPt }; + } + return dims; +} +var DEFAULT_STROKE = { kind: "solid", pt: 0.5, color: "000000" }; + +// src/model/builders.ts +function buildRoot(meta = {}, kids = []) { + return { tag: "root", meta, kids }; +} +function buildSheet(kids = [], dims = A4, opts) { + const node = { tag: "sheet", dims, kids }; + if (opts?.headers) node.headers = opts.headers; + if (opts?.footers) node.footers = opts.footers; + return node; +} +function buildPageNum(format) { + return { tag: "pagenum", format }; +} +function buildBr() { + return { tag: "br" }; +} +function buildPb() { + return { tag: "pb" }; +} +function buildPara(kids = [], props = {}) { + return { tag: "para", props, kids }; +} +function buildSpan(content, props = {}) { + const txt = { tag: "txt", content }; + return { tag: "span", props, kids: [txt] }; +} +function buildImg(b64, mime, w, h, alt, layout) { + const node = { tag: "img", b64, mime, w, h }; + if (alt) node.alt = alt; + if (layout) node.layout = layout; + return node; +} +function buildGrid(kids, props = {}) { + return { tag: "grid", props, kids }; +} +function buildRow(kids, heightPt) { + const node = { tag: "row", kids }; + if (heightPt != null) node.heightPt = heightPt; + return node; +} +function buildCell(kids, opts = {}) { + return { tag: "cell", cs: opts.cs ?? 1, rs: opts.rs ?? 1, props: opts.props ?? {}, kids }; +} + +// src/safety/ShieldedParser.ts +var ShieldedParser = class { + constructor() { + this.log = []; + } + /** 단일 요소 안전 파싱 */ + guard(fn, fallback, label) { + try { + const v = fn(); + if (v == null) { + this.warn(label, "returned null/undefined"); + return fallback; + } + return v; + } catch (e) { + this.warn(label, e?.message ?? String(e)); + return fallback; + } + } + /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */ + guardAll(items, fn, fb, label) { + return items.map( + (x, i) => this.guard(() => fn(x, i), fb(x, i), `${label}[${i}]`) + ); + } + /** + * 표 전용 4단계 폴백 + * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text + */ + guardGrid(node, lv1Full, lv2Grid, lv3Flat, lv4Text, label) { + const levels = [ + [lv1Full, 1], + [lv2Grid, 2], + [lv3Flat, 3], + [lv4Text, 4] + ]; + for (const [fn, lv] of levels) { + try { + const v = fn(node); + if (v != null) { + if (lv> 1) this.warn(label, `degraded to level ${lv}`); + return { value: v, level: lv }; + } + } catch (e) { + this.warn(label, `Lv${lv} failed: ${e?.message ?? String(e)}`); + } + } + this.warn(label, "ALL LEVELS FAILED \u2014 returning lv4Text forced"); + return { value: lv4Text(null), level: 4 }; + } + /** 이미지 안전 파싱 */ + guardImg(node, fn, placeholder, label) { + try { + const v = fn(node); + if (v != null) return v; + } catch (e) { + this.warn(label, e?.message ?? String(e)); + } + this.warn(label, "using placeholder image"); + return placeholder(`[\uC774\uBBF8\uC9C0 \uB85C\uB4DC \uC2E4\uD328: ${label}]`); + } + warn(label, msg) { + const w = `[SHIELD] ${label}: ${msg}`; + console.warn(w); + this.log.push(w); + } + flush() { + const r = [...this.log]; + this.log = []; + return r; + } +}; + +// src/safety/StyleBridge.ts +var Metric = { + // HWP 세계 (1 inch = 7200 HWPUNIT) + hwpToPt: (v) => v / 100, + ptToHwp: (v) => Math.round(v * 100), + hwpToDxa: (v) => Math.round(v / 5), + dxaToHwp: (v) => Math.round(v * 5), + hwpToEmu: (v) => Math.round(v * 127), + emuToHwp: (v) => Math.round(v / 127), + // DOCX 세계 (1 inch = 1440 dxa, 1 pt = 20 dxa) + dxaToPt: (v) => v / 20, + ptToDxa: (v) => Math.round(v * 20), + dxaToEmu: (v) => Math.round(v * 635), + emuToDxa: (v) => Math.round(v / 635), + emuToPt: (v) => v / 12700, + ptToEmu: (v) => Math.round(v * 12700), + // HWPX charPr height: 1000 = 10pt + hHeightToPt: (v) => v / 100, + ptToHHeight: (v) => Math.round(v * 100), + // DOCX half-point: 24 = 12pt + halfPtToPt: (v) => v / 2, + ptToHalfPt: (v) => Math.round(v * 2) +}; +function safeHex(raw) { + if (raw == null) return void 0; + if (typeof raw === "number") { + if (raw <= 0) return "000000"; + if (raw>= 16777215) return void 0; + return raw.toString(16).padStart(6, "0").toUpperCase(); + } + let s = String(raw).replace(/^#/, "").toUpperCase(); + if (/^[0-9A-F]{3}$/.test(s)) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2]; + if (/^[0-9A-F]{6}$/.test(s)) return s; + if (s === "AUTO" || s === "NONE" || s === "TRANSPARENT") return void 0; + return void 0; +} +var ALIGN_MAP = { + LEFT: "left", + CENTER: "center", + RIGHT: "right", + JUSTIFY: "justify", + BOTH: "justify", + DISTRIBUTE: "justify", + left: "left", + center: "center", + right: "right", + both: "justify", + start: "left", + end: "right" +}; +function safeAlign(raw) { + return ALIGN_MAP[raw ?? ""] ?? "left"; +} +var HWPX_STROKE = { + SOLID: "solid", + NONE: "none", + DASH: "dash", + DOT: "dot", + DOUBLE: "double", + LONG_DASH: "dash", + DASH_DOT: "dashDot", + DASH_DOT_DOT: "dashDotDot", + THICK_THIN: "double", + THIN_THICK: "double", + TRIPLE: "double" +}; +var DOCX_STROKE = { + single: "solid", + none: "none", + nil: "none", + dashed: "dash", + dotted: "dot", + double: "double", + dotDash: "dashDot", + dotDotDash: "dashDotDot", + thickThin: "double", + thinThick: "double", + triple: "double", + wave: "wave", + dashDotStroked: "dashDot", + threeDEmboss: "solid", + threeDEngrave: "solid" +}; +function safeStrokeHwpx(type, w, c) { + return { + kind: HWPX_STROKE[type ?? ""] ?? "solid", + pt: w != null ? Metric.hwpToPt(w) : 0.5, + color: safeHex(c) ?? "000000" + }; +} +function safeStrokeDocx(val, sz, c) { + return { + kind: DOCX_STROKE[val ?? ""] ?? "solid", + pt: sz != null ? sz / 8 : 0.5, + color: safeHex(c) ?? "000000" + }; +} +var FONT_MAP = { + // 맑은 고딕 계열 + "\uB9D1\uC740 \uACE0\uB515": "Malgun Gothic", + "\uB9D1\uC740\uACE0\uB515": "Malgun Gothic", + // 바탕 계열 (serif) + "\uBC14\uD0D5": "Batang", + "\uBC14\uD0D5\uCCB4": "BatangChe", + "\uD55C\uCEF4\uBC14\uD0D5": "Batang", + "\uD568\uCD08\uB86C\uBC14\uD0D5": "Batang", + "HY\uC2E0\uBA85\uC870": "Batang", + "HY\uACAC\uBA85\uC870": "Batang", + "HY\uADF8\uB798\uD53D": "Batang", + "\uAD81\uC11C": "Gungsuh", + "\uAD81\uC11C\uCCB4": "GungsuhChe", + // 고딕 계열 (sans-serif) + "\uB3CB\uC6C0": "Dotum", + "\uB3CB\uC6C0\uCCB4": "DotumChe", + "\uAD74\uB9BC": "Gulim", + "\uAD74\uB9BC\uCCB4": "GulimChe", + "\uD55C\uCEF4\uB3CB\uC6C0": "Malgun Gothic", + "\uD568\uCD08\uB86C\uB3CB\uC6C0": "Malgun Gothic", + "HY\uACAC\uACE0\uB515": "Malgun Gothic", + "HY\uC911\uACE0\uB515": "Malgun Gothic", + "HY\uD5E4\uB4DC\uB77C\uC778M": "Malgun Gothic", + "HY\uAC15B": "Malgun Gothic", + "HY\uB098\uBB34M": "Malgun Gothic", + "HY\uBAA9\uAC01\uD30C\uC784B": "Malgun Gothic", + "HY\uC5FD\uC11CM": "Malgun Gothic", + "HY\uC5FD\uC11CL": "Malgun Gothic", + // 나눔 계열 + "\uB098\uB214\uACE0\uB515": "Malgun Gothic", + "\uB098\uB214\uBA85\uC870": "Batang" +}; +function safeFont(raw) { + return FONT_MAP[raw ?? ""] ?? raw ?? "Malgun Gothic"; +} +var FONT_MAP_KR = { + "Malgun Gothic": "\uB9D1\uC740 \uACE0\uB515", + "Batang": "\uBC14\uD0D5", + "Dotum": "\uB3CB\uC6C0", + "Gulim": "\uAD74\uB9BC" +}; +function safeFontToKr(raw) { + return FONT_MAP_KR[raw ?? ""] ?? raw ?? "\uB9D1\uC740 \uACE0\uB515"; +} + +// src/toolkit/ArchiveKit.ts +var import_pako = __toESM(require("pako")); +var ArchiveKit = { + async inflate(compressed) { + return import_pako.default.inflate(compressed); + }, + async deflate(data) { + return import_pako.default.deflate(data, { level: 6 }); + }, + async unzip(zipData) { + const files = /* @__PURE__ */ new Map(); + const view = new DataView(zipData.buffer, zipData.byteOffset, zipData.byteLength); + let eocdOffset = -1; + const searchStart = Math.max(0, zipData.length - 65558); + for (let i = zipData.length - 22; i>= searchStart; i--) { + if (view.getUint32(i, true) === 101010256) { + eocdOffset = i; + break; + } + } + if (eocdOffset !== -1) { + const entryCount = view.getUint16(eocdOffset + 10, true); + const centralDirOffset = view.getUint32(eocdOffset + 16, true); + let cdOffset = centralDirOffset; + for (let i = 0; i < entryCount; i++) { + if (cdOffset + 46> zipData.length) break; + if (view.getUint32(cdOffset, true) !== 33639248) break; + const compressionMethod = view.getUint16(cdOffset + 10, true); + const compressedSize = view.getUint32(cdOffset + 20, true); + const uncompressedSize = view.getUint32(cdOffset + 24, true); + const fileNameLength = view.getUint16(cdOffset + 28, true); + const extraLength = view.getUint16(cdOffset + 30, true); + const commentLength = view.getUint16(cdOffset + 32, true); + const localHeaderOffset = view.getUint32(cdOffset + 42, true); + const nameBytes = zipData.subarray(cdOffset + 46, cdOffset + 46 + fileNameLength); + const name = new TextDecoder("utf-8").decode(nameBytes); + cdOffset += 46 + fileNameLength + extraLength + commentLength; + if (name.endsWith("/")) continue; + const localFnLen = view.getUint16(localHeaderOffset + 26, true); + const localExtraLen = view.getUint16(localHeaderOffset + 28, true); + const dataOffset = localHeaderOffset + 30 + localFnLen + localExtraLen; + let fileData; + if (compressionMethod === 0) { + fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize); + } else if (compressionMethod === 8) { + const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize); + fileData = import_pako.default.inflateRaw(compressed); + } else { + throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`); + } + files.set(name, new Uint8Array(fileData)); + } + return files; + } + let offset = 0; + while (offset < zipData.length - 4) { + const sig = view.getUint32(offset, true); + if (sig === 67324752) { + const compressionMethod = view.getUint16(offset + 8, true); + const compressedSize = view.getUint32(offset + 18, true); + const uncompressedSize = view.getUint32(offset + 22, true); + const fileNameLength = view.getUint16(offset + 26, true); + const extraLength = view.getUint16(offset + 28, true); + const nameBytes = zipData.subarray(offset + 30, offset + 30 + fileNameLength); + const name = new TextDecoder("utf-8").decode(nameBytes); + const dataOffset = offset + 30 + fileNameLength + extraLength; + let fileData; + if (compressionMethod === 0) { + fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize); + } else if (compressionMethod === 8) { + const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize); + fileData = import_pako.default.inflateRaw(compressed); + } else { + throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`); + } + files.set(name, new Uint8Array(fileData)); + offset = dataOffset + compressedSize; + } else if (sig === 33639248 || sig === 101010256) { + break; + } else { + offset++; + } + } + return files; + }, + async zip(entries) { + const localHeaders = []; + const centralHeaders = []; + let localOffset = 0; + for (const entry of entries) { + const nameBytes = new TextEncoder().encode(entry.name); + const crc = crc32(entry.data); + const store = entry.name === "mimetype" || entry.name === "version.xml"; + const method = store ? 0 : 8; + const payload = store ? entry.data : import_pako.default.deflateRaw(entry.data, { level: 6 }); + const local = new Uint8Array(30 + nameBytes.length + payload.length); + const lv = new DataView(local.buffer); + lv.setUint32(0, 67324752, true); + lv.setUint16(4, 20, true); + lv.setUint16(6, 0, true); + lv.setUint16(8, method, true); + lv.setUint16(10, 0, true); + lv.setUint16(12, 33, true); + lv.setUint32(14, crc, true); + lv.setUint32(18, payload.length, true); + lv.setUint32(22, entry.data.length, true); + lv.setUint16(26, nameBytes.length, true); + lv.setUint16(28, 0, true); + local.set(nameBytes, 30); + local.set(payload, 30 + nameBytes.length); + const central = new Uint8Array(46 + nameBytes.length); + const cv = new DataView(central.buffer); + cv.setUint32(0, 33639248, true); + cv.setUint16(4, 20, true); + cv.setUint16(6, 20, true); + cv.setUint16(8, 0, true); + cv.setUint16(10, method, true); + cv.setUint16(12, 0, true); + cv.setUint16(14, 33, true); + cv.setUint32(16, crc, true); + cv.setUint32(20, payload.length, true); + cv.setUint32(24, entry.data.length, true); + cv.setUint16(28, nameBytes.length, true); + cv.setUint16(30, 0, true); + cv.setUint16(32, 0, true); + cv.setUint16(34, 0, true); + cv.setUint16(36, 0, true); + cv.setUint32(38, 0, true); + cv.setUint32(42, localOffset, true); + central.set(nameBytes, 46); + localHeaders.push(local); + centralHeaders.push(central); + localOffset += local.length; + } + const centralDir = concat(centralHeaders); + const eocd = new Uint8Array(22); + const ev = new DataView(eocd.buffer); + ev.setUint32(0, 101010256, true); + ev.setUint16(4, 0, true); + ev.setUint16(6, 0, true); + ev.setUint16(8, entries.length, true); + ev.setUint16(10, entries.length, true); + ev.setUint32(12, centralDir.length, true); + ev.setUint32(16, localOffset, true); + ev.setUint16(20, 0, true); + return concat([...localHeaders, centralDir, eocd]); + } +}; +function concat(arrays) { + const total = arrays.reduce((s, a) => s + a.length, 0); + const out = new Uint8Array(total); + let offset = 0; + for (const a of arrays) { + out.set(a, offset); + offset += a.length; + } + return out; +} +function crc32(data) { + let crc = 4294967295; + for (const byte of data) { + crc ^= byte; + for (let i = 0; i < 8; i++) { + crc = crc & 1 ? crc>>> 1 ^ 3988292384 : crc>>> 1; + } + } + return (crc ^ 4294967295)>>> 0; +} + +// src/toolkit/XmlKit.ts +var import_saxes = require("saxes"); +function parseXmlStrict(xml) { + return new Promise((resolve, reject) => { + const parser = new import_saxes.SaxesParser({ xmlns: false }); + const stack = []; + let result = null; + parser.on("error", (err) => reject(err)); + parser.on("opentag", (node) => { + const obj = {}; + const attrs = node.attributes; + if (attrs && Object.keys(attrs).length> 0) { + obj["_attr"] = { ...attrs }; + } + stack.push({ tag: node.name, obj }); + }); + const appendText = (text) => { + if (stack.length> 0 && text) { + const frame = stack[stack.length - 1]; + const cur = frame.obj["_text"]; + frame.obj["_text"] = typeof cur === "string" ? cur + text : text; + } + }; + parser.on("text", (text) => appendText(text)); + parser.on("cdata", (cdata) => appendText(cdata)); + parser.on("closetag", () => { + const frame = stack.pop(); + if (!frame) return; + const { tag, obj } = frame; + if (stack.length === 0) { + result = { [tag]: [obj] }; + } else { + const parent = stack[stack.length - 1].obj; + const existing = parent[tag]; + if (Array.isArray(existing)) { + existing.push(obj); + } else { + parent[tag] = [obj]; + } + if (!parent["_childOrder"]) parent["_childOrder"] = []; + parent["_childOrder"].push(tag); + } + }); + try { + parser.write(xml).close(); + resolve(result); + } catch (e) { + reject(e); + } + }); +} +var XmlKit = { + /** @deprecated Use parseStrict instead */ + async parse(xml) { + return parseXmlStrict(xml); + }, + async parseStrict(xml) { + return parseXmlStrict(xml); + }, + attr(node, key) { + const a = node["_attr"]; + return a?.[key]; + }, + text(node) { + if (node == null) return ""; + if (typeof node === "string") return node; + const t = node["_text"]; + return typeof t === "string" ? t : ""; + } +}; + +// src/toolkit/TextKit.ts +var TextKit = { + decode(data, encoding = "utf-8") { + try { + return new TextDecoder(encoding, { fatal: true }).decode(data); + } catch { + return new TextDecoder("utf-8", { fatal: false }).decode(data); + } + }, + encode(text) { + return new TextEncoder().encode(text); + }, + escapeXml(s) { + return s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + }, + unescapeXml(s) { + return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'"); + }, + normalizeWhitespace(s) { + return s.replace(/\s+/g, " ").trim(); + }, + stripControl(s) { + return s.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ""); + }, + base64Encode(data) { + let binary = ""; + for (let i = 0; i < data.length; i++) { + binary += String.fromCharCode(data[i]); + } + return btoa(binary); + }, + base64Decode(b64) { + const binary = atob(b64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytes; + } +}; + +// src/core/BaseDecoder.ts +var BaseDecoder = class { + constructor() { + this.format = this.getFormat(); + this.aliases = this.getAliases(); + } + /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */ + getAliases() { + return []; + } + // ─── 공통 유틸리티 메서드 ────────────────────────── + /** 바이트를 UTF-8 문자열로 변환 */ + bytesToString(data) { + return TextKit.decode(data); + } + /** 문자열을 UTF-8 바이트로 변환 */ + stringToBytes(s) { + return TextKit.encode(s); + } + /** XML 이스케이프 */ + escapeXml(s) { + return TextKit.escapeXml(s); + } + /** XML 언이스케이프 */ + unescapeXml(s) { + return TextKit.unescapeXml(s); + } + /** base64 문자열을 Uint8Array 로 변환 */ + base64ToBytes(b64) { + return TextKit.base64Decode(b64); + } + /** Uint8Array 를 base64 문자열로 변환 */ + bytesToBase64(data) { + return TextKit.base64Encode(data); + } + /** ZIP 해제 */ + async unzip(data) { + return ArchiveKit.unzip(data); + } + /** ZIP 압축 */ + async zip(entries) { + return ArchiveKit.zip(entries); + } + /** inflate 해제 */ + async inflate(data) { + return ArchiveKit.inflate(data); + } + /** deflate 압축 */ + async deflate(data) { + return ArchiveKit.deflate(data); + } + /** 제어 문자 제거 */ + stripControl(s) { + return TextKit.stripControl(s); + } + /** 공백 정규화 */ + normalizeWhitespace(s) { + return TextKit.normalizeWhitespace(s); + } + /** XML 파싱 (DOMParser 사용) */ + parseXml(xmlString) { + const parser = new DOMParser(); + return parser.parseFromString(xmlString, "text/xml"); + } + /** XML 요소에서 텍스트 내용 추출 */ + getTextContent(element) { + if (!element) return ""; + return element.textContent ?? ""; + } + /** XML 요소의 속성 값 추출 */ + getAttr(element, name) { + return element?.getAttribute(name) ?? null; + } + /** XML 요소의 자식 요소 찾기 */ + getChild(element, tagName) { + if (!element) return null; + return element.querySelector(`>${tagName}`) ?? null; + } + /** XML 요소의 모든 자식 요소 찾기 */ + getChildren(element, tagName) { + if (!element) return []; + return Array.from(element.querySelectorAll(`>${tagName}`)); + } +}; + +// src/encoders/hwpx/constants.ts +var HWPX_MIME_TYPE = "application/hwp+zip"; +var NAMESPACES = { + /** Hancom 문서 네임스페이스 */ + HANCOM: "http://www.hancom.co.kr/hwp/xml", + /** Hancom 공통 네임스페이스 */ + HANCOM_COMMON: "http://www.hancom.co.kr/hwp/xml/common", + /** Hancom 버전 네임스페이스 */ + HANCOM_VERSION: "http://www.hancom.co.kr/hwp/xml/version", + /** Hancom 속성 네임스페이스 */ + HANCOM_PROP: "http://www.hancom.co.kr/hwp/xml/property" +}; +var NAMESPACE_DECLARATIONS = { + HEAD: `xmlns:hh="${NAMESPACES.HANCOM}" xmlns:hc="${NAMESPACES.HANCOM_COMMON}" xmlns:hv="${NAMESPACES.HANCOM_VERSION}" xmlns:hp="${NAMESPACES.HANCOM_PROP}"`, + SECTION: `xmlns:hs="${NAMESPACES.HANCOM}" xmlns:hp="${NAMESPACES.HANCOM_PROP}"` +}; +var PT_PER_INCH = 72; +var PIXELS_PER_INCH = 96; +var PT_PER_PIXEL = PT_PER_INCH / PIXELS_PER_INCH; + +// src/decoders/hwpx/HwpxDecoder.ts +var HwpxDecoder = class extends BaseDecoder { + getFormat() { + return "hwpx"; + } + getAliases() { + return [HWPX_MIME_TYPE, "application/hwp+zip"]; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const files = await ArchiveKit.unzip(data); + const sectionFiles = []; + for (let i = 0; ; i++) { + const sec = files.get(`Contents/section${i}.xml`) ?? files.get(`section${i}.xml`); + if (!sec) break; + sectionFiles.push(sec); + } + if (sectionFiles.length === 0) { + const fallback = findSectionFile(files); + if (fallback) sectionFiles.push(fallback); + } + if (sectionFiles.length === 0) + return fail("HWPX: No section files found"); + const headXml = files.get("Contents/header.xml") ?? files.get("header.xml"); + let meta = {}; + let dims = { ...A4 }; + let borderFills = /* @__PURE__ */ new Map(); + let charPrs = /* @__PURE__ */ new Map(); + let paraPrs = /* @__PURE__ */ new Map(); + if (headXml) { + try { + const headStr = TextKit.decode(headXml); + const headObj = await XmlKit.parseStrict(headStr); + if (headObj) { + meta = extractMeta(headObj); + dims = extractDims(headObj) ?? dims; + borderFills = extractBorderFills(headObj); + charPrs = extractCharPrs(headObj); + paraPrs = extractParaPrs(headObj); + } + } catch { + } + } + const ctx = { + files, + shield, + borderFills, + charPrs, + paraPrs, + warns + }; + const allSections = []; + for (const secFile of sectionFiles) { + const bodyStr = TextKit.decode(secFile); + const bodyObj = await XmlKit.parseStrict(bodyStr); + allSections.push(...normalizeSections(bodyObj)); + } + const kids = shield.guardAll( + allSections, + (sec) => decodeSection(sec, dims, ctx), + () => buildSheet([buildPara([buildSpan("[\uC139\uC158 \uD30C\uC2F1 \uC2E4\uD328]")])], dims), + "hwpx:section" + ); + warns.push(...shield.flush()); + return succeed(buildRoot(meta, kids), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`HWPX decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function findSectionFile(files) { + for (const [key, val] of files) { + if (key.toLowerCase().includes("section") && key.endsWith(".xml")) + return val; + } + return void 0; +} +function normalizeSections(bodyObj) { + if (bodyObj?.["hs:sec"]) return toArr(bodyObj["hs:sec"]); + if (bodyObj?.["hp:SEC"]) return toArr(bodyObj["hp:SEC"]); + const root = bodyObj?.["hp:HWPML"] ?? bodyObj?.HWPML ?? bodyObj; + const body = root?.["hp:BODY"]?.[0] ?? root?.BODY?.[0] ?? root?.["hp:BODY"] ?? root?.BODY; + if (!body) return [bodyObj]; + const sections = body?.["hp:SECTION"] ?? body?.SECTION ?? []; + return Array.isArray(sections) ? sections : [sections]; +} +function getTag(obj, ...names) { + for (const n of names) { + const v = obj?.[n]; + if (v != null) return toArr(v); + } + return []; +} +function extractMeta(headObj) { + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const info = root?.["hh:DOCSUMMARY"]?.[0] ?? root?.DOCSUMMARY?.[0]; + if (!info) return {}; + const a = (k) => info?.[`hh:${k}`]?.[0]?._text ?? info?.[k]?.[0]?._text ?? ""; + return { + title: a("TITLE") || void 0, + author: a("AUTHOR") || void 0, + subject: a("SUBJECT") || void 0 + }; + } catch { + return {}; + } +} +function extractDims(headObj) { + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return null; + const secPrList = refList?.["hh:SECPRLST"]?.[0]?.["hh:SECPR"] ?? refList?.SECPRLST?.[0]?.SECPR; + const sec = Array.isArray(secPrList) ? secPrList[0] : secPrList; + if (!sec) return null; + const pa = sec?.["hh:PAGEPROPERTY"]?.[0]?._attr ?? sec?.PAGEPROPERTY?.[0]?._attr; + if (!pa) return null; + const ew = Number(pa.Width ?? 59528); + const eh = Number(pa.Height ?? 84188); + return { + wPt: Metric.hwpToPt(ew), + hPt: Metric.hwpToPt(eh), + mt: Metric.hwpToPt(Number(pa.TopMargin ?? 5670)), + mb: Metric.hwpToPt(Number(pa.BottomMargin ?? 4252)), + ml: Metric.hwpToPt(Number(pa.LeftMargin ?? 8504)), + mr: Metric.hwpToPt(Number(pa.RightMargin ?? 8504)), + orient: ew> eh ? "landscape" : "portrait" + }; + } catch { + return null; + } +} +function extractBorderFills(headObj) { + const map = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return map; + const bfList = refList?.["hh:borderFills"]?.[0] ?? refList?.["hh:BORDERFILLLIST"]?.[0] ?? refList?.BORDERFILLLIST?.[0]; + if (!bfList) return map; + const bfs = getTag(bfList, "hh:borderFill", "hh:BORDERFILL"); + for (const bf of bfs) { + const attr = bf?._attr ?? {}; + const id = Number(attr.id ?? 0); + if (id === 0) continue; + const info = {}; + const parseBorderEl = (el) => { + if (!el) return void 0; + const a = el?._attr ?? {}; + const mmVal = parseFloat(a.width) || void 0; + const hwpVal = mmVal != null ? mmVal * 2.835 * 100 : void 0; + return safeStrokeHwpx(a.type, hwpVal, a.color); + }; + const topEl = bf?.["hh:topBorder"]?.[0] ?? bf?.["hh:top"]?.[0] ?? bf?.top?.[0]; + const rightEl = bf?.["hh:rightBorder"]?.[0] ?? bf?.["hh:right"]?.[0] ?? bf?.right?.[0]; + const bottomEl = bf?.["hh:bottomBorder"]?.[0] ?? bf?.["hh:bottom"]?.[0] ?? bf?.bottom?.[0]; + const leftEl = bf?.["hh:leftBorder"]?.[0] ?? bf?.["hh:left"]?.[0] ?? bf?.left?.[0]; + info.top = parseBorderEl(topEl); + info.right = parseBorderEl(rightEl); + info.bottom = parseBorderEl(bottomEl); + info.left = parseBorderEl(leftEl); + info.stroke = info.top ?? info.left ?? info.right ?? info.bottom; + const fillBrush = bf?.["hc:fillBrush"]?.[0] ?? bf?.["hh:fillBrush"]?.[0] ?? bf?.["hh:fill"]?.[0] ?? bf?.fill?.[0] ?? bf?.fillBrush?.[0]; + if (fillBrush) { + const winBrush = fillBrush?.["hc:winBrush"]?.[0]?._attr ?? fillBrush?.["hh:winBrush"]?.[0]?._attr ?? fillBrush?.winBrush?.[0]?._attr; + if (winBrush?.faceColor && winBrush.faceColor !== "none") { + info.bgColor = safeHex(winBrush.faceColor); + } + } + map.set(id, info); + } + } catch { + } + return map; +} +function buildFontIdMap(headObj) { + const fontMap = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return fontMap; + const fontfaces = refList?.["hh:fontfaces"]?.[0] ?? refList?.["hh:FONTFACES"]?.[0]; + if (!fontfaces) return fontMap; + const ffGroups = getTag(fontfaces, "hh:fontface", "hh:FONTFACE"); + for (const ff of ffGroups) { + const fonts = getTag(ff, "hh:font", "hh:FONT"); + for (const font of fonts) { + const fa = font?._attr ?? {}; + const fid = Number(fa.id ?? -1); + const name = fa.face ?? fa.name ?? fa.Face ?? ""; + if (fid>= 0 && name && !fontMap.has(fid)) fontMap.set(fid, name); + } + if (fontMap.size> 0) break; + } + } catch { + } + return fontMap; +} +function extractCharPrs(headObj) { + const map = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return map; + const fontIdMap = buildFontIdMap(headObj); + const cpList = refList?.["hh:charProperties"]?.[0] ?? refList?.["hh:CHARPROPERTIES"]?.[0]; + if (!cpList) return map; + const cps = getTag(cpList, "hh:charPr", "hh:CHARPR"); + for (const cp of cps) { + const attr = cp?._attr ?? {}; + const id = Number(attr.id ?? -1); + if (id < 0) continue; + const info = {}; + if (attr.height) info.pt = Metric.hHeightToPt(Number(attr.height)); + if (attr.textColor) info.color = safeHex(attr.textColor); + if (cp?.["hh:bold"]?.[0] != null) info.b = true; + if (cp?.["hh:italic"]?.[0] != null) info.i = true; + const ulAttr = cp?.["hh:underline"]?.[0]?._attr; + if (ulAttr?.type && ulAttr.type !== "NONE") info.u = true; + const stAttr = cp?.["hh:strikeout"]?.[0]?._attr; + if (stAttr?.shape && stAttr.shape !== "NONE" && stAttr.shape !== "3D") + info.s = true; + const fontRefAttr = cp?.["hh:fontRef"]?.[0]?._attr ?? cp?.["hh:FONTREF"]?.[0]?._attr; + if (fontRefAttr) { + const fid = Number( + fontRefAttr.hangul ?? fontRefAttr.latin ?? fontRefAttr.Hangul ?? 0 + ); + const name = fontIdMap.get(fid); + if (name) info.font = safeFont(name); + } + map.set(id, info); + } + } catch { + } + return map; +} +function extractParaPrs(headObj) { + const map = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return map; + const ppList = refList?.["hh:paraProperties"]?.[0] ?? refList?.["hh:PARAPROPERTIES"]?.[0]; + if (!ppList) return map; + const pps = getTag(ppList, "hh:paraPr", "hh:PARAPR"); + for (const pp of pps) { + const attr = pp?._attr ?? {}; + const id = Number(attr.id ?? -1); + if (id < 0) continue; + const alignNode = pp?.["hh:align"]?.[0]?._attr ?? pp?.["hh:ALIGN"]?.[0]?._attr; + const align = alignNode?.horizontal ?? alignNode?.Horizontal; + let marginEl = pp?.["hh:margin"]?.[0] ?? null; + let lineSpEl = pp?.["hh:lineSpacing"]?.[0] ?? null; + if (!marginEl) { + const sw = pp?.["hp:switch"]?.[0]; + const container = sw?.["hp:default"]?.[0] ?? sw?.["hp:case"]?.[0]; + marginEl = container?.["hh:margin"]?.[0] ?? null; + lineSpEl = lineSpEl ?? container?.["hh:lineSpacing"]?.[0] ?? null; + } + let indentPt; + let indentRightPt; + let firstLineIndentPt; + let spaceBefore; + let spaceAfter; + let lineHeight; + let lineHeightFixed; + if (marginEl) { + const leftEl = marginEl?.["hc:left"]?.[0]; + const rightEl = marginEl?.["hc:right"]?.[0]; + const indentEl = marginEl?.["hc:intent"]?.[0] ?? marginEl?.["hc:indent"]?.[0]; + const prevEl = marginEl?.["hc:prev"]?.[0]; + const nextEl = marginEl?.["hc:next"]?.[0]; + const leftVal = Number(leftEl?._attr?.value ?? 0); + const rightVal = Number(rightEl?._attr?.value ?? 0); + const indentVal = Number(indentEl?._attr?.value ?? 0); + const prevVal = Number(prevEl?._attr?.value ?? 0); + const nextVal = Number(nextEl?._attr?.value ?? 0); + if (leftVal !== 0) indentPt = Metric.hwpToPt(leftVal); + if (rightVal !== 0) indentRightPt = Metric.hwpToPt(rightVal); + if (indentVal !== 0) firstLineIndentPt = Metric.hwpToPt(indentVal); + if (prevVal> 0) spaceBefore = Metric.hwpToPt(prevVal); + if (nextVal> 0) spaceAfter = Metric.hwpToPt(nextVal); + } + if (lineSpEl) { + const lsAttr = lineSpEl._attr ?? {}; + const lsType = lsAttr.type ?? "PERCENT"; + const lsVal = Number(lsAttr.value ?? 160); + if (lsType === "PERCENT" && lsVal> 0 && lsVal !== 160) { + lineHeight = lsVal / 100; + } else if (lsType === "FIXED" && lsVal> 0) { + lineHeightFixed = Metric.hwpToPt(lsVal); + } + } + map.set(id, { + align, + indentPt, + indentRightPt, + firstLineIndentPt, + spaceBefore, + spaceAfter, + lineHeight, + lineHeightFixed + }); + } + } catch { + } + return map; +} +function addParaItems(p, items) { + const runs = getTag(p, "hp:run", "hp:RUN"); + let hasTable = false; + for (const run of runs) { + const tbls = getTag(run, "hp:tbl", "hp:TABLE"); + if (tbls.length> 0) { + for (const tbl of tbls) { + items.push({ type: "table", node: tbl }); + } + hasTable = true; + } + } + if (!hasTable) { + items.push({ type: "para", node: p }); + } +} +function decodeSection(sec, dims, ctx) { + const firstParas = getTag(sec, "hp:p", "hp:P"); + const pageDims = extractSecPrDims(firstParas[0]) ?? dims; + const items = []; + const paras = getTag(sec, "hp:p", "hp:P"); + const tbls = getTag(sec, "hp:tbl", "hp:TABLE"); + const childOrder = sec?.["_childOrder"]; + if (Array.isArray(childOrder)) { + let pi = 0; + let ti = 0; + for (const tag of childOrder) { + if ((tag === "hp:p" || tag === "hp:P") && pi < paras.length) { + addParaItems(paras[pi++], items); + } else if ((tag === "hp:tbl" || tag === "hp:TABLE") && ti < tbls.length) { + items.push({ type: "table", node: tbls[ti++] }); + } + } + while (pi < paras.length) addParaItems(paras[pi++], items); + while (ti < tbls.length) items.push({ type: "table", node: tbls[ti++] }); + } else { + for (const p of paras) addParaItems(p, items); + for (const t of tbls) items.push({ type: "table", node: t }); + } + const kids = ctx.shield.guardAll( + items, + (item) => { + if (item.type === "table") { + try { + const { value } = ctx.shield.guardGrid( + item.node, + (n) => decodeGrid(n, ctx), + (n) => decodeGridSimple(n, ctx), + (n) => decodeGridFlat(n), + (n) => decodeGridText(n), + "hwpx:table" + ); + return value; + } catch { + return buildPara([buildSpan("[\uD45C \uD30C\uC2F1 \uC2E4\uD328]")]); + } + } + return decodePara(item.node, ctx); + }, + () => buildPara([buildSpan("[\uD30C\uC2F1 \uC2E4\uD328]")]), + "hwpx:content" + ); + const headerParas = decodeHeaderFooter(sec, "header", ctx); + const footerParas = decodeHeaderFooter(sec, "footer", ctx); + return buildSheet(kids.filter(Boolean), pageDims, { + headers: { default: headerParas }, + footers: { default: footerParas } + }); +} +function parseSecPrDims(secPr) { + const pagePr = secPr?.["hp:pagePr"]?.[0]?._attr ?? secPr?.["hp:PAGEPR"]?.[0]?._attr; + if (!pagePr) return null; + const margin = secPr?.["hp:pagePr"]?.[0]?.["hp:margin"]?.[0]?._attr ?? secPr?.["hp:PAGEPR"]?.[0]?.["hp:MARGIN"]?.[0]?._attr ?? {}; + const pw = Number(pagePr.width ?? 59528); + const ph = Number(pagePr.height ?? 84188); + return { + wPt: Metric.hwpToPt(pw), + hPt: Metric.hwpToPt(ph), + mt: Metric.hwpToPt(Number(margin.top ?? 5670)), + mb: Metric.hwpToPt(Number(margin.bottom ?? 4252)), + ml: Metric.hwpToPt(Number(margin.left ?? 8504)), + mr: Metric.hwpToPt(Number(margin.right ?? 8504)), + orient: pw> ph ? "landscape" : "portrait" + }; +} +function extractSecPrDims(p) { + if (!p) return null; + try { + const secPrDirect = p?.["hp:secPr"]?.[0] ?? p?.["hp:SECPR"]?.[0]; + if (secPrDirect) { + const dims = parseSecPrDims(secPrDirect); + if (dims) return dims; + } + const runs = getTag(p, "hp:run", "hp:RUN"); + for (const run of runs) { + const secPr = run?.["hp:secPr"]?.[0] ?? run?.["hp:SECPR"]?.[0]; + if (!secPr) continue; + const dims = parseSecPrDims(secPr); + if (dims) return dims; + } + } catch { + } + return null; +} +function decodeHeaderFooter(sec, kind, ctx) { + try { + const hf = sec?.["hp:headerFooter"]?.[0] ?? sec?.["hp:HEADERFOOTER"]?.[0] ?? sec?.headerFooter?.[0] ?? sec?.HEADERFOOTER?.[0]; + if (!hf) return void 0; + const part = hf?.["hp:" + kind]?.[0] ?? hf?.["hp:" + kind.toUpperCase()]?.[0] ?? hf?.[kind]?.[0] ?? hf?.[kind.toUpperCase()]?.[0]; + if (!part) return void 0; + const paras = getTag(part, "hp:p", "hp:P"); + if (paras.length === 0) return void 0; + return paras.map((p) => decodePara(p, ctx)); + } catch { + return void 0; + } +} +function decodePara(p, ctx) { + const pAttr = p?._attr ?? {}; + const paraPrIdRef = Number(pAttr.paraPrIDRef ?? -1); + let align; + const paraPrDef = ctx.paraPrs.get(paraPrIdRef); + if (paraPrDef?.align) align = paraPrDef.align; + const inlineParaPr = p?.["hp:PARAPR"]?.[0] ?? p?.["hp:paraPr"]?.[0] ?? p?.PARAPR?.[0]; + if (inlineParaPr) { + const alignNode = inlineParaPr?.["hp:ALIGN"]?.[0]?._attr ?? inlineParaPr?.["hp:align"]?.[0]?._attr ?? inlineParaPr?.ALIGN?.[0]?._attr; + if (alignNode?.Type) align = alignNode.Type; + if (alignNode?.horizontal) align = alignNode.horizontal; + } + const inlineAttr = inlineParaPr?._attr ?? {}; + const props = { align: safeAlign(align) }; + if (paraPrDef) { + if (paraPrDef.indentPt !== void 0) props.indentPt = paraPrDef.indentPt; + if (paraPrDef.indentRightPt !== void 0) + props.indentRightPt = paraPrDef.indentRightPt; + if (paraPrDef.firstLineIndentPt !== void 0) + props.firstLineIndentPt = paraPrDef.firstLineIndentPt; + if (paraPrDef.spaceBefore !== void 0) + props.spaceBefore = paraPrDef.spaceBefore; + if (paraPrDef.spaceAfter !== void 0) + props.spaceAfter = paraPrDef.spaceAfter; + if (paraPrDef.lineHeight !== void 0) + props.lineHeight = paraPrDef.lineHeight; + if (paraPrDef.lineHeightFixed !== void 0) + props.lineHeightFixed = paraPrDef.lineHeightFixed; + } + if (inlineAttr.listType) { + props.listOrd = inlineAttr.listType === "DIGIT" || inlineAttr.listType === "DECIMAL"; + props.listLv = Number(inlineAttr.listLevel ?? 0); + } + const runs = getTag(p, "hp:run", "hp:RUN"); + const kids = []; + const collectPics = (container) => { + const direct = getTag(container, "hp:pic", "hp:PIC"); + const ctrls = getTag(container, "hp:ctrl", "hp:CTRL"); + const nested = ctrls.flatMap((c) => getTag(c, "hp:pic", "hp:PIC")); + return [...direct, ...nested]; + }; + for (const pic of collectPics(p)) { + const img = decodePic(pic, ctx); + if (img) kids.push(img); + } + for (const run of runs) { + for (const pic of collectPics(run)) { + const img = decodePic(pic, ctx); + if (img) kids.push(img); + } + const pageNums = getTag(run, "hp:pageNum", "hp:PAGENUM"); + if (pageNums.length> 0) { + const pn = pageNums[0]?._attr ?? {}; + const fmt = pn.formatType === "ROMAN_LOWER" ? "roman" : pn.formatType === "ROMAN_UPPER" ? "romanCaps" : "decimal"; + const pageNumNode = { tag: "pagenum", format: fmt }; + const spanProps = resolveCharPr(run, ctx); + kids.push({ tag: "span", props: spanProps, kids: [pageNumNode] }); + continue; + } + const runPics = collectPics(run); + const textNodes = getTag(run, "hp:t", "hp:T", "hp:CHAR"); + const content = textNodes.map((t) => { + const val = typeof t === "string" ? t : t?._text ?? t?._ ?? t?.["#text"] ?? ""; + return val.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + }).join(""); + if (content === "" && (run?.["hp:secPr"]?.[0] || run?.["hp:SECPR"]?.[0]) && runPics.length === 0 && pageNums.length === 0) + continue; + if (content !== "" || runPics.length === 0 && pageNums.length === 0) { + const spanProps = resolveCharPr(run, ctx); + kids.push(buildSpan(content, spanProps)); + } + } + if (pAttr.pageBreak === "1") { + kids.unshift({ tag: "span", props: {}, kids: [buildPb()] }); + } + return buildPara(kids.filter(Boolean), props); +} +function resolveCharPr(run, ctx) { + const runAttr = run?._attr ?? {}; + const charPrIdRef = Number(runAttr.charPrIDRef ?? runAttr.CharPrIDRef ?? -1); + const def = ctx.charPrs.get(charPrIdRef); + if (def) { + return { + b: def.b, + i: def.i, + u: def.u, + s: def.s, + pt: def.pt, + color: def.color, + font: def.font, + bg: def.bg + }; + } + const inlinePr = run?.["hp:CHARPR"]?.[0] ?? run?.["hp:charPr"]?.[0] ?? run?.CHARPR?.[0] ?? run?.charPr?.[0]; + const ca = inlinePr?._attr ?? {}; + const bVal = ca.Bold ?? ca.bold ?? ca.B ?? ""; + const iVal = ca.Italic ?? ca.italic ?? ca.I ?? ""; + const uVal = ca.Underline ?? ca.underline ?? ""; + const sVal = ca.Strikeout ?? ca.strikeout ?? ""; + const fontName = ca.FontName ?? ca.fontName ?? ca.FaceNameHangul ?? ca.faceNameHangul ?? ""; + const heightVal = ca.Height ?? ca.height ?? ""; + return { + b: bVal === "1" || bVal === "true" || bVal === "True" || void 0, + i: iVal === "1" || iVal === "true" || iVal === "True" || void 0, + u: uVal && uVal !== "NONE" ? true : void 0, + s: sVal && sVal !== "NONE" && sVal !== "3D" ? true : void 0, + font: fontName ? safeFont(fontName) : void 0, + pt: heightVal ? Metric.hHeightToPt(Number(heightVal)) : void 0, + color: safeHex(ca.TextColor ?? ca.textColor), + bg: safeHex(ca.BgColor ?? ca.bgColor) + }; +} +function decodePic(pic, ctx) { + try { + const szAttr = pic?.["hp:sz"]?.[0]?._attr ?? pic?.sz?.[0]?._attr ?? {}; + const w = Metric.hwpToPt(Number(szAttr.width ?? 0)); + const h = Metric.hwpToPt(Number(szAttr.height ?? 0)); + const imgNode = pic?.["hp:img"]?.[0]?._attr ?? pic?.["hc:img"]?.[0]?._attr ?? pic?.img?.[0]?._attr ?? {}; + const binRef = imgNode.binaryItemIDRef ?? imgNode.BinaryItemIDRef; + if (!binRef) return null; + let imgData; + for (const [key, val] of ctx.files) { + if (key.includes(binRef) || key.toLowerCase().includes(binRef.toLowerCase())) { + imgData = val; + break; + } + } + if (!imgData) return null; + const ext = binRef.split(".").pop()?.toLowerCase() ?? "png"; + const mimeMap = { + png: "image/png", + jpg: "image/jpeg", + jpeg: "image/jpeg", + gif: "image/gif", + bmp: "image/bmp" + }; + const posAttr = pic?.["hp:pos"]?.[0]?._attr ?? pic?.pos?.[0]?._attr ?? {}; + const layout = extractHwpxLayout(posAttr, pic); + return buildImg( + TextKit.base64Encode(imgData), + mimeMap[ext] ?? "image/png", + w, + h, + void 0, + layout + ); + } catch { + return null; + } +} +function extractHwpxLayout(posAttr, pic) { + const treatAsChar = posAttr.treatAsChar === "1" || posAttr.treatAsChar === "true"; + if (treatAsChar) return { wrap: "inline" }; + const textWrap = pic?._attr?.textWrap ?? pic?.pic?.[0]?._attr?.textWrap ?? "TOP_AND_BOTTOM"; + const wrapMap = { + TOP_AND_BOTTOM: "topAndBottom", + // float, 위아래 텍스트 흐름 + SQUARE: "square", + BOTH_SIDES: "tight", + LEFT: "tight", + RIGHT: "tight", + LARGER_ONLY: "tight", + SMALLER_ONLY: "tight", + LARGEST_ONLY: "tight", + BEHIND_TEXT: "behind", + FRONT_TEXT: "front" + }; + const wrap = wrapMap[textWrap] ?? "square"; + const horzRelToMap = { + PARA: "para", + MARGIN: "margin", + PAGE: "page", + COLUMN: "column" + }; + const vertRelToMap = { + PARA: "para", + MARGIN: "margin", + PAGE: "page", + PAPER: "page", + LINE: "line" + }; + const horzRelTo = horzRelToMap[posAttr.horzRelTo ?? ""] ?? "para"; + const vertRelTo = vertRelToMap[posAttr.vertRelTo ?? ""] ?? "para"; + const horzAlignMap = { + LEFT: "left", + CENTER: "center", + RIGHT: "right" + }; + const vertAlignMap = { + TOP: "top", + CENTER: "center", + BOTTOM: "bottom" + }; + const horzAlign = horzAlignMap[posAttr.horzAlign ?? ""]; + const vertAlign = vertAlignMap[posAttr.vertAlign ?? ""]; + const horzOffset = Number(posAttr.horzOffset ?? 0); + const vertOffset = Number(posAttr.vertOffset ?? 0); + const xPt = horzOffset !== 0 ? Metric.hwpToPt(horzOffset) : void 0; + const yPt = vertOffset !== 0 ? Metric.hwpToPt(vertOffset) : void 0; + return { wrap, horzAlign, vertAlign, horzRelTo, vertRelTo, xPt, yPt }; +} +function decodeGrid(tbl, ctx) { + const tblAttr = tbl?._attr ?? {}; + const borderFillId = Number(tblAttr.borderFillIDRef ?? 0); + const borderFill = ctx.borderFills.get(borderFillId); + const headerRow = tblAttr.repeatHeader === "1"; + const gridProps = { headerRow: headerRow || void 0 }; + if (borderFill?.stroke) gridProps.defaultStroke = borderFill.stroke; + const rowArr = getTag(tbl, "hp:tr", "hp:ROW"); + for (const row of rowArr) { + const cells = getTag(row, "hp:tc", "hp:CELL"); + const rowWidths = []; + let allSingle = true; + for (const cell of cells) { + const cellSpanAttr = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cs = Number(cellSpanAttr.colSpan ?? cell?._attr?.ColSpan ?? 1); + if (cs> 1) { + allSingle = false; + break; + } + const szAttr = cell?.["hp:cellSz"]?.[0]?._attr ?? {}; + const w = Number(szAttr.width ?? 0); + rowWidths.push(Metric.hwpToPt(w)); + } + if (allSingle && rowWidths.length> 0 && rowWidths.some((w) => w> 0)) { + gridProps.colWidths = rowWidths; + break; + } + } + if (!gridProps.colWidths) { + let detectedCols = 0; + for (const row of rowArr) { + let ci = 0; + for (const cell of getTag(row, "hp:tc", "hp:CELL")) { + const csEl = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + ci += Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1); + } + if (ci> detectedCols) detectedCols = ci; + } + if (detectedCols> 0) { + const sums = new Float64Array(detectedCols); + const counts = new Int32Array(detectedCols); + for (const row of rowArr) { + let ci = 0; + for (const cell of getTag(row, "hp:tc", "hp:CELL")) { + const csEl = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cs = Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1); + const szAttr = cell?.["hp:cellSz"]?.[0]?._attr ?? {}; + const w = Number(szAttr.width ?? 0); + if (w> 0 && cs> 0) { + const perCol = w / cs; + for (let k = 0; k < cs && ci + k < detectedCols; k++) { + sums[ci + k] += perCol; + counts[ci + k]++; + } + } + ci += cs; + } + } + const estimated = Array.from(sums).map( + (s, i) => counts[i]> 0 ? Metric.hwpToPt(s / counts[i]) : 0 + ); + if (estimated.some((w) => w> 0)) gridProps.colWidths = estimated; + } + } + const rowNodes = rowArr.map((row) => { + const cellArr = getTag(row, "hp:tc", "hp:CELL"); + const cellNodes = cellArr.map((cell) => { + const ca = cell?._attr ?? {}; + const cellBfId = Number(ca.borderFillIDRef ?? 0); + const cellBf = ctx.borderFills.get(cellBfId); + const cellProps = { + bg: cellBf?.bgColor ?? safeHex(ca.BgColor) + }; + if (cellBf) { + cellProps.top = cellBf.top ?? cellBf.stroke; + cellProps.bot = cellBf.bottom ?? cellBf.stroke; + cellProps.left = cellBf.left ?? cellBf.stroke; + cellProps.right = cellBf.right ?? cellBf.stroke; + } + const subList = cell?.["hp:subList"]?.[0] ?? cell?.subList?.[0]; + const subAttr = subList?._attr ?? {}; + if (subAttr.vertAlign) { + const vaMap = { + TOP: "top", + CENTER: "mid", + BOTTOM: "bot" + }; + cellProps.va = vaMap[subAttr.vertAlign]; + } + const HWPX_DEFAULT_MARGIN_LR = 360; + const HWPX_DEFAULT_MARGIN_TB = 141; + const mL = Number(subAttr.marginLeft ?? HWPX_DEFAULT_MARGIN_LR); + const mR = Number(subAttr.marginRight ?? HWPX_DEFAULT_MARGIN_LR); + const mT = Number(subAttr.marginTop ?? HWPX_DEFAULT_MARGIN_TB); + const mB = Number(subAttr.marginBottom ?? HWPX_DEFAULT_MARGIN_TB); + if (mL !== HWPX_DEFAULT_MARGIN_LR) cellProps.padL = Metric.hwpToPt(mL); + if (mR !== HWPX_DEFAULT_MARGIN_LR) cellProps.padR = Metric.hwpToPt(mR); + if (mT !== HWPX_DEFAULT_MARGIN_TB) cellProps.padT = Metric.hwpToPt(mT); + if (mB !== HWPX_DEFAULT_MARGIN_TB) cellProps.padB = Metric.hwpToPt(mB); + const cellSpan = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cs = Number(cellSpan.colSpan ?? ca.ColSpan ?? 1); + const rs = Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1); + const cellKids = []; + const source = subList ?? cell; + const sourcePSource = getTag(source, "hp:p", "hp:P"); + for (const sp of sourcePSource) { + try { + const runs = getTag(sp, "hp:run", "hp:RUN"); + let hasNestedTable = false; + for (const run of runs) { + const nestedTbls = getTag(run, "hp:tbl", "hp:TABLE"); + for (const nestedTbl of nestedTbls) { + try { + cellKids.push(decodeGrid(nestedTbl, ctx)); + } catch { + } + hasNestedTable = true; + } + } + if (!hasNestedTable) { + cellKids.push(decodePara(sp, ctx)); + } + } catch { + } + } + return buildCell( + cellKids.length> 0 ? cellKids : [buildPara([buildSpan("")])], + { cs, rs, props: cellProps } + ); + }); + let rowHeightPt; + for (const cell of cellArr) { + const ca = cell?._attr ?? {}; + const cellSpan = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cellRs = Math.max(1, Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1)); + const hSz = cell?.["hp:cellSz"]?.[0]?._attr ?? {}; + const hVal = Number(hSz.height ?? 0); + if (hVal> 0) { + rowHeightPt = Metric.hwpToPt(hVal) / cellRs; + if (cellRs === 1) break; + } + } + return buildRow(cellNodes, rowHeightPt); + }); + return buildGrid(rowNodes, gridProps); +} +function decodeGridSimple(tbl, ctx) { + const rowArr = getTag(tbl, "hp:tr", "hp:ROW"); + const rowNodes = rowArr.map((row) => { + const cellArr = getTag(row, "hp:tc", "hp:CELL"); + return buildRow( + cellArr.map( + (cell) => buildCell([buildPara([buildSpan(cellText(cell))])]) + ) + ); + }); + return buildGrid(rowNodes); +} +function decodeGridFlat(tbl) { + return buildGrid([ + buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])]) + ]); +} +function decodeGridText(tbl) { + return buildPara([buildSpan(tableText(tbl))]); +} +function cellText(cell) { + const subList = cell?.["hp:subList"]?.[0] ?? cell?.subList?.[0]; + const source = subList ?? cell; + return getTag(source, "hp:p", "hp:P").map( + (p) => getTag(p, "hp:run", "hp:RUN").map( + (r) => getTag(r, "hp:t", "hp:T").map((t) => { + const val = typeof t === "string" ? t : t?._text ?? t?._ ?? t?.["#text"] ?? ""; + return val.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + }).join("") + ).join("") + ).join(" "); +} +function tableText(tbl) { + return getTag(tbl, "hp:tr", "hp:ROW").map( + (row) => getTag(row, "hp:tc", "hp:CELL").map((c) => cellText(c)).join(" ") + ).join("\n"); +} +function toArr(v) { + return v == null ? [] : Array.isArray(v) ? v : [v]; +} +registry.registerDecoder(new HwpxDecoder()); + +// src/toolkit/BinaryKit.ts +var BinaryKit = { + readU16LE(buf, offset) { + return buf[offset] | buf[offset + 1] << 8; + }, + readU32LE(buf, offset) { + return ((buf[offset] | buf[offset + 1] << 8 | buf[offset + 2] << 16)>>> 0) + buf[offset + 3] * 16777216; + }, + isOle2(data) { + return data.length>= 8 && data[0] === 208 && data[1] === 207 && data[2] === 17 && data[3] === 224 && data[4] === 161 && data[5] === 177 && data[6] === 26 && data[7] === 225; + }, + parseCfb(data) { + const streams = /* @__PURE__ */ new Map(); + if (!this.isOle2(data)) { + throw new Error("Not a valid OLE2 file"); + } + const view = new DataView(data.buffer, data.byteOffset, data.byteLength); + const sectorSize = 1 << view.getUint16(30, true); + const miniSectorSz = 1 << view.getUint16(32, true); + const dirFirstSec = view.getUint32(48, true); + const miniStreamCutoff = view.getUint32(56, true); + const miniFatFirst = view.getUint32(60, true); + const miniFatCnt = view.getUint32(64, true); + const difatFirst = view.getUint32(68, true); + const ENDOFCHAIN = 4294967294; + const FREESECT = 4294967295; + const sectorAt = (sec) => data.subarray(512 + sec * sectorSize, 512 + (sec + 1) * sectorSize); + const fatSecNums = []; + for (let i = 0; i < 109; i++) { + const s = view.getUint32(76 + i * 4, true); + if (s === FREESECT || s === ENDOFCHAIN) break; + fatSecNums.push(s); + } + if (difatFirst !== ENDOFCHAIN && difatFirst !== FREESECT) { + let difSec = difatFirst; + while (difSec !== ENDOFCHAIN && difSec !== FREESECT) { + const sec = sectorAt(difSec); + const sv = new DataView(sec.buffer, sec.byteOffset, sec.byteLength); + for (let i = 0; i < sectorSize / 4 - 1; i++) { + const s = sv.getUint32(i * 4, true); + if (s === FREESECT || s === ENDOFCHAIN) break; + fatSecNums.push(s); + } + difSec = sv.getUint32(sectorSize - 4, true); + } + } + const fat = []; + for (const sec of fatSecNums) { + const s = sectorAt(sec); + const sv = new DataView(s.buffer, s.byteOffset, s.byteLength); + for (let i = 0; i < sectorSize / 4; i++) { + fat.push(sv.getUint32(i * 4, true)); + } + } + const readChain = (startSec) => { + const chunks = []; + let sec = startSec; + while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < fat.length) { + chunks.push(sectorAt(sec)); + sec = fat[sec]; + } + return concatUint8(chunks); + }; + const dirData = readChain(dirFirstSec); + const dirView = new DataView(dirData.buffer, dirData.byteOffset, dirData.byteLength); + const dirCount = dirData.length / 128; + const dirEntries = []; + for (let i = 0; i < dirCount; i++) { + const base = i * 128; + const nameLen = dirView.getUint16(base + 64, true); + const nameBytes = dirData.subarray(base, base + Math.max(0, nameLen - 2)); + const name = new TextDecoder("utf-16le").decode(nameBytes); + const type = dirData[base + 66]; + const childId = dirView.getInt32(base + 76, true); + const sibLeft = dirView.getInt32(base + 68, true); + const sibRight = dirView.getInt32(base + 72, true); + const startSec = dirView.getUint32(base + 116, true); + const size = dirView.getUint32(base + 120, true); + dirEntries.push({ name, type, startSec, size, childId, siblingLeftId: sibLeft, siblingRightId: sibRight }); + } + const rootEntry = dirEntries[0]; + let miniStreamData = null; + let miniFat = []; + if (rootEntry && rootEntry.startSec !== ENDOFCHAIN && rootEntry.startSec !== FREESECT) { + miniStreamData = readChain(rootEntry.startSec); + } + if (miniFatCnt> 0 && miniFatFirst !== ENDOFCHAIN && miniFatFirst !== FREESECT) { + const mfData = readChain(miniFatFirst); + const mfv = new DataView(mfData.buffer, mfData.byteOffset, mfData.byteLength); + for (let i = 0; i < mfData.length / 4; i++) { + miniFat.push(mfv.getUint32(i * 4, true)); + } + } + const readMiniChain = (startSec, size) => { + if (!miniStreamData) return new Uint8Array(0); + const chunks = []; + let sec = startSec; + let remaining = size; + while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < miniFat.length && remaining> 0) { + const off = sec * miniSectorSz; + const chunk = miniStreamData.subarray(off, off + Math.min(miniSectorSz, remaining)); + chunks.push(chunk); + remaining -= chunk.length; + sec = miniFat[sec]; + } + return concatUint8(chunks).subarray(0, size); + }; + const visit = (id, path) => { + if (id < 0 || id>= dirEntries.length) return; + const entry = dirEntries[id]; + const fullPath = path ? `${path}/${entry.name}` : entry.name; + if (entry.type === 2) { + let streamData; + if (entry.size < miniStreamCutoff && miniStreamData) { + streamData = readMiniChain(entry.startSec, entry.size); + } else { + streamData = readChain(entry.startSec).subarray(0, entry.size); + } + streams.set(fullPath, streamData); + streams.set(entry.name, streamData); + } + if (entry.childId>= 0) visit(entry.childId, fullPath); + if (entry.siblingLeftId>= 0) visit(entry.siblingLeftId, path); + if (entry.siblingRightId>= 0) visit(entry.siblingRightId, path); + }; + if (dirEntries.length> 0 && dirEntries[0].childId>= 0) { + visit(dirEntries[0].childId, ""); + } + return streams; + } +}; +function concatUint8(arrays) { + const total = arrays.reduce((s, a) => s + a.length, 0); + const out = new Uint8Array(total); + let off = 0; + for (const a of arrays) { + out.set(a, off); + off += a.length; + } + return out; +} + +// src/decoders/hwp/HwpScanner.ts +var import_pako2 = __toESM(require("pako")); +var HWPTAG_BEGIN = 16; +var TAG_FACE_NAME = HWPTAG_BEGIN + 3; +var TAG_BORDER_FILL = HWPTAG_BEGIN + 4; +var TAG_CHAR_SHAPE = HWPTAG_BEGIN + 5; +var TAG_PARA_SHAPE = HWPTAG_BEGIN + 9; +var TAG_PARA_HEADER = HWPTAG_BEGIN + 50; +var TAG_PARA_TEXT = HWPTAG_BEGIN + 51; +var TAG_PARA_CHAR_SHAPE = HWPTAG_BEGIN + 52; +var TAG_CTRL_HEADER = HWPTAG_BEGIN + 55; +var TAG_PAGE_DEF = HWPTAG_BEGIN + 57; +var TAG_LIST_HEADER = HWPTAG_BEGIN + 56; +var TAG_TABLE_A = HWPTAG_BEGIN + 61; +var TAG_CELL_A = HWPTAG_BEGIN + 62; +var TAG_TABLE_B = HWPTAG_BEGIN + 64; +var TAG_CELL_B = HWPTAG_BEGIN + 65; +function isTableTag(t) { + return t === TAG_TABLE_A || t === TAG_TABLE_B; +} +function isCellTag(t) { + return t === TAG_CELL_A || t === TAG_CELL_B || t === TAG_LIST_HEADER; +} +var CTRL_TABLE = 1952607264; +var CTRL_IMAGE = 1768777504; +var CTRL_OBJ = 1868720672; +var CTRL_FIG = 1718183712; +var CTRL_GSO = 1735618336; +function parseRecords(data) { + const out = []; + let off = 0; + while (off + 4 <= data.length) { + const hdr = BinaryKit.readU32LE(data, off); + const tag = hdr & 1023; + const level = hdr>> 10 & 1023; + let size = hdr>> 20 & 4095; + off += 4; + if (size === 4095) { + if (off + 4> data.length) break; + size = BinaryKit.readU32LE(data, off); + off += 4; + } + if (off + size> data.length) break; + out.push({ tag, level, data: data.subarray(off, off + size) }); + off += size; + } + return out; +} +function tryInflate(data) { + try { + return import_pako2.default.inflate(data); + } catch { + try { + return import_pako2.default.inflateRaw(data); + } catch { + return data; + } + } +} +function parseFileHeader(buf) { + if (buf.length < 40) return { compressed: true, encrypted: false }; + const props = BinaryKit.readU32LE(buf, 36); + return { compressed: (props & 1) !== 0, encrypted: (props & 2) !== 0 }; +} +function parseDocInfo(data, compressed) { + const raw = compressed ? tryInflate(data) : data; + const recs = parseRecords(raw); + const info = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] }; + for (const r of recs) { + try { + if (r.tag === TAG_FACE_NAME) info.faceNames.push(parseFaceName(r.data)); + if (r.tag === TAG_CHAR_SHAPE) info.charShapes.push(parseCharShape(r.data)); + if (r.tag === TAG_PARA_SHAPE) info.paraShapes.push(parseParaShape(r.data)); + if (r.tag === TAG_BORDER_FILL) info.borderFills.push(parseBorderFill(r.data)); + } catch { + } + } + return info; +} +function parseFaceName(d) { + if (d.length < 3) return ""; + const len = BinaryKit.readU16LE(d, 1); + if (d.length < 3 + len * 2) return ""; + return new TextDecoder("utf-16le").decode(d.subarray(3, 3 + len * 2)); +} +function parseCharShape(d) { + const faceIds = []; + for (let i = 0; i < 7; i++) faceIds.push(d.length>= (i + 1) * 2 ? BinaryKit.readU16LE(d, i * 2) : 0); + const height = d.length>= 46 ? BinaryKit.readU32LE(d, 42) : 1e3; + const attr = d.length>= 50 ? BinaryKit.readU32LE(d, 46) : 0; + const ulType = attr>> 2 & 7; + const skType = attr>> 18 & 7; + const suType = attr>> 16 & 3; + return { + faceIds, + height: height> 0 && height < 1e5 ? height : 1e3, + italic: (attr & 1) !== 0, + bold: (attr>> 1 & 1) !== 0, + underline: ulType !== 0, + strikeout: skType !== 0, + superscript: suType === 1, + subscript: suType === 2, + textColor: d.length>= 56 ? colorRef(d, 52) : "000000" + }; +} +var ALIGN_TBL = { 0: "justify", 1: "left", 2: "right", 3: "center", 4: "justify" }; +function parseParaShape(d) { + if (d.length < 4) return { align: "left", spaceBefore: 0, spaceAfter: 0, lineSpacing: 160, leftMargin: 0, indent: 0 }; + const attr = BinaryKit.readU32LE(d, 0); + return { + align: ALIGN_TBL[attr>> 2 & 7] ?? "left", + leftMargin: d.length>= 8 ? i32(d, 4) : 0, + // offset 4: leftMargin (들여쓰기) + indent: d.length>= 16 ? i32(d, 12) : 0, + // offset 12: first-line indent + spaceBefore: d.length>= 20 ? i32(d, 16) : 0, + spaceAfter: d.length>= 24 ? i32(d, 20) : 0, + lineSpacing: d.length>= 28 ? i32(d, 24) : 160 + }; +} +var BORDER_W_PT = [0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.7, 1.98, 2.84, 4.25, 5.67, 8.5, 11.34, 14.17]; +var BORDER_KIND = { 0: "solid", 1: "dash", 2: "dash", 3: "dot", 4: "dash", 5: "dash", 6: "dash", 7: "double", 8: "double", 9: "double", 10: "none" }; +function parseBorderFill(d) { + const borders = []; + const BASE_TYPE = 2; + const BASE_WIDTH = 6; + const BASE_COLOR = 10; + for (let i = 0; i < 4; i++) { + const type = BASE_TYPE + i < d.length ? d[BASE_TYPE + i] : 0; + const widthPt = BASE_WIDTH + i < d.length ? BORDER_W_PT[d[BASE_WIDTH + i]] ?? 0.5 : 0.5; + const color = BASE_COLOR + i * 4 + 4 <= d.length ? colorRef(d, BASE_COLOR + i * 4) : "000000"; + borders.push({ type, widthPt, color }); + } + let bgColor; + const fOff = 32; + if (d.length>= fOff + 8) { + const ft = BinaryKit.readU32LE(d, fOff); + if (ft & 1) bgColor = colorRef(d, fOff + 4); + } + return { borders, bgColor }; +} +function parseBody(raw, compressed, di, shield, gsoCtx) { + const recs = parseRecords(compressed ? tryInflate(raw) : raw); + const content = []; + let pageDims; + for (const r of recs) { + if (r.tag === TAG_PAGE_DEF) { + pageDims = shield.guard(() => parsePageDef(r.data), A4, "hwp:pageDef"); + break; + } + } + let i = 0; + while (i < recs.length) { + if (recs[i].tag === TAG_PAGE_DEF) { + i++; + } else if (recs[i].tag === TAG_PARA_HEADER) { + const r = shield.guard( + () => parseParagraphGroup(recs, i, di, shield, gsoCtx), + { nodes: [], next: i + 1 }, + `hwp:para@${i}` + ); + content.push(...r.nodes); + i = r.next; + } else { + i++; + } + } + return { content, pageDims }; +} +function parseParagraphGroup(recs, start, di, shield, gsoCtx) { + const hdr = recs[start]; + const lv = hdr.level; + const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0; + const ps = di.paraShapes[psId]; + let text = null; + let csPairs = []; + const grids = []; + const ctrlHeaders = []; + let i = start + 1; + while (i < recs.length && recs[i].level> lv) { + const r = recs[i]; + if (r.tag === TAG_PARA_TEXT && r.level === lv + 1) { + text = decodeParaText(r.data); + i++; + } else if (r.tag === TAG_PARA_CHAR_SHAPE && r.level === lv + 1) { + csPairs = parseCharShapePairs(r.data); + i++; + } else if (r.tag === TAG_CTRL_HEADER && r.level === lv + 1) { + if (r.data.length>= 4) { + const ctrlId = BinaryKit.readU32LE(r.data, 0); + const MAX_HWP = 1e6; + const rawW = r.data.length>= 24 ? BinaryKit.readU32LE(r.data, 16) : 0; + const rawH = r.data.length>= 28 ? BinaryKit.readU32LE(r.data, 20) : 0; + const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0; + const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0; + const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : r.data.length>= 6 ? BinaryKit.readU16LE(r.data, 4) : 0; + ctrlHeaders.push({ ctrlId, imgId, wPt, hPt }); + if (ctrlId === CTRL_TABLE) { + const tr = shield.guard( + () => parseTableCtrl(recs, i, di, shield, gsoCtx), + { grid: null, next: skipKids(recs, i) }, + `hwp:tbl@${i}` + ); + if (tr.grid) grids.push(tr.grid); + i = tr.next; + } else { + i = skipKids(recs, i); + } + } else { + i = skipKids(recs, i); + } + } else { + i++; + } + } + const nodes = []; + if (text && (text.chars.length> 0 || text.controls.length> 0)) { + const paraContent = []; + if (text.chars.length> 0) { + const spans = resolveCharShapes(text.chars, csPairs, di); + paraContent.push(...spans); + } + if (text.controls.length> 0) { + for (let ci = 0; ci < text.controls.length; ci++) { + const ch = ctrlHeaders[ci]; + if (!ch) continue; + const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO; + if (!isImg) continue; + const dimStr = ch.wPt> 0 && ch.hPt> 0 ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}` : ""; + paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`)); + } + } + if (paraContent.length> 0) { + nodes.push(buildPara(paraContent, buildParaProps(ps))); + } + } + nodes.push(...grids); + return { nodes, next: i }; +} +function skipKids(recs, idx) { + const lv = recs[idx].level; + let i = idx + 1; + while (i < recs.length && recs[i].level> lv) i++; + return i; +} +var EXT_CTRL = /* @__PURE__ */ new Set([2, 3, 11, 12, 14, 15]); +var INL_CTRL = /* @__PURE__ */ new Set([4, 5, 6, 7, 8]); +function decodeParaText(d) { + const chars = []; + const controls = []; + let i = 0, pos = 0; + while (i + 1 < d.length) { + const c = d[i] | d[i + 1] << 8; + if (c === 0) { + i += 2; + pos++; + continue; + } + if (c === 13) { + break; + } + if (c === 10) { + chars.push({ pos, ch: "\n" }); + i += 2; + pos++; + continue; + } + if (EXT_CTRL.has(c)) { + let objId = 0; + if (i + 16 <= d.length) { + objId = BinaryKit.readU16LE(d, i + 8); + } + controls.push({ pos, ctrlId: 0, objId, matched: false }); + i += 16; + pos += 8; + continue; + } + if (INL_CTRL.has(c)) { + i += 16; + pos += 8; + continue; + } + if (c === 9) { + chars.push({ pos, ch: " " }); + i += 16; + pos += 8; + continue; + } + if (c>= 1 && c <= 31) { + i += 2; + pos++; + continue; + } + chars.push({ pos, ch: String.fromCharCode(c) }); + i += 2; + pos++; + } + return { chars, controls }; +} +function parseCharShapePairs(d) { + const out = []; + for (let i = 0; i + 7 < d.length; i += 8) + out.push([BinaryKit.readU32LE(d, i), BinaryKit.readU32LE(d, i + 4)]); + return out; +} +function resolveCharShapes(chars, pairs, di) { + if (chars.length === 0) return [buildSpan("")]; + const defaultId = pairs.length> 0 ? pairs[0][1] : 0; + function idFor(pos) { + let id = defaultId; + for (const [p, sid] of pairs) { + if (p <= pos) id = sid; + else break; + } + return id; + } + const spans = []; + let curId = idFor(chars[0].pos); + let buf = chars[0].ch; + for (let k = 1; k < chars.length; k++) { + const sid = idFor(chars[k].pos); + if (sid !== curId) { + spans.push(styledSpan(buf, curId, di)); + buf = ""; + curId = sid; + } + buf += chars[k].ch; + } + if (buf) spans.push(styledSpan(buf, curId, di)); + return spans; +} +function styledSpan(text, shapeId, di) { + const cs = di.charShapes[shapeId]; + if (!cs) return buildSpan(text); + const props = {}; + const fid = cs.faceIds[0] ?? 0; + if (fid < di.faceNames.length && di.faceNames[fid]) props.font = safeFont(di.faceNames[fid]); + if (cs.height> 0) props.pt = Metric.hwpToPt(cs.height); + if (cs.bold) props.b = true; + if (cs.italic) props.i = true; + if (cs.underline) props.u = true; + if (cs.strikeout) props.s = true; + if (cs.superscript) props.sup = true; + if (cs.subscript) props.sub = true; + const hex = safeHex(cs.textColor); + if (hex && hex !== "000000") props.color = hex; + return buildSpan(text, props); +} +function parseTableCtrl(recs, ctrlIdx, di, shield, gsoCtx) { + const ctrlLv = recs[ctrlIdx].level; + let i = ctrlIdx + 1; + let tblData = null; + const cells = []; + const tblLevel = ctrlLv + 1; + while (i < recs.length && recs[i].level> ctrlLv) { + const r = recs[i]; + if (isTableTag(r.tag) && r.level === tblLevel) { + tblData = r.data; + i++; + } else if (r.tag === TAG_LIST_HEADER && r.level === tblLevel) { + const cellData = r.data; + const paraCount = cellData.length>= 2 ? BinaryKit.readU16LE(cellData, 0) : 0; + i++; + const cStart = i; + let consumed = 0; + while (i < recs.length && consumed < paraCount) { + if (recs[i].tag === TAG_PARA_HEADER && recs[i].level === tblLevel) { + consumed++; + i++; + while (i < recs.length && recs[i].level> tblLevel) i++; + } else if (recs[i].level> tblLevel) { + i++; + } else { + break; + } + } + cells.push({ data: cellData, tag: TAG_LIST_HEADER, cStart, cEnd: i }); + } else if (isCellTag(r.tag) && r.level === tblLevel) { + const cellData = r.data; + const cellTag = r.tag; + i++; + const cStart = i; + while (i < recs.length && recs[i].level> tblLevel) i++; + cells.push({ data: cellData, tag: cellTag, cStart, cEnd: i }); + } else { + i++; + } + } + if (!tblData || cells.length === 0) return { grid: null, next: i }; + const rowCnt = tblData.length>= 6 ? BinaryKit.readU16LE(tblData, 4) : 1; + const colCnt = tblData.length>= 8 ? BinaryKit.readU16LE(tblData, 6) : 1; + const parsed = []; + for (let ci = 0; ci < cells.length; ci++) { + const c = cells[ci]; + const seqIdx = ci; + const pc = shield.guard( + () => parseCellRec(c.data, c.tag, recs, c.cStart, c.cEnd, di, shield, seqIdx, colCnt, gsoCtx), + { row: Math.floor(ci / (colCnt || 1)), col: ci % (colCnt || 1), cs: 1, rs: 1, widthHwp: 0, heightHwp: void 0, props: {}, cellChildren: [buildPara([buildSpan("")])] }, + `hwp:cell@${c.cStart}` + ); + parsed.push(pc); + } + const maxRow = parsed.reduce((m, c) => Math.max(m, c.row + c.rs), 0); + const actualRowCnt = Math.max(rowCnt, maxRow); + const posValid = parsed.every((c) => c.row>= 0 && c.col>= 0 && c.col < colCnt); + if (!posValid) { + let idx = 0; + for (const c of parsed) { + c.row = Math.floor(idx / colCnt); + c.col = idx % colCnt; + idx++; + } + } + const colWidthsPt = new Array(colCnt).fill(0); + for (const c of parsed) { + if (c.cs === 1 && c.widthHwp> 0) { + const wPt = Metric.hwpToPt(c.widthHwp); + if (wPt> colWidthsPt[c.col]) colWidthsPt[c.col] = wPt; + } + } + const zeroColumns = colWidthsPt.filter((w) => w === 0).length; + if (zeroColumns> 0) { + const spanCells = parsed.filter((c) => c.cs> 1 && c.widthHwp> 0).sort((a, b) => a.cs - b.cs); + for (const c of spanCells) { + if (c.cs> 1 && c.widthHwp> 0) { + let known = 0; + let unknownCols = 0; + for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) { + if (colWidthsPt[ci]> 0) known += colWidthsPt[ci]; + else unknownCols++; + } + if (unknownCols> 0) { + const remaining = Metric.hwpToPt(c.widthHwp) - known; + const each = remaining> 0 ? remaining / unknownCols : 0; + for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) { + if (colWidthsPt[ci] === 0 && each> 0) colWidthsPt[ci] = each; + } + } + } + } + } + for (let i2 = 0; i2 < colWidthsPt.length; i2++) { + if (colWidthsPt[i2]> 0 && colWidthsPt[i2] < 1) colWidthsPt[i2] = 1; + } + const rows = []; + for (let r = 0; r < actualRowCnt; r++) { + const rc = parsed.filter((c) => c.row === r).sort((a, b) => a.col - b.col); + if (rc.length === 0) continue; + let rowHeightPt = void 0; + for (const c of rc) { + if (c.heightHwp && c.heightHwp> 0 && c.rs === 1) { + const hPt = Metric.hwpToPt(c.heightHwp); + if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt; + } + } + if (rowHeightPt == null) { + for (const c of rc) { + if (c.heightHwp && c.heightHwp> 0) { + const hPt = Metric.hwpToPt(c.heightHwp) / c.rs; + if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt; + } + } + } + rows.push(buildRow(rc.map((c) => { + return buildCell(c.cellChildren, { cs: c.cs, rs: c.rs, props: c.props }); + }), rowHeightPt)); + } + if (rows.length === 0) return { grid: null, next: i }; + let defStroke; + const bfOff = 18 + rowCnt * 2; + if (tblData.length>= bfOff + 2) { + const bfId = BinaryKit.readU16LE(tblData, bfOff); + defStroke = strokeFromBF(bfId, di); + } + const gp = {}; + if (defStroke) gp.defaultStroke = defStroke; + const hasWidths = colWidthsPt.some((w) => w> 0); + if (hasWidths) gp.colWidths = colWidthsPt; + return { grid: buildGrid(rows, gp), next: i }; +} +function parseCellRec(d, tag, recs, cStart, cEnd, di, shield, seqIdx, colCnt, gsoCtx) { + let col, row, cs = 1, rs = 1; + let widthHwp = 0; + let heightHwp = 0; + const props = {}; + const attr = d.length>= 6 ? BinaryKit.readU32LE(d, 2) : 0; + const va = attr>> 6 & 3; + if (va === 1) props.va = "mid"; + else if (va === 2) props.va = "bot"; + const HWP_PAD_LR_DEFAULT = 360; + const HWP_PAD_TB_DEFAULT = 141; + if (tag === TAG_LIST_HEADER && d.length>= 22) { + col = BinaryKit.readU16LE(d, 8); + row = BinaryKit.readU16LE(d, 10); + cs = Math.max(1, BinaryKit.readU16LE(d, 12)); + rs = Math.max(1, BinaryKit.readU16LE(d, 14)); + widthHwp = BinaryKit.readU32LE(d, 16); + heightHwp = d.length>= 24 ? BinaryKit.readU32LE(d, 20) : 0; + if (d.length>= 32) { + const pL = BinaryKit.readU16LE(d, 24); + const pR = BinaryKit.readU16LE(d, 26); + const pT = BinaryKit.readU16LE(d, 28); + const pB = BinaryKit.readU16LE(d, 30); + if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL); + if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR); + if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT); + if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB); + } + const bfId = d.length>= 34 ? BinaryKit.readU16LE(d, 32) : 0; + if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props); + } else if (tag !== TAG_LIST_HEADER) { + col = d.length>= 8 ? BinaryKit.readU16LE(d, 6) : seqIdx % (colCnt || 1); + row = d.length>= 10 ? BinaryKit.readU16LE(d, 8) : Math.floor(seqIdx / (colCnt || 1)); + cs = d.length>= 12 ? Math.max(1, BinaryKit.readU16LE(d, 10)) : 1; + rs = d.length>= 14 ? Math.max(1, BinaryKit.readU16LE(d, 12)) : 1; + widthHwp = d.length>= 18 ? BinaryKit.readU32LE(d, 14) : 0; + heightHwp = d.length>= 22 ? BinaryKit.readU32LE(d, 18) : 0; + if (d.length>= 30) { + const pL = BinaryKit.readU16LE(d, 22); + const pR = BinaryKit.readU16LE(d, 24); + const pT = BinaryKit.readU16LE(d, 26); + const pB = BinaryKit.readU16LE(d, 28); + if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL); + if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR); + if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT); + if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB); + } + const bfId = d.length>= 32 ? BinaryKit.readU16LE(d, 30) : 0; + if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props); + } else { + row = Math.floor(seqIdx / (colCnt || 1)); + col = seqIdx % (colCnt || 1); + } + const cellChildren = []; + const MAX_HWP = 1e6; + let k = cStart; + while (k < cEnd) { + if (recs[k].tag === TAG_PARA_HEADER) { + const r = shield.guard( + () => { + const hdr = recs[k]; + const lv = hdr.level; + const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0; + const ps = di.paraShapes[psId]; + let txt = null; + let csp = []; + const ctrlHdrs = []; + const innerGrids = []; + let j = k + 1; + while (j < cEnd && recs[j].level> lv) { + if (recs[j].tag === TAG_PARA_TEXT) { + txt = decodeParaText(recs[j].data); + j++; + } else if (recs[j].tag === TAG_PARA_CHAR_SHAPE) { + csp = parseCharShapePairs(recs[j].data); + j++; + } else if (recs[j].tag === TAG_CTRL_HEADER && recs[j].level === lv + 1) { + if (recs[j].data.length>= 4) { + const ctrlId = BinaryKit.readU32LE(recs[j].data, 0); + if (ctrlId === CTRL_TABLE) { + const nestedTr = shield.guard( + () => parseTableCtrl(recs, j, di, shield, gsoCtx), + { grid: null, next: skipKids(recs, j) }, + `hwp:innerNestedTbl@${j}` + ); + if (nestedTr.grid) innerGrids.push(nestedTr.grid); + j = nestedTr.next; + } else { + const rawW = recs[j].data.length>= 24 ? BinaryKit.readU32LE(recs[j].data, 16) : 0; + const rawH = recs[j].data.length>= 28 ? BinaryKit.readU32LE(recs[j].data, 20) : 0; + const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0; + const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0; + const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : recs[j].data.length>= 6 ? BinaryKit.readU16LE(recs[j].data, 4) : 0; + ctrlHdrs.push({ ctrlId, imgId, wPt, hPt }); + j = skipKids(recs, j); + } + } else { + j = skipKids(recs, j); + } + } else j++; + } + const paraContent = []; + if (txt && txt.chars.length> 0) paraContent.push(...resolveCharShapes(txt.chars, csp, di)); + if (txt && txt.controls.length> 0) { + for (let ci = 0; ci < txt.controls.length; ci++) { + const ch = ctrlHdrs[ci]; + if (!ch) continue; + const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO; + if (!isImg) continue; + const dimStr = ch.wPt> 0 && ch.hPt> 0 ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}` : ""; + paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`)); + } + } + const kids = paraContent.length> 0 ? paraContent : [buildSpan("")]; + const items = [buildPara(kids, buildParaProps(ps)), ...innerGrids]; + return { items, next: j }; + }, + { items: [buildPara([buildSpan("")])], next: k + 1 }, + `hwp:cellP@${k}` + ); + cellChildren.push(...r.items); + k = r.next; + } else if (recs[k].tag === TAG_CTRL_HEADER && recs[k].data.length>= 4) { + const cellCtrlId = BinaryKit.readU32LE(recs[k].data, 0); + if (cellCtrlId === CTRL_GSO) { + const gsoId = gsoCtx.count++; + const rawW = recs[k].data.length>= 24 ? BinaryKit.readU32LE(recs[k].data, 16) : 0; + const rawH = recs[k].data.length>= 28 ? BinaryKit.readU32LE(recs[k].data, 20) : 0; + const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0; + const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0; + const dimStr = wPt> 0 && hPt> 0 ? `_W${Math.round(wPt)}_H${Math.round(hPt)}` : ""; + cellChildren.push(buildPara([buildSpan(`__EXT_${gsoId}${dimStr}__`)])); + k = skipKids(recs, k); + } else if (cellCtrlId === CTRL_TABLE) { + const tr = shield.guard( + () => parseTableCtrl(recs, k, di, shield, gsoCtx), + { grid: null, next: skipKids(recs, k) }, + `hwp:nestedTbl@${k}` + ); + if (tr.grid) cellChildren.push(tr.grid); + k = tr.next; + } else { + k = skipKids(recs, k); + } + } else { + k++; + } + } + return { + row, + col, + cs, + rs, + props, + widthHwp, + heightHwp: heightHwp || void 0, + cellChildren: cellChildren.length ? cellChildren : [buildPara([buildSpan("")])] + }; +} +function parsePageDef(d) { + if (d.length < 24) return A4; + const w = BinaryKit.readU32LE(d, 0); + const h = BinaryKit.readU32LE(d, 4); + const ml = BinaryKit.readU32LE(d, 8); + const mr = BinaryKit.readU32LE(d, 12); + const mt = BinaryKit.readU32LE(d, 16); + const mb = BinaryKit.readU32LE(d, 20); + const at = d.length>= 40 ? BinaryKit.readU32LE(d, 36) : 0; + return { + wPt: Metric.hwpToPt(w), + hPt: Metric.hwpToPt(h), + ml: Metric.hwpToPt(ml), + mr: Metric.hwpToPt(mr), + mt: Metric.hwpToPt(mt), + mb: Metric.hwpToPt(mb), + orient: at & 1 ? "landscape" : "portrait" + }; +} +function i32(d, o) { + const u = BinaryKit.readU32LE(d, o); + return u> 2147483647 ? u - 4294967296 : u; +} +function colorRef(d, o) { + if (o + 3> d.length) return "000000"; + return (d[o] << 16 | d[o + 1] << 8 | d[o + 2]).toString(16).padStart(6, "0").toUpperCase(); +} +function toStroke(b) { + return { kind: BORDER_KIND[b.type] ?? "solid", pt: b.widthPt, color: b.color }; +} +function applyCellBorderFill(bf, props) { + if (bf.borders.length>= 4) { + props.left = toStroke(bf.borders[0]); + props.right = toStroke(bf.borders[1]); + props.top = toStroke(bf.borders[2]); + props.bot = toStroke(bf.borders[3]); + } + if (bf.bgColor && bf.bgColor !== "FFFFFF") props.bg = bf.bgColor; +} +function strokeFromBF(bfId, di) { + if (bfId <= 0 || bfId> di.borderFills.length) return void 0; + const bf = di.borderFills[bfId - 1]; + if (!bf.borders.length) return void 0; + const b = bf.borders[0]; + return { kind: BORDER_KIND[b.type] ?? "solid", pt: b.widthPt, color: b.color }; +} +function buildParaProps(ps) { + if (!ps) return {}; + const p = {}; + if (ps.align && ps.align !== "left") p.align = ps.align; + if (ps.spaceBefore> 0) p.spaceBefore = Metric.hwpToPt(ps.spaceBefore); + if (ps.spaceAfter> 0) p.spaceAfter = Metric.hwpToPt(ps.spaceAfter); + if (ps.lineSpacing> 0 && ps.lineSpacing !== 160) p.lineHeight = ps.lineSpacing / 100; + const leftMarginPt = Math.max(0, Metric.hwpToPt(ps.leftMargin)); + if (leftMarginPt> 0) p.leftMargin = leftMarginPt; + if (ps.indent !== 0) p.firstLineIndentPt = Metric.hwpToPt(ps.indent); + return p; +} +var HwpScanner = class { + constructor() { + this.format = "hwp"; + this.aliases = ["application/vnd.hancom.hwp"]; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + if (!BinaryKit.isOle2(data)) return fail("HWP: Invalid OLE2 signature"); + const streams = BinaryKit.parseCfb(data); + const fh = streams.get("FileHeader"); + const { compressed, encrypted } = fh ? parseFileHeader(fh) : { compressed: true, encrypted: false }; + if (encrypted) return fail("HWP: \uC554\uD638\uD654\uB41C \uD30C\uC77C\uC740 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4"); + const diRaw = streams.get("DocInfo"); + let di = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] }; + if (diRaw) { + di = shield.guard(() => parseDocInfo(diRaw, compressed), di, "hwp:docInfo"); + } + const binEntries = []; + for (const [path, streamData] of streams) { + const m = path.match(/^BinData[/\\]BIN(\d+)\.\w+$/i); + if (m) binEntries.push({ binNum: parseInt(m[1], 10), data: streamData }); + } + binEntries.sort((a, b) => a.binNum - b.binNum); + const objectMap = /* @__PURE__ */ new Map(); + for (let idx = 0; idx < binEntries.length; idx++) { + const { data: imgData } = binEntries[idx]; + let mimeType = "image/jpeg"; + if (imgData[0] === 137 && imgData[1] === 80) mimeType = "image/png"; + else if (imgData[0] === 71 && imgData[1] === 73) mimeType = "image/gif"; + else if (imgData[0] === 66 && imgData[1] === 77) mimeType = "image/bmp"; + const base64 = TextKit.base64Encode(imgData); + const { wPt, hPt } = getImageDimsPt(imgData, mimeType); + objectMap.set(idx, buildImg(base64, mimeType, wPt, hPt)); + } + const gsoCtx = { count: 0 }; + const allContent = []; + let pageDims = A4; + for (let s = 0; s < 100; s++) { + const sec = streams.get(`BodyText/Section${s}`) ?? streams.get(`Section${s}`); + if (!sec) { + if (s === 0) { + const fb = findBodySection(streams); + if (fb) { + const r2 = parseBody(fb, compressed, di, shield, gsoCtx); + allContent.push(...r2.content); + if (r2.pageDims) pageDims = r2.pageDims; + } + } + break; + } + const r = shield.guard( + () => parseBody(sec, compressed, di, shield, gsoCtx), + { content: [], pageDims: void 0 }, + `hwp:sec${s}` + ); + allContent.push(...r.content); + if (r.pageDims) pageDims = r.pageDims; + } + if (objectMap.size> 0) { + injectImagesIntoContent(allContent, objectMap); + } + warns.push(...shield.flush()); + const content = allContent.length> 0 ? allContent : [buildPara([buildSpan("")])]; + return succeed(buildRoot({}, [buildSheet(content, pageDims)]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`HWP decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function findBodySection(streams) { + for (const [k, v] of streams) + if (k.includes("Section") && !k.includes("Header") && !k.includes("Info")) return v; + return void 0; +} +function getImageDimsPt(data, mime) { + const fallback = { wPt: 72, hPt: 72 }; + try { + if (mime === "image/png" && data.length>= 24) { + const w = (data[16] << 24 | data[17] << 16 | data[18] << 8 | data[19])>>> 0; + const h = (data[20] << 24 | data[21] << 16 | data[22] << 8 | data[23])>>> 0; + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + if (mime === "image/jpeg") { + let i = 2; + while (i + 8 < data.length) { + if (data[i] !== 255) { + i++; + continue; + } + const marker = data[i + 1]; + if (marker>= 192 && marker <= 195) { + const h = (data[i + 5] << 8 | data[i + 6])>>> 0; + const w = (data[i + 7] << 8 | data[i + 8])>>> 0; + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + const segLen = data[i + 2] << 8 | data[i + 3]; + i += 2 + (segLen> 0 ? segLen : 2); + } + } + if (mime === "image/bmp" && data.length>= 26) { + const w = BinaryKit.readU32LE(data, 18); + const h = Math.abs(BinaryKit.readU32LE(data, 22) | 0); + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + if (mime === "image/gif" && data.length>= 10) { + const w = data[6] | data[7] << 8; + const h = data[8] | data[9] << 8; + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + } catch { + } + return fallback; +} +function injectImagesIntoContent(content, objectMap) { + if (objectMap.size === 0) return; + const processKids = (kids) => { + for (let i = 0; i < kids.length; i++) { + const kid = kids[i]; + if (kid.tag === "span" && kid.kids && kid.kids[0]?.tag === "txt") { + const text = kid.kids[0].content; + const match = text.match?.(/^__(?:IMG|EXT)_(\d+)(?:_W(\d+)_H(\d+))?__$/); + if (match) { + const objId = parseInt(match[1], 10); + const base = objectMap.get(objId); + if (base) { + const wPt = match[2] ? parseInt(match[2], 10) : 0; + const hPt = match[3] ? parseInt(match[3], 10) : 0; + kids[i] = wPt> 0 && hPt> 0 ? { ...base, w: wPt, h: hPt } : base; + } + } + } + } + }; + const processGridKids = (grid) => { + if (!grid.kids || !Array.isArray(grid.kids)) return; + for (const row of grid.kids) { + if (!row.kids || !Array.isArray(row.kids)) continue; + for (const cell of row.kids) { + if (!cell.kids || !Array.isArray(cell.kids)) continue; + for (const cellKid of cell.kids) { + if (cellKid.tag === "grid") { + processGridKids(cellKid); + } else if (cellKid.tag === "para" && cellKid.kids) { + processKids(cellKid.kids); + } + } + } + } + }; + for (const node of content) { + if (node.tag === "para" && node.kids) { + processKids(node.kids); + for (const kid of node.kids) { + if (kid.tag === "grid") { + processGridKids(kid); + } + } + } else if (node.tag === "grid") { + processGridKids(node); + } + } +} +registry.registerDecoder(new HwpScanner()); + +// src/decoders/docx/DocxDecoder.ts +var DocxDecoder = class extends BaseDecoder { + getFormat() { + return "docx"; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const files = await ArchiveKit.unzip(data); + const getFile = (path) => { + const lower = path.toLowerCase(); + for (const [name, data2] of files.entries()) { + if (name.toLowerCase() === lower) return data2; + } + return void 0; + }; + const docXml = getFile("word/document.xml"); + if (!docXml) return fail("DOCX: word/document.xml not found"); + const relsXml = getFile("word/_rels/document.xml.rels"); + const relsMap = relsXml ? await parseRels(TextKit.decode(relsXml)) : /* @__PURE__ */ new Map(); + const coreXml2 = getFile("docProps/core.xml"); + let meta = {}; + if (coreXml2) { + try { + meta = await parseCoreProps(TextKit.decode(coreXml2)); + } catch { + } + } + const numXml = getFile("word/numbering.xml"); + let numMap = /* @__PURE__ */ new Map(); + if (numXml) { + try { + numMap = await parseNumbering(TextKit.decode(numXml)); + } catch { + } + } + let stylesMap = /* @__PURE__ */ new Map(); + let paraStyleMap = /* @__PURE__ */ new Map(); + const stylesXml2 = getFile("word/styles.xml"); + if (stylesXml2) { + try { + const stylesStr = TextKit.decode(stylesXml2); + stylesMap = await parseStylesMap(stylesStr); + paraStyleMap = await parseParaStyleMap(stylesStr); + } catch { + } + } + let docStr = TextKit.decode(docXml).trim(); + if (!docStr) { + warns.push( + "DOCX: word/document.xml is empty, using fallback empty document" + ); + docStr = ''; + } + const docObj = await XmlKit.parseStrict(docStr); + const body = getBody(docObj); + const dims = extractDims2(body) ?? { ...A4 }; + const elements = getBodyElements(body); + console.log( + `[DocxDecoder] \uD30C\uC2F1\uB41C \uC804\uCCB4 \uBCF8\uBB38 \uC694\uC18C \uAC1C\uC218: ${elements.length}` + ); + const decCtx = { + relsMap, + files, + shield, + numMap, + warns, + stylesMap, + paraStyleMap + }; + const kids = []; + for (const el of elements) { + const nodes = shield.guard( + () => decodeElement(el, decCtx), + [buildPara([buildSpan("[\uC694\uC18C \uD30C\uC2F1 \uC2E4\uD328]")])], + "docx:bodyElement" + ); + if (Array.isArray(nodes)) { + kids.push(...nodes); + } else { + kids.push(nodes); + } + if (el.type === "para") { + const pPr = el.node?.["w:pPr"]?.[0] ?? el.node?.pPr?.[0] ?? {}; + const inlineSectPr = pPr?.["w:sectPr"]?.[0] ?? pPr?.sectPr?.[0]; + if (inlineSectPr) { + const typeAttr = inlineSectPr?.["w:type"]?.[0]?._attr; + const sectType = typeAttr?.["w:val"] ?? typeAttr?.val ?? "nextPage"; + if (sectType !== "continuous") { + kids.push( + buildPara([{ tag: "span", props: {}, kids: [buildPb()] }]) + ); + } + } + } + } + const headersMap = await decodeHeaderFooter2( + "header", + body, + relsMap, + files, + decCtx + ); + const footersMap = await decodeHeaderFooter2( + "footer", + body, + relsMap, + files, + decCtx + ); + warns.push(...shield.flush()); + const sheet = buildSheet(kids.filter(Boolean), dims, { + headers: headersMap, + footers: footersMap + }); + return succeed(buildRoot(meta, [sheet]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`DOCX decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function toArr2(v) { + return v == null ? [] : Array.isArray(v) ? v : [v]; +} +function resolveDocxPath(baseDir, target) { + if (target.startsWith("/")) return target.slice(1); + const parts = (baseDir + "/" + target).split("/"); + const stack = []; + for (const p of parts) { + if (p === "..") { + stack.pop(); + } else if (p !== ".") { + stack.push(p); + } + } + return stack.join("/"); +} +async function parseRels(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + for (const rel of toArr2(obj?.Relationships?.[0]?.Relationship)) { + const a = rel?._attr ?? {}; + if (a.Id && a.Target) map.set(a.Id, a.Target); + } + } catch { + } + return map; +} +async function parseCoreProps(xml) { + const trimmed = xml.trim(); + if (!trimmed) return {}; + try { + const obj = await XmlKit.parseStrict(trimmed); + const c = obj?.["cp:coreProperties"]?.[0] ?? obj?.coreProperties?.[0] ?? {}; + return { + title: c?.["dc:title"]?.[0]?._text ?? void 0, + author: c?.["dc:creator"]?.[0]?._text ?? void 0, + subject: c?.["dc:subject"]?.[0]?._text ?? void 0, + created: c?.["dcterms:created"]?.[0]?._text ?? void 0, + modified: c?.["dcterms:modified"]?.[0]?._text ?? void 0 + }; + } catch { + return {}; + } +} +async function parseNumbering(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + const root = obj?.["w:numbering"]?.[0] ?? obj?.numbering?.[0] ?? obj; + const absMap = /* @__PURE__ */ new Map(); + for (const abs of toArr2(root?.["w:abstractNum"] ?? root?.abstractNum)) { + const absId = Number( + abs?._attr?.["w:abstractNumId"] ?? abs?._attr?.abstractNumId ?? 0 + ); + const levels = /* @__PURE__ */ new Map(); + for (const lvl of toArr2(abs?.["w:lvl"] ?? abs?.lvl)) { + const ilvl = Number(lvl?._attr?.["w:ilvl"] ?? lvl?._attr?.ilvl ?? 0); + const fmtNode = lvl?.["w:numFmt"]?.[0]?._attr ?? lvl?.numFmt?.[0]?._attr ?? {}; + const fmt = fmtNode?.["w:val"] ?? fmtNode?.val ?? "decimal"; + levels.set(ilvl, { fmt, isOrdered: fmt !== "bullet" }); + } + absMap.set(absId, levels); + } + for (const num of toArr2(root?.["w:num"] ?? root?.num)) { + const numId = Number(num?._attr?.["w:numId"] ?? num?._attr?.numId ?? 0); + const absRef = num?.["w:abstractNumId"]?.[0]?._attr ?? num?.abstractNumId?.[0]?._attr ?? {}; + const absId = Number(absRef?.["w:val"] ?? absRef?.val ?? 0); + const levels = absMap.get(absId) ?? /* @__PURE__ */ new Map(); + map.set(numId, { levels }); + } + } catch { + } + return map; +} +function getBody(obj) { + const doc = obj?.["w:document"]?.[0] ?? obj?.document?.[0] ?? obj; + const body = doc?.["w:body"]?.[0] ?? doc?.body?.[0] ?? doc; + if (!body) { + console.error("[DocxDecoder] \uBCF8\uBB38(body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."); + } + return body; +} +function extractDims2(body) { + try { + const sp = body?.["w:sectPr"]?.[0] ?? body?.sectPr?.[0]; + if (!sp) return null; + const sz = sp?.["w:pgSz"]?.[0]?._attr ?? sp?.pgSz?.[0]?._attr; + const mar = sp?.["w:pgMar"]?.[0]?._attr ?? sp?.pgMar?.[0]?._attr; + if (!sz) return null; + const headerDxa = Number(mar?.["w:header"] ?? mar?.header ?? 0); + const footerDxa = Number(mar?.["w:footer"] ?? mar?.footer ?? 0); + return { + wPt: Metric.dxaToPt(Number(sz["w:w"] ?? sz.w ?? 11906)), + hPt: Metric.dxaToPt(Number(sz["w:h"] ?? sz.h ?? 16838)), + mt: Metric.dxaToPt(Number(mar?.["w:top"] ?? mar?.top ?? 1440)), + mb: Metric.dxaToPt(Number(mar?.["w:bottom"] ?? mar?.bottom ?? 1440)), + ml: Metric.dxaToPt(Number(mar?.["w:left"] ?? mar?.left ?? 1800)), + mr: Metric.dxaToPt(Number(mar?.["w:right"] ?? mar?.right ?? 1800)), + orient: (sz["w:orient"] ?? sz.orient) === "landscape" ? "landscape" : "portrait", + headerPt: headerDxa> 0 ? Metric.dxaToPt(headerDxa) : void 0, + footerPt: footerDxa> 0 ? Metric.dxaToPt(footerDxa) : void 0 + }; + } catch { + return null; + } +} +function getBodyElements(body) { + const paras = toArr2(body?.["w:p"] ?? body?.p); + const tables = toArr2(body?.["w:tbl"] ?? body?.tbl); + const sdts = toArr2(body?.["w:sdt"] ?? body?.sdt); + const childOrder = body?.["_childOrder"]; + if (Array.isArray(childOrder)) { + const items = []; + let pi = 0, ti = 0, si = 0; + for (const tag of childOrder) { + if ((tag === "w:p" || tag === "p") && pi < paras.length) { + items.push({ type: "para", node: paras[pi++] }); + } else if ((tag === "w:tbl" || tag === "tbl") && ti < tables.length) { + items.push({ type: "table", node: tables[ti++] }); + } else if ((tag === "w:sdt" || tag === "sdt") && si < sdts.length) { + items.push({ type: "sdt", node: sdts[si++] }); + } + } + while (pi < paras.length) items.push({ type: "para", node: paras[pi++] }); + while (ti < tables.length) + items.push({ type: "table", node: tables[ti++] }); + while (si < sdts.length) items.push({ type: "sdt", node: sdts[si++] }); + return items; + } + return [ + ...paras.map((n) => ({ type: "para", node: n })), + ...tables.map((n) => ({ type: "table", node: n })), + ...sdts.map((n) => ({ type: "sdt", node: n })) + ]; +} +async function decodeHeaderFooter2(kind, body, relsMap, files, ctx) { + try { + const sp = body?.["w:sectPr"]?.[0] ?? body?.sectPr?.[0]; + if (!sp) return void 0; + const refTag = kind === "header" ? "w:headerReference" : "w:footerReference"; + const refs = toArr2(sp?.[refTag] ?? sp?.[refTag.replace("w:", "")]); + if (refs.length === 0) return void 0; + const result = {}; + for (const ref of refs) { + const type = ref._attr?.["w:type"] ?? ref._attr?.type ?? "default"; + const rId = ref._attr?.["r:id"] ?? ref._attr?.["r:Id"] ?? ref._attr?.id; + if (!rId) continue; + const target = relsMap.get(rId); + if (!target) continue; + const filePath = resolveDocxPath("word", target); + const fileData = files.get(filePath); + if (!fileData) continue; + const hfFileName = filePath.split("/").pop() ?? ""; + const hfRelsPath = `word/_rels/${hfFileName}.rels`; + const hfRelsData = files.get(hfRelsPath); + let hfRelsMap = relsMap; + if (hfRelsData) { + const hfRelsStr = TextKit.decode(hfRelsData).trim(); + const parsed = hfRelsStr ? await parseRels(hfRelsStr) : /* @__PURE__ */ new Map(); + hfRelsMap = new Map([...relsMap, ...parsed]); + } + const xmlStr = TextKit.decode(fileData).trim(); + if (!xmlStr) continue; + const watermark = extractWatermark(xmlStr); + if (watermark) { + result[type] = [ + buildPara([ + buildSpan(watermark, { pt: 80, color: "CCCCCC", b: true }) + ]) + ]; + continue; + } + try { + const obj = await XmlKit.parseStrict(xmlStr); + const rootTag = kind === "header" ? "w:hdr" : "w:ftr"; + const root = obj?.[rootTag]?.[0] ?? obj?.[rootTag.replace("w:", "")]?.[0] ?? obj; + const origRelsMap = ctx.relsMap; + ctx.relsMap = hfRelsMap; + const paras = toArr2(root?.["w:p"] ?? root?.p); + result[type] = paras.map((p) => decodePara2(p, ctx)); + ctx.relsMap = origRelsMap; + } catch (err) { + console.warn(`[DocxDecoder] ${kind} (${type}) XML \uD30C\uC2F1 \uC2E4\uD328:`, err); + continue; + } + } + return Object.keys(result).length> 0 ? result : void 0; + } catch { + return void 0; + } +} +function extractWatermark(xml) { + if (!xml.includes("v:textpath")) return null; + const m = xml.match(/string="([^"]+)"/); + return m ? m[1] : null; +} +function hasDrawingDeep(node) { + if (!node || typeof node !== "object") return false; + if (node["w:drawing"] || node["w:pict"]) return true; + return Object.values(node).some((v) => { + if (Array.isArray(v)) return v.some(hasDrawingDeep); + return hasDrawingDeep(v); + }); +} +function decodeElement(el, ctx) { + if (el.type === "table") { + const { value } = ctx.shield.guardGrid( + el.node, + (n) => decodeGrid2(n, ctx), + (n) => decodeGridSimple2(n), + (n) => decodeGridFlat2(n), + (n) => decodeGridText2(n), + "docx:table" + ); + return value; + } else if (el.type === "sdt") { + return decodeSdt(el.node, ctx); + } + return decodePara2(el.node, ctx); +} +function decodeSdt(sdt, ctx) { + const content = sdt?.["w:sdtContent"]?.[0] ?? sdt?.sdtContent?.[0]; + if (!content) return []; + const elements = getBodyElements(content); + const kids = []; + for (const el of elements) { + const res = decodeElement(el, ctx); + if (Array.isArray(res)) kids.push(...res); + else kids.push(res); + } + return kids; +} +function decodePara2(p, ctx) { + const pPr = p?.["w:pPr"]?.[0] ?? {}; + const alignVal = pPr?.["w:jc"]?.[0]?._attr?.["w:val"] ?? pPr?.["w:jc"]?.[0]?._attr?.val; + const headStyle = pPr?.["w:pStyle"]?.[0]?._attr?.["w:val"] ?? pPr?.["w:pStyle"]?.[0]?._attr?.val ?? ""; + const styleInherited = resolveParaStyle( + headStyle || void 0, + ctx.paraStyleMap + ); + const props = { + align: safeAlign(alignVal), + heading: parseHeading(headStyle), + styleId: headStyle || void 0 + }; + const spacingAttr = pPr?.["w:spacing"]?.[0]?._attr ?? pPr?.spacing?.[0]?._attr ?? {}; + const beforeVal = Number( + spacingAttr?.["w:before"] ?? spacingAttr?.before ?? 0 + ); + const afterVal = Number(spacingAttr?.["w:after"] ?? spacingAttr?.after ?? 0); + const lineVal = Number(spacingAttr?.["w:line"] ?? spacingAttr?.line ?? 0); + const lineRule = spacingAttr?.["w:lineRule"] ?? spacingAttr?.lineRule ?? "auto"; + if (beforeVal> 0) props.spaceBefore = Metric.dxaToPt(beforeVal); + else if (styleInherited.pPr?.spaceBefore) + props.spaceBefore = styleInherited.pPr.spaceBefore; + if (afterVal> 0) props.spaceAfter = Metric.dxaToPt(afterVal); + else if (styleInherited.pPr?.spaceAfter) + props.spaceAfter = styleInherited.pPr.spaceAfter; + if (lineVal> 0 && lineRule === "auto") props.lineHeight = lineVal / 240; + else if (styleInherited.pPr?.lineHeight) + props.lineHeight = styleInherited.pPr.lineHeight; + const indAttr = pPr?.["w:ind"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {}; + const leftVal = Number(indAttr?.["w:left"] ?? indAttr?.left ?? 0); + const rightVal = Number(indAttr?.["w:right"] ?? indAttr?.right ?? 0); + const firstLineVal = Number( + indAttr?.["w:firstLine"] ?? indAttr?.firstLine ?? 0 + ); + const hangingVal = Number(indAttr?.["w:hanging"] ?? indAttr?.hanging ?? 0); + if (leftVal> 0) props.indentPt = Metric.dxaToPt(leftVal); + else if (styleInherited.pPr?.indentPt) + props.indentPt = styleInherited.pPr.indentPt; + if (rightVal> 0) props.indentRightPt = Metric.dxaToPt(rightVal); + else if (styleInherited.pPr?.indentRightPt) + props.indentRightPt = styleInherited.pPr.indentRightPt; + if (firstLineVal> 0) props.firstLineIndentPt = Metric.dxaToPt(firstLineVal); + else if (hangingVal> 0) + props.firstLineIndentPt = -Metric.dxaToPt(hangingVal); + else if (styleInherited.pPr?.firstLineIndentPt) + props.firstLineIndentPt = styleInherited.pPr.firstLineIndentPt; + if (!alignVal && styleInherited.pPr?.align) + props.align = safeAlign(styleInherited.pPr.align); + const numPr = pPr?.["w:numPr"]?.[0] ?? pPr?.numPr?.[0]; + if (numPr) { + const ilvlNode = numPr?.["w:ilvl"]?.[0]?._attr ?? numPr?.ilvl?.[0]?._attr ?? {}; + const numIdNode = numPr?.["w:numId"]?.[0]?._attr ?? numPr?.numId?.[0]?._attr ?? {}; + const ilvl = Number(ilvlNode?.["w:val"] ?? ilvlNode?.val ?? 0); + const numId = Number(numIdNode?.["w:val"] ?? numIdNode?.val ?? 0); + props.listLv = ilvl; + const numEntry = ctx.numMap.get(numId); + if (numEntry) { + const lvlInfo = numEntry.levels.get(ilvl) ?? numEntry.levels.get(0); + props.listOrd = lvlInfo?.isOrdered ?? false; + } else { + props.listOrd = numId>= 2; + } + } + const pbBeforeNode = pPr?.["w:pageBreakBefore"]?.[0] ?? pPr?.pageBreakBefore?.[0]; + const hasPageBreakBefore = pbBeforeNode != null && (pbBeforeNode?._attr?.["w:val"] ?? pbBeforeNode?._attr?.val ?? "1") !== "0"; + const children = p?.["_childOrder"]; + const kids = []; + if (Array.isArray(children)) { + const runsArr = toArr2(p?.["w:r"] ?? p?.r); + const hlArr = toArr2(p?.["w:hyperlink"] ?? p?.hyperlink); + const sdtArr = toArr2(p?.["w:sdt"] ?? p?.sdt); + let ri = 0; + let hi = 0; + let si = 0; + for (const tag of children) { + if (tag === "w:r" || tag === "r") { + const run = runsArr[ri++]; + if (run) { + kids.push( + ctx.shield.guard( + () => hasDrawingDeep(run) ? decodeRunOrImage(run, ctx) : decodeRun(run, ctx, styleInherited.rPr), + buildSpan(""), + "docx:run" + ) + ); + } + } else if (tag === "w:hyperlink" || tag === "hyperlink") { + const hl = hlArr[hi++]; + if (hl) { + const rId = hl?._attr?.["r:id"] ?? hl?._attr?.id; + const url = rId ? ctx.relsMap.get(rId) : ""; + const hlRuns = toArr2(hl?.["w:r"] ?? hl?.r); + const hlKids = hlRuns.map( + (r) => decodeRun(r, ctx, { + ...styleInherited.rPr, + u: true, + color: "0000FF" + }) + ); + kids.push({ + tag: "link", + href: url || "", + kids: hlKids + }); + } + } else if (tag === "w:sdt" || tag === "sdt") { + const sdt = sdtArr[si++]; + if (sdt) { + const sdtContent = sdt?.["w:sdtContent"]?.[0] ?? sdt?.sdtContent?.[0]; + if (sdtContent) { + const innerRuns = toArr2(sdtContent?.["w:r"] ?? sdtContent?.r); + for (const ir of innerRuns) { + kids.push( + ctx.shield.guard( + () => hasDrawingDeep(ir) ? decodeRunOrImage(ir, ctx) : decodeRun(ir, ctx, styleInherited.rPr), + buildSpan(""), + "docx:run" + ) + ); + } + } + } + } + } + } else { + const runs = toArr2(p?.["w:r"] ?? p?.r); + const legacyKids = ctx.shield.guardAll( + runs, + (run) => hasDrawingDeep(run) ? decodeRunOrImage(run, ctx) : decodeRun(run, ctx, styleInherited.rPr), + () => buildSpan(""), + "docx:run" + ); + kids.push(...legacyKids); + } + const filteredKids = kids.filter(Boolean); + if (hasPageBreakBefore) { + filteredKids.unshift({ tag: "span", props: {}, kids: [buildPb()] }); + } + return buildPara(filteredKids, props); +} +function decodeRunOrImage(run, ctx) { + function findFirstDrawing(node) { + if (!node || typeof node !== "object") return null; + if (node["w:drawing"]) return node["w:drawing"][0]; + if (node["w:pict"]) return node["w:pict"][0]; + for (const value of Object.values(node)) { + if (Array.isArray(value)) { + for (const v of value) { + const found = findFirstDrawing(v); + if (found) return found; + } + } else { + const found = findFirstDrawing(value); + if (found) return found; + } + } + return null; + } + const drawing = findFirstDrawing(run); + if (drawing) { + const img = decodeDrawing(drawing, ctx); + if (img) return img; + } + return decodeRun(run, ctx); +} +function decodeImageLayout(anchor) { + const wrap = anchor?.["wp:wrapTop"]?.[0] ?? anchor?.wrapTop?.[0]; + const anchorPos = anchor?.["wp:anchorPos"]?.[0]?._attr ?? anchor?.anchorPos?.[0]?._attr ?? {}; + const layout = { + wrap: "square", + horzAlign: "left", + vertAlign: "top", + horzRelTo: "page", + vertRelTo: "page", + xPt: Number(anchorPos?.x ?? 0) / 12700, + // emu to pt + yPt: Number(anchorPos?.y ?? 0) / 12700 + // emu to pt + }; + if (wrap?.["wp:none"]) layout.wrap = "none"; + else if (wrap?.["wp:square"]) layout.wrap = "square"; + else if (wrap?.["wp:tight"]) layout.wrap = "tight"; + else if (wrap?.["wp:through"]) layout.wrap = "through"; + else if (wrap?.["wp:behind"]) layout.wrap = "behind"; + else if (wrap?.["wp:inFront"]) layout.wrap = "front"; + return layout; +} +function decodeDrawing(drawing, ctx) { + try { + const inline = drawing?.["wp:inline"]?.[0] ?? drawing?.inline?.[0]; + const anchor = drawing?.["wp:anchor"]?.[0] ?? drawing?.anchor?.[0]; + const container = inline ?? anchor; + if (!container) return null; + const extent = container?.["wp:extent"]?.[0]?._attr ?? container?.extent?.[0]?._attr ?? {}; + const cx = Number(extent?.cx ?? 0); + const cy = Number(extent?.cy ?? 0); + const wPt = Metric.emuToPt(cx); + const hPt = Metric.emuToPt(cy); + const docPr = container?.["wp:docPr"]?.[0]?._attr ?? container?.docPr?.[0]?._attr ?? {}; + const alt = docPr?.descr ?? docPr?.name ?? ""; + const graphic = container?.["a:graphic"]?.[0] ?? container?.graphic?.[0]; + const graphicData = graphic?.["a:graphicData"]?.[0] ?? graphic?.graphicData?.[0]; + if (graphicData?.["c:chart"] || graphicData?.chart) { + return { + tag: "img", + b64: "", + // 플레이스홀더 + mime: "image/png", + w: wPt, + h: hPt, + alt: `[\uCC28\uD2B8: ${alt || "\uCC28\uD2B8"}]`, + layout: decodeImageLayout(anchor) + }; + } + const pic = graphicData?.["pic:pic"]?.[0] ?? graphicData?.pic?.[0]; + const blipFill = pic?.["pic:blipFill"]?.[0] ?? pic?.blipFill?.[0]; + const blip = blipFill?.["a:blip"]?.[0]?._attr ?? blipFill?.blip?.[0]?._attr ?? {}; + const rId = blip?.["r:embed"] ?? blip?.embed; + if (!rId) return null; + const target = ctx.relsMap.get(rId); + if (!target) return null; + let filePath = resolveDocxPath("word", target); + let fileData = ctx.files.get(filePath); + if (!fileData) { + filePath = resolveDocxPath("word/_rels", target); + fileData = ctx.files.get(filePath); + } + if (!fileData) { + const fileName = target.split("/").pop() ?? ""; + for (const [k, v] of ctx.files) { + if (fileName && (k.endsWith("/" + fileName) || k === fileName)) { + fileData = v; + filePath = k; + break; + } + } + } + if (!fileData) { + console.warn(`[DocxDecoder] image not found: "${target}"`); + return null; + } + const ext = target.split(".").pop()?.toLowerCase() ?? "png"; + const mimeMap = { + png: "image/png", + jpg: "image/jpeg", + jpeg: "image/jpeg", + gif: "image/gif", + bmp: "image/bmp" + }; + const mime = mimeMap[ext] ?? "image/png"; + console.log( + `[DocxDecoder] image loaded: ${filePath} (${mime}, ${fileData.length} bytes)` + ); + const layout = inline ? { wrap: "inline" } : extractAnchorLayout(anchor); + return buildImg( + TextKit.base64Encode(fileData), + mime, + wPt, + hPt, + alt || void 0, + layout + ); + } catch { + return null; + } +} +var HIGHLIGHT_COLOR_MAP = { + yellow: "FFFF00", + green: "00FF00", + cyan: "00FFFF", + magenta: "FF00FF", + blue: "0000FF", + red: "FF0000", + darkBlue: "00008B", + darkCyan: "008B8B", + darkGreen: "006400", + darkMagenta: "8B008B", + darkRed: "8B0000", + darkYellow: "808000", + darkGray: "A9A9A9", + lightGray: "D3D3D3", + black: "000000", + white: "FFFFFF" +}; +function decodeRun(run, ctx, styleRpr) { + const rPr = run?.["w:rPr"]?.[0] ?? run?.rPr?.[0] ?? {}; + const vanishNode = rPr?.["w:vanish"]?.[0] ?? rPr?.vanish?.[0]; + if (vanishNode != null) { + const vanishVal = vanishNode?._attr?.["w:val"] ?? vanishNode?._attr?.val ?? "1"; + if (vanishVal !== "0") return buildSpan(""); + } + const szAttr = rPr?.["w:sz"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {}; + const szVal = szAttr?.["w:val"] ?? szAttr?.val; + const szCsAttr = rPr?.["w:szCs"]?.[0]?._attr ?? rPr?.szCs?.[0]?._attr ?? {}; + const szCsVal = szCsAttr?.["w:val"] ?? szCsAttr?.val; + const effectiveSzVal = szVal ?? szCsVal; + const colorAttr = rPr?.["w:color"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {}; + const colorVal = colorAttr?.["w:val"] ?? colorAttr?.val; + const fontAttr = rPr?.["w:rFonts"]?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {}; + const fontName = fontAttr?.["w:ascii"] ?? fontAttr?.ascii ?? fontAttr?.["w:hAnsi"] ?? fontAttr?.hAnsi ?? fontAttr?.["w:eastAsia"] ?? fontAttr?.eastAsia; + const underVal = rPr?.["w:u"]?.[0]?._attr?.["w:val"] ?? rPr?.["w:u"]?.[0]?._attr?.val; + const shdAttr = rPr?.["w:shd"]?.[0]?._attr ?? rPr?.shd?.[0]?._attr ?? {}; + const shdBg = safeHex(shdAttr?.["w:fill"] ?? shdAttr?.fill); + const hlAttr = rPr?.["w:highlight"]?.[0]?._attr ?? rPr?.highlight?.[0]?._attr ?? {}; + const hlVal = hlAttr?.["w:val"] ?? hlAttr?.val; + const bgVal = (hlVal ? HIGHLIGHT_COLOR_MAP[hlVal] : void 0) ?? shdBg; + const vertAlignVal = rPr?.["w:vertAlign"]?.[0]?._attr?.["w:val"] ?? rPr?.["w:vertAlign"]?.[0]?._attr?.val; + const posAttr = rPr?.["w:position"]?.[0]?._attr ?? rPr?.position?.[0]?._attr ?? {}; + const posVal = Number(posAttr?.["w:val"] ?? posAttr?.val ?? 0); + let isSup = vertAlignVal === "superscript"; + let isSub = vertAlignVal === "subscript"; + if (!isSup && !isSub && posVal !== 0) { + if (posVal>= 4) isSup = true; + else if (posVal <= -4) isSub = true; + } + const bNode = rPr?.["w:b"]?.[0] ?? rPr?.b?.[0]; + const isBold = bNode != null && (bNode?._attr?.["w:val"] ?? bNode?._attr?.val ?? "1") !== "0"; + const iNode = rPr?.["w:i"]?.[0] ?? rPr?.i?.[0]; + const isItalic = iNode != null && (iNode?._attr?.["w:val"] ?? iNode?._attr?.val ?? "1") !== "0"; + const sNode = rPr?.["w:strike"]?.[0] ?? rPr?.strike?.[0]; + const isStrike = sNode != null && (sNode?._attr?.["w:val"] ?? sNode?._attr?.val ?? "1") !== "0"; + const props = { + b: (bNode != null ? isBold : styleRpr?.b) || void 0, + i: (iNode != null ? isItalic : styleRpr?.i) || void 0, + u: (underVal ? underVal !== "none" : styleRpr?.u) || void 0, + s: (sNode != null ? isStrike : styleRpr?.s) || void 0, + sup: isSup || void 0, + sub: isSub || void 0, + pt: effectiveSzVal ? Metric.halfPtToPt(Number(effectiveSzVal)) : styleRpr?.pt, + color: safeHex(colorVal) ?? styleRpr?.color, + font: fontName ? safeFont(fontName) : styleRpr?.font, + bg: bgVal + }; + const fldChar = run?.["w:fldChar"]?.[0]?._attr ?? run?.fldChar?.[0]?._attr; + const instrText = run?.["w:instrText"]?.[0]; + const brNodes = toArr2(run?.["w:br"] ?? run?.br ?? []); + for (const br of brNodes) { + const brType = br?._attr?.["w:type"] ?? br?._attr?.type; + if (brType === "page") { + return { tag: "span", props, kids: [buildPb()] }; + } + } + const textNodes = toArr2(run?.["w:t"] ?? run?.t); + const content = textNodes.map((t) => typeof t === "string" ? t : t?._ ?? t?._text ?? "").join(""); + if (instrText) { + const instrStr = typeof instrText === "string" ? instrText : instrText?._text ?? ""; + if (instrStr.trim().toUpperCase() === "PAGE") { + const pageNum = { tag: "pagenum", format: "decimal" }; + return { tag: "span", props, kids: [pageNum] }; + } + } + return buildSpan(content, props); +} +function parseBorderDef(bdrNode) { + const sides = [ + ["top", "top"], + ["bottom", "bottom"], + ["left", "left"], + ["right", "right"], + ["insideH", "insideH"], + ["insideV", "insideV"] + ]; + const result = {}; + for (const [xml, prop] of sides) { + const bdr = bdrNode?.["w:" + xml]?.[0]?._attr ?? bdrNode?.[xml]?.[0]?._attr; + if (!bdr) continue; + const val = bdr?.["w:val"] ?? bdr?.val; + if (val === "none" || val === "nil") continue; + result[prop] = safeStrokeDocx( + val, + Number(bdr?.["w:sz"] ?? bdr?.sz ?? 4), + bdr?.["w:color"] ?? bdr?.color + ); + } + return result; +} +async function parseStylesMap(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + const stylesRoot = obj?.["w:styles"]?.[0] ?? obj?.styles?.[0] ?? obj; + const styleArr = toArr2(stylesRoot?.["w:style"] ?? stylesRoot?.style); + for (const style of styleArr) { + const attr = style?._attr ?? {}; + const type = attr?.["w:type"] ?? attr?.type; + if (type !== "table") continue; + const id = attr?.["w:styleId"] ?? attr?.styleId; + if (!id) continue; + const tblPr = style?.["w:tblPr"]?.[0] ?? style?.tblPr?.[0]; + const tblBdrNode = tblPr?.["w:tblBorders"]?.[0] ?? tblPr?.tblBorders?.[0]; + const tblBorders = tblBdrNode ? parseBorderDef(tblBdrNode) : void 0; + const tcStyle = style?.["w:tcStyle"]?.[0] ?? style?.tcStyle?.[0]; + const tcBdrNode = tcStyle?.["w:tcBdr"]?.[0] ?? tcStyle?.tcBdr?.[0]; + if (tcBdrNode) { + const cellDef = parseBorderDef(tcBdrNode); + if (!tblBorders) { + map.set(id, { tblBorders: cellDef }); + } else { + map.set(id, { tblBorders: { ...cellDef, ...tblBorders } }); + } + } else if (tblBorders) { + map.set(id, { tblBorders }); + } + } + } catch { + } + return map; +} +async function parseParaStyleMap(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + const stylesRoot = obj?.["w:styles"]?.[0] ?? obj?.styles?.[0] ?? obj; + const styleArr = toArr2(stylesRoot?.["w:style"] ?? stylesRoot?.style); + for (const style of styleArr) { + const attr = style?._attr ?? {}; + const type = attr?.["w:type"] ?? attr?.type; + if (type !== "paragraph" && type !== "character") continue; + const id = attr?.["w:styleId"] ?? attr?.styleId; + if (!id) continue; + const basedOn = (style?.["w:basedOn"]?.[0]?._attr ?? style?.basedOn?.[0]?._attr)?.["w:val"]; + const def = { basedOn }; + const rPr = style?.["w:rPr"]?.[0] ?? style?.rPr?.[0]; + if (rPr) { + const szAttr = rPr?.["w:sz"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {}; + const szVal = szAttr?.["w:val"] ?? szAttr?.val; + const colorAttr = rPr?.["w:color"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {}; + const colorVal = colorAttr?.["w:val"] ?? colorAttr?.val; + const fontAttr = rPr?.["w:rFonts"]?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {}; + const fontName = fontAttr?.["w:ascii"] ?? fontAttr?.ascii ?? fontAttr?.["w:eastAsia"] ?? fontAttr?.eastAsia; + const bNode = rPr?.["w:b"]?.[0] ?? rPr?.b?.[0]; + const isBold = bNode != null && (bNode?._attr?.["w:val"] ?? bNode?._attr?.val ?? "1") !== "0"; + const iNode = rPr?.["w:i"]?.[0] ?? rPr?.i?.[0]; + const isItalic = iNode != null && (iNode?._attr?.["w:val"] ?? iNode?._attr?.val ?? "1") !== "0"; + const underVal = rPr?.["w:u"]?.[0]?._attr?.["w:val"] ?? rPr?.["w:u"]?.[0]?._attr?.val; + const sNode = rPr?.["w:strike"]?.[0] ?? rPr?.strike?.[0]; + const isStrike = sNode != null && (sNode?._attr?.["w:val"] ?? sNode?._attr?.val ?? "1") !== "0"; + def.rPr = { + b: isBold || void 0, + i: isItalic || void 0, + u: underVal && underVal !== "none" ? true : void 0, + s: isStrike || void 0, + pt: szVal ? Metric.halfPtToPt(Number(szVal)) : void 0, + color: safeHex(colorVal), + font: fontName ? safeFont(fontName) : void 0 + }; + } + const pPr = style?.["w:pPr"]?.[0] ?? style?.pPr?.[0]; + if (pPr) { + const spacingAttr = pPr?.["w:spacing"]?.[0]?._attr ?? pPr?.spacing?.[0]?._attr ?? {}; + const beforeVal = Number( + spacingAttr?.["w:before"] ?? spacingAttr?.before ?? 0 + ); + const afterVal = Number( + spacingAttr?.["w:after"] ?? spacingAttr?.after ?? 0 + ); + const lineVal = Number( + spacingAttr?.["w:line"] ?? spacingAttr?.line ?? 0 + ); + const lineRule = spacingAttr?.["w:lineRule"] ?? spacingAttr?.lineRule ?? "auto"; + const indAttr = pPr?.["w:ind"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {}; + const leftVal = Number(indAttr?.["w:left"] ?? indAttr?.left ?? 0); + const rightVal = Number(indAttr?.["w:right"] ?? indAttr?.right ?? 0); + const firstLineVal = Number( + indAttr?.["w:firstLine"] ?? indAttr?.firstLine ?? 0 + ); + const hangingVal = Number( + indAttr?.["w:hanging"] ?? indAttr?.hanging ?? 0 + ); + const alignVal = pPr?.["w:jc"]?.[0]?._attr?.["w:val"] ?? pPr?.["w:jc"]?.[0]?._attr?.val; + def.pPr = { + align: alignVal, + spaceBefore: beforeVal> 0 ? Metric.dxaToPt(beforeVal) : void 0, + spaceAfter: afterVal> 0 ? Metric.dxaToPt(afterVal) : void 0, + lineHeight: lineVal> 0 && lineRule === "auto" ? lineVal / 240 : void 0, + indentPt: leftVal> 0 ? Metric.dxaToPt(leftVal) : void 0, + indentRightPt: rightVal> 0 ? Metric.dxaToPt(rightVal) : void 0, + firstLineIndentPt: firstLineVal> 0 ? Metric.dxaToPt(firstLineVal) : hangingVal> 0 ? -Metric.dxaToPt(hangingVal) : void 0 + }; + } + map.set(id, def); + } + } catch { + } + return map; +} +function resolveParaStyle(styleId, map) { + let merged = {}; + const visited = /* @__PURE__ */ new Set(); + let cur = styleId; + while (cur && !visited.has(cur)) { + visited.add(cur); + const def = map.get(cur); + if (!def) break; + if (def.rPr) { + merged.rPr = { ...def.rPr, ...merged.rPr }; + } + if (def.pPr) { + merged.pPr = { ...def.pPr, ...merged.pPr }; + } + cur = def.basedOn; + } + return merged; +} +function resolveCellBorders(cp, ri, ci, rs, cs, rowCount, colCount, tblBdr) { + const isTopEdge = ri === 0; + const isBottomEdge = ri + rs>= rowCount; + const isLeftEdge = ci === 0; + const isRightEdge = ci + cs>= colCount; + const resolved = { ...cp }; + if (!resolved.top) resolved.top = isTopEdge ? tblBdr.top : tblBdr.insideH; + if (!resolved.bot) + resolved.bot = isBottomEdge ? tblBdr.bottom : tblBdr.insideH; + if (!resolved.left) resolved.left = isLeftEdge ? tblBdr.left : tblBdr.insideV; + if (!resolved.right) + resolved.right = isRightEdge ? tblBdr.right : tblBdr.insideV; + return resolved; +} +function decodeGrid2(tbl, ctx) { + const tblPr = tbl?.["w:tblPr"]?.[0] ?? tbl?.tblPr?.[0] ?? {}; + const tblLookAttr = tblPr?.["w:tblLook"]?.[0]?._attr ?? tblPr?.tblLook?.[0]?._attr ?? {}; + const look = { + firstRow: tblLookAttr?.["w:firstRow"] === "1" || void 0, + lastRow: tblLookAttr?.["w:lastRow"] === "1" || void 0, + firstCol: tblLookAttr?.["w:firstColumn"] === "1" || tblLookAttr?.["w:firstCol"] === "1" || void 0, + lastCol: tblLookAttr?.["w:lastColumn"] === "1" || tblLookAttr?.["w:lastCol"] === "1" || void 0, + bandedRows: tblLookAttr?.["w:noHBand"] === "0" || void 0, + bandedCols: tblLookAttr?.["w:noVBand"] === "0" || void 0 + }; + const tblStyleId = (tblPr?.["w:tblStyle"]?.[0]?._attr ?? tblPr?.tblStyle?.[0]?._attr)?.["w:val"]; + const styleDef = tblStyleId ? ctx.stylesMap.get(tblStyleId) : void 0; + let tblBdr = styleDef?.tblBorders ?? {}; + const tblBordersNode = tblPr?.["w:tblBorders"]?.[0] ?? tblPr?.tblBorders?.[0]; + if (tblBordersNode) { + const parsed = parseBorderDef(tblBordersNode); + tblBdr = { ...tblBdr, ...parsed }; + } + const defaultStroke = tblBdr.insideH ?? tblBdr.top; + const gridProps = { look, defaultStroke }; + const tblGrid = tbl?.["w:tblGrid"]?.[0] ?? tbl?.tblGrid?.[0]; + if (tblGrid) { + const gridCols = toArr2(tblGrid?.["w:gridCol"] ?? tblGrid?.gridCol ?? []); + const colWidthsPt = gridCols.map( + (gc) => Metric.dxaToPt(Number(gc?._attr?.["w:w"] ?? gc?._attr?.w ?? 0)) + ).filter((w) => w> 0); + if (colWidthsPt.length> 0) gridProps.colWidths = colWidthsPt; + } + const rowArr = toArr2(tbl?.["w:tr"] ?? tbl?.tr); + const rawGrid = rowArr.map((row) => { + const cellArr = toArr2(row?.["w:tc"] ?? row?.tc); + return cellArr.map((cell) => { + const tcPr = cell?.["w:tcPr"]?.[0] ?? {}; + const gridSpan = Number(tcPr?.["w:gridSpan"]?.[0]?._attr?.["w:val"] ?? 1); + const vMergeNode = tcPr?.["w:vMerge"]?.[0]; + const vMergeVal = vMergeNode?._attr?.["w:val"] ?? vMergeNode?._attr?.val; + const vMergeRestart = vMergeVal === "restart"; + const vMergeContinue = vMergeNode != null && !vMergeRestart; + return { cell, gridSpan, vMergeRestart, vMergeContinue }; + }); + }); + const rsMap = /* @__PURE__ */ new Map(); + for (let ri = 0; ri < rawGrid.length; ri++) { + let gridCol = 0; + for (let ci = 0; ci < rawGrid[ri].length; ci++) { + const rc = rawGrid[ri][ci]; + if (rc.vMergeRestart) { + let span = 1; + for (let nr = ri + 1; nr < rawGrid.length; nr++) { + let col = 0; + let found = false; + for (const nc of rawGrid[nr]) { + if (col === gridCol && nc.vMergeContinue) { + span++; + found = true; + break; + } + col += nc.gridSpan; + } + if (!found) break; + } + rsMap.set(`${ri},${ci}`, span); + } + gridCol += rc.gridSpan; + } + } + const rowNodes = rawGrid.map((rawRow, ri) => { + const row = rowArr[ri]; + const trPr = row?.["w:trPr"]?.[0] ?? row?.trPr?.[0] ?? {}; + const isHeaderRow = trPr?.["w:tblHeader"]?.[0] != null || trPr?.tblHeader?.[0] != null; + if (ri === 0 && isHeaderRow) gridProps.headerRow = true; + let rowHeightPt; + const trHAttr = trPr?.["w:trHeight"]?.[0]?._attr ?? trPr?.trHeight?.[0]?._attr; + if (trHAttr) { + const hDxa = Number(trHAttr?.["w:val"] ?? trHAttr?.val ?? 0); + if (hDxa> 0) rowHeightPt = Metric.dxaToPt(hDxa); + } + const cellNodes = []; + for (let ci = 0; ci < rawRow.length; ci++) { + const rc = rawRow[ci]; + if (rc.vMergeContinue) continue; + const cell = rc.cell; + const tcPr = cell?.["w:tcPr"]?.[0] ?? {}; + const bgAttr = tcPr?.["w:shd"]?.[0]?._attr ?? {}; + const bg = safeHex(bgAttr?.["w:fill"] ?? bgAttr?.fill); + const tcBordersNode = tcPr?.["w:tcBorders"]?.[0] ?? tcPr?.tcBorders?.[0]; + const cp = { bg, isHeader: isHeaderRow || void 0 }; + if (tcBordersNode) { + const dirs = [ + ["top", "top"], + ["bottom", "bot"], + ["left", "left"], + ["right", "right"] + ]; + for (const [xmlTag, propKey] of dirs) { + const bdr = tcBordersNode?.["w:" + xmlTag]?.[0]?._attr ?? tcBordersNode?.[xmlTag]?.[0]?._attr; + if (!bdr) continue; + const val = bdr?.["w:val"] ?? bdr?.val; + if (val === "none" || val === "nil") { + } else { + cp[propKey] = safeStrokeDocx( + val, + Number(bdr?.["w:sz"] ?? bdr?.sz ?? 4), + bdr?.["w:color"] ?? bdr?.color + ); + } + } + } + const vaAttr = tcPr?.["w:vAlign"]?.[0]?._attr ?? tcPr?.vAlign?.[0]?._attr ?? {}; + const vaVal = vaAttr?.["w:val"] ?? vaAttr?.val; + if (vaVal) { + const vaMap = { + top: "top", + center: "mid", + bottom: "bot" + }; + cp.va = vaMap[vaVal]; + } + const tcMar = tcPr?.["w:tcMar"]?.[0] ?? tcPr?.tcMar?.[0]; + if (tcMar) { + const top = tcMar?.["w:top"]?.[0]?._attr ?? tcMar?.top?.[0]?._attr; + const bot = tcMar?.["w:bottom"]?.[0]?._attr ?? tcMar?.bottom?.[0]?._attr; + const left = tcMar?.["w:left"]?.[0]?._attr ?? tcMar?.left?.[0]?._attr; + const right = tcMar?.["w:right"]?.[0]?._attr ?? tcMar?.right?.[0]?._attr; + if (top) cp.padT = Metric.dxaToPt(Number(top?.["w:w"] ?? top?.w ?? 0)); + if (bot) cp.padB = Metric.dxaToPt(Number(bot?.["w:w"] ?? bot?.w ?? 0)); + if (left) + cp.padL = Metric.dxaToPt(Number(left?.["w:w"] ?? left?.w ?? 0)); + if (right) + cp.padR = Metric.dxaToPt(Number(right?.["w:w"] ?? right?.w ?? 0)); + } + const rs = rsMap.get(`${ri},${ci}`) ?? 1; + let gridColIdx = 0; + for (let prevCi = 0; prevCi < ci; prevCi++) { + if (!rawRow[prevCi].vMergeContinue) + gridColIdx += rawRow[prevCi].gridSpan; + } + const colCount = gridProps.colWidths?.length ?? rawGrid[0]?.reduce((s, c) => s + c.gridSpan, 0) ?? 1; + const resolvedCp = resolveCellBorders( + cp, + ri, + gridColIdx, + rs, + rc.gridSpan, + rawGrid.length, + colCount, + tblBdr + ); + const paras = toArr2(cell?.["w:p"] ?? cell?.p).map( + (p) => decodePara2(p, ctx) + ); + cellNodes.push( + buildCell(paras.length> 0 ? paras : [buildPara([buildSpan("")])], { + cs: rc.gridSpan, + rs, + props: resolvedCp + }) + ); + } + return buildRow(cellNodes, rowHeightPt); + }); + return buildGrid(rowNodes, gridProps); +} +function decodeGridSimple2(tbl) { + const rowArr = toArr2(tbl?.["w:tr"] ?? tbl?.tr); + const rowNodes = rowArr.map((row) => { + const cellArr = toArr2(row?.["w:tc"] ?? row?.tc); + return buildRow( + cellArr.map((c) => buildCell([buildPara([buildSpan(cellText2(c))])])) + ); + }); + return buildGrid(rowNodes); +} +function decodeGridFlat2(tbl) { + return buildGrid([ + buildRow([buildCell([buildPara([buildSpan(tableText2(tbl))])])]) + ]); +} +function decodeGridText2(tbl) { + return buildPara([buildSpan(tableText2(tbl))]); +} +function cellText2(cell) { + return toArr2(cell?.["w:p"] ?? cell?.p).map( + (p) => toArr2(p?.["w:r"] ?? p?.r).map( + (r) => toArr2(r?.["w:t"] ?? r?.t).map((t) => typeof t === "string" ? t : t?._ ?? "").join("") + ).join("") + ).join(" "); +} +function tableText2(tbl) { + return toArr2(tbl?.["w:tr"] ?? tbl?.tr).map( + (row) => toArr2(row?.["w:tc"] ?? row?.tc).map((c) => cellText2(c)).join(" ") + ).join("\n"); +} +function parseHeading(style) { + if (!style) return void 0; + const m = style.match(/[Hh]eading(\d)/); + if (m) { + const n = Number(m[1]); + if (n>= 1 && n <= 6) return n; + } + return void 0; +} +registry.registerDecoder(new DocxDecoder()); +function extractAnchorLayout(anchor) { + const attr = anchor?._attr ?? {}; + const behindDoc = attr.behindDoc === "1"; + let wrap = "square"; + if (anchor?.["wp:wrapNone"]?.[0] != null) + wrap = behindDoc ? "behind" : "none"; + else if (anchor?.["wp:wrapTight"]?.[0] != null) wrap = "tight"; + else if (anchor?.["wp:wrapThrough"]?.[0] != null) wrap = "through"; + else if (anchor?.["wp:wrapSquare"]?.[0] != null) wrap = "square"; + else if (anchor?.["wp:wrapTopAndBottom"]?.[0] != null) wrap = "square"; + else if (anchor?.["wp:wrapBehind"]?.[0] != null || behindDoc) wrap = "behind"; + const posH = anchor?.["wp:positionH"]?.[0]; + const horzRelTo = parseHorzRelTo(posH?._attr?.relativeFrom); + const horzAlignTxt = posH?.["wp:align"]?.[0]?._text; + const horzOffsetTxt = posH?.["wp:posOffset"]?.[0]?._text; + const horzAlign = horzAlignTxt ? parseHorzAlign(horzAlignTxt) : void 0; + const xPt = horzOffsetTxt && !horzAlignTxt ? Metric.emuToPt(Number(horzOffsetTxt)) : void 0; + const posV = anchor?.["wp:positionV"]?.[0]; + const vertRelTo = parseVertRelTo(posV?._attr?.relativeFrom); + const vertAlignTxt = posV?.["wp:align"]?.[0]?._text; + const vertOffsetTxt = posV?.["wp:posOffset"]?.[0]?._text; + const vertAlign = vertAlignTxt ? parseVertAlign(vertAlignTxt) : void 0; + const yPt = vertOffsetTxt && !vertAlignTxt ? Metric.emuToPt(Number(vertOffsetTxt)) : void 0; + const distT = attr.distT ? Metric.emuToPt(Number(attr.distT)) : void 0; + const distB = attr.distB ? Metric.emuToPt(Number(attr.distB)) : void 0; + const distL = attr.distL ? Metric.emuToPt(Number(attr.distL)) : void 0; + const distR = attr.distR ? Metric.emuToPt(Number(attr.distR)) : void 0; + const zOrder = attr.relativeHeight ? Number(attr.relativeHeight) : void 0; + return { + wrap, + horzAlign, + vertAlign, + horzRelTo, + vertRelTo, + xPt, + yPt, + distT, + distB, + distL, + distR, + behindDoc, + zOrder + }; +} +var HORZ_RELTO_MAP = { + margin: "margin", + leftMargin: "margin", + rightMargin: "margin", + insideMargin: "margin", + outsideMargin: "margin", + column: "column", + page: "page", + character: "para", + paragraph: "para" +}; +var VERT_RELTO_MAP = { + margin: "margin", + topMargin: "margin", + bottomMargin: "margin", + insideMargin: "margin", + outsideMargin: "margin", + line: "line", + page: "page", + paragraph: "para" +}; +var HORZ_ALIGN_MAP = { + left: "left", + center: "center", + right: "right", + inside: "left", + outside: "right" +}; +var VERT_ALIGN_MAP = { + top: "top", + center: "center", + bottom: "bottom", + inside: "top", + outside: "bottom" +}; +function parseHorzRelTo(v) { + return HORZ_RELTO_MAP[v ?? ""] ?? "column"; +} +function parseVertRelTo(v) { + return VERT_RELTO_MAP[v ?? ""] ?? "para"; +} +function parseHorzAlign(v) { + return HORZ_ALIGN_MAP[v ?? ""]; +} +function parseVertAlign(v) { + return VERT_ALIGN_MAP[v ?? ""]; +} + +// src/decoders/md/MdDecoder.ts +var MdDecoder = class extends BaseDecoder { + getFormat() { + return "md"; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const text = this.bytesToString(data); + const lines = text.split(/\r?\n/); + const kids = []; + let i = 0; + while (i < lines.length) { + const line = lines[i]; + const headingMatch = line.match(/^(#{1,6})\s+(.+)$/); + if (headingMatch) { + const level = headingMatch[1].length; + kids.push(buildPara([buildSpan(headingMatch[2], { b: level <= 2 })], { heading: level })); + i++; + continue; + } + if (line.includes("|") && i + 1 < lines.length && lines[i + 1].match(/^\s*\|?\s*[-:]+\s*\|/)) { + const tableResult = shield.guard(() => parseMdTable(lines, i), null, `md:table@${i}`); + if (tableResult) { + kids.push(tableResult.node); + i = tableResult.nextLine; + continue; + } + } + if (line.match(/^[-*_]{3,}$/)) { + kids.push(buildPara([buildSpan("")], {})); + i++; + continue; + } + const listMatch = line.match(/^(\s*)([-*+]|\d+\.)\s+(.+)$/); + if (listMatch) { + kids.push(buildPara(parseInline(listMatch[3]), { + listLv: Math.floor(listMatch[1].length / 2), + listOrd: /\d+\./.test(listMatch[2]) + })); + i++; + continue; + } + const bqMatch = line.match(/^>\s*(.*)$/); + if (bqMatch) { + kids.push(buildPara([buildSpan(bqMatch[1])], { indentPt: 28 })); + i++; + continue; + } + if (line.startsWith("```")) { + const codeLines = []; + i++; + while (i < lines.length && !lines[i].startsWith("```")) { + codeLines.push(lines[i]); + i++; + } + i++; + kids.push(buildPara([buildSpan(codeLines.join("\n"), { font: "Courier New" })], {})); + continue; + } + if (line.trim() === "") { + i++; + continue; + } + const alignMatch = line.match(/^(.*?)<\/div>$/i); + if (alignMatch) { + const align = alignMatch[1].toLowerCase(); + kids.push(buildPara(parseInline(alignMatch[2]), { align })); + i++; + continue; + } + kids.push(buildPara(parseInline(line), {})); + i++; + } + warns.push(...shield.flush()); + const sheet = buildSheet(kids.length> 0 ? kids : [buildPara([buildSpan("")])], A4); + return succeed(buildRoot({}, [sheet]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`MD decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function parseInline(text) { + const result = []; + let rem = text; + while (rem.length> 0) { + let m = rem.match(/^(.*?)!\[([^\]]*)\]\((data:([^;]+);base64,([^)]+))\)(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + const mime = m[4]; + const validMimes = ["image/png", "image/jpeg", "image/gif", "image/bmp"]; + result.push(buildImg(m[5], validMimes.includes(mime) ? mime : "image/png", 100, 100, m[2] || void 0)); + rem = m[6]; + continue; + } + m = rem.match(/^(.*?)!\[([^\]]*)\]\(([^)]+)\)(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(`[\uC774\uBBF8\uC9C0: ${m[2] || m[3]}]`)); + rem = m[4]; + continue; + } + m = rem.match(/^(.*?)\*\*\*(.+?)\*\*\*(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { b: true, i: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)\*\*(.+?)\*\*(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { b: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)\*(.+?)\*(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { i: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)~~(.+?)~~(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { s: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)(.+?)<\/u>(.*)/si); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { u: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)(.+?)<\/sup>(.*)/si); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { sup: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)(.+?)<\/sub>(.*)/si); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { sub: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)`(.+?)`(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { font: "Courier New" })); + rem = m[3]; + continue; + } + result.push(buildSpan(rem)); + break; + } + return result.length> 0 ? result : [buildSpan(text)]; +} +function parseMdTable(lines, startLine) { + const parse = (line) => line.split("|").map((c) => c.trim()).filter((c, i, arr) => i> 0 || c !== ""); + const headers = parse(lines[startLine]); + let cur = startLine + 2; + const rows = []; + while (cur < lines.length) { + if (!lines[cur].includes("|")) break; + const cells = parse(lines[cur]); + if (cells.length === 0) break; + rows.push(cells); + cur++; + } + const allRows = [headers, ...rows]; + const gridRows = allRows.map( + (row, ri) => buildRow(row.map((cell) => buildCell([buildPara([buildSpan(cell, ri === 0 ? { b: true } : {})])]))) + ); + return { node: buildGrid(gridRows), nextLine: cur }; +} +registry.registerDecoder(new MdDecoder()); + +// src/decoders/html/HtmlDecoder.ts +var HtmlDecoder = class extends BaseDecoder { + getFormat() { + return "html"; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const html = this.bytesToString(data); + const tokens = shield.guard(() => tokenize(html), [], "html:tokenize"); + const kids = shield.guard(() => parseTokens(tokens), [], "html:parse"); + warns.push(...shield.flush()); + const sheet = buildSheet(kids.length> 0 ? kids : [buildPara([buildSpan("")])], A4); + return succeed(buildRoot({}, [sheet]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`HTML decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function tokenize(html) { + const tokens = []; + let i = 0; + while (i < html.length) { + if (html[i] === "<") { + if (html[i + 1] === "!") { + const end2 = html.indexOf(">", i); + i = end2 + 1; + continue; + } + const isClose = html[i + 1] === "/"; + const start = isClose ? i + 2 : i + 1; + const end = html.indexOf(">", i); + if (end === -1) break; + const tagContent = html.slice(start, end).trim(); + const spaceIdx = tagContent.search(/\s/); + const name = spaceIdx> 0 ? tagContent.slice(0, spaceIdx) : tagContent; + const attrsStr = spaceIdx> 0 ? tagContent.slice(spaceIdx + 1).trim() : ""; + const attrs = {}; + if (attrsStr) { + const attrRegex = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=`]+)))?/g; + let m; + while ((m = attrRegex.exec(attrsStr)) !== null) { + attrs[m[1].toLowerCase()] = m[2] ?? m[3] ?? m[4] ?? ""; + } + } + tokens.push({ + type: "tag", + name: name.toLowerCase(), + attrs, + selfClose: html[end - 1] === "/", + close: isClose + }); + i = end + 1; + } else { + const end = html.indexOf("<", i); + const text = end === -1 ? html.slice(i) : html.slice(i, end); + if (text.trim()) { + tokens.push({ type: "text", content: text }); + } + i = end === -1 ? html.length : end; + } + } + return tokens; +} +function parseTokens(tokens) { + const kids = []; + let i = 0; + while (i < tokens.length) { + const t = tokens[i]; + if (t.type === "tag" && !t.close) { + switch (t.name) { + case "html": + i++; + let bodyStart = -1; + let depth = 1; + while (i < tokens.length && depth> 0) { + if (tokens[i].type === "tag" && !tokens[i].close && tokens[i].name === "html") depth++; + else if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === "html") depth--; + else if (tokens[i].type === "tag" && !tokens[i].close && tokens[i].name === "body") { + bodyStart = i + 1; + } + i++; + } + if (bodyStart> 0) { + let bodyEnd = bodyStart; + let bodyDepth = 1; + while (bodyEnd < tokens.length && bodyDepth> 0) { + if (tokens[bodyEnd].type === "tag" && !tokens[bodyEnd].close && tokens[bodyEnd].name === "body") bodyDepth++; + else if (tokens[bodyEnd].type === "tag" && tokens[bodyEnd].close && tokens[bodyEnd].name === "body") bodyDepth--; + bodyEnd++; + } + bodyEnd--; + const bodyTokens = tokens.slice(bodyStart, bodyEnd); + const bodyKids = parseTokens(bodyTokens); + kids.push(...bodyKids); + } + continue; + case "head": + case "style": + case "script": + i = skipBlock(tokens, i, t.name); + continue; + case "body": + case "div": + case "section": + case "article": + case "main": + const start = i + 1; + let end = start; + let divDepth = 1; + while (end < tokens.length && divDepth> 0) { + const t2 = tokens[end]; + if (t2.type === "tag" && !t2.close) { + if (["html", "head", "body", "div", "section", "article", "main"].includes(t2.name ?? "")) divDepth++; + } else if (t2.type === "tag" && t2.close) { + if (["html", "head", "body", "div", "section", "article", "main"].includes(t2.name ?? "")) divDepth--; + } + end++; + } + end--; + const subTokens = tokens.slice(start, end); + const subKids = parseTokens(subTokens); + kids.push(...subKids); + i = end + 1; + continue; + case "p": + i++; + const paraKids = collectInline(tokens, i, ["p", "div", "br"]); + i = paraKids.nextI; + const align = t.attrs?.style?.includes("text-align: center") ? "center" : t.attrs?.style?.includes("text-align: right") ? "right" : t.attrs?.style?.includes("text-align: left") ? "left" : void 0; + kids.push(buildPara(paraKids.nodes, { align })); + continue; + case "br": + kids.push(buildPara([buildSpan("")], {})); + i++; + continue; + case "img": + i++; + const src = t.attrs?.src; + const alt = t.attrs?.alt || ""; + if (src?.startsWith("data:")) { + const match = src.match(/^data:([^;]+);base64,(.+)$/); + if (match) { + kids.push(buildPara([buildImg(match[2], match[1], 100, 100, alt)], {})); + } + } + continue; + case "table": + i++; + const rows = []; + while (i < tokens.length) { + if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === "table") { + i++; + break; + } + if (tokens[i].type === "tag" && tokens[i].name === "tr" && !tokens[i].close) { + i++; + const cells = []; + while (i < tokens.length) { + if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === "tr") { + i++; + break; + } + if (tokens[i].type === "tag" && (tokens[i].name === "td" || tokens[i].name === "th") && !tokens[i].close) { + i++; + const cellKids = collectInline(tokens, i, ["td", "th", "tr"]); + i = cellKids.nextI; + const isHeader = tokens[i - 2]?.name === "th"; + const paraKids2 = cellKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, b: isHeader } } : n); + cells.push(buildCell([buildPara(paraKids2, {})])); + } else if (tokens[i].type === "text" && tokens[i].content?.trim()) { + cells.push(buildCell([buildPara([buildSpan(tokens[i].content.trim())])])); + i++; + } else { + i++; + } + } + if (cells.length> 0) rows.push(buildRow(cells)); + } else { + i++; + } + } + if (rows.length> 0) kids.push(buildGrid(rows)); + continue; + case "ul": + case "ol": + i++; + const isOrdered = t.name === "ol"; + while (i < tokens.length) { + if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === t.name) { + i++; + break; + } + if (tokens[i].type === "tag" && tokens[i].name === "li" && !tokens[i].close) { + i++; + const liKids = collectInline(tokens, i, ["li", "ul", "ol"]); + i = liKids.nextI; + kids.push(buildPara(liKids.nodes, { listOrd: isOrdered })); + } else { + i++; + } + } + continue; + default: + i++; + } + } else if (t.type === "text" && t.content?.trim()) { + kids.push(buildPara([buildSpan(t.content.trim())], {})); + i++; + } else { + i++; + } + } + return kids; +} +function collectInline(tokens, start, stopTags) { + const nodes = []; + let i = start; + while (i < tokens.length) { + const t = tokens[i]; + if (t.type === "tag" && !t.close) { + if (t.name && stopTags.includes(t.name)) { + break; + } + switch (t.name) { + case "b": + case "strong": + i++; + const boldKids = collectInline(tokens, i, ["b", "strong", ...stopTags]); + i = boldKids.nextI; + nodes.push(...boldKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, b: true } } : n)); + continue; + case "i": + case "em": + i++; + const italicKids = collectInline(tokens, i, ["i", "em", ...stopTags]); + i = italicKids.nextI; + nodes.push(...italicKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, i: true } } : n)); + continue; + case "u": + i++; + const underlineKids = collectInline(tokens, i, ["u", ...stopTags]); + i = underlineKids.nextI; + nodes.push(...underlineKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, u: true } } : n)); + continue; + case "s": + case "strike": + i++; + const strikeKids = collectInline(tokens, i, ["s", "strike", ...stopTags]); + i = strikeKids.nextI; + nodes.push(...strikeKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, s: true } } : n)); + continue; + case "span": + i++; + const spanKids = collectInline(tokens, i, ["span", ...stopTags]); + i = spanKids.nextI; + const color = t.attrs?.style?.match(/color:\s*([^;]+)/)?.[1]; + nodes.push(...spanKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, color: color || n.props.color } } : n)); + continue; + case "img": + const src = t.attrs?.src; + const alt = t.attrs?.alt || ""; + if (src?.startsWith("data:")) { + const match = src.match(/^data:([^;]+);base64,(.+)$/); + if (match) { + nodes.push(buildImg(match[2], match[1], 100, 100, alt)); + } + } + i++; + continue; + default: + i++; + } + } else if (t.type === "text") { + if (t.content?.trim()) { + nodes.push(buildSpan(t.content.trim())); + } + i++; + } else { + i++; + } + } + return { nodes: nodes.length> 0 ? nodes : [buildSpan("")], nextI: i }; +} +function skipBlock(tokens, start, name) { + let i = start + 1; + let depth = 1; + while (i < tokens.length && depth> 0) { + if (tokens[i].type === "tag") { + if (!tokens[i].close && tokens[i].name === name) depth++; + if (tokens[i].close && tokens[i].name === name) depth--; + } + i++; + } + return i; +} +registry.registerDecoder(new HtmlDecoder()); + +// src/core/BaseEncoder.ts +var BaseEncoder = class { + constructor() { + this.format = this.getFormat(); + this.aliases = this.getAliases(); + } + /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */ + getAliases() { + return []; + } + // ─── 공통 유틸리티 메서드 ─────────────────────────── + /** 문서 내 모든 이미지 노드 수집 */ + collectImages(doc) { + const images = []; + this.collectImagesRecursive(doc, images); + return images; + } + /** 재귀적으로 이미지 수집 */ + collectImagesRecursive(node, images) { + if (node.tag === "img") { + images.push(node); + return; + } + const children = this.getChildren(node); + for (const child of children) { + this.collectImagesRecursive(child, images); + } + } + /** 노드의 자식 노드 반환 */ + getChildren(node) { + switch (node.tag) { + case "root": + return node.kids; + case "sheet": + return [...node.kids, ...node.headers?.default ?? [], ...node.footers?.default ?? []]; + case "para": + return node.kids; + case "span": + return node.kids; + case "link": + return node.kids; + case "row": + return node.kids; + case "cell": + return node.kids; + case "grid": + return node.kids; + default: + return []; + } + } + /** base64 문자열을 Uint8Array 로 변환 */ + base64ToBytes(b64) { + return TextKit.base64Decode(b64); + } + /** Uint8Array 를 base64 문자열로 변환 */ + bytesToBase64(data) { + return TextKit.base64Encode(data); + } + /** XML 이스케이프 */ + escapeXml(s) { + return TextKit.escapeXml(s); + } + /** XML 언이스케이프 */ + unescapeXml(s) { + return TextKit.unescapeXml(s); + } + /** 문자열을 UTF-8 바이트로 변환 */ + stringToBytes(s) { + return TextKit.encode(s); + } + /** 바이트를 UTF-8 문자열로 변환 */ + bytesToString(data) { + return TextKit.decode(data); + } + /** ZIP 압축 */ + async zip(entries) { + return ArchiveKit.zip(entries); + } + /** ZIP 해제 */ + async unzip(data) { + return ArchiveKit.unzip(data); + } + /** deflate 압축 */ + async deflate(data) { + return ArchiveKit.deflate(data); + } + /** inflate 해제 */ + async inflate(data) { + return ArchiveKit.inflate(data); + } + /** 제어 문자 제거 */ + stripControl(s) { + return TextKit.stripControl(s); + } + /** 공백 정규화 */ + normalizeWhitespace(s) { + return TextKit.normalizeWhitespace(s); + } +}; + +// src/encoders/hwpx/HwpxEncoder.ts +var NS = [ + 'xmlns:ha="http://www.hancom.co.kr/hwpml/2011/app"', + 'xmlns:hp="http://www.hancom.co.kr/hwpml/2011/paragraph"', + 'xmlns:hp10="http://www.hancom.co.kr/hwpml/2016/paragraph"', + 'xmlns:hs="http://www.hancom.co.kr/hwpml/2011/section"', + 'xmlns:hc="http://www.hancom.co.kr/hwpml/2011/core"', + 'xmlns:hh="http://www.hancom.co.kr/hwpml/2011/head"', + 'xmlns:hhs="http://www.hancom.co.kr/hwpml/2011/history"', + 'xmlns:hm="http://www.hancom.co.kr/hwpml/2011/master-page"', + 'xmlns:hpf="http://www.hancom.co.kr/schema/2011/hpf"', + 'xmlns:dc="http://purl.org/dc/elements/1.1/"', + 'xmlns:opf="http://www.idpf.org/2007/opf"', + 'xmlns:ooxmlchart="http://www.hancom.co.kr/hwpml/2016/ooxmlchart"', + 'xmlns:epub="http://www.idpf.org/2007/ops"', + 'xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"' +].join(" "); +var LINESEG_FLAGS_FIRST = 1441792; +var LINESEG_FLAGS_OTHER = 393216; +var LANG_GROUPS = [ + "HANGUL", + "LATIN", + "HANJA", + "JAPANESE", + "OTHER", + "SYMBOL", + "USER" +]; +var LangFontBank = class { + constructor() { + // 언어 그룹별 독립 폰트 맵: face → localId (0-based) + this.maps = new Map( + LANG_GROUPS.map((g) => [g, /* @__PURE__ */ new Map()]) + ); + this.registerAll("\uD568\uCD08\uB86C\uBC14\uD0D5"); + } + /** 모든 언어 그룹에 동일 폰트 등록 */ + registerAll(face) { + for (const g of LANG_GROUPS) { + const m = this.maps.get(g); + if (!m.has(face)) m.set(face, m.size); + } + } + /** 특정 언어 그룹에 폰트 등록, 이미 있으면 기존 ID 반환 */ + register(lang, face) { + const m = this.maps.get(lang); + if (m.has(face)) return m.get(face); + const id = m.size; + m.set(face, id); + return id; + } + /** 폰트 이름 → 한글 폰트 여부 판별 (ANYTOHWP 방식) */ + isKorean(face) { + return /[\uAC00-\uD7A3\u3131-\u318E]/.test(face) || ["\uB9D1\uC740", "\uB098\uB214", "\uAD74\uB9BC", "\uB3CB\uC6C0", "\uBC14\uD0D5", "\uD568\uCD08\uB86C", "\uD55C\uCEF4", "HY"].some( + (k) => face.includes(k) + ); + } + /** TextProps.font 문자열에서 적절한 HANGUL/LATIN 그룹에 등록 */ + registerFont(rawFace) { + const face = safeFontToKr(rawFace) || "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const isKor = this.isKorean(face); + const hangulId = this.register("HANGUL", isKor ? face : "\uD568\uCD08\uB86C\uBC14\uD0D5"); + const latinId = this.register("LATIN", isKor ? "\uD568\uCD08\uB86C\uBC14\uD0D5" : face); + for (const g of [ + "HANJA", + "JAPANESE", + "OTHER", + "SYMBOL", + "USER" + ]) { + this.register(g, isKor ? face : "\uD568\uCD08\uB86C\uBC14\uD0D5"); + } + return { hangulId, latinId }; + } + /** 언어 그룹별 폰트 목록 반환 */ + getFaces(lang) { + return [...this.maps.get(lang).keys()]; + } + getId(lang, face) { + return this.maps.get(lang).get(face) ?? 0; + } + /** hh:fontfaces XML 생성 */ + toXml() { + let xml = ``; + for (const lang of LANG_GROUPS) { + const faces = this.getFaces(lang); + xml += ``; + faces.forEach((face, i) => { + xml += ``; + }); + xml += ``; + } + return xml + ``; + } +}; +var KIND_MAP = { + solid: "SOLID", + dash: "DASH", + dot: "DOT", + double: "DOUBLE", + none: "NONE", + dash_dot: "DASH_DOT", + dash_dot_dot: "DASH_DOT_DOT" +}; +var BorderFillBank = class { + constructor() { + this.fills = []; + this.keyMap = /* @__PURE__ */ new Map(); + this._addXml( + this._buildXml(void 0, void 0, void 0, void 0, void 0) + ); + const defS = { kind: "solid", pt: 0.5, color: "000000" }; + this._addXml(this._buildXml(defS, defS, defS, defS, void 0)); + } + _strokeXml(tag, s) { + const type = s && s.kind !== "none" ? KIND_MAP[s.kind] ?? "SOLID" : "NONE"; + const w = s && s.kind !== "none" ? `${(s.pt * 0.3528).toFixed(2)} mm` : "0.12 mm"; + const c = s ? s.color.startsWith("#") ? s.color : `#${s.color}` : "#000000"; + return ``; + } + _buildXml(top, right, bottom, left, bg) { + const fill = bg ? `` : ""; + return `` + this._strokeXml("leftBorder", left) + this._strokeXml("rightBorder", right) + this._strokeXml("topBorder", top) + this._strokeXml("bottomBorder", bottom) + `` + fill + ``; + } + _addXml(xml) { + const id = this.fills.length + 1; + this.fills.push({ id, xml: xml.replace("__ID__", String(id)) }); + return id; + } + _key(top, right, bottom, left, bg) { + const sk = (s) => s ? `${s.kind}:${s.pt.toFixed(2)}:${s.color}` : "none"; + return `${sk(top)}|${sk(right)}|${sk(bottom)}|${sk(left)}|${bg ?? ""}`; + } + /** 균일 테두리 등록 */ + addUniform(s, bg) { + const key = this._key(s, s, s, s, bg); + if (this.keyMap.has(key)) return this.keyMap.get(key); + const id = this._addXml(this._buildXml(s, s, s, s, bg)); + this.keyMap.set(key, id); + return id; + } + /** 방향별 테두리 등록 */ + addPerSide(top, right, bottom, left, bg) { + const key = this._key(top, right, bottom, left, bg); + if (this.keyMap.has(key)) return this.keyMap.get(key); + const id = this._addXml(this._buildXml(top, right, bottom, left, bg)); + this.keyMap.set(key, id); + return id; + } + /** CellProps에서 적절한 borderFill ID 계산 (하드코딩 "1" 완전 제거) */ + addFromCellProps(cp, defStroke) { + const d = defStroke ?? DEFAULT_STROKE; + const top = cp.top ?? d; + const right = cp.right ?? d; + const bottom = cp.bot ?? d; + const left = cp.left ?? d; + const bg = cp.bg; + const uniform = top.kind === right.kind && top.kind === bottom.kind && top.kind === left.kind && top.pt === right.pt && top.pt === bottom.pt && top.pt === left.pt && top.color === right.color && top.color === bottom.color && top.color === left.color; + return uniform ? this.addUniform(top, bg) : this.addPerSide(top, right, bottom, left, bg); + } + toXml() { + return `${this.fills.map((f) => f.xml).join("")}`; + } +}; +function readPixelDims(b64, mime) { + try { + const raw = TextKit.base64Decode(b64); + const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); + if (mime.includes("png")) { + if (raw.length>= 24 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) { + return { w: view.getUint32(16), h: view.getUint32(20) }; + } + } else if (mime.includes("jpeg") || mime.includes("jpg")) { + let off = 2; + while (off < raw.length - 4) { + const marker = view.getUint16(off); + off += 2; + if (marker === 65472 || marker === 65474) { + return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) }; + } + if ((marker & 65280) !== 65280) break; + const segLen = view.getUint16(off); + off += segLen; + } + } + } catch { + } + return null; +} +function charPrKey(p) { + return `${p.b ? 1 : 0}|${p.i ? 1 : 0}|${p.u ? 1 : 0}|${p.s ? 1 : 0}|${p.pt ?? 10}|${p.color ?? "000000"}|${p.font ?? ""}|${p.bg ?? ""}`; +} +function paraPrKey(p) { + return `${p.align ?? "left"}|${p.listOrd ?? ""}|${p.listLv ?? 0}|${p.indentPt ?? 0}|${p.firstLineIndentPt ?? 0}|${p.spaceBefore ?? 0}|${p.spaceAfter ?? 0}|${p.lineHeight ?? 0}|${p.styleId ?? ""}`; +} +function registerCharPr(props, ctx) { + const key = charPrKey(props); + const existing = ctx.charPrMap.get(key); + if (existing !== void 0) return existing; + const rawFont = props.font ?? "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const { hangulId, latinId } = ctx.fontBank.registerFont(rawFont); + const id = ctx.charPrs.length; + ctx.charPrs.push({ + id, + height: Metric.ptToHHeight(props.pt ?? 10), + bold: !!props.b, + italic: !!props.i, + underline: props.u ? "BOTTOM" : "NONE", + strikeout: props.s ? "SOLID" : "NONE", + textColor: props.color ? `#${props.color}` : "#000000", + hangulId, + latinId, + bg: props.bg + }); + ctx.charPrMap.set(key, id); + return id; +} +function registerParaPr(props, ctx) { + const key = paraPrKey(props); + const existing = ctx.paraPrMap.get(key); + if (existing !== void 0) return existing; + const id = ctx.paraPrs.length; + const def = { + id, + align: (props.align ?? "left").toUpperCase(), + leftHwp: Metric.ptToHwp(props.indentPt ?? 0), + rightHwp: Metric.ptToHwp(props.indentRightPt ?? 0), + intentHwp: Metric.ptToHwp(props.firstLineIndentPt ?? 0), + prevHwp: Metric.ptToHwp(props.spaceBefore ?? 0), + nextHwp: Metric.ptToHwp(props.spaceAfter ?? 0), + lineSpacing: props.lineHeight ? Math.round(props.lineHeight * 100) : 160 + }; + if (props.listOrd !== void 0) { + def.listType = props.listOrd ? "DIGIT" : "BULLET"; + def.listLevel = props.listLv ?? 0; + } + ctx.paraPrs.push(def); + ctx.paraPrMap.set(key, id); + return id; +} +function mimeToExt(mime) { + if (mime.includes("jpeg")) return "jpg"; + if (mime.includes("gif")) return "gif"; + if (mime.includes("bmp")) return "bmp"; + return "png"; +} +function registerImage(img, ctx) { + if (ctx.imgMap.has(img)) return; + const ext = mimeToExt(img.mime); + const id = `BIN${String(ctx.nextBinNum).padStart(4, "0")}`; + const name = `${id}.${ext}`; + ctx.nextBinNum++; + const data = TextKit.base64Decode(img.b64); + ctx.bins.push({ id, name, data }); + ctx.imgMap.set(img, id); +} +var STYLE_NAME_MAP = { + Normal: "\uBC14\uD0D5\uAE00", + "Heading 1": "\uAC1C\uC694 1", + "Heading 2": "\uAC1C\uC694 2", + "Heading 3": "\uAC1C\uC694 3", + "Heading 4": "\uAC1C\uC694 4", + "Heading 5": "\uAC1C\uC694 5", + "Heading 6": "\uAC1C\uC694 6", + "Body Text": "\uBCF8\uBB38" +}; +function registerStyle(styleId, paraPrId, charPrId, ctx) { + if (!styleId || ctx.styleIdToHwpxId.has(styleId)) return; + if (styleId === "Normal") { + ctx.styleIdToHwpxId.set(styleId, 0); + return; + } + const hwpxId = ctx.hwpxStyles.length; + ctx.styleIdToHwpxId.set(styleId, hwpxId); + ctx.hwpxStyles.push({ + id: hwpxId, + name: STYLE_NAME_MAP[styleId] ?? styleId, + engName: "", + paraPrIDRef: paraPrId, + charPrIDRef: charPrId + }); +} +function scanPara(para, ctx) { + const paraPrId = registerParaPr(para.props, ctx); + let firstCharPrId = 0; + let hasFirstSpan = false; + function scanKids(kids) { + for (const kid of kids) { + if (kid.tag === "span") { + const cId = registerCharPr(kid.props, ctx); + if (!hasFirstSpan) { + firstCharPrId = cId; + hasFirstSpan = true; + } + } else if (kid.tag === "img") { + registerImage(kid, ctx); + } else if (kid.tag === "link") { + scanKids(kid.kids); + } + } + } + scanKids(para.kids); + if (para.props.styleId) + registerStyle(para.props.styleId, paraPrId, firstCharPrId, ctx); +} +function scanGrid(grid, ctx) { + const defStroke = grid.props.defaultStroke ?? DEFAULT_STROKE; + ctx.borderFillBank.addUniform(defStroke); + for (const row of grid.kids) { + for (const cell of row.kids) { + ctx.borderFillBank.addFromCellProps(cell.props, defStroke); + for (const p of cell.kids) { + if (p.tag === "grid") scanGrid(p, ctx); + else scanPara(p, ctx); + } + } + } +} +function scanContent(kids, ctx) { + for (const kid of kids) { + if (kid.tag === "para") scanPara(kid, ctx); + else if (kid.tag === "grid") scanGrid(kid, ctx); + } +} +var HwpxEncoder = class extends BaseEncoder { + getFormat() { + return "hwpx"; + } + getAliases() { + return [HWPX_MIME_TYPE, "application/hwp+zip"]; + } + async encode(doc) { + try { + const sheet = doc.kids[0]; + const dims = normalizeDims(sheet?.dims ?? A4); + const safeML = dims.ml> 0 ? dims.ml : 70.87; + const safeMR = dims.mr> 0 ? dims.mr : 70.87; + const availableWidth = Math.round( + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(safeML) - Metric.ptToHwp(safeMR) + ); + const ctx = { + fontBank: new LangFontBank(), + // ANYTOHWP 방식 언어별 폰트 + borderFillBank: new BorderFillBank(), + // 하드코딩 없는 테두리 관리 + charPrs: [], + charPrMap: /* @__PURE__ */ new Map(), + paraPrs: [], + paraPrMap: /* @__PURE__ */ new Map(), + bins: [], + nextBinNum: 1, + nextElementId: 1e4, + availableWidth, + imgMap: /* @__PURE__ */ new WeakMap(), + nextZOrder: 0, + styleIdToHwpxId: /* @__PURE__ */ new Map(), + hwpxStyles: [] + }; + registerCharPr({}, ctx); + registerParaPr({}, ctx); + ctx.hwpxStyles.push({ + id: 0, + name: "\uBC14\uD0D5\uAE00", + engName: "Normal", + paraPrIDRef: 0, + charPrIDRef: 0 + }); + ctx.styleIdToHwpxId.set("Normal", 0); + scanContent(sheet?.kids ?? [], ctx); + if (sheet?.headers?.default) for (const p of sheet.headers.default) scanPara(p, ctx); + if (sheet?.footers?.default) for (const p of sheet.footers.default) scanPara(p, ctx); + const sectionData = this.stringToBytes(buildSectionXml(sheet, dims, ctx)); + const headerData = this.stringToBytes(buildHeaderXml(dims, doc.meta, ctx)); + const previewText = extractPreviewText(sheet); + const entries = [ + { + name: "mimetype", + data: new TextEncoder().encode(HWPX_MIME_TYPE), + compression: "STORE", + mime: "" + }, + { + name: "version.xml", + data: this.stringToBytes(VERSION_XML), + mime: "application/xml" + }, + { + name: "META-INF/container.xml", + data: this.stringToBytes(CONTAINER_XML), + mime: "application/xml" + }, + { + name: "META-INF/container.rdf", + data: this.stringToBytes(CONTAINER_RDF), + mime: "application/rdf+xml" + }, + { + name: "Contents/content.hpf", + data: this.stringToBytes(buildContentHpf(ctx, doc.meta)), + mime: "application/hwpml-package+xml" + }, + { + name: "Contents/header.xml", + data: headerData, + mime: "application/xml" + }, + { + name: "Contents/section0.xml", + data: sectionData, + mime: "application/xml" + }, + { + name: "Preview/PrvText.txt", + data: this.stringToBytes(previewText), + mime: "text/plain" + }, + { + name: "settings.xml", + data: this.stringToBytes(buildSettingsXml()), + mime: "application/xml" + } + ]; + for (const bin of ctx.bins) { + const ext = bin.name.split(".").pop()?.toLowerCase() ?? "png"; + const ct = ext === "png" ? "image/png" : ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "gif" ? "image/gif" : "image/bmp"; + entries.push({ name: `BinData/${bin.name}`, data: bin.data, mime: ct }); + } + return succeed(await this.zip(entries)); + } catch (e) { + return fail(`HWPX \uC778\uCF54\uB529 \uC624\uB958: ${e?.message ?? String(e)}`); + } + } +}; +var VERSION_XML = ``; +var CONTAINER_XML = ``; +var CONTAINER_RDF = ``; +function buildContentHpf(ctx, meta) { + const title = esc(meta?.title ?? ""); + const creator = esc(meta?.author ?? "text"); + const subject = esc(meta?.subject ?? "text"); + const desc = esc(meta?.desc ?? "text"); + const keyword = esc(meta?.keywords ?? "text"); + const created = meta?.created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z"); + const modified = meta?.modified ?? created; + let items = ``; + for (const bin of ctx.bins) { + const ext = bin.name.split(".").pop()?.toLowerCase() ?? "png"; + const ct = ext === "png" ? "image/png" : ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "gif" ? "image/gif" : "image/bmp"; + items += ``; + } + return `${title}ko${creator}${subject}${desc}${created}${modified}${keyword}0${items}`; +} +function buildSettingsXml() { + return `falsefalse4000100100`; +} +function buildNumberingsXml() { + return ``; +} +function buildBulletsXml() { + return ``; +} +function buildHeaderXml(dims, meta, ctx) { + const fontFacesXml = ctx.fontBank.toXml(); + let charPrXml = ""; + for (const cp of ctx.charPrs) { + const bold = cp.bold ? "" : ""; + const italic = cp.italic ? "" : ""; + const hid = cp.hangulId; + const lid = cp.latinId; + const shadeColor = cp.bg ? cp.bg.startsWith("#") ? cp.bg : `#${cp.bg}` : "none"; + charPrXml += `` + bold + italic + ``; + } + let paraPrXml = ""; + for (const pp of ctx.paraPrs) { + paraPrXml += ``; + } + const borderFillXml = ctx.borderFillBank.toXml(); + const stylesXml2 = `` + ctx.hwpxStyles.map( + (s) => `` + ).join("") + ``; + return `` + fontFacesXml + borderFillXml + `${charPrXml}` + buildNumberingsXml() + buildBulletsXml() + `${paraPrXml}` + stylesXml2 + ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; +} +function buildHeaderFooterRunXml(sheet, dims, ctx) { + const headers = sheet.headers || {}; + const footers = sheet.footers || {}; + const hasAny = Object.keys(headers).length> 0 || Object.keys(footers).length> 0; + if (!hasAny) return ""; + const availW = ctx.availableWidth; + const mtHwp = Metric.ptToHwp(dims.mt); + const mbHwp = Metric.ptToHwp(dims.mb); + const headerZoneH = dims.headerPt ? Math.max(100, mtHwp - Metric.ptToHwp(dims.headerPt)) : 3600; + const footerZoneH = dims.footerPt ? Math.max(100, mbHwp - Metric.ptToHwp(dims.footerPt)) : 3600; + let inner = ""; + const hideFirst = !!(headers.first || footers.first); + inner += ``; + for (const [type, paras] of Object.entries(headers)) { + const applyPageType = type === "even" ? "EVEN" : type === "default" || type === "first" ? "BOTH" : "ODD"; + const savedId = ctx.nextElementId; + ctx.nextElementId = 0; + const parasXml = paras.map((p) => encodeParaPositioned(p, ctx, 0, "", availW).xml).join(""); + ctx.nextElementId = savedId; + inner += `` + parasXml + ``; + } + for (const [type, paras] of Object.entries(footers)) { + const applyPageType = type === "even" ? "EVEN" : type === "default" || type === "first" ? "BOTH" : "ODD"; + const savedId = ctx.nextElementId; + ctx.nextElementId = 0; + const parasXml = paras.map((p) => encodeParaPositioned(p, ctx, 0, "", availW).xml).join(""); + ctx.nextElementId = savedId; + inner += `` + parasXml + ``; + } + return `${inner}`; +} +function buildSectionXml(sheet, dims, ctx) { + const secPrXml = buildSecPrXml(dims); + const kids = sheet?.kids ?? []; + const hfRunXml = sheet ? buildHeaderFooterRunXml(sheet, dims, ctx) : ""; + const availWidth = Math.max( + 1e3, + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr) + ); + ctx.availableWidth = availWidth; + let contentXml = ""; + let vertPos = 0; + for (let i = 0; i < kids.length; i++) { + const kid = kids[i]; + const isFirst = i === 0; + const curSecPr = isFirst ? secPrXml : ""; + const curHfRun = isFirst ? hfRunXml : ""; + if (kid.tag === "para") { + const { xml, nextVertPos } = encodeParaPositioned( + kid, + ctx, + vertPos, + curSecPr, + availWidth, + curHfRun + ); + contentXml += xml; + vertPos = nextVertPos; + } else if (kid.tag === "grid") { + const { xml, nextVertPos } = encodeGridPositioned( + kid, + ctx, + vertPos, + curSecPr, + curHfRun + ); + contentXml += xml; + vertPos = nextVertPos; + } + } + if (kids.length === 0) { + const fs = 1e3; + const vs = 1600; + const { xml: linesegXml } = buildLinesegarray(" ", 0, fs, vs / (fs / 100), availWidth); + contentXml = `` + secPrXml + hfRunXml + `` + linesegXml + ``; + } + return `${contentXml}`; +} +function buildSecPrXml(dims) { + const wHwp = Metric.ptToHwp(dims.wPt); + const hHwp = Metric.ptToHwp(dims.hPt); + const ml = Metric.ptToHwp(dims.ml); + const mr = Metric.ptToHwp(dims.mr); + const mt = Metric.ptToHwp(dims.mt); + const mb = Metric.ptToHwp(dims.mb); + const headerZone = dims.headerPt ? Math.max(0, mt - Metric.ptToHwp(dims.headerPt)) : 0; + const footerZone = dims.footerPt ? Math.max(0, mb - Metric.ptToHwp(dims.footerPt)) : 0; + const pageBorderFill = ``; + return `` + pageBorderFill + ``; +} +function buildLinesegarray(text, vertPosStart, fontSize, lineSpacingPct, horzSize) { + const vertsizeLine = Math.round(fontSize * lineSpacingPct / 100); + const spacing = vertsizeLine - fontSize; + const baseline = Math.round(fontSize * 0.83); + const isKorean = /[\uAC00-\uD7A3\u3131-\u318E]/.test(text); + const charW = isKorean ? fontSize : Math.round(fontSize * 0.47); + const charsPerLine = Math.max(1, Math.floor(horzSize / charW)); + const lineCount = text.length === 0 ? 1 : Math.ceil(text.length / charsPerLine); + const linesegParts = []; + for (let i = 0; i < lineCount; i++) { + const flags = i === 0 ? LINESEG_FLAGS_FIRST : LINESEG_FLAGS_OTHER; + linesegParts.push( + `` + ); + } + return { + xml: `${linesegParts.join("")}`, + totalHeight: lineCount * vertsizeLine + }; +} +function extractParaText(para) { + let text = ""; + const walk = (kids) => { + for (const k of kids) { + if (k.tag === "span") { + for (const c of k.kids) if (c.tag === "txt") text += c.content; + } else if (k.tag === "link") { + walk(k.kids); + } + } + }; + walk(para.kids); + return text; +} +function fontSizeForPara(para, ctx) { + for (const kid of para.kids) { + if (kid.tag === "span") { + const id = ctx.charPrMap.get(charPrKey(kid.props)); + if (id !== void 0 && ctx.charPrs[id]) return ctx.charPrs[id].height; + } + } + return 1e3; +} +function encodeParaPositioned(para, ctx, vertPos, secPr = "", availWidth, hfRun = "") { + const gridKid = para.kids.find((k) => k.tag === "grid"); + if (gridKid) { + return encodeTablePara(para, gridKid, ctx, vertPos, secPr, hfRun); + } + const paraPrId = ctx.paraPrMap.get(paraPrKey(para.props)) ?? 0; + const styleIDRef = para.props.styleId ? ctx.styleIdToHwpxId.get(para.props.styleId) ?? 0 : 0; + const fontSize = fontSizeForPara(para, ctx); + const paraPr = ctx.paraPrs[paraPrId]; + const lineSpacing = paraPr?.lineSpacing ?? 160; + const spacing = Math.max(0, Math.round(fontSize * (lineSpacing / 100 - 1))); + let vertSize = fontSize + spacing; + const horzSize = availWidth ?? ctx.availableWidth; + const isCourierFont = (kids) => kids.some( + (k) => k.tag === "span" && k.props.font?.toLowerCase().includes("courier") || k.tag === "link" && isCourierFont(k.kids) + ); + const isCode = availWidth === void 0 && (para.props.styleId?.toLowerCase().includes("code") || isCourierFont(para.kids)); + if (isCode) + return encodeCodeBlockPositioned( + para, + ctx, + vertPos, + secPr, + fontSize, + spacing, + vertSize + ); + let runsXml = encodeParaKids(para.kids, ctx); + if (!runsXml) runsXml = ``; + const paraText = extractParaText(para); + const { xml: linesegXml, totalHeight } = buildLinesegarray( + paraText, + vertPos, + fontSize, + lineSpacing, + horzSize + ); + const hasPageBreak = para.kids.some( + (k) => k.tag === "span" && k.kids.some((c) => c.tag === "pb") + ); + const xml = `` + secPr + hfRun + runsXml + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function encodeTablePara(para, grid, ctx, vertPos, secPr, hfRun) { + const paraPrId = ctx.paraPrMap.get(paraPrKey(para.props)) ?? 0; + const { xml: gridXml, height: tblHeight } = buildGridXml(grid, ctx); + const fontSize = 1e3; + const totalHeight = Math.max(1600, tblHeight); + const baseline = 850; + const spacing = Math.max(0, totalHeight - fontSize); + const linesegXml = ``; + const xml = `` + secPr + gridXml + hfRun + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function encodeCodeBlockPositioned(para, ctx, vertPos, secPr, fontSize, spacing, vertSize) { + const codeBfId = ctx.borderFillBank.addUniform( + { kind: "solid", pt: 0.5, color: "aaaaaa" }, + "f4f4f4" + ); + const cellW = ctx.availableWidth; + const innerW = Math.max(cellW - 510, 100); + const subListId = ctx.nextElementId++; + const { xml: innerXml } = encodeParaPositioned(para, ctx, 0, "", innerW); + const paraText = extractParaText(para); + const { xml: linesegXml, totalHeight } = buildLinesegarray( + paraText, + vertPos, + fontSize, + 160, + // 코드 블록 기본 줄간격 160% + ctx.availableWidth + ); + const xml = `` + secPr + `` + innerXml + `` + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function encodeParaKids(kids, ctx) { + let xml = ""; + let currentRunCharPrId = null; + let currentRunContent = ""; + const flushRun = () => { + if (currentRunCharPrId !== null) { + const content = currentRunContent || ``; + xml += `${content}`; + } + currentRunCharPrId = null; + currentRunContent = ""; + }; + for (const kid of kids) { + if (kid.tag === "span") { + const span = kid; + const charPrId = ctx.charPrMap.get(charPrKey(span.props)) ?? 0; + if (currentRunCharPrId !== null && currentRunCharPrId !== charPrId) { + flushRun(); + } + currentRunCharPrId = charPrId; + currentRunContent += encodeRunInner(span); + } else if (kid.tag === "link") { + const link = kid; + let charPrId = 0; + if (link.kids.length> 0 && link.kids[0].tag === "span") { + charPrId = ctx.charPrMap.get(charPrKey(link.kids[0].props)) ?? 0; + } + if (currentRunCharPrId !== null && currentRunCharPrId !== charPrId) { + flushRun(); + } + currentRunCharPrId = charPrId; + currentRunContent += encodeLinkInner(link, ctx); + } else if (kid.tag === "img") { + flushRun(); + xml += encodeImgWrapped(kid, ctx); + } + } + flushRun(); + return xml; +} +function encodeRunInner(span) { + let xml = ""; + for (const kid of span.kids) { + if (kid.tag === "txt") { + const content = esc(kid.content); + if (content) xml += `${content}`; + } else if (kid.tag === "br") { + xml += ` +`; + } else if (kid.tag === "pagenum") { + const fmt = kid.format === "roman" ? "ROMAN_LOWER" : kid.format === "romanCaps" ? "ROMAN_UPPER" : "DIGIT"; + xml += ``; + } + } + return xml; +} +function encodeLinkInner(link, ctx) { + const fieldId = 6e8 + ctx.nextElementId++ % 1e8; + const instanceId = 21e8 + ctx.nextElementId++ % 1e8; + const url = link.href; + let xml = `0${esc(url.replace(/:/g, "\\:"))};1;5;-1;${esc(url)}HWPHYPERLINK_TYPE_URLHWPHYPERLINK_TARGET_HYPERLINKHWPHYPERLINK_JUMP_DONTCARE`; + for (const kid of link.kids) { + if (kid.tag === "span") { + xml += encodeRunInner(kid); + } + } + xml += ``; + return xml; +} +var WRAP_MAP = { + inline: "TOP_AND_BOTTOM", + square: "SQUARE", + tight: "BOTH_SIDES", + through: "BOTH_SIDES", + none: "FRONT_TEXT", + behind: "BEHIND_TEXT", + front: "FRONT_TEXT" +}; +var FLOW_MAP = { + inline: "BOTH_SIDES", + square: "LARGEST_ONLY", + tight: "BOTH_SIDES", + through: "BOTH_SIDES", + none: "BOTH_SIDES", + behind: "BOTH_SIDES", + front: "BOTH_SIDES" +}; +function encodeImage(img, ctx) { + if (!img.b64) { + return `${esc(img.alt || "[\uAC1C\uCCB4]")}`; + } + const binId = ctx.imgMap.get(img); + if (!binId) return ""; + const pixelDims = readPixelDims(img.b64, img.mime); + let wHwp, hHwp; + if (pixelDims && pixelDims.w> 0 && pixelDims.h> 0) { + wHwp = Metric.ptToHwp(pixelDims.w * 72 / 96); + hHwp = Metric.ptToHwp(pixelDims.h * 72 / 96); + } else { + wHwp = Metric.ptToHwp(img.w); + hHwp = Metric.ptToHwp(img.h); + } + if (wHwp> ctx.availableWidth) { + hHwp = Math.round(hHwp * ctx.availableWidth / wHwp); + wHwp = ctx.availableWidth; + } + const rotationCenterX = Math.round(wHwp / 2); + const rotationCenterY = Math.round(hHwp / 2); + const layout = img.layout; + const isInline = !layout || layout.wrap === "inline"; + const textWrap = layout ? WRAP_MAP[layout.wrap] ?? "SQUARE" : "SQUARE"; + const textFlow = layout ? FLOW_MAP[layout.wrap] ?? "BOTH_SIDES" : "BOTH_SIDES"; + const zOrder = ctx.nextZOrder++; + return ``; +} +function encodeImgWrapped(img, ctx) { + const content = encodeImage(img, ctx); + if (!img.b64) { + return `${content}`; + } + return `${content}`; +} +function encodeGridPositioned(grid, ctx, vertPos, secPr = "", hfRun = "") { + const { xml: gridXml, height: tblHeight } = buildGridXml(grid, ctx); + const totalHeight = Math.max(1600, tblHeight); + const fontSize = 1e3; + const baseline = Math.round(fontSize * 0.83); + const spacing = Math.max(0, totalHeight - fontSize); + const linesegXml = ``; + const xml = `` + secPr + hfRun + gridXml + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function buildGridXml(grid, ctx) { + const rowCount = grid.kids.length; + const tableMap = Array.from({ length: rowCount }, () => []); + for (let ri = 0; ri < rowCount; ri++) { + let ci = 0; + for (const cell of grid.kids[ri].kids) { + while (tableMap[ri][ci]) ci++; + tableMap[ri][ci] = { type: "real", cell }; + for (let rr = 0; rr < cell.rs; rr++) { + const tri = ri + rr; + if (tri>= rowCount) break; + for (let cc = 0; cc < cell.cs; cc++) { + if (rr === 0 && cc === 0) continue; + tableMap[tri][ci + cc] = { type: "absorbed" }; + } + } + ci += cell.cs; + } + } + let colCount = 0; + for (let ri = 0; ri < rowCount; ri++) + colCount = Math.max(colCount, tableMap[ri].length); + if (colCount === 0) colCount = 1; + const totalW = ctx.availableWidth; + const colWidths = []; + if (grid.props.colWidths && grid.props.colWidths.length === colCount) { + for (const wPt of grid.props.colWidths) { + colWidths.push(Metric.ptToHwp(wPt)); + } + } else { + const defW = Math.round(totalW / colCount); + for (let c = 0; c < colCount; c++) colWidths.push(defW); + } + const rawTotal = colWidths.reduce((s, w) => s + w, 0); + if (rawTotal> totalW && rawTotal> 0) { + const scale = totalW / rawTotal; + for (let i = 0; i < colWidths.length; i++) { + colWidths[i] = Math.max(100, Math.round(colWidths[i] * scale)); + } + } + const actualTotal = colWidths.reduce((s, w) => s + w, 0); + const rowHeights = []; + for (let ri = 0; ri < rowCount; ri++) { + if (grid.kids[ri].heightPt != null && grid.kids[ri].heightPt> 0) { + rowHeights.push(Metric.ptToHwp(grid.kids[ri].heightPt)); + } else { + let maxH = 0; + for (let ci = 0; ci < colCount; ci++) { + const entry = tableMap[ri][ci]; + if (entry?.type === "real") { + const h = estimateCellHeight(entry.cell, ctx); + if (h> maxH) maxH = h; + } + } + rowHeights.push(maxH || Math.round(1e3 * 1.6)); + } + } + const totalH = rowHeights.reduce((s, h) => s + h, 0); + const defStroke = grid.props.defaultStroke ?? DEFAULT_STROKE; + const tblBfId = ctx.borderFillBank.addUniform(defStroke); + let rowsXml = ""; + for (let ri = 0; ri < rowCount; ri++) { + let cellsXml = ""; + for (let ci = 0; ci < colCount; ci++) { + const entry = tableMap[ri][ci]; + if (!entry || entry.type === "absorbed") continue; + const cell = entry.cell; + const cp = cell.props; + const cellBfId = ctx.borderFillBank.addFromCellProps(cp, defStroke); + let cellW = 0; + for (let sc = ci; sc < ci + cell.cs && sc < colWidths.length; sc++) + cellW += colWidths[sc]; + if (!cellW) cellW = Math.round(totalW / colCount) * cell.cs; + const subListId = ctx.nextElementId++; + const padL = cp.padL !== void 0 ? Metric.ptToHwp(cp.padL) : 141; + const padR = cp.padR !== void 0 ? Metric.ptToHwp(cp.padR) : 141; + const padT = cp.padT !== void 0 ? Metric.ptToHwp(cp.padT) : 141; + const padB = cp.padB !== void 0 ? Metric.ptToHwp(cp.padB) : 141; + const innerW = Math.max(cellW - padL - padR, 100); + let parasXml = ""; + if (cell.kids.length> 0) { + for (const kid of cell.kids) { + if (kid.tag === "grid") { + const { xml: tblXml } = buildGridXml(kid, ctx); + const pid = ctx.nextElementId++; + const rid = ctx.nextElementId++; + parasXml += `${tblXml}`; + } else { + parasXml += encodeParaPositioned(kid, ctx, 0, "", innerW).xml; + } + } + } else { + parasXml = ``; + } + const vAlign = cp.va === "mid" ? "CENTER" : cp.va === "bot" ? "BOTTOM" : "TOP"; + cellsXml += `` + parasXml + ``; + } + rowsXml += `${cellsXml}`; + } + const alignMap = { + left: "LEFT", + right: "RIGHT", + center: "CENTER", + justify: "JUSTIFY" + }; + const horzAlign = alignMap[grid.props.align ?? "left"] ?? "LEFT"; + const headerRow = grid.props.headerRow ? ' repeatHeader="1"' : ""; + const xml = `` + rowsXml + ``; + return { xml, height: totalH }; +} +function estimateCellHeight(cell, ctx) { + const topPad = 141; + const botPad = 141; + let h = 0; + for (const kid of cell.kids) { + if (kid.tag === "grid") { + h += 1600; + continue; + } + const para = kid; + const fs = fontSizeForPara(para, ctx); + const ppId = ctx.paraPrMap.get(paraPrKey(para.props)); + const pp = ppId !== void 0 ? ctx.paraPrs[ppId] : null; + const ls = pp?.lineSpacing ?? 160; + const before = pp?.prevHwp ?? 0; + const after = pp?.nextHwp ?? 0; + h += Math.round(fs * ls / 100) + before + after; + } + if (!h) h = Math.round(1e3 * 1.6); + return h + topPad + botPad; +} +function extractPreviewText(sheet) { + if (!sheet) return ""; + const lines = []; + for (const kid of sheet.kids) { + if (kid.tag === "para") { + const text = kid.kids.flatMap( + (k) => k.tag === "span" ? k.kids.flatMap((c) => c.tag === "txt" ? [c.content] : []) : [] + ).join(""); + if (text) lines.push(text); + } else if (kid.tag === "grid") { + for (const row of kid.kids) { + const cells = row.kids.map( + (cell) => cell.kids.flatMap( + (p) => p.tag === "para" ? p.kids.flatMap( + (k) => k.tag === "span" ? k.kids.flatMap((c) => c.tag === "txt" ? [c.content] : []) : [] + ) : [] + ).join("") + ); + lines.push(cells.join(" ")); + } + } + } + return lines.join("\r\n"); +} +function esc(s) { + if (!s) return ""; + s = s.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + s = s.replace(/湰灧/g, "").replace(/\uFEFF/g, ""); + s = s.replace( + /[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/gu, + "" + ); + return TextKit.escapeXml(s); +} +registry.registerEncoder(new HwpxEncoder()); + +// src/encoders/docx/DocxEncoder.ts +var DocxEncoder = class extends BaseEncoder { + getFormat() { + return "docx"; + } + async encode(doc) { + try { + const sheets = doc.kids.length> 0 ? doc.kids : []; + const firstSheet = sheets[0]; + const dims = normalizeDims(firstSheet?.dims ?? A4); + const allKids = sheets.flatMap((s) => s?.kids ?? []); + const images = []; + const ctx = { + images, + nextId: 10, + nextImgNum: 1, + warns: [], + imgMap: /* @__PURE__ */ new WeakMap() + }; + collectImages(allKids, ctx); + let headerParas = firstSheet?.headers?.default; + let footerParas = firstSheet?.footers?.default; + const hasHeader = headerParas && headerParas.length> 0; + const hasFooter = footerParas && footerParas.length> 0; + if (hasHeader) collectImagesFromParas(headerParas, ctx); + if (hasFooter) collectImagesFromParas(footerParas, ctx); + const headerRId = hasHeader ? `rId${ctx.nextId++}` : ""; + const footerRId = hasFooter ? `rId${ctx.nextId++}` : ""; + const numInfo = collectNumbering(allKids); + const kids = allKids; + const entries = [ + { + name: "[Content_Types].xml", + data: this.stringToBytes(contentTypes(images, hasHeader, hasFooter)) + }, + { name: "_rels/.rels", data: this.stringToBytes(pkgRels()) }, + { + name: "word/document.xml", + data: this.stringToBytes( + documentXml(kids, dims, ctx, headerRId, footerRId) + ) + }, + { name: "word/styles.xml", data: this.stringToBytes(stylesXml()) }, + { name: "word/settings.xml", data: this.stringToBytes(settingsXml()) }, + { + name: "word/_rels/document.xml.rels", + data: this.stringToBytes( + docRels(images, headerRId, footerRId, numInfo.hasLists) + ) + }, + { name: "docProps/app.xml", data: this.stringToBytes(appXml()) }, + { + name: "docProps/core.xml", + data: this.stringToBytes(coreXml(doc.meta)) + } + ]; + if (numInfo.hasLists) { + entries.push({ + name: "word/numbering.xml", + data: this.stringToBytes(numberingXml(numInfo)) + }); + } + if (hasHeader) { + entries.push({ + name: "word/header1.xml", + data: this.stringToBytes(headerFooterXml("hdr", headerParas, ctx)) + }); + } + if (hasFooter) { + entries.push({ + name: "word/footer1.xml", + data: this.stringToBytes(headerFooterXml("ftr", footerParas, ctx)) + }); + } + for (const img of images) { + entries.push({ name: `word/media/${img.name}`, data: img.data }); + } + return succeed(await this.zip(entries)); + } catch (e) { + return fail(`DOCX encode error: ${e?.message ?? String(e)}`); + } + } +}; +function mimeToExt2(mime) { + if (mime.includes("jpeg")) return "jpeg"; + if (mime.includes("gif")) return "gif"; + if (mime.includes("bmp")) return "bmp"; + return "png"; +} +function collectImages(kids, ctx) { + for (const kid of kids) { + if (kid.tag === "para") collectImagesFromPara(kid, ctx); + else if (kid.tag === "grid") { + for (const row of kid.kids) + for (const cell of row.kids) + for (const p of cell.kids) + if (p.tag === "para") collectImagesFromPara(p, ctx); + else collectImages([p], ctx); + } + } +} +function collectImagesFromParas(paras, ctx) { + for (const p of paras) collectImagesFromPara(p, ctx); +} +function collectImagesFromPara(para, ctx) { + for (const kid of para.kids) { + if (kid.tag === "img") registerImage2(kid, ctx); + } +} +function registerImage2(img, ctx) { + if (ctx.imgMap.has(img)) return; + const ext = mimeToExt2(img.mime); + const name = `image${ctx.nextImgNum++}.${ext}`; + const rId = `rId${ctx.nextId++}`; + const data = TextKit.base64Decode(img.b64); + ctx.images.push({ rId, name, data, ext }); + ctx.imgMap.set(img, rId); +} +function collectNumbering(kids) { + let hasBullet = false; + let hasNumbered = false; + for (const kid of kids) { + if (kid.tag === "para") { + if (kid.props.listOrd === true) hasNumbered = true; + else if (kid.props.listOrd === false) hasBullet = true; + } + } + return { hasLists: hasBullet || hasNumbered, hasBullet, hasNumbered }; +} +function contentTypes(images, hasHeader, hasFooter) { + const imgDefaults = /* @__PURE__ */ new Set(); + for (const img of images) imgDefaults.add(img.ext); + let defaults = ` + `; + for (const ext of imgDefaults) { + const ct = ext === "png" ? "image/png" : ext === "jpeg" ? "image/jpeg" : ext === "gif" ? "image/gif" : "image/bmp"; + defaults += ` + `; + } + let overrides = ` + + + + `; + if (hasHeader) + overrides += ` + `; + if (hasFooter) + overrides += ` + `; + return ` + + ${defaults} + ${overrides} +`; +} +function pkgRels() { + return ` + + + + +`; +} +function docRels(images, headerRId, footerRId, hasLists) { + let rels = ` + `; + if (hasLists) { + rels += ` + `; + } + for (const img of images) { + rels += ` + `; + } + if (headerRId) { + rels += ` + `; + } + if (footerRId) { + rels += ` + `; + } + return ` + + ${rels} +`; +} +function appXml() { + return ` + + hwpkit +`; +} +function coreXml(meta) { + const now = (/* @__PURE__ */ new Date()).toISOString(); + return ` + + ${esc2(meta.title ?? "")} + ${esc2(meta.author ?? "")} + ${meta.created ?? now} + ${now} +`; +} +function stylesXml() { + return ` + + + + + + + + + + + + + + + + + + + + +`; +} +function settingsXml() { + return ` + + + + + + + + + + + + + + +`; +} +function numberingXml(info) { + let abstractNums = ""; + let nums = ""; + if (info.hasBullet) { + abstractNums += ``; + for (let lvl = 0; lvl < 9; lvl++) { + const marker = lvl === 0 ? "\u25CF" : lvl === 1 ? "\u25CB" : "\u25A0"; + const indent = (lvl + 1) * 720; + abstractNums += ``; + } + abstractNums += ``; + nums += ``; + } + if (info.hasNumbered) { + abstractNums += ``; + for (let lvl = 0; lvl < 9; lvl++) { + const fmt = lvl % 3 === 0 ? "decimal" : lvl % 3 === 1 ? "lowerLetter" : "lowerRoman"; + const indent = (lvl + 1) * 720; + abstractNums += ``; + } + abstractNums += ``; + nums += ``; + } + return ` + + ${abstractNums} + ${nums} +`; +} +function headerFooterXml(type, paras, ctx) { + const tag = type === "hdr" ? "w:hdr" : "w:ftr"; + const body = paras.map((p) => encodeParaInner(p, ctx)).join("\n"); + return ` +<${tag} xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"> +${body} +`; +} +function documentXml(kids, dims, ctx, headerRId, footerRId) { + const body = kids.map((k) => encodeContent(k, ctx, dims)).join("\n"); + let sectRefs = ""; + if (headerRId) + sectRefs += ` + `; + if (footerRId) + sectRefs += ` + `; + return ` + + +${body} + ${sectRefs} + + + + +`; +} +function encodeContent(node, ctx, dims) { + return node.tag === "grid" ? encodeGrid(node, ctx, dims) : encodeParaInner(node, ctx); +} +function encodeParaInner(para, ctx) { + const align = para.props.align ?? "left"; + const headStyle = para.props.heading ? `` : ""; + let numPr = ""; + if (para.props.listOrd !== void 0) { + const numId = para.props.listOrd ? 2 : 1; + const ilvl = para.props.listLv ?? 0; + numPr = ``; + } + let spacingXml = ""; + const { spaceBefore, spaceAfter, lineHeight, lineHeightFixed } = para.props; + if (spaceBefore !== void 0 || spaceAfter !== void 0 || lineHeight !== void 0 || lineHeightFixed !== void 0) { + const parts = []; + if (spaceBefore !== void 0) + parts.push(`w:before="${Math.max(0, Metric.ptToDxa(spaceBefore))}"`); + if (spaceAfter !== void 0) + parts.push(`w:after="${Math.max(0, Metric.ptToDxa(spaceAfter))}"`); + if (lineHeightFixed !== void 0) { + parts.push( + `w:line="${Math.max(1, Metric.ptToDxa(lineHeightFixed))}" w:lineRule="exact"` + ); + } else if (lineHeight !== void 0) { + parts.push(`w:line="${Math.round(lineHeight * 240)}" w:lineRule="auto"`); + } + spacingXml = ``; + } + let indentXml = ""; + const leftDxa = Math.round(Metric.ptToDxa(para.props.indentPt ?? 0)); + const rightDxa = Math.round(Metric.ptToDxa(para.props.indentRightPt ?? 0)); + const firstPt = para.props.firstLineIndentPt ?? 0; + const indParts = []; + if (leftDxa> 0) indParts.push(`w:left="${leftDxa}"`); + if (rightDxa> 0) indParts.push(`w:right="${rightDxa}"`); + if (firstPt> 0) + indParts.push(`w:firstLine="${Math.round(Metric.ptToDxa(firstPt))}"`); + if (firstPt < 0) + indParts.push(`w:hanging="${Math.round(Metric.ptToDxa(-firstPt))}"`); + if (indParts.length> 0) indentXml = ``; + const runs = para.kids.map((k) => { + if (k.tag === "span") return encodeRun(k, ctx); + if (k.tag === "img") return encodeImage2(k, ctx); + return ""; + }).join(""); + return ` + ${headStyle}${numPr}${spacingXml}${indentXml} + ${runs} + `; +} +function encodeRun(span, _ctx) { + const p = span.props; + const rPr = []; + if (p.b) rPr.push(""); + if (p.i) rPr.push(""); + if (p.u) rPr.push(''); + if (p.s) rPr.push(""); + if (p.sup) rPr.push(''); + if (p.sub) rPr.push(''); + if (p.pt) + rPr.push( + `` + ); + if (p.color) rPr.push(``); + if (p.font) + rPr.push( + `` + ); + if (p.bg) rPr.push(``); + const parts = []; + for (const kid of span.kids) { + if (kid.tag === "txt") { + const content = kid.content.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + if (content) { + parts.push( + `${rPr.join("")}${esc2(content)}` + ); + } + } else if (kid.tag === "pagenum") { + parts.push( + `${rPr.join("")}${rPr.join("")} PAGE ${rPr.join("")}${rPr.join("")}1${rPr.join("")}` + ); + } else if (kid.tag === "br") { + parts.push(``); + } else if (kid.tag === "pb") { + parts.push(``); + } + } + return parts.join(""); +} +function encodeImage2(img, ctx) { + const rId = ctx.imgMap.get(img); + if (!rId) return ""; + const cx = Metric.ptToEmu(img.w> 0 ? img.w : 72); + const cy = Metric.ptToEmu(img.h> 0 ? img.h : 72); + const alt = esc2(img.alt ?? ""); + const docPrId = ctx.nextId++; + const graphic = ``; + const layout = img.layout; + const isInline = !layout || layout.wrap === "inline"; + const forceAnchor = layout?.wrap === "topAndBottom" || layout?.wrap === "square" || layout?.wrap === "tight" || layout?.wrap === "behind" || layout?.wrap === "front"; + if (isInline && !forceAnchor) { + return `${graphic}`; + } + return `${encodeAnchor(img, cx, cy, alt, docPrId, graphic, layout)}`; +} +function encodeAnchor(_img, cx, cy, alt, docPrId, graphic, layout) { + const distT = Metric.ptToEmu(layout.distT ?? 0); + const distB = Metric.ptToEmu(layout.distB ?? 0); + const distL = Metric.ptToEmu(layout.distL ?? 9144); + const distR = Metric.ptToEmu(layout.distR ?? 9144); + const behindDoc = layout.behindDoc || layout.wrap === "behind" ? "1" : "0"; + const relH = layout.zOrder ?? 251658240; + const horzRelFrom = HORZ_RELTO_DOCX[layout.horzRelTo ?? "column"] ?? "column"; + let posH; + if (layout.xPt != null) { + posH = `${Metric.ptToEmu(layout.xPt)}`; + } else { + const ha = HORZ_ALIGN_DOCX[layout.horzAlign ?? "left"] ?? "left"; + posH = `${ha}`; + } + const vertRelFrom = VERT_RELTO_DOCX[layout.vertRelTo ?? "para"] ?? "paragraph"; + let posV; + if (layout.yPt != null) { + posV = `${Metric.ptToEmu(layout.yPt)}`; + } else { + const va = VERT_ALIGN_DOCX[layout.vertAlign ?? "top"] ?? "top"; + posV = `${va}`; + } + const wrapXml = WRAP_DOCX[layout.wrap] ?? ''; + return `${posH}${posV}${wrapXml}${graphic}`; +} +var HORZ_RELTO_DOCX = { + margin: "margin", + column: "column", + page: "page", + para: "paragraph" +}; +var VERT_RELTO_DOCX = { + margin: "margin", + line: "line", + page: "page", + para: "paragraph" +}; +var HORZ_ALIGN_DOCX = { + left: "left", + center: "center", + right: "right" +}; +var VERT_ALIGN_DOCX = { + top: "top", + center: "center", + bottom: "bottom" +}; +var WRAP_DOCX = { + square: '', + tight: '', + through: '', + // ECMA-376 §20.4.2.15: wrapTopAndBottom — 텍스트가 이미지 위아래로만 흐름 + topAndBottom: "", + none: "", + behind: "", + front: "" +}; +function encodeGrid(grid, ctx, dims = A4) { + const gp = grid.props; + const look = gp.look; + const firstRow = look?.firstRow ? "1" : "0"; + const lastRow = look?.lastRow ? "1" : "0"; + const firstCol = look?.firstCol ? "1" : "0"; + const lastCol = look?.lastCol ? "1" : "0"; + const noHBand = look?.bandedRows ? "0" : "1"; + const noVBand = look?.bandedCols ? "0" : "1"; + const d = dims ?? A4; + const availDxa = Metric.ptToDxa(d.wPt - d.ml - d.mr); + const tableMap = Array.from( + { length: grid.kids.length }, + () => [] + ); + for (let ri = 0; ri < grid.kids.length; ri++) { + let c = 0; + for (const cell of grid.kids[ri].kids) { + while (tableMap[ri][c]) c++; + tableMap[ri][c] = { type: "real", cell, width: cell.cs }; + for (let rr = 0; rr < cell.rs; rr++) { + const targetRi = ri + rr; + if (targetRi>= grid.kids.length) break; + if (!tableMap[targetRi]) tableMap[targetRi] = []; + for (let cc = 0; cc < cell.cs; cc++) { + if (rr === 0 && cc === 0) continue; + if (rr> 0 && cc === 0) { + tableMap[targetRi][c + cc] = { type: "continue", width: cell.cs }; + } else { + tableMap[targetRi][c + cc] = { type: "absorbed" }; + } + } + } + c += cell.cs; + } + } + let colCount = 0; + for (let ri = 0; ri < grid.kids.length; ri++) { + colCount = Math.max(colCount, tableMap[ri].length); + } + if (colCount === 0) colCount = 1; + for (let ri = 0; ri < grid.kids.length; ri++) { + for (let c = 0; c < colCount; c++) { + if (!tableMap[ri][c]) tableMap[ri][c] = { type: "void" }; + } + } + const defaultColDxa = Math.round(availDxa / colCount); + let colWidthsDxa = []; + if (grid.props.colWidths && grid.props.colWidths.length> 0) { + const srcPt = [...grid.props.colWidths]; + while (srcPt.length < colCount) srcPt.push(0); + srcPt.length = colCount; + const knownTotalPt = srcPt.filter((w) => w> 0).reduce((s, w) => s + w, 0); + const zeroCount = srcPt.filter((w) => w <= 0).length; + const availPt = Metric.dxaToPt(availDxa); + const remainingPt = Math.max(0, availPt - knownTotalPt); + const zeroFillPt = zeroCount> 0 ? remainingPt / zeroCount : 0; + for (let i = 0; i < srcPt.length; i++) { + if (srcPt[i] <= 0) { + srcPt[i] = zeroFillPt> 0 ? zeroFillPt : availPt / colCount; + } + } + colWidthsDxa = srcPt.map((w) => Math.round(Metric.ptToDxa(w))); + const computedTotalDxa = colWidthsDxa.reduce((s, w) => s + w, 0); + if (computedTotalDxa> availDxa) { + const scale = availDxa / computedTotalDxa; + colWidthsDxa = colWidthsDxa.map((w) => Math.round(w * scale)); + } + } else { + for (let c = 0; c < colCount; c++) colWidthsDxa.push(defaultColDxa); + } + const totalDxa = colWidthsDxa.reduce((s, w) => s + w, 0); + const gridCols = colWidthsDxa.map((w) => ``).join(""); + const rows = tableMap.map((rowMap, ri) => { + const cellXmls = []; + for (let c = 0; c < colCount; c++) { + const mapEntry = rowMap[c]; + if (mapEntry.type === "absorbed") continue; + const isContinue = mapEntry.type === "continue"; + const isReal = mapEntry.type === "real"; + const isVoid = mapEntry.type === "void"; + if (isContinue || isReal || isVoid) { + let cw = 0; + const cellWidth = mapEntry.width || 1; + const safeColWidths = colWidthsDxa.length>= colCount ? colWidthsDxa : [ + ...colWidthsDxa, + ...Array(colCount - colWidthsDxa.length).fill(defaultColDxa) + ]; + for (let sc = c; sc < c + cellWidth && sc < safeColWidths.length; sc++) { + cw += safeColWidths[sc]; + } + if (cw <= 0) cw = defaultColDxa * cellWidth; + const tcPrParts = []; + tcPrParts.push(``); + if (cellWidth> 1) { + tcPrParts.push(``); + } + if (isContinue) { + tcPrParts.push(``); + } + let cellContent = ""; + if (isReal) { + const cell = mapEntry.cell; + const cp = cell.props; + if (cell.rs> 1) tcPrParts.push(``); + const borders = encodeCellBorders(cp); + if (borders) tcPrParts.push(borders); + if (cp.bg) + tcPrParts.push( + `` + ); + if (cp.va) { + const vaMap = { + top: "top", + mid: "center", + bot: "bottom" + }; + tcPrParts.push(``); + } + const cPadT = cp.padT != null ? Math.round(Metric.ptToDxa(cp.padT)) : null; + const cPadB = cp.padB != null ? Math.round(Metric.ptToDxa(cp.padB)) : null; + const cPadL = cp.padL != null ? Math.round(Metric.ptToDxa(cp.padL)) : null; + const cPadR = cp.padR != null ? Math.round(Metric.ptToDxa(cp.padR)) : null; + if (cPadT != null || cPadB != null || cPadL != null || cPadR != null) { + const t = cPadT ?? 28; + const b = cPadB ?? 28; + const l = cPadL ?? 72; + const r = cPadR ?? 72; + tcPrParts.push( + `` + ); + } + const parts = []; + for (const kid of cell.kids) { + if (kid.tag === "grid") { + parts.push(encodeGrid(kid, ctx)); + } else if (kid.tag === "para") { + parts.push(encodeParaInner(kid, ctx)); + } + } + const lastKid = cell.kids[cell.kids.length - 1]; + if (cell.kids.length === 0 || lastKid?.tag === "grid") { + parts.push(''); + } + cellContent = parts.join(""); + } else { + cellContent = ``; + } + const tcPr = `${tcPrParts.join("")}`; + cellXmls.push(` ${tcPr}${cellContent}`); + } + } + const trPrParts = []; + if (ri === 0 && (gp.headerRow || look?.firstRow)) { + trPrParts.push(""); + } + const originalRow = grid.kids[ri]; + if (originalRow?.heightPt != null && originalRow.heightPt> 0) { + const hDxa = Math.round(Metric.ptToDxa(originalRow.heightPt)); + trPrParts.push(``); + } + const trPr = trPrParts.length> 0 ? `${trPrParts.join("")}` : ""; + return ` ${trPr} +${cellXmls.join("\n")} + `; + }).join("\n"); + let tblBorders = ""; + const strokeKindMap = { + solid: "single", + dash: "dash", + dot: "dot", + double: "double", + none: "none", + dotDash: "dotDash", + dotDotDash: "dotDotDash", + triple: "triple", + thinThickSmallGap: "thinThickSmallGap", + thickThinSmallGap: "thickThinSmallGap", + thinThickThinSmallGap: "thinThickThinSmallGap" + }; + if (gp.defaultStroke) { + const s = gp.defaultStroke; + const val = strokeKindMap[s.kind] ?? "single"; + if (val === "none" || s.pt <= 0) { + tblBorders = ''; + } else { + const sz = Math.max(2, Math.round(s.pt * 8)); + const clr = s.color ? s.color.replace("#", "") : "auto"; + const bdr = `w:val="${val}" w:sz="${sz}" w:space="0" w:color="${clr}"`; + tblBorders = ``; + } + } + const tblAlignMap = { + left: "start", + center: "center", + right: "end", + justify: "start" + }; + const tblJc = gp.align ? `` : ""; + return ` + ${tblBorders}${tblJc} + ${gridCols} +${rows} + `; +} +function encodeCellBorders(cp) { + if (!cp.top && !cp.bot && !cp.left && !cp.right) return ""; + const strokeKindMap = { + solid: "single", + dash: "dash", + dot: "dot", + double: "double", + none: "none", + dotDash: "dotDash", + dotDotDash: "dotDotDash", + triple: "triple" + }; + const encode = (s, tag) => { + if (!s || !tag) return ""; + const val = strokeKindMap[s.kind] ?? "single"; + if (val === "none" || s.pt <= 0) { + return ``; + } + const sz = Math.max(2, Math.round(s.pt * 8)); + const clr = s.color ? s.color.replace("#", "") : "auto"; + return ``; + }; + return `${encode(cp.top, "top")}${encode(cp.bot, "bottom")}${encode(cp.left, "left")}${encode(cp.right, "right")}`; +} +function esc2(s) { + if (!s) return ""; + s = s.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + s = s.replace(/湰灧/g, ""); + s = s.replace(/\uFEFF/g, ""); + s = s.replace(/[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD]/g, ""); + return TextKit.escapeXml(s); +} +registry.registerEncoder(new DocxEncoder()); + +// src/encoders/md/MdEncoder.ts +var MdEncoder = class extends BaseEncoder { + getFormat() { + return "md"; + } + async encode(doc, options) { + const includeImages = options?.includeImages !== false; + try { + const warns = []; + const parts = []; + for (const sheet of doc.kids) { + if (sheet.headers && sheet.headers.default && sheet.headers.default.length> 0) warns.push("[SHIELD] MD: \uBA38\uB9AC\uAE00(header) \uD45C\uD604 \uBD88\uAC00 \u2014 \uC190\uC2E4\uB428"); + if (sheet.footers && sheet.footers.default && sheet.footers.default.length> 0) warns.push("[SHIELD] MD: \uBC14\uB2E5\uAE00(footer) \uD45C\uD604 \uBD88\uAC00 \u2014 \uC190\uC2E4\uB428"); + for (const kid of sheet.kids) parts.push(encodeContent2(kid, warns, includeImages)); + } + return succeed(this.stringToBytes(parts.join("\n\n")), warns); + } catch (e) { + return fail(`MD encode error: ${e?.message ?? String(e)}`); + } + } +}; +function encodeContent2(node, warns, includeImages) { + return node.tag === "grid" ? encodeGrid2(node, warns, includeImages) : encodePara(node, warns, includeImages); +} +function encodePara(para, warns, includeImages) { + const text = para.kids.map((k) => { + if (k.tag === "span") return encodeSpan(k, warns); + if (k.tag === "img") return encodeImage3(k, includeImages); + return ""; + }).join(""); + if (para.props.heading) return `${"#".repeat(para.props.heading)} ${text}`; + if (para.props.listOrd !== void 0) { + const indent = " ".repeat(para.props.listLv ?? 0); + return `${indent}${para.props.listOrd ? "1." : "-"} ${text}`; + } + if (para.props.align && para.props.align !== "left" && para.props.align !== "justify") { + return `
      ${text}
      `; + } + return text; +} +function encodeSpan(span, warns) { + let hasPageNum = false; + const textParts = []; + for (const kid of span.kids) { + if (kid.tag === "txt") textParts.push(kid.content); + else if (kid.tag === "pagenum") { + hasPageNum = true; + warns.push("[SHIELD] MD: \uD398\uC774\uC9C0 \uBC88\uD638 \uD45C\uD604 \uBD88\uAC00 \u2014 \uC190\uC2E4\uB428"); + } + } + let r = textParts.join(""); + if (hasPageNum && r === "") r = "[\uD398\uC774\uC9C0 \uBC88\uD638]"; + const cssStyles = []; + if (span.props.font) cssStyles.push(`font-family: ${span.props.font}`); + if (span.props.pt) cssStyles.push(`font-size: ${span.props.pt}pt`); + if (span.props.color) cssStyles.push(`color: #${span.props.color}`); + if (span.props.bg) cssStyles.push(`background-color: #${span.props.bg}`); + const hasHtmlStyle = cssStyles.length> 0; + if (hasHtmlStyle) { + if (span.props.b) cssStyles.push("font-weight: bold"); + if (span.props.i) cssStyles.push("font-style: italic"); + if (span.props.s) cssStyles.push("text-decoration: line-through"); + if (span.props.u) { + const existing = cssStyles.find((s) => s.startsWith("text-decoration:")); + if (existing) { + const idx = cssStyles.indexOf(existing); + cssStyles[idx] = existing.replace("line-through", "underline line-through"); + if (!existing.includes("line-through")) cssStyles[idx] = existing + " underline"; + } else { + cssStyles.push("text-decoration: underline"); + } + } + const styleAttr = cssStyles.join("; "); + if (span.props.sup) return `${r}`; + if (span.props.sub) return `${r}`; + return `${r}`; + } + if (span.props.b && span.props.i) r = `***${r}***`; + else if (span.props.b) r = `**${r}**`; + else if (span.props.i) r = `*${r}*`; + if (span.props.s) r = `~~${r}~~`; + if (span.props.u) r = `${r}`; + if (span.props.sup) r = `${r}`; + if (span.props.sub) r = `${r}`; + return r; +} +function encodeImage3(img, includeImages) { + if (!includeImages) { + return `![${img.alt ?? ""}]`; + } + return `![${img.alt ?? ""}](data:${img.mime};base64,${img.b64})`; +} +function strokeToCss(s) { + if (!s || s.kind === "none" || s.pt <= 0) return void 0; + const kindMap = { solid: "solid", dash: "dashed", dot: "dotted", double: "double", none: "none" }; + const style = kindMap[s.kind] ?? "solid"; + const px = Math.max(1, Math.round(s.pt * 96 / 72)); + const color = s.color.startsWith("#") ? s.color : `#${s.color}`; + return `${px}px ${style} ${color}`; +} +function encodeGrid2(grid, warns, includeImages) { + if (grid.kids.length === 0) return ""; + const rowCount = grid.kids.length; + const occupancy = Array.from({ length: rowCount }, () => /* @__PURE__ */ new Set()); + let colCount = 0; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let ci = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(ci)) ci++; + if (cell.rs> 1) { + for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) { + for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c); + } + } + ci += cell.cs; + } + while (occupancy[ri].has(ci)) ci++; + if (ci> colCount) colCount = ci; + } + let rows = ""; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let cells = ""; + let colIdx = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(colIdx)) colIdx++; + const cs = cell.cs> 1 ? ` colspan="${cell.cs}"` : ""; + const rs = cell.rs> 1 ? ` rowspan="${cell.rs}"` : ""; + const styles = ["padding:4px 6px", "vertical-align:top"]; + const top = strokeToCss(cell.props.top); + const bot = strokeToCss(cell.props.bot); + const left = strokeToCss(cell.props.left); + const right = strokeToCss(cell.props.right); + if (top) styles.push(`border-top:${top}`); + if (bot) styles.push(`border-bottom:${bot}`); + if (left) styles.push(`border-left:${left}`); + if (right) styles.push(`border-right:${right}`); + if (cell.props.bg) styles.push(`background-color:#${cell.props.bg}`); + if (cell.props.va === "mid") styles[1] = "vertical-align:middle"; + else if (cell.props.va === "bot") styles[1] = "vertical-align:bottom"; + const tag = grid.props.headerRow && ri === 0 || cell.props.isHeader ? "th" : "td"; + const content = cell.kids.map((p) => p.tag === "para" ? encodePara(p, warns, includeImages) : encodeGrid2(p, warns, includeImages)).join("\n"); + cells += `<${tag}${cs}${rs} ;")}">${content}`; + colIdx += cell.cs; + } + rows += `
      ${cells}
      +`; + } + return ` + +${rows} + +`; +} +registry.registerEncoder(new MdEncoder()); + +// src/encoders/html/HtmlEncoder.ts +var HtmlEncoder = class extends BaseEncoder { + getFormat() { + return "html"; + } + async encode(doc) { + try { + const warns = []; + const bodyParts = []; + for (const sheet of doc.kids) { + if (sheet.headers?.default && sheet.headers.default.length> 0) { + const hText = sheet.headers.default.map((p) => encodePara2(p, warns)).join(""); + bodyParts.push(`
      ${hText}
      `); + } + for (const kid of sheet.kids) { + bodyParts.push(encodeContent3(kid, warns)); + } + if (sheet.footers?.default && sheet.footers.default.length> 0) { + const fText = sheet.footers.default.map((p) => encodePara2(p, warns)).join(""); + bodyParts.push(`
      ${fText}
      `); + } + } + const title = this.escapeXml(doc.meta?.title ?? ""); + const html = ` + + + + +${title} + + +

      ${title}

      +
      +${bodyParts.join("\n")} +
      +

      AltStyle によって変換されたページ (->オリジナル) /

      +`; + return succeed(this.stringToBytes(html), warns); + } catch (e) { + return fail(`HTML encode error: ${e?.message ?? String(e)}`); + } + } +}; +var BASE_CSS = ` +body { margin: 0; padding: 0; background: #f0f0f0; } +.hwp-doc { max-width: 800px; margin: 0 auto; background: #fff; padding: 40px 60px; box-shadow: 0 0 8px rgba(0,0,0,0.15); } +.hwp-header, .hwp-footer { color: #666; font-size: 0.9em; border-bottom: 1px solid #ddd; margin-bottom: 8px; padding-bottom: 4px; } +.hwp-footer { border-top: 1px solid #ddd; border-bottom: none; margin-top: 8px; padding-top: 4px; } +p { margin: 0; padding: 0; line-height: 1; } +table { border-collapse: collapse; width: 100%; margin: 8px 0; } +td, th { border: 1px solid #ccc; padding: 4px 8px; vertical-align: top; } +img { max-width: 100%; height: auto; } +`.trim(); +function encodeContent3(node, warns) { + return node.tag === "grid" ? encodeGrid3(node, warns) : encodePara2(node, warns); +} +function encodePara2(para, warns) { + const kids = para.kids.map((k) => { + if (k.tag === "span") return encodeSpan2(k, warns); + if (k.tag === "img") return encodeImage4(k); + if (k.tag === "link") { + const link = k; + const inner = link.kids.map((s) => encodeSpan2(s, warns)).join(""); + return `${inner}`; + } + return ""; + }).join(""); + if (para.props.heading) { + const tag = `h${para.props.heading}`; + return `<${tag}>${kids} +`; + } + if (para.props.listOrd !== void 0) { + const indent = (para.props.listLv ?? 0) * 20; + const style = indent> 0 ? ` style="margin-left:${indent}px"` : ""; + const marker = para.props.listOrd ? `1. ` : `\u2022 `; + return `${marker}${kids}

      +`; + } + const align = para.props.align; + const styleAttrs = []; + if (align && align !== "left") styleAttrs.push(`text-align:${align}`); + if (para.props.indentPt) styleAttrs.push(`margin-left:${para.props.indentPt.toFixed(1)}pt`); + if (para.props.spaceBefore) styleAttrs.push(`margin-top:${para.props.spaceBefore.toFixed(1)}pt`); + if (para.props.spaceAfter) styleAttrs.push(`margin-bottom:${para.props.spaceAfter.toFixed(1)}pt`); + if (para.props.lineHeight) styleAttrs.push(`line-height:${para.props.lineHeight}`); + const styleAttr = styleAttrs.length> 0 ? ` style="${styleAttrs.join(";")}"` : ""; + return `${kids || " "}

      +`; +} +function encodeSpan2(span, warns) { + const parts = []; + let hasPageNum = false; + for (const kid of span.kids) { + if (kid.tag === "txt") { + const content = kid.content.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + if (content) parts.push(TextKit.escapeXml(content)); + } else if (kid.tag === "br") { + parts.push("
      "); + } else if (kid.tag === "pb") { + parts.push(''); + } else if (kid.tag === "pagenum") { + hasPageNum = true; + warns.push("[SHIELD] HTML: \uD398\uC774\uC9C0 \uBC88\uD638 \u2014 \uC815\uC801 \uAC12\uC73C\uB85C \uB300\uCCB4\uB428"); + parts.push('[\uD398\uC774\uC9C0]'); + } + } + let text = parts.join(""); + if (hasPageNum && text.trim() === '[\uD398\uC774\uC9C0]') { + } + const p = span.props; + const css = []; + if (p.font) css.push(`font-family:${TextKit.escapeXml(p.font)}`); + if (p.pt) css.push(`font-size:${p.pt}pt`); + if (p.color) css.push(`color:#${p.color}`); + if (p.bg) css.push(`background-color:#${p.bg}`); + if (p.b) css.push("font-weight:bold"); + if (p.i) css.push("font-style:italic"); + const decorations = []; + if (p.u) decorations.push("underline"); + if (p.s) decorations.push("line-through"); + if (decorations.length> 0) css.push(`text-decoration:${decorations.join(" ")}`); + if (p.sup) return `${text}
      `; + if (p.sub) return `${text}`; + if (css.length> 0) return `${text}`; + return text; +} +function encodeImage4(img) { + const wStyle = img.w ? ` width="${Math.round(img.w / 72 * 96)}px"` : ""; + const hStyle = img.h ? ` height="${Math.round(img.h / 72 * 96)}px"` : ""; + const alt = TextKit.escapeXml(img.alt ?? ""); + return `${alt}`; +} +function encodeGrid3(grid, warns) { + if (grid.kids.length === 0) return ""; + const rowCount = grid.kids.length; + const occupancy = Array.from({ length: rowCount }, () => /* @__PURE__ */ new Set()); + let colCount = 0; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let ci = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(ci)) ci++; + if (cell.rs> 1) { + for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) { + for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c); + } + } + ci += cell.cs; + } + while (occupancy[ri].has(ci)) ci++; + if (ci> colCount) colCount = ci; + } + let rows = ""; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let cells = ""; + let ci = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(ci)) ci++; + const isHeader = cell.props.isHeader || grid.props.headerRow && ri === 0; + const tag = isHeader ? "th" : "td"; + const cs = cell.cs> 1 ? ` colspan="${cell.cs}"` : ""; + const rs = cell.rs> 1 ? ` rowspan="${cell.rs}"` : ""; + const styleAttrs = []; + if (cell.props.bg) styleAttrs.push(`background-color:#${cell.props.bg}`); + const va = cell.props.va; + if (va === "mid") styleAttrs.push("vertical-align:middle"); + else if (va === "bot") styleAttrs.push("vertical-align:bottom"); + const styleAttr = styleAttrs.length> 0 ? ` style="${styleAttrs.join(";")}"` : ""; + const content = cell.kids.map((p) => p.tag === "para" ? encodePara2(p, warns) : encodeGrid3(p, warns)).join(""); + cells += `<${tag}${cs}${rs}${styleattr}>${content}`; + ci += cell.cs; + } + rows += `
      ${cells}
      +`; + } + return ` + +${rows} + +`; +} +registry.registerEncoder(new HtmlEncoder()); + +// src/encoders/hwp/HwpEncoder.ts +var import_pako3 = __toESM(require("pako")); +var T = 16; +var TAG_DOCUMENT_PROPERTIES = T + 0; +var TAG_ID_MAPPINGS = T + 1; +var TAG_BIN_DATA = T + 2; +var TAG_FACE_NAME2 = T + 3; +var TAG_BORDER_FILL2 = T + 4; +var TAG_CHAR_SHAPE2 = T + 5; +var TAG_PARA_SHAPE2 = T + 9; +var TAG_STYLE = T + 10; +var TAG_PARA_HEADER2 = T + 50; +var TAG_PARA_TEXT2 = T + 51; +var TAG_PARA_CHAR_SHAPE2 = T + 52; +var TAG_PARA_LINE_SEG = T + 53; +var TAG_CTRL_HEADER2 = T + 55; +var TAG_LIST_HEADER2 = T + 56; +var TAG_PAGE_DEF2 = T + 57; +var TAG_FOOTNOTE_SHAPE = T + 58; +var TAG_TABLE = T + 61; +var TAG_SHAPE_COMPONENT_PICTURE = T + 69; +var CTRL_TABLE2 = 1952607264; +var CTRL_SECD = 1936024420; +var CTRL_PIC = 611346787; +var CTRL_FIELD_BEGIN = 1684825637; +var CTRL_FIELD_END = 1684825692; +var BORDER_W_PT2 = [ + 0.28, + 0.34, + 0.43, + 0.57, + 0.71, + 0.85, + 1.13, + 1.42, + 1.7, + 1.98, + 2.84, + 4.25, + 5.67, + 8.5, + 11.34, + 14.17 +]; +var BORDER_KIND_IDX = { + solid: 0, + dot: 1, + dash: 2, + double: 7, + triple: 8, + none: 0 +}; +var ALIGN_CODE = { + justify: 0, + left: 1, + right: 2, + center: 3, + distribute: 4 +}; +var BufWriter = class { + constructor() { + this.chunks = []; + this._sz = 0; + } + get size() { + return this._sz; + } + u8(v) { + this.chunks.push(new Uint8Array([v & 255])); + this._sz++; + return this; + } + u16(v) { + this.chunks.push(new Uint8Array([v & 255, v>> 8 & 255])); + this._sz += 2; + return this; + } + u32(v) { + const b = new Uint8Array(4); + b[0] = v & 255; + b[1] = v>>> 8 & 255; + b[2] = v>>> 16 & 255; + b[3] = v>>> 24 & 255; + this.chunks.push(b); + this._sz += 4; + return this; + } + i32(v) { + return this.u32(v < 0 ? v + 4294967296 : v); + } + i16(v) { + return this.u16(v < 0 ? v + 65536 : v); + } + bytes(d) { + this.chunks.push(d); + this._sz += d.length; + return this; + } + zeros(n) { + this.chunks.push(new Uint8Array(n)); + this._sz += n; + return this; + } + utf16(s) { + for (let i = 0; i < s.length; i++) this.u16(s.charCodeAt(i)); + return this; + } + colorRef(hex) { + const h = (hex || "000000").replace("#", "").padStart(6, "0"); + return this.u8(parseInt(h.slice(0, 2), 16)).u8(parseInt(h.slice(2, 4), 16)).u8(parseInt(h.slice(4, 6), 16)).u8(0); + } + build() { + const out = new Uint8Array(this._sz); + let off = 0; + for (const c of this.chunks) { + out.set(c, off); + off += c.length; + } + return out; + } +}; +function mkRec(tag, level, data) { + const sz = data.length; + const enc = Math.min(sz, 4095); + const hdr = enc << 20 | (level & 1023) << 10 | tag & 1023; + const w = new BufWriter().u32(hdr); + if (enc>= 4095) w.u32(sz); + w.bytes(data); + return w.build(); +} +function readPixelDims2(data, mime) { + try { + const view = new DataView(data.buffer, data.byteOffset, data.byteLength); + if (mime.includes("png")) { + if (data.length>= 24 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) { + return { w: view.getUint32(16), h: view.getUint32(20) }; + } + } else if (mime.includes("jpeg") || mime.includes("jpg")) { + let off = 2; + while (off < data.length - 4) { + const marker = view.getUint16(off); + off += 2; + if (marker === 65472 || marker === 65474) { + return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) }; + } + if ((marker & 65280) !== 65280) break; + off += view.getUint16(off); + } + } + } catch { + } + return null; +} +var LANG_GROUPS2 = [ + "HANGUL", + "LATIN", + "HANJA", + "JAPANESE", + "OTHER", + "SYMBOL", + "USER" +]; +function isKoreanFont(face) { + return /[\uAC00-\uD7A3\u3131-\u318E]/.test(face) || ["\uB9D1\uC740", "\uB098\uB214", "\uAD74\uB9BC", "\uB3CB\uC6C0", "\uBC14\uD0D5", "\uD568\uCD08\uB86C", "\uD55C\uCEF4", "HY"].some( + (k) => face.includes(k) + ); +} +var HwpStyleBank = class { + // id=0 → 모두 0 + constructor() { + this.DEF_STROKE = { kind: "solid", pt: 0.5, color: "000000" }; + // 언어별 독립 폰트 목록 (ANYTOHWP langFontFaces) + this.langFonts = new Map( + LANG_GROUPS2.map((g) => [g, []]) + ); + this.langFontIdx = new Map( + LANG_GROUPS2.map((g) => [g, /* @__PURE__ */ new Map()]) + ); + // charShape, parShape, borderFill 레지스트리 + this.csProps = [{}]; + this.csIdx = /* @__PURE__ */ new Map([[csKey({}), 0]]); + this.psProps = [{}]; + this.psIdx = /* @__PURE__ */ new Map([[psKey({}), 0]]); + this.bfData = []; + this.bfIdx = /* @__PURE__ */ new Map(); + // charShape마다 언어별 fontId를 기록 + this.csFontIds = [[0, 0, 0, 0, 0, 0, 0]]; + for (const g of LANG_GROUPS2) this._registerLangFont(g, "\uD568\uCD08\uB86C\uBC14\uD0D5"); + this.addBorderFill(this.DEF_STROKE); + } + _registerLangFont(lang, face) { + const idx = this.langFontIdx.get(lang); + if (idx.has(face)) return idx.get(face); + const id = this.langFonts.get(lang).length; + this.langFonts.get(lang).push(face); + idx.set(face, id); + return id; + } + /** 폰트 이름 → 언어별 7개 ID 반환 (ANYTOHWP 방식) */ + registerFontForLangs(rawFace) { + const face = safeFontToKr(rawFace) || "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const isKor = isKoreanFont(face); + const hangulFace = isKor ? face : "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const latinFace = isKor ? "\uD568\uCD08\uB86C\uBC14\uD0D5" : face; + const ids = []; + for (const lang of LANG_GROUPS2) { + const f = lang === "LATIN" ? latinFace : hangulFace; + ids.push(this._registerLangFont(lang, f)); + } + return ids; + } + /** 언어별 폰트 목록 반환 */ + getFontsForLang(lang) { + return [...this.langFonts.get(lang) ?? []]; + } + /** 폰트 수 반환 (mkIdMappings용) */ + getFontCount(lang) { + return this.langFonts.get(lang)?.length ?? 0; + } + addCharShape(p) { + const k = csKey(p); + if (this.csIdx.has(k)) return this.csIdx.get(k); + const id = this.csProps.length; + const fIds = p.font ? this.registerFontForLangs(p.font) : [0, 0, 0, 0, 0, 0, 0]; + this.csProps.push(p); + this.csFontIds.push(fIds); + this.csIdx.set(k, id); + return id; + } + addParaShape(p) { + const k = psKey(p); + if (this.psIdx.has(k)) return this.psIdx.get(k); + const id = this.psProps.length; + this.psProps.push(p); + this.psIdx.set(k, id); + return id; + } + addBorderFill(s, bg) { + const k = bfKey(s, bg); + if (this.bfIdx.has(k)) return this.bfIdx.get(k); + const id = this.bfData.length + 1; + this.bfData.push({ uniform: true, s, bg }); + this.bfIdx.set(k, id); + return id; + } + addBorderFillPerSide(l, r, t, b, bg) { + const k = bfPerSideKey(l, r, t, b, bg); + if (this.bfIdx.has(k)) return this.bfIdx.get(k); + const id = this.bfData.length + 1; + this.bfData.push({ uniform: false, l, r, t, b, bg }); + this.bfIdx.set(k, id); + return id; + } +}; +function csKey(p) { + return [ + p.font ?? "", + p.pt ?? 10, + p.b ? 1 : 0, + p.i ? 1 : 0, + p.u ? 1 : 0, + p.s ? 1 : 0, + p.sup ? 1 : 0, + p.sub ? 1 : 0, + p.color ?? "000000" + ].join("|"); +} +function psKey(p) { + return [ + p.align ?? "left", + p.indentPt ?? 0, + p.firstLineIndentPt ?? 0, + p.spaceBefore ?? 0, + p.spaceAfter ?? 0, + p.lineHeight ?? 1 + ].join("|"); +} +function bfKey(s, bg) { + return `${s.kind}|${s.pt}|${s.color}|${bg ?? ""}`; +} +function bfPerSideKey(l, r, t, b, bg) { + return `${bfKey(l)}/${bfKey(r)}/${bfKey(t)}/${bfKey(b)}/${bg ?? ""}`; +} +function collectNode(node, bank) { + if (node.tag === "para") { + bank.addParaShape(node.props); + for (const kid of node.kids) { + if (kid.tag === "span") bank.addCharShape(kid.props); + } + } else if (node.tag === "grid") { + if (node.props.defaultStroke) bank.addBorderFill(node.props.defaultStroke); + for (const row of node.kids) { + for (const cell of row.kids) { + const defStroke = node.props.defaultStroke ?? bank.DEF_STROKE; + const cp = cell.props; + if (cp.top || cp.bot || cp.left || cp.right) { + bank.addBorderFillPerSide( + cp.left ?? defStroke, + cp.right ?? defStroke, + cp.top ?? defStroke, + cp.bot ?? defStroke, + cp.bg + ); + } else { + bank.addBorderFill(defStroke, cp.bg); + } + for (const para of cell.kids) collectNode(para, bank); + } + } + } +} +function mkDocumentProperties() { + return new BufWriter().u16(1).u16(1).u16(1).u16(1).u16(1).u16(1).u16(1).u32(0).u32(0).u32(0).build(); +} +function mkIdMappings(bank, nBinData = 0) { + const w = new BufWriter(); + w.u32(nBinData); + for (const lang of LANG_GROUPS2) w.u32(bank.getFontCount(lang)); + w.u32(bank.bfData.length); + w.u32(bank.csProps.length); + w.u32(0); + w.u32(0); + w.u32(0); + w.u32(bank.psProps.length); + w.u32(1); + w.u32(0); + w.u32(0); + w.u32(0); + return w.build(); +} +function mkStyle(name, engName, paraPrId, charPrId) { + return new BufWriter().u16(name.length).utf16(name).u16(engName.length).utf16(engName).u16(paraPrId).u16(charPrId).u16(0).u16(1042).u16(0).build(); +} +function mkFaceName(name) { + return new BufWriter().u8(0).u16(name.length).utf16(name).u8(0).u16(0).zeros(10).u16(0).build(); +} +function borderWidthIdx(pt) { + let best = 0; + for (let i = 0; i < BORDER_W_PT2.length; i++) { + if (Math.abs(BORDER_W_PT2[i] - pt) < Math.abs(BORDER_W_PT2[best] - pt)) + best = i; + } + return best; +} +function mkBorderFill(s, bg) { + const w = new BufWriter(); + const t = BORDER_KIND_IDX[s.kind] ?? 0; + const wi = borderWidthIdx(s.pt); + const col = s.color || "000000"; + w.u16(0); + for (let i = 0; i < 4; i++) w.u8(t); + for (let i = 0; i < 4; i++) w.u8(wi); + for (let i = 0; i < 4; i++) w.colorRef(col); + w.u8(0).u8(0).colorRef("000000"); + if (bg) { + w.u32(1).colorRef(bg).colorRef("FFFFFF").u32(0); + } else { + w.u32(0); + } + return w.build(); +} +function mkBorderFillPerSide(l, r, t, b, bg) { + const w = new BufWriter(); + w.u16(0); + w.u8(BORDER_KIND_IDX[l.kind] ?? 0).u8(BORDER_KIND_IDX[r.kind] ?? 0).u8(BORDER_KIND_IDX[t.kind] ?? 0).u8(BORDER_KIND_IDX[b.kind] ?? 0); + w.u8(borderWidthIdx(l.pt)).u8(borderWidthIdx(r.pt)).u8(borderWidthIdx(t.pt)).u8(borderWidthIdx(b.pt)); + w.colorRef(l.color || "000000").colorRef(r.color || "000000").colorRef(t.color || "000000").colorRef(b.color || "000000"); + w.u8(0).u8(0).colorRef("000000"); + if (bg) { + w.u32(1).colorRef(bg).colorRef("FFFFFF").u32(0); + } else { + w.u32(0); + } + return w.build(); +} +function mkCharShape(fontIds, p) { + const height = Math.round((p.pt ?? 10) * 100); + let attr = 0; + if (p.i) attr |= 1 << 0; + if (p.b) attr |= 1 << 1; + if (p.u) attr |= 1 << 2; + if (p.s) attr |= 1 << 18; + if (p.sup) attr |= 1 << 16; + if (p.sub) attr |= 2 << 16; + const w = new BufWriter(); + for (const id of fontIds) w.u16(id); + for (let i = 0; i < 7; i++) w.u8(100); + for (let i = 0; i < 7; i++) w.u8(0); + for (let i = 0; i < 7; i++) w.u8(100); + for (let i = 0; i < 7; i++) w.u8(0); + w.i32(height).u32(attr).u8(0).u8(0); + w.colorRef(p.color ?? "000000"); + w.colorRef("000000"); + w.colorRef(p.bg ?? "FFFFFF"); + w.colorRef("000000"); + w.u16(0); + w.colorRef("000000"); + return w.build(); +} +function mkParaShape(p) { + const alignVal = ALIGN_CODE[p.align ?? "left"] ?? 1; + const attr1 = (alignVal & 7) << 2; + const lineSpacePct = p.lineHeight ? Math.round(p.lineHeight * 100) : 160; + return new BufWriter().u32(attr1).i32(Metric.ptToHwp(p.indentPt ?? 0)).i32(Metric.ptToHwp(p.indentRightPt ?? 0)).i32(Metric.ptToHwp(p.firstLineIndentPt ?? 0)).i32(Metric.ptToHwp(p.spaceBefore ?? 0)).i32(Metric.ptToHwp(p.spaceAfter ?? 0)).i32(lineSpacePct).u16(0).u16(0).u16(0).i16(0).i16(0).i16(0).i16(0).u32(0).u32(4).u32(lineSpacePct).build(); +} +function mkBinData(id, ext) { + return new BufWriter().u16(2).u16(id).u16(ext.length).utf16(ext).build(); +} +function buildDocInfoStream(bank, images = []) { + const chunks = []; + chunks.push(mkRec(TAG_DOCUMENT_PROPERTIES, 0, mkDocumentProperties())); + chunks.push(mkRec(TAG_ID_MAPPINGS, 1, mkIdMappings(bank, images.length))); + for (const img of images) { + chunks.push(mkRec(TAG_BIN_DATA, 1, mkBinData(img.id, img.ext))); + } + for (const lang of LANG_GROUPS2) { + for (const face of bank.getFontsForLang(lang)) { + chunks.push(mkRec(TAG_FACE_NAME2, 1, mkFaceName(face))); + } + } + for (const entry of bank.bfData) { + chunks.push( + mkRec( + TAG_BORDER_FILL2, + 1, + entry.uniform ? mkBorderFill(entry.s, entry.bg) : mkBorderFillPerSide(entry.l, entry.r, entry.t, entry.b, entry.bg) + ) + ); + } + for (let i = 0; i < bank.csProps.length; i++) { + chunks.push( + mkRec(TAG_CHAR_SHAPE2, 1, mkCharShape(bank.csFontIds[i], bank.csProps[i])) + ); + } + for (const p of bank.psProps) { + chunks.push(mkRec(TAG_PARA_SHAPE2, 1, mkParaShape(p))); + } + chunks.push(mkRec(TAG_STYLE, 1, mkStyle("\uBC14\uD0D5\uAE00", "Normal", 0, 0))); + return concatU8(chunks); +} +function mkPageDef(dims) { + return new BufWriter().u32(Metric.ptToHwp(dims.wPt)).u32(Metric.ptToHwp(dims.hPt)).u32(Metric.ptToHwp(dims.ml)).u32(Metric.ptToHwp(dims.mr)).u32(Metric.ptToHwp(dims.mt)).u32(Metric.ptToHwp(dims.mb)).zeros(12).u32(dims.orient === "landscape" ? 1 : 0).build(); +} +function mkParaHeader(nchars, ctrlMask, psId, csCount, lineAlignCount = 0, instanceId = 0) { + return new BufWriter().u32(nchars).u32(ctrlMask).u16(psId).u8(0).u8(0).u16(csCount).u16(0).u16(lineAlignCount).u32(instanceId).u16(0).build(); +} +function mkParaText(text) { + const w = new BufWriter(); + for (let i = 0; i < text.length; i++) { + const c = text.charCodeAt(i); + w.u16(c); + } + w.u16(13); + return w.build(); +} +function mkParaCharShape(pairs) { + const w = new BufWriter(); + for (const [pos, id] of pairs) w.u32(pos).u32(id); + return w.build(); +} +function calcLineHeight(type, value, textHeight) { + switch (type) { + case 0: + return Math.floor(textHeight * value / 100); + case 1: + return value; + case 2: + return Math.max(textHeight, value); + case 3: + return textHeight + value; + case 4: + return Math.floor(textHeight * value); + default: + return Math.floor(textHeight * value / 100); + } +} +function mkLineSeg(textStartPos, vertPos, vertSize, textHeight, baseline, spacing, horzPos, horzSize, flags) { + return new BufWriter().u32(textStartPos).i32(vertPos).i32(vertSize).i32(textHeight).i32(baseline).i32(spacing).i32(horzPos).i32(horzSize).u32(flags).build(); +} +function buildDefaultLineSeg(availWidthHwp, fontHwp, nchars, paraProps, vertPos = 0) { + const ratio = paraProps?.lineHeight ? Math.round(paraProps.lineHeight * 100) : 160; + const vertSize = calcLineHeight(0, ratio, fontHwp); + const baseline = Math.round(fontHwp * 0.85); + const spacing = vertSize - fontHwp; + const flags = 3; + return mkLineSeg( + 0, + vertPos, + vertSize, + fontHwp, + baseline, + spacing, + 0, + availWidthHwp, + flags + ); +} +function mkSecdParaText() { + const lo = CTRL_SECD & 65535; + const hi = CTRL_SECD>>> 16 & 65535; + return new BufWriter().u16(2).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(2).u16(13).build(); +} +function mkTableParaText() { + const lo = CTRL_TABLE2 & 65535; + const hi = CTRL_TABLE2>>> 16 & 65535; + return new BufWriter().u16(11).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(11).u16(13).build(); +} +function mkPicParaText() { + const lo = CTRL_PIC & 65535; + const hi = CTRL_PIC>>> 16 & 65535; + return new BufWriter().u16(11).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(11).u16(13).build(); +} +function mkShapeComponentPicture(binDataId, wHwp, hHwp) { + const w = new BufWriter(); + w.u32(CTRL_PIC).zeros(15); + w.u32(0).u32(0).u32(wHwp).u32(hHwp); + w.u32(0).u32(0).u32(wHwp).u32(hHwp); + w.zeros(36); + w.u16(binDataId).u8(0).u8(0).u8(0).zeros(5); + return w.build(); +} +function mkObjectCtrl(ctrlId, wHwp, hHwp, instanceId, layout) { + let attr = 136978960; + if (layout?.wrap === "inline") attr |= 1 << 3; + return new BufWriter().u32(ctrlId).u32(attr).i32(layout?.yPt ? Metric.ptToHwp(layout.yPt) : 0).i32(layout?.xPt ? Metric.ptToHwp(layout.xPt) : 0).u32(wHwp).u32(hHwp).i32(layout?.zOrder ?? 0).u16(layout?.distL ? Metric.ptToHwp(layout.distL) : 0).u16(layout?.distR ? Metric.ptToHwp(layout.distR) : 0).u16(layout?.distT ? Metric.ptToHwp(layout.distT) : 0).u16(layout?.distB ? Metric.ptToHwp(layout.distB) : 0).u32(instanceId).i32(0).u16(0).build(); +} +function mkFieldBeginCtrl(instanceId) { + return new BufWriter().u32(CTRL_FIELD_BEGIN).u32(2).zeros(28).u32(instanceId).zeros(6).build(); +} +function mkFieldEndCtrl(beginId) { + return new BufWriter().u32(CTRL_FIELD_END).u32(0).zeros(28).u32(beginId).zeros(6).build(); +} +function encodePicPara(imgNode, binDataId, bank, lv, idGen, availWidthHwp) { + const rawData = TextKit.base64Decode(imgNode.b64); + const pixDims = readPixelDims2(rawData, imgNode.mime); + let wHwp, hHwp; + if (pixDims && pixDims.w> 0 && pixDims.h> 0) { + wHwp = Metric.ptToHwp(pixDims.w * 72 / 96); + hHwp = Metric.ptToHwp(pixDims.h * 72 / 96); + } else { + wHwp = Metric.ptToHwp(imgNode.w); + hHwp = Metric.ptToHwp(imgNode.h); + } + if (wHwp> availWidthHwp) { + hHwp = Math.round(hHwp * availWidthHwp / wHwp); + wHwp = availWidthHwp; + } + const CTRL_MASK = 1 << 11; + const instanceId = idGen(); + const psId = bank.addParaShape({}); + return [ + mkRec( + TAG_PARA_HEADER2, + lv, + mkParaHeader(9, CTRL_MASK, psId, 1, 1, instanceId) + ), + mkRec(TAG_PARA_TEXT2, lv + 1, mkPicParaText()), + mkRec(TAG_PARA_CHAR_SHAPE2, lv + 1, mkParaCharShape([[0, 0]])), + mkRec( + TAG_PARA_LINE_SEG, + lv + 1, + buildDefaultLineSeg(availWidthHwp, hHwp, 9) + ), + mkRec( + TAG_CTRL_HEADER2, + lv + 1, + mkObjectCtrl(CTRL_PIC, wHwp, hHwp, idGen(), imgNode.layout) + ), + mkRec( + TAG_SHAPE_COMPONENT_PICTURE, + lv + 2, + mkShapeComponentPicture(binDataId, wHwp, hHwp) + ) + ]; +} +function encodePara3(para, bank, lv, instanceId, availWidthHwp, mask = 0, vertPos = 0) { + let text = ""; + const csPairs = []; + let pos = 0; + let fontHwp = 1e3; + const ctrlRecords = []; + for (const kid of para.kids) { + if (kid.tag === "span" && kid.props.pt && kid.props.pt> 0) { + fontHwp = Metric.ptToHwp(kid.props.pt); + break; + } + } + let localIdCounter = 1e4; + const localIdGen = () => localIdCounter++; + function processKids(kids) { + for (const kid of kids) { + if (kid.tag === "span") { + const span = kid; + const csId = bank.addCharShape(span.props); + if (!csPairs.length || csPairs[csPairs.length - 1][1] !== csId) { + csPairs.push([pos, csId]); + } + for (const t of span.kids) { + if (t.tag === "txt") { + text += t.content; + pos += t.content.length; + } + } + } else if (kid.tag === "link") { + const link = kid; + mask |= 1 << 11; + const fieldBeginId = localIdGen(); + text += String.fromCharCode(3); + pos += 1; + ctrlRecords.push( + mkRec(TAG_CTRL_HEADER2, lv + 1, mkFieldBeginCtrl(fieldBeginId)) + ); + processKids(link.kids); + text += String.fromCharCode(4); + pos += 1; + ctrlRecords.push( + mkRec(TAG_CTRL_HEADER2, lv + 1, mkFieldEndCtrl(fieldBeginId)) + ); + } + } + } + processKids(para.kids); + if (!csPairs.length) csPairs.push([0, 0]); + const psId = bank.addParaShape(para.props); + const nchars = text.length + 1; + return [ + mkRec( + TAG_PARA_HEADER2, + lv, + mkParaHeader(nchars, mask, psId, csPairs.length, 1, instanceId) + ), + mkRec(TAG_PARA_TEXT2, lv + 1, mkParaText(text)), + mkRec(TAG_PARA_CHAR_SHAPE2, lv + 1, mkParaCharShape(csPairs)), + mkRec( + TAG_PARA_LINE_SEG, + lv + 1, + buildDefaultLineSeg(availWidthHwp, fontHwp, nchars, para.props, vertPos) + ), + ...ctrlRecords + ]; +} +function mkTableCtrl(wHwp, hHwp, instanceId, align = "left") { + const alignFlags = { left: 0, center: 1, right: 2, justify: 3 }[align] ?? 0; + return new BufWriter().u32(CTRL_TABLE2).u32(136978961).i32(0).i32(0).u32(wHwp).u32(hHwp).i32(7).u16(140).u16(140).u16(140).u16(140).u32(instanceId).i32(alignFlags).u16(0).build(); +} +function mkTableRecord(rowCnt, colCnt, rowHwp, bfId) { + const w = new BufWriter(); + w.u32(67108870).u16(rowCnt).u16(colCnt).u16(0); + w.u16(510).u16(510).u16(141).u16(141); + for (const h of rowHwp) w.u16(Math.max(1, h & 65535)); + w.u16(bfId).u16(0); + return w.build(); +} +function mkCellListHeader(paraCount, row, col, rs, cs, wHwp, hHwp, bfId, padL = 141, padR = 141, padT = 141, padB = 141) { + return new BufWriter().u16(paraCount).u32(0).u16(0).u16(col).u16(row).u16(rs).u16(cs).u32(wHwp).u32(hHwp).u16(padL).u16(padR).u16(padT).u16(padB).u16(bfId).zeros(13).build(); +} +var DEFAULT_ROW_HEIGHT_PT = 14; +function encodeGrid4(grid, bank, lv, idGen, availWidthHwp) { + const records = []; + const rowCnt = grid.kids.length; + const colCnt = Math.max(1, grid.kids[0]?.kids.length ?? 1); + const cwPt = grid.props.colWidths ?? []; + const totalPt = cwPt.reduce((s, w) => s + w, 0) || 453; + const defColPt = totalPt / colCnt; + const defStroke = grid.props.defaultStroke ?? bank.DEF_STROKE; + const defBfId = bank.addBorderFill(defStroke); + const rowHwp = grid.kids.map( + (row) => row.heightPt != null && row.heightPt> 0 ? Metric.ptToHwp(row.heightPt) : Metric.ptToHwp(DEFAULT_ROW_HEIGHT_PT) + ); + const tblWPt = cwPt.length> 0 ? cwPt.reduce((s, w) => s + w, 0) : totalPt; + const tblHPt = grid.kids.reduce( + (s, row) => s + (row.heightPt != null && row.heightPt> 0 ? row.heightPt : DEFAULT_ROW_HEIGHT_PT), + 0 + ); + const tblInstanceId = idGen(); + const tblAlign = grid.props.align ?? "left"; + records.push( + mkRec( + TAG_CTRL_HEADER2, + lv, + mkTableCtrl( + Metric.ptToHwp(tblWPt), + Metric.ptToHwp(tblHPt), + tblInstanceId, + tblAlign + ) + ) + ); + records.push( + mkRec(TAG_TABLE, lv + 1, mkTableRecord(rowCnt, colCnt, rowHwp, defBfId)) + ); + for (let r = 0; r < grid.kids.length; r++) { + for (let c = 0; c < grid.kids[r].kids.length; c++) { + const cell = grid.kids[r].kids[c]; + const wHwp = Metric.ptToHwp(cwPt[c] ?? defColPt); + const hHwp = rowHwp[r]; + const cp = cell.props; + const hasPerSide = cp.top || cp.bot || cp.left || cp.right; + const bfId = hasPerSide ? bank.addBorderFillPerSide( + cp.left ?? defStroke, + cp.right ?? defStroke, + cp.top ?? defStroke, + cp.bot ?? defStroke, + cp.bg + ) : bank.addBorderFill(defStroke, cp.bg); + const paras = cell.kids.length> 0 ? cell.kids : [{ tag: "para", props: {}, kids: [] }]; + const padL = cp.padL !== void 0 ? Metric.ptToHwp(cp.padL) : 510; + const padR = cp.padR !== void 0 ? Metric.ptToHwp(cp.padR) : 510; + const padT = cp.padT !== void 0 ? Metric.ptToHwp(cp.padT) : 141; + const padB = cp.padB !== void 0 ? Metric.ptToHwp(cp.padB) : 141; + records.push( + mkRec( + TAG_LIST_HEADER2, + lv + 1, + mkCellListHeader( + paras.length, + r, + c, + cell.rs, + cell.cs, + wHwp, + hHwp, + bfId, + padL, + padR, + padT, + padB + ) + ) + ); + const cellWidthHwp = Metric.ptToHwp(cwPt[c] ?? defColPt); + for (const para of paras) { + records.push( + ...encodePara3(para, bank, lv + 2, idGen(), cellWidthHwp) + ); + } + } + } + return records; +} +function mkSectionCtrl() { + return new BufWriter().u32(CTRL_SECD).u32(0).u32(1134).u16(16384).u16(31).zeros(31).build(); +} +function buildSectionParagraph(dims, instanceId) { + const SECD_CTRL_MASK = 1 << 2; + const nchars = 9; + const availWidthHwp = Math.max( + 1e3, + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr) + ); + return [ + mkRec( + TAG_PARA_HEADER2, + 0, + mkParaHeader(nchars, SECD_CTRL_MASK, 0, 1, 1, instanceId) + ), + mkRec(TAG_PARA_TEXT2, 1, mkSecdParaText()), + mkRec(TAG_PARA_CHAR_SHAPE2, 1, mkParaCharShape([[0, 0]])), + mkRec( + TAG_PARA_LINE_SEG, + 1, + buildDefaultLineSeg(availWidthHwp, 1e3, nchars) + ), + mkRec(TAG_CTRL_HEADER2, 1, mkSectionCtrl()), + mkRec(TAG_PAGE_DEF2, 2, mkPageDef(dims)), + mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)), + mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)) + ]; +} +function flatImgNodes(kids) { + const result = []; + for (const kid of kids) { + if (kid.tag === "img") result.push(kid); + else if (kid.tag === "link" && Array.isArray(kid.kids)) + result.push(...flatImgNodes(kid.kids)); + } + return result; +} +function b64Matches(binImg, b64) { + const a = TextKit.base64Encode(binImg.data).replace(/\s/g, ""); + const b = b64.replace(/\s/g, ""); + return a === b; +} +function buildBodyTextStream(doc, bank, images) { + const chunks = []; + const dims = doc.kids[0]?.dims ?? A4; + let instanceIdCounter = 1; + const idGen = () => instanceIdCounter++; + const availWidthHwp = Math.max( + 1e3, + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr) + ); + for (const r of buildSectionParagraph(dims, idGen())) chunks.push(r); + const TABLE_CTRL_MASK = 1 << 11; + let vertPos = 0; + for (const sheet of doc.kids) { + for (const node of sheet.kids) { + if (node.tag === "para") { + const para = node; + const hasPageBreak = para.kids.some( + (k) => k.tag === "span" && k.kids.some((c) => c.tag === "pb") + ); + let paraMask = hasPageBreak ? 1 << 2 : 0; + const hasCourier = (kids) => kids.some( + (k) => k.tag === "span" && k.props.font?.toLowerCase().includes("courier") || k.tag === "link" && hasCourier(k.kids) + ); + const isCode = para.props.styleId?.toLowerCase().includes("code") || hasCourier(para.kids); + if (isCode) { + const gridNode = { + tag: "grid", + props: { + colWidths: [Metric.hwpToPt(availWidthHwp)], + defaultStroke: { kind: "solid", pt: 0.5, color: "aaaaaa" } + }, + kids: [ + { + tag: "row", + kids: [ + { + tag: "cell", + rs: 1, + cs: 1, + props: { bg: "f4f4f4" }, + kids: [para] + } + ] + } + ] + }; + chunks.push( + mkRec( + TAG_PARA_HEADER2, + 0, + mkParaHeader(9, TABLE_CTRL_MASK | paraMask, 0, 1, 1, idGen()) + ) + ); + chunks.push(mkRec(TAG_PARA_TEXT2, 1, mkTableParaText())); + chunks.push(mkRec(TAG_PARA_CHAR_SHAPE2, 1, mkParaCharShape([[0, 0]]))); + chunks.push( + mkRec( + TAG_PARA_LINE_SEG, + 1, + buildDefaultLineSeg(availWidthHwp, 1e3, 9, void 0, vertPos) + ) + ); + vertPos += Metric.ptToHwp(20); + for (const r of encodeGrid4(gridNode, bank, 1, idGen, availWidthHwp)) + chunks.push(r); + continue; + } + const imgNodes = flatImgNodes(para.kids); + if (imgNodes.length> 0) { + for (const img of imgNodes) { + const binImg = images.find((b) => b64Matches(b, img.b64)); + if (binImg) { + for (const r of encodePicPara( + img, + binImg.id, + bank, + 0, + idGen, + availWidthHwp + )) { + chunks.push(r); + } + vertPos += Metric.ptToHwp(img.h ?? 100); + } + } + const textKids = para.kids.filter( + (k) => k.tag !== "img" && k.tag !== "link" + ); + if (textKids.length> 0) { + const textPara = { + tag: "para", + props: para.props, + kids: textKids + }; + for (const r of encodePara3( + textPara, + bank, + 0, + idGen(), + availWidthHwp, + paraMask, + vertPos + )) { + if (r[0] === (TAG_PARA_HEADER2 & 255)) { + } + chunks.push(r); + } + const fontHwp_img = textKids.find( + (k) => k.tag === "span" && k.props?.pt + )?.props.pt ? Metric.ptToHwp( + textKids.find( + (k) => k.tag === "span" && k.props?.pt + ).props.pt + ) : 1e3; + const lineSpacePct_img = Math.round((para.props.lineHeight ?? 1.6) * 100); + vertPos += Math.round(fontHwp_img * lineSpacePct_img / 100); + } + } else { + for (const r of encodePara3( + para, + bank, + 0, + idGen(), + availWidthHwp, + paraMask, + vertPos + )) + chunks.push(r); + const fontHwp_para = para.kids.find( + (k) => k.tag === "span" && k.props?.pt + )?.props.pt ? Metric.ptToHwp( + para.kids.find( + (k) => k.tag === "span" && k.props?.pt + ).props.pt + ) : 1e3; + const lineSpacePct_para = para.props.lineHeight ? Math.round(para.props.lineHeight * 100) : 160; + vertPos += Math.round(fontHwp_para * lineSpacePct_para / 100); + } + } else if (node.tag === "grid") { + chunks.push( + mkRec( + TAG_PARA_HEADER2, + 0, + mkParaHeader(9, TABLE_CTRL_MASK, 0, 1, 1, idGen()) + ) + ); + chunks.push(mkRec(TAG_PARA_TEXT2, 1, mkTableParaText())); + chunks.push(mkRec(TAG_PARA_CHAR_SHAPE2, 1, mkParaCharShape([[0, 0]]))); + chunks.push( + mkRec( + TAG_PARA_LINE_SEG, + 1, + buildDefaultLineSeg(availWidthHwp, 1e3, 9, void 0, vertPos) + ) + ); + vertPos += Metric.ptToHwp(20); + for (const r of encodeGrid4( + node, + bank, + 1, + idGen, + availWidthHwp + )) + chunks.push(r); + } + } + } + return concatU8(chunks); +} +function buildHwpFileHeader() { + const SIZE = 256; + const buf = new Uint8Array(SIZE); + const dv = new DataView(buf.buffer); + const sig = "HWP Document File"; + for (let i = 0; i < sig.length; i++) { + buf[i] = sig.charCodeAt(i); + } + dv.setUint32(32, 83886848, true); + dv.setUint32(36, 1, true); + if (buf.length !== SIZE) { + throw new Error(`FileHeader \uD06C\uAE30 \uC624\uB958: ${buf.length} (\uAE30\uB300: ${SIZE})`); + } + if (new TextDecoder().decode(buf.subarray(0, sig.length)) !== sig) { + throw new Error("FileHeader \uC2DC\uADF8\uB2C8\uCC98 \uC624\uB958"); + } + if (dv.getUint32(32, true) !== 83886848) { + throw new Error("FileHeader \uBC84\uC804 \uC624\uB958"); + } + return buf; +} +function buildHwpOle2(fileHeaderData, docInfoData, section0Data, binImages = []) { + const SS = 512; + const ENDOFCHAIN = 4294967294; + const FREESECT = 4294967295; + const FATSECT = 4294967293; + if (fileHeaderData.length < 256) { + throw new Error( + `FileHeader \uD06C\uAE30 \uBD80\uC871: ${fileHeaderData.length} (\uCD5C\uC18C 256)` + ); + } + function padSector(d) { + const n = Math.ceil(Math.max(d.length, 1) / SS) * SS; + if (d.length === n) return d; + const out2 = new Uint8Array(n); + out2.set(d); + return out2; + } + const fhPad = padSector(fileHeaderData); + const diPad = padSector(docInfoData); + const s0Pad = padSector(section0Data); + const imgPads = binImages.map((img) => padSector(img.data)); + const fhN = fhPad.length / SS; + const diN = diPad.length / SS; + const s0N = s0Pad.length / SS; + const imgNs = imgPads.map((p) => p.length / SS); + const totalImgN = imgNs.reduce((s, n) => s + n, 0); + const numDirEntries = 5 + (binImages.length> 0 ? 1 + binImages.length : 0); + const dirN = Math.max(2, Math.ceil(numDirEntries / 4)); + let fatN = 1; + for (let iter = 0; iter < 10; iter++) { + const total = fatN + dirN + fhN + diN + s0N + totalImgN; + const needed = Math.ceil(total / 128); + if (needed <= fatN) break; + fatN = needed; + } + const dir1Sec = fatN; + const fhSec = dir1Sec + dirN; + const diSec = fhSec + fhN; + const s0Sec = diSec + diN; + const imgSecs = []; + let curSec = s0Sec + s0N; + for (const n of imgNs) { + imgSecs.push(curSec); + curSec += n; + } + const totalSec = curSec; + const fatBuf = new Uint8Array(fatN * SS).fill(255); + const setFat = (i, v) => { + fatBuf[i * 4] = v & 255; + fatBuf[i * 4 + 1] = v>>> 8 & 255; + fatBuf[i * 4 + 2] = v>>> 16 & 255; + fatBuf[i * 4 + 3] = v>>> 24 & 255; + }; + for (let i = 0; i < fatN; i++) setFat(i, FATSECT); + for (let i = 0; i < dirN; i++) + setFat(dir1Sec + i, i + 1 < dirN ? dir1Sec + i + 1 : ENDOFCHAIN); + for (let i = 0; i < fhN; i++) + setFat(fhSec + i, i + 1 < fhN ? fhSec + i + 1 : ENDOFCHAIN); + for (let i = 0; i < diN; i++) + setFat(diSec + i, i + 1 < diN ? diSec + i + 1 : ENDOFCHAIN); + for (let i = 0; i < s0N; i++) + setFat(s0Sec + i, i + 1 < s0N ? s0Sec + i + 1 : ENDOFCHAIN); + for (let ii = 0; ii < imgNs.length; ii++) { + const start = imgSecs[ii]; + const n = imgNs[ii]; + for (let i = 0; i < n; i++) + setFat(start + i, i + 1 < n ? start + i + 1 : ENDOFCHAIN); + } + const dirBuf = new Uint8Array(dirN * SS); + const dv = new DataView(dirBuf.buffer); + function writeDirEntry(idx, name, type, left, right, child, startSec, size) { + const base = idx * 128; + const nl = name.length; + for (let i = 0; i < nl; i++) + dv.setUint16(base + i * 2, name.charCodeAt(i), true); + dv.setUint16(base + 64, (nl + 1) * 2, true); + dirBuf[base + 66] = type; + dirBuf[base + 67] = 1; + dv.setInt32(base + 68, left, true); + dv.setInt32(base + 72, right, true); + dv.setInt32(base + 76, child, true); + dv.setUint32(base + 116, startSec>>> 0, true); + dv.setUint32(base + 120, size>>> 0, true); + } + for (let i = 0; i < dirN * 4; i++) { + const base = i * 128; + dv.setInt32(base + 68, -1, true); + dv.setInt32(base + 72, -1, true); + dv.setInt32(base + 76, -1, true); + } + if (binImages.length> 0) { + writeDirEntry(0, "Root Entry", 5, -1, -1, 1, ENDOFCHAIN, 0); + writeDirEntry(1, "FileHeader", 2, -1, 2, -1, fhSec, fileHeaderData.length); + writeDirEntry(2, "DocInfo", 2, -1, 3, -1, diSec, docInfoData.length); + writeDirEntry(3, "BodyText", 1, -1, 5, 4, ENDOFCHAIN, 0); + writeDirEntry(4, "Section0", 2, -1, -1, -1, s0Sec, section0Data.length); + writeDirEntry(5, "BinData", 1, -1, -1, 6, ENDOFCHAIN, 0); + for (let ii = 0; ii < binImages.length; ii++) { + const img = binImages[ii]; + const streamName = `BIN${String(img.id).padStart(4, "0")}.${img.ext}`; + const sibling = ii + 1 < binImages.length ? 7 + ii : -1; + writeDirEntry( + 6 + ii, + streamName, + 2, + -1, + sibling, + -1, + imgSecs[ii], + img.data.length + ); + } + } else { + writeDirEntry(0, "Root Entry", 5, -1, -1, 1, ENDOFCHAIN, 0); + writeDirEntry(1, "FileHeader", 2, -1, 2, -1, fhSec, fileHeaderData.length); + writeDirEntry(2, "DocInfo", 2, -1, 3, -1, diSec, docInfoData.length); + writeDirEntry(3, "BodyText", 1, -1, -1, 4, ENDOFCHAIN, 0); + writeDirEntry(4, "Section0", 2, -1, -1, -1, s0Sec, section0Data.length); + } + const HWP_CLSID = [ + 32, + 233, + 227, + 192, + 70, + 53, + 207, + 17, + 141, + 129, + 0, + 170, + 0, + 56, + 155, + 113 + ]; + for (let i = 0; i < 16; i++) dirBuf[80 + i] = HWP_CLSID[i]; + const hdr = new Uint8Array(SS); + const hdv = new DataView(hdr.buffer); + const MAGIC = [208, 207, 17, 224, 161, 177, 26, 225]; + MAGIC.forEach((b, i) => { + hdr[i] = b; + }); + hdv.setUint16(24, 62, true); + hdv.setUint16(26, 3, true); + hdv.setUint16(28, 254, true); + hdv.setUint16(30, 9, true); + hdv.setUint16(32, 6, true); + hdv.setUint32(40, fatN, true); + hdv.setUint32(44, dir1Sec, true); + hdv.setUint32(48, 0, true); + hdv.setUint32(52, 4096, true); + hdv.setUint32(56, ENDOFCHAIN, true); + hdv.setUint32(60, 0, true); + hdv.setUint32(64, ENDOFCHAIN, true); + hdv.setUint32(68, 0, true); + hdv.setUint32(72, 0, true); + for (let i = 0; i < 109; i++) { + hdv.setUint32(76 + i * 4, i < fatN ? i : FREESECT, true); + } + const out = new Uint8Array(SS + totalSec * SS); + out.set(hdr, 0); + for (let i = 0; i < fatN; i++) + out.set(fatBuf.subarray(i * SS, (i + 1) * SS), SS + i * SS); + for (let i = 0; i < dirN; i++) + out.set(dirBuf.subarray(i * SS, (i + 1) * SS), SS + (dir1Sec + i) * SS); + out.set(fhPad, SS + fhSec * SS); + out.set(diPad, SS + diSec * SS); + out.set(s0Pad, SS + s0Sec * SS); + for (let ii = 0; ii < imgPads.length; ii++) + out.set(imgPads[ii], SS + imgSecs[ii] * SS); + return out; +} +function concatU8(arrays) { + const total = arrays.reduce((s, a) => s + a.length, 0); + const out = new Uint8Array(total); + let off = 0; + for (const a of arrays) { + out.set(a, off); + off += a.length; + } + return out; +} +function validateOle2Magic(hwp) { + const OLE_MAGIC = [208, 207, 17, 224, 161, 177, 26, 225]; + return OLE_MAGIC.every((b, i) => hwp[i] === b); +} +var HwpEncoder = class extends BaseEncoder { + getFormat() { + return "hwp"; + } + getAliases() { + return ["application/vnd.hancom.hwp"]; + } + async encode(doc) { + try { + let registerImg2 = function(img) { + const key = img.b64.substring(0, 50); + if (seenB64.has(key)) return; + seenB64.add(key); + const raw = TextKit.base64Decode(img.b64); + const ext = img.mime === "image/png" ? "png" : img.mime === "image/gif" ? "gif" : img.mime === "image/bmp" ? "bmp" : "jpg"; + images.push({ id: binIdCounter++, ext, data: new Uint8Array(raw) }); + }, collectImages3 = function(node) { + if (node.tag === "para") { + for (const img of flatImgNodes(node.kids)) registerImg2(img); + } else if (node.tag === "grid") { + for (const row of node.kids) + for (const cell of row.kids) + for (const para of cell.kids) collectImages3(para); + } + }; + var registerImg = registerImg2, collectImages2 = collectImages3; + const bank = new HwpStyleBank(); + for (const sheet of doc.kids) { + for (const node of sheet.kids) collectNode(node, bank); + } + const images = []; + const seenB64 = /* @__PURE__ */ new Set(); + let binIdCounter = 1; + for (const sheet of doc.kids) { + for (const node of sheet.kids) collectImages3(node); + } + const docInfoRaw = buildDocInfoStream(bank, images); + const bodyRaw = buildBodyTextStream(doc, bank, images); + const docInfoCmp = import_pako3.default.deflateRaw(docInfoRaw); + const bodyCmp = import_pako3.default.deflateRaw(bodyRaw); + const fileHdr = buildHwpFileHeader(); + if (fileHdr.length !== 256) { + return fail( + `HwpEncoder: FileHeader \uD06C\uAE30 \uC624\uB958 - ${fileHdr.length} bytes (\uAE30\uB300: 256 bytes)` + ); + } + const hwp = buildHwpOle2(fileHdr, docInfoCmp, bodyCmp, images); + if (!validateOle2Magic(hwp)) { + return fail("HwpEncoder: OLE2 \uB9E4\uC9C1 \uBC14\uC774\uD2B8 \uC624\uB958"); + } + if (hwp.length < 512) { + return fail( + `HwpEncoder: HWP \uD30C\uC77C \uD06C\uAE30 \uBD80\uC871 - ${hwp.length} bytes (\uCD5C\uC18C 512 bytes)` + ); + } + return succeed(hwp); + } catch (e) { + return fail(`HwpEncoder: ${e instanceof Error ? e.message : String(e)}`); + } + } +}; +registry.registerEncoder(new HwpEncoder()); + +// src/pipeline/Pipeline.ts +var Pipeline = class _Pipeline { + constructor(raw, srcFmt) { + this.raw = raw; + this.srcFmt = srcFmt; + } + /** 파일을 열고 포맷을 자동 감지하거나 명시 */ + static open(input, fmt) { + if (typeof input === "string") { + return new _Pipeline(new TextEncoder().encode(input), fmt ?? "md"); + } + return new _Pipeline(input, fmt ?? detectFormat(input)); + } + /** File/Blob 비동기 입력 */ + static async openAsync(input, fmt) { + if (input instanceof Uint8Array || typeof input === "string") { + return _Pipeline.open(input, fmt); + } + const buf = await input.arrayBuffer(); + const data = new Uint8Array(buf); + const detectedFmt = fmt ?? (input instanceof File ? getExt(input.name) : void 0) ?? detectFormat(data); + return new _Pipeline(data, detectedFmt); + } + /** 목표 포맷으로 변환 */ + async to(targetFmt, options) { + const decoder = registry.getDecoder(this.srcFmt); + const encoder = registry.getEncoder(targetFmt); + if (!decoder) return fail(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC785\uB825 \uD3EC\uB9F7: ${this.srcFmt}`); + if (!encoder) return fail(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uCD9C\uB825 \uD3EC\uB9F7: ${targetFmt}`); + const docResult = await decoder.decode(this.raw); + if (!docResult.ok) return docResult; + const encResult = await encoder.encode(docResult.data, options); + if (!encResult.ok) return { ...encResult, warns: [...docResult.warns, ...encResult.warns] }; + return { ...encResult, warns: [...docResult.warns, ...encResult.warns] }; + } + /** DocRoot만 추출 (인코딩 없이) */ + async inspect() { + const decoder = registry.getDecoder(this.srcFmt); + if (!decoder) return fail(`\uB514\uCF54\uB354 \uC5C6\uC74C: ${this.srcFmt}`); + return decoder.decode(this.raw); + } +}; +function detectFormat(data) { + if (data[0] === 208 && data[1] === 207 && data[2] === 17 && data[3] === 224) return "hwp"; + if (data[0] === 80 && data[1] === 75) { + const str = new TextDecoder("utf-8", { fatal: false }).decode(data.slice(0, 4096)); + if (str.includes("wordprocessingml")) return "docx"; + if (str.includes("ha-xml")) return "hwpx"; + if (str.includes("hwpml/")) return "hwpx"; + if (str.includes("word/")) return "docx"; + return "hwpx"; + } + return "md"; +} +function getExt(name) { + const parts = name.split("."); + return parts.length> 1 ? parts[parts.length - 1].toLowerCase() : void 0; +} + +// src/walk/TreeWalker.ts +function walkNode(node, cb, parent = null, depth = 0) { + const result = cb(node, parent, depth); + if (result === "stop") return false; + if ("kids" in node && Array.isArray(node.kids)) { + for (const kid of node.kids) { + if (!walkNode(kid, cb, node, depth + 1)) return false; + } + } + return true; +} +var TreeWalker = class { + walk(root, cb) { + walkNode(root, cb); + } + findAll(root, predicate) { + const results = []; + walkNode(root, (n) => { + if (predicate(n)) results.push(n); + }); + return results; + } + extractText(root) { + const parts = []; + walkNode(root, (n) => { + if (n.tag === "txt") parts.push(n.content); + if (n.tag === "br") parts.push("\n"); + if (n.tag === "pb") parts.push("\n\n"); + }); + return parts.join(""); + } +}; + +// src/walk/tree-ops.ts +function countNodes(root) { + const counts = {}; + walkNode(root, (n) => { + counts[n.tag] = (counts[n.tag] ?? 0) + 1; + }); + return counts; +} +function validateRoot(root) { + const errors = []; + if (root.tag !== "root") errors.push('Root node must have tag "root"'); + if (!Array.isArray(root.kids)) errors.push("Root.kids must be an array"); + if (root.kids.length === 0) errors.push("Document has no sheets"); + walkNode(root, (n) => { + if (n.tag === "cell" && n.kids.length === 0) { + errors.push("CellNode must have at least one ParaNode child"); + } + if (n.tag === "grid" && n.kids.length === 0) { + errors.push("GridNode must have at least one RowNode"); + } + }); + return errors; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + A4, + A4_LANDSCAPE, + ArchiveKit, + BinaryKit, + DEFAULT_STROKE, + Metric, + Pipeline, + ShieldedParser, + TextKit, + TreeWalker, + XmlKit, + buildBr, + buildCell, + buildGrid, + buildImg, + buildPageNum, + buildPara, + buildPb, + buildRoot, + buildRow, + buildSheet, + buildSpan, + countNodes, + fail, + normalizeDims, + registry, + safeAlign, + safeFont, + safeFontToKr, + safeHex, + safeStrokeDocx, + safeStrokeHwpx, + succeed, + validateRoot, + walkNode +}); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/hwpkit-extension/index.js.map b/hwpkit-extension/index.js.map new file mode 100644 index 000000000..194725174 --- /dev/null +++ b/hwpkit-extension/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/index.ts","../src/contract/result.ts","../src/pipeline/registry.ts","../src/model/doc-props.ts","../src/model/builders.ts","../src/safety/ShieldedParser.ts","../src/safety/StyleBridge.ts","../src/toolkit/ArchiveKit.ts","../src/toolkit/XmlKit.ts","../src/toolkit/TextKit.ts","../src/core/BaseDecoder.ts","../src/encoders/hwpx/constants.ts","../src/decoders/hwpx/HwpxDecoder.ts","../src/toolkit/BinaryKit.ts","../src/decoders/hwp/HwpScanner.ts","../src/decoders/docx/DocxDecoder.ts","../src/decoders/md/MdDecoder.ts","../src/decoders/html/HtmlDecoder.ts","../src/core/BaseEncoder.ts","../src/encoders/hwpx/HwpxEncoder.ts","../src/encoders/docx/DocxEncoder.ts","../src/encoders/md/MdEncoder.ts","../src/encoders/html/HtmlEncoder.ts","../src/encoders/hwp/HwpEncoder.ts","../src/pipeline/Pipeline.ts","../src/walk/TreeWalker.ts","../src/walk/tree-ops.ts"],"sourcesContent":["// ─── 공개 API ───────────────────────────────────────────────\n\n// Pipeline\nexport { Pipeline } from './pipeline/Pipeline';\nexport { registry } from './pipeline/registry';\n\n// Side-effect imports: register all decoders/encoders\nimport './decoders/md/MdDecoder';\nimport './decoders/hwpx/HwpxDecoder';\nimport './decoders/docx/DocxDecoder';\nimport './decoders/hwp/HwpScanner';\nimport './encoders/md/MdEncoder';\nimport './encoders/html/HtmlEncoder';\nimport './encoders/hwpx/HwpxEncoder';\nimport './encoders/docx/DocxEncoder';\nimport './encoders/hwp/HwpEncoder';\n\n// Model\nexport type {\n DocRoot, SheetNode, ParaNode, SpanNode, GridNode, RowNode, CellNode,\n ImgNode, LinkNode, TxtNode, BrNode, PbNode, PageNumNode, ContentNode, AnyNode, BlockTag,\n} from './model/doc-tree';\nexport type {\n TextProps, ParaProps, CellProps, GridProps, TableLook, PageDims, DocMeta,\n Align, VAlign, Heading, StrokeKind, Stroke,\n} from './model/doc-props';\nexport { A4, A4_LANDSCAPE, DEFAULT_STROKE, normalizeDims } from './model/doc-props';\nexport { buildRoot, buildSheet, buildPara, buildSpan, buildImg, buildGrid, buildRow, buildCell, buildPageNum, buildBr, buildPb } from './model/builders';\n\n// Contract\nexport type { Decoder } from './contract/decoder';\nexport type { Encoder } from './contract/encoder';\nexport type { Outcome, Ok, Fail } from './contract/result';\nexport { succeed, fail } from './contract/result';\n\n// Safety\nexport { ShieldedParser } from './safety/ShieldedParser';\nexport { Metric, safeHex, safeAlign, safeFont, safeFontToKr, safeStrokeHwpx, safeStrokeDocx } from './safety/StyleBridge';\n\n// Walk\nexport { TreeWalker, walkNode } from './walk/TreeWalker';\nexport { countNodes, validateRoot } from './walk/tree-ops';\n\n// Toolkit\nexport { XmlKit } from './toolkit/XmlKit';\nexport { ArchiveKit } from './toolkit/ArchiveKit';\nexport { BinaryKit } from './toolkit/BinaryKit';\nexport { TextKit } from './toolkit/TextKit';\n","export type Outcome = Ok | Fail;\n\nexport interface Ok {\n ok: true;\n data: T;\n warns: string[];\n}\n\nexport interface Fail {\n ok: false;\n error: string;\n warns: string[];\n}\n\nexport function succeed(data: T, warns: string[] = []): Ok {\n return { ok: true, data, warns };\n}\n\nexport function fail(error: string, warns: string[] = []): Fail {\n return { ok: false, error, warns };\n}\n","import type { Decoder } from '../contract/decoder';\nimport type { Encoder } from '../contract/encoder';\n\nclass FormatRegistry {\n private decoders = new Map();\n private encoders = new Map();\n\n registerDecoder(d: Decoder): void {\n this.decoders.set(d.format, d);\n if (d.aliases) {\n for (const alias of d.aliases) this.decoders.set(alias, d);\n }\n }\n\n registerEncoder(e: Encoder): void {\n this.encoders.set(e.format, e);\n if (e.aliases) {\n for (const alias of e.aliases) this.encoders.set(alias, e);\n }\n }\n\n getDecoder(fmt: string): Decoder | undefined { return this.decoders.get(fmt); }\n getEncoder(fmt: string): Encoder | undefined { return this.encoders.get(fmt); }\n\n supportedInputs(): string[] { return [...this.decoders.keys()]; }\n supportedOutputs(): string[] { return [...this.encoders.keys()]; }\n}\n\nexport const registry = new FormatRegistry();\n","export type Align = 'left' | 'center' | 'right' | 'justify';\n\n// ─── 이미지 배치 ────────────────────────────────────────────\nexport type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front' | 'topAndBottom';\nexport type ImgHorzAlign = 'left' | 'center' | 'right';\nexport type ImgVertAlign = 'top' | 'center' | 'bottom';\nexport type ImgHorzRelTo = 'margin' | 'column' | 'page' | 'para';\nexport type ImgVertRelTo = 'margin' | 'line' | 'page' | 'para';\n\nexport interface ImgLayout {\n wrap: ImgWrap;\n horzAlign?: ImgHorzAlign; // 정렬 기준 (xPt 없을 때)\n vertAlign?: ImgVertAlign; // 정렬 기준 (yPt 없을 때)\n horzRelTo?: ImgHorzRelTo; // 가로 기준점\n vertRelTo?: ImgVertRelTo; // 세로 기준점\n xPt?: number; // 명시적 가로 오프셋 (pt)\n yPt?: number; // 명시적 세로 오프셋 (pt)\n distT?: number; // 텍스트와의 거리 top (pt)\n distB?: number;\n distL?: number;\n distR?: number;\n behindDoc?: boolean; // 텍스트 뒤에 배치\n zOrder?: number;\n}\nexport type VAlign = 'top' | 'mid' | 'bot';\nexport type Heading = 1 | 2 | 3 | 4 | 5 | 6;\nexport type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none' | 'dashDot' | 'dashDotDot' | 'wave';\n\nexport interface TextProps {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n sup?: boolean;\n sub?: boolean;\n font?: string;\n pt?: number;\n color?: string;\n bg?: string;\n}\n\nexport interface ParaProps {\n align?: Align;\n heading?: Heading;\n styleId?: string; // DOCX pStyle styleId (e.g. \"Heading1\", \"TOC1\")\n indentPt?: number; // 문단 왼쪽 전체 들여쓰기 (pt) — OWPML hc:left\n indentRightPt?: number; // 문단 오른쪽 전체 들여쓰기 (pt) — OWPML hc:right\n firstLineIndentPt?: number; // 첫 줄 들여쓰기 (pt, 음수=내어쓰기) — OWPML hc:indent\n leftMargin?: number; // 문단 왼쪽 여백 (HWP leftMargin, pt)\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number; // 줄 간격 배율 (예: 1.5 = 150%)\n lineHeightFixed?: number; // 고정 줄 높이 (pt) — OWPML lineSpacing type=\"FIXED\"\n listLv?: number;\n listOrd?: boolean;\n listMark?: string;\n}\n\nexport interface Stroke {\n kind: StrokeKind;\n pt: number;\n color: string;\n}\n\nexport interface CellProps {\n top?: Stroke;\n bot?: Stroke;\n left?: Stroke;\n right?: Stroke;\n bg?: string;\n padPt?: number; // 모든 방향 균일 패딩 (하위 호환)\n padT?: number; // 상단 패딩 (pt)\n padB?: number; // 하단 패딩\n padL?: number; // 좌측 패딩\n padR?: number; // 우측 패딩\n align?: Align;\n va?: VAlign;\n isHeader?: boolean;\n}\n\nexport interface TableLook {\n firstRow?: boolean;\n lastRow?: boolean;\n firstCol?: boolean;\n lastCol?: boolean;\n bandedRows?: boolean;\n bandedCols?: boolean;\n}\n\nexport interface GridProps {\n widthPct?: number;\n colWidths?: number[]; // column widths in points\n defaultStroke?: Stroke;\n look?: TableLook;\n headerRow?: boolean;\n align?: Align; // 표 정렬: 'left' | 'center' | 'right' | 'justify'\n}\n\nexport interface PageDims {\n wPt: number;\n hPt: number;\n mt: number;\n mb: number;\n ml: number;\n mr: number;\n orient?: 'portrait' | 'landscape';\n headerPt?: number; // distance from paper top to header top (DOCX w:header)\n footerPt?: number; // distance from paper bottom to footer bottom (DOCX w:footer)\n}\n\nexport interface DocMeta {\n title?: string;\n author?: string;\n subject?: string;\n desc?: string;\n keywords?: string;\n created?: string;\n modified?: string;\n zoom?: number;\n viewMode?: string;\n}\n\nexport const A4: PageDims = {\n wPt: 595.28, hPt: 841.89,\n mt: 56.69, mb: 56.69, ml: 70.87, mr: 70.87,\n orient: 'portrait',\n};\n\nexport const A4_LANDSCAPE: PageDims = {\n wPt: 841.89, hPt: 595.28,\n mt: 56.69, mb: 56.69, ml: 70.87, mr: 70.87,\n orient: 'landscape',\n};\n\n/**\n * orient === 'landscape'일 때 wPt < hPt이면 swap,\n * orient === 'portrait'일 때 wPt> hPt이면 swap하여\n * 방향과 치수가 항상 일치하도록 정규화합니다.\n */\n\nexport function normalizeDims(dims: PageDims): PageDims {\n const orient = dims.orient ?? 'portrait';\n if (orient === 'landscape' && dims.wPt < dims.hPt) {\n return { ...dims, wPt: dims.hPt, hPt: dims.wPt };\n }\n if (orient === 'portrait' && dims.wPt> dims.hPt) {\n return { ...dims, wPt: dims.hPt, hPt: dims.wPt };\n }\n return dims;\n}\n\nexport const DEFAULT_STROKE: Stroke = { kind: 'solid', pt: 0.5, color: '000000' };\n","import type {\n DocRoot, SheetNode, ParaNode, SpanNode, ImgNode,\n GridNode, RowNode, CellNode, ContentNode, TxtNode, PageNumNode, BrNode, PbNode,\n} from './doc-tree';\nimport type { TextProps, ParaProps, CellProps, GridProps, DocMeta, PageDims, ImgLayout } from './doc-props';\nimport { A4 } from './doc-props';\n\nexport function buildRoot(meta: DocMeta = {}, kids: SheetNode[] = []): DocRoot {\n return { tag: 'root', meta, kids };\n}\n\nexport function buildSheet(\n kids: ContentNode[] = [],\n dims: PageDims = A4,\n opts?: { headers?: SheetNode[\"headers\"]; footers?: SheetNode[\"footers\"] },\n): SheetNode {\n const node: SheetNode = { tag: 'sheet', dims, kids };\n if (opts?.headers) node.headers = opts.headers;\n if (opts?.footers) node.footers = opts.footers;\n return node;\n}\n\nexport function buildPageNum(format?: PageNumNode['format']): PageNumNode {\n return { tag: 'pagenum', format };\n}\n\nexport function buildBr(): BrNode { return { tag: 'br' }; }\nexport function buildPb(): PbNode { return { tag: 'pb' }; }\n\nexport function buildPara(kids: ParaNode['kids'] = [], props: ParaProps = {}): ParaNode {\n return { tag: 'para', props, kids };\n}\n\nexport function buildSpan(content: string, props: TextProps = {}): SpanNode {\n const txt: TxtNode = { tag: 'txt', content };\n return { tag: 'span', props, kids: [txt] };\n}\n\nexport function buildImg(\n b64: string,\n mime: ImgNode['mime'],\n w: number,\n h: number,\n alt?: string,\n layout?: ImgLayout,\n): ImgNode {\n const node: ImgNode = { tag: 'img', b64, mime, w, h };\n if (alt) node.alt = alt;\n if (layout) node.layout = layout;\n return node;\n}\n\nexport function buildGrid(kids: RowNode[], props: GridProps = {}): GridNode {\n return { tag: 'grid', props, kids };\n}\n\nexport function buildRow(kids: CellNode[], heightPt?: number): RowNode {\n const node: RowNode = { tag: 'row', kids };\n if (heightPt != null) node.heightPt = heightPt;\n return node;\n}\n\nexport function buildCell(\n kids: (ParaNode | GridNode)[],\n opts: { cs?: number; rs?: number; props?: CellProps } = {},\n): CellNode {\n return { tag: 'cell', cs: opts.cs ?? 1, rs: opts.rs ?? 1, props: opts.props ?? {}, kids };\n}\n","export class ShieldedParser {\n private log: string[] = [];\n\n /** 단일 요소 안전 파싱 */\n guard(fn: () => T, fallback: T, label: string): T {\n try {\n const v = fn();\n if (v == null) {\n this.warn(label, 'returned null/undefined');\n return fallback;\n }\n return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n return fallback;\n }\n }\n\n /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */\n guardAll(\n items: I[],\n fn: (x: I, i: number) => O,\n fb: (x: I, i: number) => O,\n label: string,\n ): O[] {\n return items.map((x, i) =>\n this.guard(() => fn(x, i), fb(x, i), `${label}[${i}]`),\n );\n }\n\n /**\n * 표 전용 4단계 폴백\n * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text\n */\n guardGrid(\n node: unknown,\n lv1Full: (n: unknown) => T,\n lv2Grid: (n: unknown) => T,\n lv3Flat: (n: unknown) => T,\n lv4Text: (n: unknown) => T,\n label: string,\n ): { value: T; level: 1 | 2 | 3 | 4 } {\n const levels: [(n: unknown) => T, 1 | 2 | 3 | 4][] = [\n [lv1Full, 1], [lv2Grid, 2], [lv3Flat, 3], [lv4Text, 4],\n ];\n\n for (const [fn, lv] of levels) {\n try {\n const v = fn(node);\n if (v != null) {\n if (lv> 1) this.warn(label, `degraded to level ${lv}`);\n return { value: v, level: lv };\n }\n } catch (e: any) {\n this.warn(label, `Lv${lv} failed: ${e?.message ?? String(e)}`);\n }\n }\n\n this.warn(label, 'ALL LEVELS FAILED — returning lv4Text forced');\n return { value: lv4Text(null), level: 4 };\n }\n\n /** 이미지 안전 파싱 */\n guardImg(\n node: unknown,\n fn: (n: unknown) => T,\n placeholder: (alt: string) => T,\n label: string,\n ): T {\n try {\n const v = fn(node);\n if (v != null) return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n }\n this.warn(label, 'using placeholder image');\n return placeholder(`[이미지 로드 실패: ${label}]`);\n }\n\n private warn(label: string, msg: string): void {\n const w = `[SHIELD] ${label}: ${msg}`;\n console.warn(w);\n this.log.push(w);\n }\n\n flush(): string[] {\n const r = [...this.log];\n this.log = [];\n return r;\n }\n}\n","import type { Align, StrokeKind, Stroke } from '../model/doc-props';\n\n// ─── 단위 변환 ─────────────────────────────────────────────\nexport const Metric = {\n // HWP 세계 (1 inch = 7200 HWPUNIT)\n hwpToPt: (v: number) => v / 100,\n ptToHwp: (v: number) => Math.round(v * 100),\n hwpToDxa: (v: number) => Math.round(v / 5),\n dxaToHwp: (v: number) => Math.round(v * 5),\n hwpToEmu: (v: number) => Math.round(v * 127),\n emuToHwp: (v: number) => Math.round(v / 127),\n\n // DOCX 세계 (1 inch = 1440 dxa, 1 pt = 20 dxa)\n dxaToPt: (v: number) => v / 20,\n ptToDxa: (v: number) => Math.round(v * 20),\n dxaToEmu: (v: number) => Math.round(v * 635),\n emuToDxa: (v: number) => Math.round(v / 635),\n emuToPt: (v: number) => v / 12700,\n ptToEmu: (v: number) => Math.round(v * 12700),\n\n // HWPX charPr height: 1000 = 10pt\n hHeightToPt: (v: number) => v / 100,\n ptToHHeight: (v: number) => Math.round(v * 100),\n\n // DOCX half-point: 24 = 12pt\n halfPtToPt: (v: number) => v / 2,\n ptToHalfPt: (v: number) => Math.round(v * 2),\n} as const;\n\n// ─── 색상 정규화 ───────────────────────────────────────────\nexport function safeHex(raw: string | number | null | undefined): string | undefined {\n if (raw == null) return undefined;\n if (typeof raw === 'number') {\n if (raw <= 0) return '000000';\n if (raw>= 0xFFFFFF) return undefined;\n return raw.toString(16).padStart(6, '0').toUpperCase();\n }\n let s = String(raw).replace(/^#/, '').toUpperCase();\n if (/^[0-9A-F]{3}$/.test(s)) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2];\n if (/^[0-9A-F]{6}$/.test(s)) return s;\n if (s === 'AUTO' || s === 'NONE' || s === 'TRANSPARENT') return undefined;\n return undefined;\n}\n\n// ─── 정렬 정규화 ───────────────────────────────────────────\nconst ALIGN_MAP: Record = {\n LEFT: 'left', CENTER: 'center', RIGHT: 'right', JUSTIFY: 'justify',\n BOTH: 'justify', DISTRIBUTE: 'justify',\n left: 'left', center: 'center', right: 'right', both: 'justify',\n start: 'left', end: 'right',\n};\nexport function safeAlign(raw?: string): Align {\n return ALIGN_MAP[raw ?? ''] ?? 'left';\n}\n\n// ─── 테두리 정규화 ─────────────────────────────────────────\nconst HWPX_STROKE: Record = {\n SOLID: \"solid\",\n NONE: \"none\",\n DASH: \"dash\",\n DOT: \"dot\",\n DOUBLE: \"double\",\n LONG_DASH: \"dash\",\n DASH_DOT: \"dashDot\",\n DASH_DOT_DOT: \"dashDotDot\",\n THICK_THIN: \"double\",\n THIN_THICK: \"double\",\n TRIPLE: \"double\",\n};\nconst DOCX_STROKE: Record = {\n single: \"solid\",\n none: \"none\",\n nil: \"none\",\n dashed: \"dash\",\n dotted: \"dot\",\n double: \"double\",\n dotDash: \"dashDot\",\n dotDotDash: \"dashDotDot\",\n thickThin: \"double\",\n thinThick: \"double\",\n triple: \"double\",\n wave: \"wave\",\n dashDotStroked: \"dashDot\",\n threeDEmboss: \"solid\",\n threeDEngrave: \"solid\",\n};\n\nexport function safeStrokeHwpx(type?: string, w?: number, c?: string): Stroke {\n return {\n kind: HWPX_STROKE[type ?? ''] ?? 'solid',\n pt: w != null ? Metric.hwpToPt(w) : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\nexport function safeStrokeDocx(val?: string, sz?: number, c?: string): Stroke {\n return {\n kind: DOCX_STROKE[val ?? ''] ?? 'solid',\n pt: sz != null ? sz / 8 : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\n// ─── 폰트 정규화 ───────────────────────────────────────────\nconst FONT_MAP: Record = {\n // 맑은 고딕 계열\n '맑은 고딕': 'Malgun Gothic',\n '맑은고딕': 'Malgun Gothic',\n // 바탕 계열 (serif)\n '바탕': 'Batang',\n '바탕체': 'BatangChe',\n '한컴바탕': 'Batang',\n '함초롬바탕': 'Batang',\n 'HY신명조': 'Batang',\n 'HY견명조': 'Batang',\n 'HY그래픽': 'Batang',\n '궁서': 'Gungsuh',\n '궁서체': 'GungsuhChe',\n // 고딕 계열 (sans-serif)\n '돋움': 'Dotum',\n '돋움체': 'DotumChe',\n '굴림': 'Gulim',\n '굴림체': 'GulimChe',\n '한컴돋움': 'Malgun Gothic',\n '함초롬돋움': 'Malgun Gothic',\n 'HY견고딕': 'Malgun Gothic',\n 'HY중고딕': 'Malgun Gothic',\n 'HY헤드라인M': 'Malgun Gothic',\n 'HY강B': 'Malgun Gothic',\n 'HY나무M': 'Malgun Gothic',\n 'HY목각파임B': 'Malgun Gothic',\n 'HY엽서M': 'Malgun Gothic',\n 'HY엽서L': 'Malgun Gothic',\n // 나눔 계열\n '나눔고딕': 'Malgun Gothic',\n '나눔명조': 'Batang',\n};\nexport function safeFont(raw?: string): string {\n return FONT_MAP[raw ?? ''] ?? raw ?? 'Malgun Gothic';\n}\n\n// Reverse mapping: English → Korean (for HWPX encoding)\nconst FONT_MAP_KR: Record = {\n 'Malgun Gothic': '맑은 고딕',\n 'Batang': '바탕',\n 'Dotum': '돋움',\n 'Gulim': '굴림',\n};\nexport function safeFontToKr(raw?: string): string {\n return FONT_MAP_KR[raw ?? ''] ?? raw ?? '맑은 고딕';\n}\n","import pako from 'pako';\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nexport const ArchiveKit = {\n async inflate(compressed: Uint8Array): Promise {\n return pako.inflate(compressed);\n },\n\n async deflate(data: Uint8Array): Promise {\n return pako.deflate(data, { level: 6 });\n },\n\n async unzip(zipData: Uint8Array): Promise
        > {\n const files = new Map();\n const view = new DataView(zipData.buffer, zipData.byteOffset, zipData.byteLength);\n\n // Find EOCD by scanning backward from end (supports ZIP comment up to 64KB)\n let eocdOffset = -1;\n const searchStart = Math.max(0, zipData.length - 65558);\n for (let i = zipData.length - 22; i>= searchStart; i--) {\n if (view.getUint32(i, true) === 0x06054b50) {\n eocdOffset = i;\n break;\n }\n }\n\n if (eocdOffset !== -1) {\n // Parse central directory — always has correct sizes even with data descriptors\n const entryCount = view.getUint16(eocdOffset + 10, true);\n const centralDirOffset = view.getUint32(eocdOffset + 16, true);\n\n let cdOffset = centralDirOffset;\n for (let i = 0; i < entryCount; i++) {\n if (cdOffset + 46> zipData.length) break;\n if (view.getUint32(cdOffset, true) !== 0x02014b50) break;\n\n const compressionMethod = view.getUint16(cdOffset + 10, true);\n const compressedSize = view.getUint32(cdOffset + 20, true);\n const uncompressedSize = view.getUint32(cdOffset + 24, true);\n const fileNameLength = view.getUint16(cdOffset + 28, true);\n const extraLength = view.getUint16(cdOffset + 30, true);\n const commentLength = view.getUint16(cdOffset + 32, true);\n const localHeaderOffset = view.getUint32(cdOffset + 42, true);\n\n const nameBytes = zipData.subarray(cdOffset + 46, cdOffset + 46 + fileNameLength);\n const name = new TextDecoder('utf-8').decode(nameBytes);\n cdOffset += 46 + fileNameLength + extraLength + commentLength;\n\n if (name.endsWith('/')) continue; // directory entry\n\n // Read actual data using the local header offset from central directory\n const localFnLen = view.getUint16(localHeaderOffset + 26, true);\n const localExtraLen = view.getUint16(localHeaderOffset + 28, true);\n const dataOffset = localHeaderOffset + 30 + localFnLen + localExtraLen;\n\n let fileData: Uint8Array;\n if (compressionMethod === 0) {\n fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize);\n } else if (compressionMethod === 8) {\n const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize);\n fileData = pako.inflateRaw(compressed);\n } else {\n throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`);\n }\n\n files.set(name, new Uint8Array(fileData));\n }\n\n return files;\n }\n\n // Fallback: scan local headers sequentially (no EOCD found — truncated ZIP)\n let offset = 0;\n while (offset < zipData.length - 4) {\n const sig = view.getUint32(offset, true);\n\n if (sig === 0x04034b50) {\n const compressionMethod = view.getUint16(offset + 8, true);\n const compressedSize = view.getUint32(offset + 18, true);\n const uncompressedSize = view.getUint32(offset + 22, true);\n const fileNameLength = view.getUint16(offset + 26, true);\n const extraLength = view.getUint16(offset + 28, true);\n\n const nameBytes = zipData.subarray(offset + 30, offset + 30 + fileNameLength);\n const name = new TextDecoder('utf-8').decode(nameBytes);\n\n const dataOffset = offset + 30 + fileNameLength + extraLength;\n let fileData: Uint8Array;\n\n if (compressionMethod === 0) {\n fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize);\n } else if (compressionMethod === 8) {\n const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize);\n fileData = pako.inflateRaw(compressed);\n } else {\n throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`);\n }\n\n files.set(name, new Uint8Array(fileData));\n offset = dataOffset + compressedSize;\n } else if (sig === 0x02014b50 || sig === 0x06054b50) {\n break;\n } else {\n offset++;\n }\n }\n\n return files;\n },\n\n async zip(entries: ZipEntry[]): Promise {\n const localHeaders: Uint8Array[] = [];\n const centralHeaders: Uint8Array[] = [];\n let localOffset = 0;\n\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n const crc = crc32(entry.data);\n\n // 'mimetype' and 'version.xml' must be stored uncompressed per HWPX spec\n const store = entry.name === 'mimetype' || entry.name === 'version.xml';\n const method = store ? 0 : 8;\n const payload = store ? entry.data : pako.deflateRaw(entry.data, { level: 6 });\n\n // Local file header (30 bytes + name + data)\n const local = new Uint8Array(30 + nameBytes.length + payload.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0, true);\n lv.setUint16(8, method, true);\n lv.setUint16(10, 0, true);\n lv.setUint16(12, 0x0021, true); // date (1980年01月01日)\n lv.setUint32(14, crc, true);\n lv.setUint32(18, payload.length, true);\n lv.setUint32(22, entry.data.length, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n local.set(payload, 30 + nameBytes.length);\n\n // Central directory header (46 bytes + name)\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0, true);\n cv.setUint16(10, method, true);\n cv.setUint16(12, 0, true); // mod time\n cv.setUint16(14, 0x0021, true); // mod date (1980年01月01日)\n cv.setUint32(16, crc, true);\n cv.setUint32(20, payload.length, true);\n cv.setUint32(24, entry.data.length, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, localOffset, true);\n central.set(nameBytes, 46);\n\n localHeaders.push(local);\n centralHeaders.push(central);\n localOffset += local.length;\n }\n\n const centralDir = concat(centralHeaders);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDir.length, true);\n ev.setUint32(16, localOffset, true);\n ev.setUint16(20, 0, true);\n\n return concat([...localHeaders, centralDir, eocd]);\n },\n};\n\nfunction concat(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const a of arrays) { out.set(a, offset); offset += a.length; }\n return out;\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xFFFFFFFF;\n for (const byte of data) {\n crc ^= byte;\n for (let i = 0; i < 8; i++) {\n crc = (crc & 1) ? (crc>>> 1) ^ 0xEDB88320 : crc>>> 1;\n }\n }\n return (crc ^ 0xFFFFFFFF)>>> 0;\n}\n","import { SaxesParser } from 'saxes';\n\n// Parses XML into an xml2js-compatible object structure:\n// { tagName: [{ _attr: { k: v }, _text: '...', childTag: [...] }] }\nfunction parseXmlStrict(xml: string): Promise {\n return new Promise((resolve, reject) => {\n const parser = new SaxesParser({ xmlns: false });\n\n interface Frame { tag: string; obj: Record }\n const stack: Frame[] = [];\n let result: unknown = null;\n\n parser.on('error', (err: Error) => reject(err));\n\n parser.on('opentag', (node: any) => {\n const obj: Record = {};\n const attrs = node.attributes as Record;\n if (attrs && Object.keys(attrs).length> 0) {\n obj['_attr'] = { ...attrs };\n }\n stack.push({ tag: node.name as string, obj });\n });\n\n const appendText = (text: string) => {\n if (stack.length> 0 && text) {\n const frame = stack[stack.length - 1];\n const cur = frame.obj['_text'];\n frame.obj['_text'] = typeof cur === 'string' ? cur + text : text;\n }\n };\n\n parser.on('text', (text: string) => appendText(text));\n parser.on('cdata', (cdata: string) => appendText(cdata));\n\n parser.on('closetag', () => {\n const frame = stack.pop();\n if (!frame) return;\n const { tag, obj } = frame;\n\n if (stack.length === 0) {\n result = { [tag]: [obj] };\n } else {\n const parent = stack[stack.length - 1].obj;\n const existing = parent[tag];\n if (Array.isArray(existing)) {\n (existing as unknown[]).push(obj);\n } else {\n parent[tag] = [obj];\n }\n // Track child order for document-order iteration\n if (!parent['_childOrder']) parent['_childOrder'] = [];\n (parent['_childOrder'] as string[]).push(tag);\n }\n });\n\n try {\n parser.write(xml).close();\n resolve(result);\n } catch (e) {\n reject(e);\n }\n });\n}\n\nexport const XmlKit = {\n /** @deprecated Use parseStrict instead */\n async parse(xml: string): Promise {\n return parseXmlStrict(xml);\n },\n\n async parseStrict(xml: string): Promise {\n return parseXmlStrict(xml);\n },\n\n attr(node: Record, key: string): string | undefined {\n const a = node['_attr'] as Record | undefined;\n return a?.[key];\n },\n\n text(node: Record | string | undefined): string {\n if (node == null) return '';\n if (typeof node === 'string') return node;\n const t = node['_text'];\n return typeof t === 'string' ? t : '';\n },\n};\n","export const TextKit = {\n decode(data: Uint8Array, encoding = 'utf-8'): string {\n try {\n return new TextDecoder(encoding, { fatal: true }).decode(data);\n } catch {\n return new TextDecoder('utf-8', { fatal: false }).decode(data);\n }\n },\n\n encode(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n },\n\n escapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n },\n\n unescapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\");\n },\n\n normalizeWhitespace(s: string): string {\n return s.replace(/\\s+/g, ' ').trim();\n },\n\n stripControl(s: string): string {\n // eslint-disable-next-line no-control-regex\n return s.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n },\n\n base64Encode(data: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < data.length; i++) {\n binary += String.fromCharCode(data[i]);\n }\n return btoa(binary);\n },\n\n base64Decode(b64: string): Uint8Array {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n },\n};\n","/**\n * BaseDecoder - 모든 디코더의 기본 클래스\n *\n * 공통 로직을 제공하여 각 포맷별 디코더가 포맷 특유의 로직만 구현하도록 합니다.\n */\n\nimport type { Decoder } from '../contract/decoder';\nimport type { Outcome } from '../contract/result';\nimport type { DocRoot } from '../model/doc-tree';\nimport { TextKit } from '../toolkit/TextKit';\nimport { ArchiveKit } from '../toolkit/ArchiveKit';\n\n// ─── BaseDecoder ───────────────────────────────────\n\nexport abstract class BaseDecoder implements Decoder {\n readonly format: string = this.getFormat();\n readonly aliases: string[] = this.getAliases();\n\n /** 포맷 이름 반환 (하위 클래스에서 오버라이드) */\n protected abstract getFormat(): string;\n\n /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */\n protected getAliases(): string[] { return []; }\n\n /** 데이터 디코딩 (하위 클래스에서 오버라이드) */\n abstract decode(data: Uint8Array): Promise>;\n\n // ─── 공통 유틸리티 메서드 ──────────────────────────\n\n /** 바이트를 UTF-8 문자열로 변환 */\n protected bytesToString(data: Uint8Array): string {\n return TextKit.decode(data);\n }\n\n /** 문자열을 UTF-8 바이트로 변환 */\n protected stringToBytes(s: string): Uint8Array {\n return TextKit.encode(s);\n }\n\n /** XML 이스케이프 */\n protected escapeXml(s: string): string {\n return TextKit.escapeXml(s);\n }\n\n /** XML 언이스케이프 */\n protected unescapeXml(s: string): string {\n return TextKit.unescapeXml(s);\n }\n\n /** base64 문자열을 Uint8Array 로 변환 */\n protected base64ToBytes(b64: string): Uint8Array {\n return TextKit.base64Decode(b64);\n }\n\n /** Uint8Array 를 base64 문자열로 변환 */\n protected bytesToBase64(data: Uint8Array): string {\n return TextKit.base64Encode(data);\n }\n\n /** ZIP 해제 */\n protected async unzip(data: Uint8Array): Promise
          > {\n return ArchiveKit.unzip(data);\n }\n\n /** ZIP 압축 */\n protected async zip(entries: { name: string; data: Uint8Array }[]): Promise {\n return ArchiveKit.zip(entries);\n }\n\n /** inflate 해제 */\n protected async inflate(data: Uint8Array): Promise {\n return ArchiveKit.inflate(data);\n }\n\n /** deflate 압축 */\n protected async deflate(data: Uint8Array): Promise {\n return ArchiveKit.deflate(data);\n }\n\n /** 제어 문자 제거 */\n protected stripControl(s: string): string {\n return TextKit.stripControl(s);\n }\n\n /** 공백 정규화 */\n protected normalizeWhitespace(s: string): string {\n return TextKit.normalizeWhitespace(s);\n }\n\n /** XML 파싱 (DOMParser 사용) */\n protected parseXml(xmlString: string): Document {\n const parser = new DOMParser();\n return parser.parseFromString(xmlString, 'text/xml');\n }\n\n /** XML 요소에서 텍스트 내용 추출 */\n protected getTextContent(element: Element | null | undefined): string {\n if (!element) return '';\n return element.textContent ?? '';\n }\n\n /** XML 요소의 속성 값 추출 */\n protected getAttr(element: Element | null | undefined, name: string): string | null {\n return element?.getAttribute(name) ?? null;\n }\n\n /** XML 요소의 자식 요소 찾기 */\n protected getChild(element: Element | null | undefined, tagName: string): Element | null {\n if (!element) return null;\n return element.querySelector(`>${tagName}`) ?? null;\n }\n\n /** XML 요소의 모든 자식 요소 찾기 */\n protected getChildren(element: Element | null | undefined, tagName: string): Element[] {\n if (!element) return [];\n return Array.from(element.querySelectorAll(`>${tagName}`));\n }\n}\n","/**\n * HWPX 인코더 관련 상수\n *\n * HWPX 파일 생성에 필요한 모든 설정값을 한곳에 모아 관리합니다.\n * 초중급 개발자도 쉽게 수정할 수 있도록 명확한 주석을 포함했습니다.\n */\n\n// ==================== 파일 형식 관련 ====================\n\n/** HWPX 파일의 MIME 타입 (ZIP 파일 내 mimetype 파일에 저장됨) */\nexport const HWPX_MIME_TYPE = \"application/hwp+zip\";\n\n/** HWPX 파일의 버전 */\nexport const HWPX_VERSION = \"1.2\";\n\n// ==================== XML 네임스페이스 ====================\n\n/** HWPX XML 문서에서 사용되는 네임스페이스 */\nexport const NAMESPACES = {\n /** Hancom 문서 네임스페이스 */\n HANCOM: \"http://www.hancom.co.kr/hwp/xml\",\n /** Hancom 공통 네임스페이스 */\n HANCOM_COMMON: \"http://www.hancom.co.kr/hwp/xml/common\",\n /** Hancom 버전 네임스페이스 */\n HANCOM_VERSION: \"http://www.hancom.co.kr/hwp/xml/version\",\n /** Hancom 속성 네임스페이스 */\n HANCOM_PROP: \"http://www.hancom.co.kr/hwp/xml/property\",\n} as const;\n\n/** XML 헤더에 포함될 네임스페이스 선언 문자열 */\nexport const NAMESPACE_DECLARATIONS = {\n HEAD: `xmlns:hh=\"${NAMESPACES.HANCOM}\" xmlns:hc=\"${NAMESPACES.HANCOM_COMMON}\" xmlns:hv=\"${NAMESPACES.HANCOM_VERSION}\" xmlns:hp=\"${NAMESPACES.HANCOM_PROP}\"`,\n SECTION: `xmlns:hs=\"${NAMESPACES.HANCOM}\" xmlns:hp=\"${NAMESPACES.HANCOM_PROP}\"`,\n} as const;\n\n// ==================== 단위 변환 ====================\n\n/** 1 포인트 (pt) 를 HWPUNIT 으로 변환한 값 (HWPX 내부 단위) */\nexport const HWPUNIT_PER_PT = 1000;\n\n/** 1 인치 (inch) 를 포인트 (pt) 로 변환한 값 */\nexport const PT_PER_INCH = 72;\n\n/** 1 인치 (inch) 를 픽셀로 변환한 값 (표준 96 DPI 기준) */\nexport const PIXELS_PER_INCH = 96;\n\n/** 픽셀을 포인트로 변환하는 계수 */\nexport const PT_PER_PIXEL = PT_PER_INCH / PIXELS_PER_INCH; // 0.75\n\n// ==================== 페이지 크기 (A4 기준) ====================\n\n/** A4 용지 너비 (포인트) */\nexport const A4_WIDTH_PT = 794;\n\n/** A4 용지 높이 (포인트) */\nexport const A4_HEIGHT_PT = 1123;\n\n/** A4 용지 상단 여백 (포인트) */\nexport const A4_TOP_MARGIN_PT = 72;\n\n/** A4 용지 하단 여백 (포인트) */\nexport const A4_BOTTOM_MARGIN_PT = 72;\n\n/** A4 용지 왼쪽 여백 (포인트) */\nexport const A4_LEFT_MARGIN_PT = 83;\n\n/** A4 용지 오른쪽 여백 (포인트) */\nexport const A4_RIGHT_MARGIN_PT = 83;\n\n/** A4 용지 상단 머리글 영역 (포인트) */\nexport const A4_HEADER_MARGIN_PT = 40;\n\n/** A4 용지 하단 바닥글 영역 (포인트) */\nexport const A4_FOOTER_MARGIN_PT = 40;\n\n// ==================== 폰트 관련 ====================\n\n/** 기본 한글 폰트 */\nexport const DEFAULT_KOREAN_FONT = \"Batang\";\n\n/** 기본 영문 폰트 */\nexport const DEFAULT_LATIN_FONT = \"Arial\";\n\n/** 기본 폰트 크기 (포인트) */\nexport const DEFAULT_FONT_SIZE_PT = 10;\n\n// ==================== 줄 간격 ====================\n\n/** 기본 줄 간격 (폰트 크기의 %) */\nexport const DEFAULT_LINE_SPACING_PERCENT = 160;\n\n/** 최소 줄 간격 (HWPUNIT) */\nexport const MIN_LINE_SPACING_HWPUNIT = 1000;\n\n// ==================== 스타일 ID ====================\n\n/** 바탕글 스타일 ID */\nexport const STYLE_ID_BATANGGUL = \"0\";\n\n/** 개요 1 스타일 ID */\nexport const STYLE_ID_GYEYOE1 = \"1\";\n\n/** 개요 2 스타일 ID */\nexport const STYLE_ID_GYEYOE2 = \"2\";\n\n// ==================== 이미지 관련 ====================\n\n/** 이미지 파일이 저장될 디렉토리 경로 (ZIP 내) */\nexport const IMAGE_DIR_PATH = \"image/\";\n\n/** 이미지 파일명 접미사 */\nexport const IMAGE_FILE_EXTENSION = \".png\";\n\n// ==================== 테이블 관련 ====================\n\n/** 테이블 테두리 기본 두께 (HWPUNIT) */\nexport const TABLE_BORDER_WIDTH_HWPUNIT = 500; // 0.5pt\n\n/** 테이블 셀 기본 패딩 (HWPUNIT) */\nexport const TABLE_CELL_PADDING_HWPUNIT = 200; // 0.2pt\n\n// ==================== 색상 코드 ====================\n\n/** 검정색 (hex) */\nexport const COLOR_BLACK = \"#000000\";\n\n/** 흰색 (hex) */\nexport const COLOR_WHITE = \"#FFFFFF\";\n\n/** 회색 (워터마크용) */\nexport const COLOR_GRAY = \"#CCCCCC\";\n\n/** 코드 블록 배경색 */\nexport const COLOR_CODE_BLOCK_BG = \"#f4f4f4\";\n\n// ==================== ZIP 파일 구조 ====================\n\n/** HWPX 파일 내 파일 목록 */\nexport const HWPX_FILE_STRUCTURE = [\n { name: \"mimetype\", mimeType: \"\" },\n { name: \".hwpversions/version.xml\", mimeType: \"application/xml\" },\n { name: \"header.xml\", mimeType: \"application/xml\" },\n { name: \"section0.xml\", mimeType: \"application/xml\" },\n { name: \"content.hpf\", mimeType: \"application/octet-stream\" },\n] as const;\n\n/** ZIP 파일 생성 시 사용할 압축 레벨 (0=압축안함, 9=최대압축) */\nexport const ZIP_COMPRESSION_LEVEL = 9;\n","import type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n PageNumNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n DocMeta,\n PageDims,\n TextProps,\n ParaProps,\n CellProps,\n GridProps,\n Stroke,\n ImgLayout,\n ImgWrap,\n ImgHorzAlign,\n ImgVertAlign,\n ImgHorzRelTo,\n ImgVertRelTo,\n} from \"../../model/doc-props\";\nimport { A4 } from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport {\n buildRoot,\n buildSheet,\n buildPara,\n buildSpan,\n buildImg,\n buildGrid,\n buildRow,\n buildCell,\n buildPb,\n} from \"../../model/builders\";\nimport { ShieldedParser } from \"../../safety/ShieldedParser\";\nimport {\n Metric,\n safeAlign,\n safeFont,\n safeHex,\n safeStrokeHwpx,\n} from \"../../safety/StyleBridge\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { XmlKit } from \"../../toolkit/XmlKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\nimport { BaseDecoder } from \"../../core/BaseDecoder\";\nimport { HWPX_MIME_TYPE } from \"../../encoders/hwpx/constants\";\n\ninterface BorderFillInfo {\n stroke?: Stroke; // uniform fallback (used when all sides are the same)\n top?: Stroke;\n right?: Stroke;\n bottom?: Stroke;\n left?: Stroke;\n bgColor?: string;\n}\n\ninterface CharPrInfo {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n pt?: number;\n color?: string;\n font?: string;\n bg?: string;\n}\n\ninterface ParaPrInfo {\n align?: string;\n indentPt?: number; // hc:left → 문단 전체 왼쪽 여백\n indentRightPt?: number; // hc:right → 문단 전체 오른쪽 여백\n firstLineIndentPt?: number; // hc:indent → 첫 줄 들여쓰기 (양수=들여쓰기, 음수=내어쓰기)\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n lineHeightFixed?: number; // FIXED 행 높이 (pt)\n}\n\ninterface DecCtx {\n files: Map;\n shield: ShieldedParser;\n borderFills: Map;\n charPrs: Map;\n paraPrs: Map;\n warns: string[];\n}\n\nexport class HwpxDecoder extends BaseDecoder {\n protected getFormat(): string {\n return \"hwpx\";\n }\n protected getAliases(): string[] {\n return [HWPX_MIME_TYPE, \"application/hwp+zip\"];\n }\n\n async decode(data: Uint8Array): Promise> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const sectionFiles: Uint8Array[] = [];\n for (let i = 0; ; i++) {\n const sec =\n files.get(`Contents/section${i}.xml`) ?? files.get(`section${i}.xml`);\n if (!sec) break;\n sectionFiles.push(sec);\n }\n if (sectionFiles.length === 0) {\n const fallback = findSectionFile(files);\n if (fallback) sectionFiles.push(fallback);\n }\n\n if (sectionFiles.length === 0)\n return fail(\"HWPX: No section files found\");\n\n const headXml =\n files.get(\"Contents/header.xml\") ?? files.get(\"header.xml\");\n\n let meta: DocMeta = {};\n let dims: PageDims = { ...A4 };\n let borderFills = new Map();\n let charPrs = new Map();\n let paraPrs = new Map();\n\n if (headXml) {\n try {\n const headStr = TextKit.decode(headXml);\n const headObj: any = await XmlKit.parseStrict(headStr);\n if (headObj) {\n meta = extractMeta(headObj);\n dims = extractDims(headObj) ?? dims;\n borderFills = extractBorderFills(headObj);\n charPrs = extractCharPrs(headObj);\n paraPrs = extractParaPrs(headObj);\n }\n } catch {\n // header parse failure is non-fatal\n }\n }\n\n const ctx: DecCtx = {\n files,\n shield,\n borderFills,\n charPrs,\n paraPrs,\n warns,\n };\n\n const allSections: any[] = [];\n for (const secFile of sectionFiles) {\n const bodyStr = TextKit.decode(secFile);\n const bodyObj: any = await XmlKit.parseStrict(bodyStr);\n allSections.push(...normalizeSections(bodyObj));\n }\n\n const kids = shield.guardAll(\n allSections,\n (sec: any) => decodeSection(sec, dims, ctx),\n () => buildSheet([buildPara([buildSpan(\"[섹션 파싱 실패]\")])], dims),\n \"hwpx:section\",\n );\n\n warns.push(...shield.flush());\n return succeed(buildRoot(meta, kids), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWPX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction findSectionFile(\n files: Map,\n): Uint8Array | undefined {\n for (const [key, val] of files) {\n if (key.toLowerCase().includes(\"section\") && key.endsWith(\".xml\"))\n return val;\n }\n return undefined;\n}\n\nfunction normalizeSections(bodyObj: any): any[] {\n // (real HWPX), (legacy)\n if (bodyObj?.[\"hs:sec\"]) return toArr(bodyObj[\"hs:sec\"]);\n if (bodyObj?.[\"hp:SEC\"]) return toArr(bodyObj[\"hp:SEC\"]);\n\n const root = bodyObj?.[\"hp:HWPML\"] ?? bodyObj?.HWPML ?? bodyObj;\n const body =\n root?.[\"hp:BODY\"]?.[0] ??\n root?.BODY?.[0] ??\n root?.[\"hp:BODY\"] ??\n root?.BODY;\n if (!body) return [bodyObj];\n const sections = body?.[\"hp:SECTION\"] ?? body?.SECTION ?? [];\n return Array.isArray(sections) ? sections : [sections];\n}\n\n// Get a tag regardless of namespace/case variations\nfunction getTag(obj: any, ...names: string[]): any[] {\n for (const n of names) {\n const v = obj?.[n];\n if (v != null) return toArr(v);\n }\n return [];\n}\n\nfunction extractMeta(headObj: any): DocMeta {\n try {\n // Support both and \n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const info = root?.[\"hh:DOCSUMMARY\"]?.[0] ?? root?.DOCSUMMARY?.[0];\n if (!info) return {};\n const a = (k: string) =>\n info?.[`hh:${k}`]?.[0]?._text ?? info?.[k]?.[0]?._text ?? \"\";\n return {\n title: a(\"TITLE\") || undefined,\n author: a(\"AUTHOR\") || undefined,\n subject: a(\"SUBJECT\") || undefined,\n };\n } catch {\n return {};\n }\n}\n\nfunction extractDims(headObj: any): PageDims | null {\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return null;\n\n const secPrList =\n refList?.[\"hh:SECPRLST\"]?.[0]?.[\"hh:SECPR\"] ??\n refList?.SECPRLST?.[0]?.SECPR;\n const sec = Array.isArray(secPrList) ? secPrList[0] : secPrList;\n if (!sec) return null;\n\n const pa =\n sec?.[\"hh:PAGEPROPERTY\"]?.[0]?._attr ?? sec?.PAGEPROPERTY?.[0]?._attr;\n if (!pa) return null;\n\n const ew = Number(pa.Width ?? 59528);\n const eh = Number(pa.Height ?? 84188);\n return {\n wPt: Metric.hwpToPt(ew),\n hPt: Metric.hwpToPt(eh),\n mt: Metric.hwpToPt(Number(pa.TopMargin ?? 5670)),\n mb: Metric.hwpToPt(Number(pa.BottomMargin ?? 4252)),\n ml: Metric.hwpToPt(Number(pa.LeftMargin ?? 8504)),\n mr: Metric.hwpToPt(Number(pa.RightMargin ?? 8504)),\n orient: ew> eh ? \"landscape\" : \"portrait\",\n };\n } catch {\n return null;\n }\n}\n\nfunction extractBorderFills(headObj: any): Map {\n const map = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n const bfList =\n refList?.[\"hh:borderFills\"]?.[0] ??\n refList?.[\"hh:BORDERFILLLIST\"]?.[0] ??\n refList?.BORDERFILLLIST?.[0];\n if (!bfList) return map;\n\n const bfs = getTag(bfList, \"hh:borderFill\", \"hh:BORDERFILL\");\n for (const bf of bfs) {\n const attr = bf?._attr ?? {};\n const id = Number(attr.id ?? 0);\n if (id === 0) continue;\n\n const info: BorderFillInfo = {};\n\n // Helper: parse a border element into a Stroke\n const parseBorderEl = (el: any): Stroke | undefined => {\n if (!el) return undefined;\n const a = el?._attr ?? {};\n const mmVal = parseFloat(a.width) || undefined;\n const hwpVal = mmVal != null ? mmVal * 2.835 * 100 : undefined;\n return safeStrokeHwpx(a.type, hwpVal, a.color);\n };\n\n // Parse all four sides\n const topEl =\n bf?.[\"hh:topBorder\"]?.[0] ?? bf?.[\"hh:top\"]?.[0] ?? bf?.top?.[0];\n const rightEl =\n bf?.[\"hh:rightBorder\"]?.[0] ?? bf?.[\"hh:right\"]?.[0] ?? bf?.right?.[0];\n const bottomEl =\n bf?.[\"hh:bottomBorder\"]?.[0] ??\n bf?.[\"hh:bottom\"]?.[0] ??\n bf?.bottom?.[0];\n const leftEl =\n bf?.[\"hh:leftBorder\"]?.[0] ?? bf?.[\"hh:left\"]?.[0] ?? bf?.left?.[0];\n\n info.top = parseBorderEl(topEl);\n info.right = parseBorderEl(rightEl);\n info.bottom = parseBorderEl(bottomEl);\n info.left = parseBorderEl(leftEl);\n\n // Set uniform stroke fallback = top border (for defaultStroke etc.)\n info.stroke = info.top ?? info.left ?? info.right ?? info.bottom;\n\n // Parse fill (real HWPX uses hc:fillBrush, not hh:fillBrush)\n const fillBrush =\n bf?.[\"hc:fillBrush\"]?.[0] ??\n bf?.[\"hh:fillBrush\"]?.[0] ??\n bf?.[\"hh:fill\"]?.[0] ??\n bf?.fill?.[0] ??\n bf?.fillBrush?.[0];\n if (fillBrush) {\n const winBrush =\n fillBrush?.[\"hc:winBrush\"]?.[0]?._attr ??\n fillBrush?.[\"hh:winBrush\"]?.[0]?._attr ??\n fillBrush?.winBrush?.[0]?._attr;\n if (winBrush?.faceColor && winBrush.faceColor !== \"none\") {\n info.bgColor = safeHex(winBrush.faceColor);\n }\n }\n\n map.set(id, info);\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction buildFontIdMap(headObj: any): Map {\n const fontMap = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return fontMap;\n\n const fontfaces =\n refList?.[\"hh:fontfaces\"]?.[0] ?? refList?.[\"hh:FONTFACES\"]?.[0];\n if (!fontfaces) return fontMap;\n\n // Try each fontface group (HANGUL, LATIN, etc.) — use the first group that has entries\n const ffGroups = getTag(fontfaces, \"hh:fontface\", \"hh:FONTFACE\");\n for (const ff of ffGroups) {\n const fonts = getTag(ff, \"hh:font\", \"hh:FONT\");\n for (const font of fonts) {\n const fa = font?._attr ?? {};\n const fid = Number(fa.id ?? -1);\n const name = fa.face ?? fa.name ?? fa.Face ?? \"\";\n if (fid>= 0 && name && !fontMap.has(fid)) fontMap.set(fid, name);\n }\n if (fontMap.size> 0) break; // use first group (usually HANGUL)\n }\n } catch {\n /* non-fatal */\n }\n return fontMap;\n}\n\nfunction extractCharPrs(headObj: any): Map {\n const map = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n // Build font id → name map from fontfaces\n const fontIdMap = buildFontIdMap(headObj);\n\n const cpList =\n refList?.[\"hh:charProperties\"]?.[0] ??\n refList?.[\"hh:CHARPROPERTIES\"]?.[0];\n if (!cpList) return map;\n\n const cps = getTag(cpList, \"hh:charPr\", \"hh:CHARPR\");\n for (const cp of cps) {\n const attr = cp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const info: CharPrInfo = {};\n\n // height → pt\n if (attr.height) info.pt = Metric.hHeightToPt(Number(attr.height));\n\n // textColor\n if (attr.textColor) info.color = safeHex(attr.textColor);\n\n // bold\n if (cp?.[\"hh:bold\"]?.[0] != null) info.b = true;\n\n // italic\n if (cp?.[\"hh:italic\"]?.[0] != null) info.i = true;\n\n // underline\n const ulAttr = cp?.[\"hh:underline\"]?.[0]?._attr;\n if (ulAttr?.type && ulAttr.type !== \"NONE\") info.u = true;\n\n // strikeout — shape=\"3D\" is default \"no strikeout\" in real HWPX; only SOLID/etc means active\n const stAttr = cp?.[\"hh:strikeout\"]?.[0]?._attr;\n if (stAttr?.shape && stAttr.shape !== \"NONE\" && stAttr.shape !== \"3D\")\n info.s = true;\n\n // font name — resolve from fontRef.hangul → fontfaces\n const fontRefAttr =\n cp?.[\"hh:fontRef\"]?.[0]?._attr ?? cp?.[\"hh:FONTREF\"]?.[0]?._attr;\n if (fontRefAttr) {\n const fid = Number(\n fontRefAttr.hangul ?? fontRefAttr.latin ?? fontRefAttr.Hangul ?? 0,\n );\n const name = fontIdMap.get(fid);\n if (name) info.font = safeFont(name);\n }\n\n map.set(id, info);\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction extractParaPrs(headObj: any): Map {\n const map = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n const ppList =\n refList?.[\"hh:paraProperties\"]?.[0] ??\n refList?.[\"hh:PARAPROPERTIES\"]?.[0];\n if (!ppList) return map;\n\n const pps = getTag(ppList, \"hh:paraPr\", \"hh:PARAPR\");\n for (const pp of pps) {\n const attr = pp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const alignNode =\n pp?.[\"hh:align\"]?.[0]?._attr ?? pp?.[\"hh:ALIGN\"]?.[0]?._attr;\n const align = alignNode?.horizontal ?? alignNode?.Horizontal;\n\n // Read margin and lineSpacing from direct child OR hp:switch> hp:default/hp:case\n let marginEl = pp?.[\"hh:margin\"]?.[0] ?? null;\n let lineSpEl = pp?.[\"hh:lineSpacing\"]?.[0] ?? null;\n if (!marginEl) {\n const sw = pp?.[\"hp:switch\"]?.[0];\n const container = sw?.[\"hp:default\"]?.[0] ?? sw?.[\"hp:case\"]?.[0];\n marginEl = container?.[\"hh:margin\"]?.[0] ?? null;\n lineSpEl = lineSpEl ?? container?.[\"hh:lineSpacing\"]?.[0] ?? null;\n }\n\n let indentPt: number | undefined;\n let indentRightPt: number | undefined;\n let firstLineIndentPt: number | undefined;\n let spaceBefore: number | undefined;\n let spaceAfter: number | undefined;\n let lineHeight: number | undefined;\n let lineHeightFixed: number | undefined;\n\n if (marginEl) {\n // OWPML §7.5.4.4: hc:left=전체왼쪽여백, hc:right=전체오른쪽여백,\n // hc:indent=첫줄들여쓰기(양수)/내어쓰기(음수)\n // hc:intent는 자사 인코더가 생성하는 오기 표기로, hc:indent와 동일하게 처리\n const leftEl = marginEl?.[\"hc:left\"]?.[0];\n const rightEl = marginEl?.[\"hc:right\"]?.[0];\n const indentEl =\n marginEl?.[\"hc:intent\"]?.[0] ?? marginEl?.[\"hc:indent\"]?.[0];\n const prevEl = marginEl?.[\"hc:prev\"]?.[0];\n const nextEl = marginEl?.[\"hc:next\"]?.[0];\n\n const leftVal = Number(leftEl?._attr?.value ?? 0);\n const rightVal = Number(rightEl?._attr?.value ?? 0);\n const indentVal = Number(indentEl?._attr?.value ?? 0);\n const prevVal = Number(prevEl?._attr?.value ?? 0);\n const nextVal = Number(nextEl?._attr?.value ?? 0);\n\n if (leftVal !== 0) indentPt = Metric.hwpToPt(leftVal);\n if (rightVal !== 0) indentRightPt = Metric.hwpToPt(rightVal);\n if (indentVal !== 0) firstLineIndentPt = Metric.hwpToPt(indentVal);\n if (prevVal> 0) spaceBefore = Metric.hwpToPt(prevVal);\n if (nextVal> 0) spaceAfter = Metric.hwpToPt(nextVal);\n }\n\n if (lineSpEl) {\n const lsAttr = lineSpEl._attr ?? {};\n const lsType = lsAttr.type ?? \"PERCENT\";\n const lsVal = Number(lsAttr.value ?? 160);\n // OWPML §7.5.4.6: PERCENT(비율), FIXED(고정), BETWEEN_LINE(줄간격), AT_LEAST(최소)\n if (lsType === \"PERCENT\" && lsVal> 0 && lsVal !== 160) {\n lineHeight = lsVal / 100;\n } else if (lsType === \"FIXED\" && lsVal> 0) {\n // FIXED: 값이 HWPUNIT 단위의 고정 줄 높이\n lineHeightFixed = Metric.hwpToPt(lsVal);\n }\n }\n\n map.set(id, {\n align,\n indentPt,\n indentRightPt,\n firstLineIndentPt,\n spaceBefore,\n spaceAfter,\n lineHeight,\n lineHeightFixed,\n });\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\n// ─── Section decoding ──────────────────────────────────────\n\nfunction addParaItems(p: any, items: { type: string; node: any }[]): void {\n // Check if this paragraph contains a table in its runs\n const runs = getTag(p, \"hp:run\", \"hp:RUN\");\n let hasTable = false;\n for (const run of runs) {\n const tbls = getTag(run, \"hp:tbl\", \"hp:TABLE\");\n if (tbls.length> 0) {\n for (const tbl of tbls) {\n items.push({ type: \"table\", node: tbl });\n }\n hasTable = true;\n }\n }\n // 테이블을 포함한 단락은 일반 단락으로 다시 추가하지 않음 (중복 방지)\n if (!hasTable) {\n items.push({ type: \"para\", node: p });\n }\n}\n\nfunction decodeSection(sec: any, dims: PageDims, ctx: DecCtx) {\n // Try to extract dims from first paragraph's secPr\n const firstParas = getTag(sec, \"hp:p\", \"hp:P\");\n const pageDims = extractSecPrDims(firstParas[0]) ?? dims;\n\n // Build items list preserving document order via _childOrder\n const items: { type: string; node: any }[] = [];\n const paras = getTag(sec, \"hp:p\", \"hp:P\");\n const tbls = getTag(sec, \"hp:tbl\", \"hp:TABLE\");\n\n const childOrder = sec?.[\"_childOrder\"] as string[] | undefined;\n\n if (Array.isArray(childOrder)) {\n let pi = 0;\n let ti = 0;\n for (const tag of childOrder) {\n if ((tag === \"hp:p\" || tag === \"hp:P\") && pi < paras.length) {\n addParaItems(paras[pi++], items);\n } else if ((tag === \"hp:tbl\" || tag === \"hp:TABLE\") && ti < tbls.length) {\n items.push({ type: \"table\", node: tbls[ti++] });\n }\n }\n // Append any remaining (fallback)\n while (pi < paras.length) addParaItems(paras[pi++], items);\n while (ti < tbls.length) items.push({ type: \"table\", node: tbls[ti++] });\n } else {\n // No order info — process paragraphs sequentially (fallback to previous logic)\n for (const p of paras) addParaItems(p, items);\n // Note: direct tables are appended after paras in this fallback\n for (const t of tbls) items.push({ type: \"table\", node: t });\n }\n\n const kids: ContentNode[] = ctx.shield.guardAll(\n items,\n (item: any) => {\n if (item.type === \"table\") {\n try {\n const { value } = ctx.shield.guardGrid(\n item.node,\n (n) => decodeGrid(n, ctx),\n (n) => decodeGridSimple(n, ctx),\n (n) => decodeGridFlat(n),\n (n) => decodeGridText(n) as unknown as GridNode,\n \"hwpx:table\",\n );\n return value;\n } catch {\n return buildPara([buildSpan(\"[표 파싱 실패]\")]);\n }\n }\n return decodePara(item.node, ctx);\n },\n () => buildPara([buildSpan(\"[파싱 실패]\")]),\n \"hwpx:content\",\n );\n\n // Decode header/footer\n const headerParas = decodeHeaderFooter(sec, \"header\", ctx);\n const footerParas = decodeHeaderFooter(sec, \"footer\", ctx);\n\n return buildSheet(kids.filter(Boolean) as ContentNode[], pageDims, {\n headers: { default: headerParas },\n footers: { default: footerParas },\n });\n}\n\nfunction parseSecPrDims(secPr: any): PageDims | null {\n const pagePr =\n secPr?.[\"hp:pagePr\"]?.[0]?._attr ?? secPr?.[\"hp:PAGEPR\"]?.[0]?._attr;\n if (!pagePr) return null;\n const margin =\n secPr?.[\"hp:pagePr\"]?.[0]?.[\"hp:margin\"]?.[0]?._attr ??\n secPr?.[\"hp:PAGEPR\"]?.[0]?.[\"hp:MARGIN\"]?.[0]?._attr ??\n {};\n const pw = Number(pagePr.width ?? 59528);\n const ph = Number(pagePr.height ?? 84188);\n return {\n wPt: Metric.hwpToPt(pw),\n hPt: Metric.hwpToPt(ph),\n mt: Metric.hwpToPt(Number(margin.top ?? 5670)),\n mb: Metric.hwpToPt(Number(margin.bottom ?? 4252)),\n ml: Metric.hwpToPt(Number(margin.left ?? 8504)),\n mr: Metric.hwpToPt(Number(margin.right ?? 8504)),\n orient: pw> ph ? \"landscape\" : \"portrait\",\n };\n}\n\nfunction extractSecPrDims(p: any): PageDims | null {\n if (!p) return null;\n try {\n // Primary: hp:secPr is a DIRECT child of hp:p (as generated by HwpxEncoder)\n const secPrDirect = p?.[\"hp:secPr\"]?.[0] ?? p?.[\"hp:SECPR\"]?.[0];\n if (secPrDirect) {\n const dims = parseSecPrDims(secPrDirect);\n if (dims) return dims;\n }\n // Fallback: legacy format may nest hp:secPr inside hp:run\n const runs = getTag(p, \"hp:run\", \"hp:RUN\");\n for (const run of runs) {\n const secPr = run?.[\"hp:secPr\"]?.[0] ?? run?.[\"hp:SECPR\"]?.[0];\n if (!secPr) continue;\n const dims = parseSecPrDims(secPr);\n if (dims) return dims;\n }\n } catch {\n /* ignore */\n }\n return null;\n}\n\nfunction decodeHeaderFooter(\n sec: any,\n kind: \"header\" | \"footer\",\n ctx: DecCtx,\n): ParaNode[] | undefined {\n try {\n const hf =\n sec?.[\"hp:headerFooter\"]?.[0] ??\n sec?.[\"hp:HEADERFOOTER\"]?.[0] ??\n sec?.headerFooter?.[0] ??\n sec?.HEADERFOOTER?.[0];\n if (!hf) return undefined;\n\n const part =\n hf?.[\"hp:\" + kind]?.[0] ??\n hf?.[\"hp:\" + kind.toUpperCase()]?.[0] ??\n hf?.[kind]?.[0] ??\n hf?.[kind.toUpperCase()]?.[0];\n if (!part) return undefined;\n\n const paras = getTag(part, \"hp:p\", \"hp:P\");\n if (paras.length === 0) return undefined;\n\n return paras.map((p: any) => decodePara(p, ctx));\n } catch {\n return undefined;\n }\n}\n\n// ─── Paragraph & run decoding ──────────────────────────────\n\nfunction decodePara(p: any, ctx: DecCtx): ParaNode {\n const pAttr = p?._attr ?? {};\n const paraPrIdRef = Number(pAttr.paraPrIDRef ?? -1);\n\n // Resolve paraPr from IDRef or inline\n let align: string | undefined;\n const paraPrDef = ctx.paraPrs.get(paraPrIdRef);\n if (paraPrDef?.align) align = paraPrDef.align;\n\n // Check inline PARAPR too\n const inlineParaPr =\n p?.[\"hp:PARAPR\"]?.[0] ?? p?.[\"hp:paraPr\"]?.[0] ?? p?.PARAPR?.[0];\n if (inlineParaPr) {\n const alignNode =\n inlineParaPr?.[\"hp:ALIGN\"]?.[0]?._attr ??\n inlineParaPr?.[\"hp:align\"]?.[0]?._attr ??\n inlineParaPr?.ALIGN?.[0]?._attr;\n if (alignNode?.Type) align = alignNode.Type;\n if (alignNode?.horizontal) align = alignNode.horizontal;\n }\n\n const inlineAttr = inlineParaPr?._attr ?? {};\n const props: ParaProps = { align: safeAlign(align) };\n\n // Apply spacing/indent/lineHeight from paraPr definition\n if (paraPrDef) {\n if (paraPrDef.indentPt !== undefined) props.indentPt = paraPrDef.indentPt;\n if (paraPrDef.indentRightPt !== undefined)\n props.indentRightPt = paraPrDef.indentRightPt;\n if (paraPrDef.firstLineIndentPt !== undefined)\n props.firstLineIndentPt = paraPrDef.firstLineIndentPt;\n if (paraPrDef.spaceBefore !== undefined)\n props.spaceBefore = paraPrDef.spaceBefore;\n if (paraPrDef.spaceAfter !== undefined)\n props.spaceAfter = paraPrDef.spaceAfter;\n if (paraPrDef.lineHeight !== undefined)\n props.lineHeight = paraPrDef.lineHeight;\n if (paraPrDef.lineHeightFixed !== undefined)\n props.lineHeightFixed = paraPrDef.lineHeightFixed;\n }\n\n // List support (from inline attr)\n if (inlineAttr.listType) {\n props.listOrd =\n inlineAttr.listType === \"DIGIT\" || inlineAttr.listType === \"DECIMAL\";\n props.listLv = Number(inlineAttr.listLevel ?? 0);\n }\n\n const runs = getTag(p, \"hp:run\", \"hp:RUN\");\n const kids: (SpanNode | ImgNode)[] = [];\n\n // Helper: collect hp:pic elements from a container (direct child OR inside hp:ctrl)\n const collectPics = (container: any): any[] => {\n const direct = getTag(container, \"hp:pic\", \"hp:PIC\");\n const ctrls = getTag(container, \"hp:ctrl\", \"hp:CTRL\");\n const nested = ctrls.flatMap((c: any) => getTag(c, \"hp:pic\", \"hp:PIC\"));\n return [...direct, ...nested];\n };\n\n // Images that are direct children of (common in table cells and floats)\n for (const pic of collectPics(p)) {\n const img = decodePic(pic, ctx);\n if (img) kids.push(img);\n }\n\n for (const run of runs) {\n // Images: directly in run OR in run→ctrl (both patterns appear in practice)\n for (const pic of collectPics(run)) {\n const img = decodePic(pic, ctx);\n if (img) kids.push(img);\n }\n\n // Page number\n const pageNums = getTag(run, \"hp:pageNum\", \"hp:PAGENUM\");\n if (pageNums.length> 0) {\n const pn = pageNums[0]?._attr ?? {};\n const fmt =\n pn.formatType === \"ROMAN_LOWER\"\n ? (\"roman\" as const)\n : pn.formatType === \"ROMAN_UPPER\"\n ? (\"romanCaps\" as const)\n : (\"decimal\" as const);\n const pageNumNode: PageNumNode = { tag: \"pagenum\", format: fmt };\n const spanProps = resolveCharPr(run, ctx);\n kids.push({ tag: \"span\", props: spanProps, kids: [pageNumNode] });\n continue;\n }\n\n // Text\n const runPics = collectPics(run);\n const textNodes = getTag(run, \"hp:t\", \"hp:T\", \"hp:CHAR\");\n const content = textNodes\n .map((t: any) => {\n const val =\n typeof t === \"string\" ? t : (t?._text ?? t?._ ?? t?.[\"#text\"] ?? \"\");\n return val.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n })\n .join(\"\");\n\n // Skip empty secPr-only runs that produced no images\n if (\n content === \"\" &&\n (run?.[\"hp:secPr\"]?.[0] || run?.[\"hp:SECPR\"]?.[0]) &&\n runPics.length === 0 &&\n pageNums.length === 0\n )\n continue;\n\n // Only push text span when there's actual content and no image already pushed for this run\n if (content !== \"\" || (runPics.length === 0 && pageNums.length === 0)) {\n const spanProps = resolveCharPr(run, ctx);\n kids.push(buildSpan(content, spanProps));\n }\n }\n\n // pageBreak=\"1\" → prepend a pb node in its own span\n if (pAttr.pageBreak === \"1\") {\n kids.unshift({ tag: \"span\", props: {}, kids: [buildPb()] });\n }\n\n return buildPara(kids.filter(Boolean) as ParaNode[\"kids\"], props);\n}\n\nfunction resolveCharPr(run: any, ctx: DecCtx): TextProps {\n const runAttr = run?._attr ?? {};\n const charPrIdRef = Number(runAttr.charPrIDRef ?? runAttr.CharPrIDRef ?? -1);\n\n // IDRef로 먼저 조회\n const def = ctx.charPrs.get(charPrIdRef);\n if (def) {\n return {\n b: def.b,\n i: def.i,\n u: def.u,\n s: def.s,\n pt: def.pt,\n color: def.color,\n font: def.font,\n bg: def.bg,\n };\n }\n\n // 인라인 CHARPR fallback — 대소문자 모두 시도\n const inlinePr =\n run?.[\"hp:CHARPR\"]?.[0] ??\n run?.[\"hp:charPr\"]?.[0] ??\n run?.CHARPR?.[0] ??\n run?.charPr?.[0];\n const ca = inlinePr?._attr ?? {};\n\n const bVal = ca.Bold ?? ca.bold ?? ca.B ?? \"\";\n const iVal = ca.Italic ?? ca.italic ?? ca.I ?? \"\";\n const uVal = ca.Underline ?? ca.underline ?? \"\";\n const sVal = ca.Strikeout ?? ca.strikeout ?? \"\";\n const fontName =\n ca.FontName ?? ca.fontName ?? ca.FaceNameHangul ?? ca.faceNameHangul ?? \"\";\n const heightVal = ca.Height ?? ca.height ?? \"\";\n\n return {\n b: bVal === \"1\" || bVal === \"true\" || bVal === \"True\" || undefined,\n i: iVal === \"1\" || iVal === \"true\" || iVal === \"True\" || undefined,\n u: uVal && uVal !== \"NONE\" ? true : undefined,\n s: sVal && sVal !== \"NONE\" && sVal !== \"3D\" ? true : undefined,\n font: fontName ? safeFont(fontName) : undefined,\n pt: heightVal ? Metric.hHeightToPt(Number(heightVal)) : undefined,\n color: safeHex(ca.TextColor ?? ca.textColor),\n bg: safeHex(ca.BgColor ?? ca.bgColor),\n };\n}\n\n// ─── Image decoding ────────────────────────────────────────\n\nfunction decodePic(pic: any, ctx: DecCtx): ImgNode | null {\n try {\n const szAttr = pic?.[\"hp:sz\"]?.[0]?._attr ?? pic?.sz?.[0]?._attr ?? {};\n const w = Metric.hwpToPt(Number(szAttr.width ?? 0));\n const h = Metric.hwpToPt(Number(szAttr.height ?? 0));\n\n // Try multiple tag patterns for image reference\n const imgNode =\n pic?.[\"hp:img\"]?.[0]?._attr ??\n pic?.[\"hc:img\"]?.[0]?._attr ??\n pic?.img?.[0]?._attr ??\n {};\n const binRef = imgNode.binaryItemIDRef ?? imgNode.BinaryItemIDRef;\n if (!binRef) return null;\n\n // Find binary data\n let imgData: Uint8Array | undefined;\n for (const [key, val] of ctx.files) {\n if (\n key.includes(binRef) ||\n key.toLowerCase().includes(binRef.toLowerCase())\n ) {\n imgData = val;\n break;\n }\n }\n if (!imgData) return null;\n\n const ext = binRef.split(\".\").pop()?.toLowerCase() ?? \"png\";\n const mimeMap: Record = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n\n // ── hp:pos에서 layout 추출 ───────────────────────────────\n const posAttr = pic?.[\"hp:pos\"]?.[0]?._attr ?? pic?.pos?.[0]?._attr ?? {};\n const layout = extractHwpxLayout(posAttr, pic);\n\n return buildImg(\n TextKit.base64Encode(imgData),\n mimeMap[ext] ?? \"image/png\",\n w,\n h,\n undefined,\n layout,\n );\n } catch {\n return null;\n }\n}\n\nfunction extractHwpxLayout(posAttr: any, pic: any): ImgLayout {\n const treatAsChar =\n posAttr.treatAsChar === \"1\" || posAttr.treatAsChar === \"true\";\n if (treatAsChar) return { wrap: \"inline\" };\n\n // textWrap → wrap (direct attribute of hp:pic element)\n const textWrap: string =\n pic?._attr?.textWrap ?? pic?.pic?.[0]?._attr?.textWrap ?? \"TOP_AND_BOTTOM\";\n // OWPML §7.5.8.1 textWrap → ImgWrap 매핑\n // TOP_AND_BOTTOM: 텍스트가 이미지 위아래로만 흐름 → DOCX wrapTopAndBottom (float anchor)\n const wrapMap: Record = {\n TOP_AND_BOTTOM: \"topAndBottom\", // float, 위아래 텍스트 흐름\n SQUARE: \"square\",\n BOTH_SIDES: \"tight\",\n LEFT: \"tight\",\n RIGHT: \"tight\",\n LARGER_ONLY: \"tight\",\n SMALLER_ONLY: \"tight\",\n LARGEST_ONLY: \"tight\",\n BEHIND_TEXT: \"behind\",\n FRONT_TEXT: \"front\",\n };\n const wrap: ImgWrap = wrapMap[textWrap] ?? \"square\";\n\n // 기준점\n const horzRelToMap: Record = {\n PARA: \"para\",\n MARGIN: \"margin\",\n PAGE: \"page\",\n COLUMN: \"column\",\n };\n const vertRelToMap: Record = {\n PARA: \"para\",\n MARGIN: \"margin\",\n PAGE: \"page\",\n PAPER: \"page\",\n LINE: \"line\",\n };\n const horzRelTo = horzRelToMap[posAttr.horzRelTo ?? \"\"] ?? \"para\";\n const vertRelTo = vertRelToMap[posAttr.vertRelTo ?? \"\"] ?? \"para\";\n\n // 정렬\n const horzAlignMap: Record = {\n LEFT: \"left\",\n CENTER: \"center\",\n RIGHT: \"right\",\n };\n const vertAlignMap: Record = {\n TOP: \"top\",\n CENTER: \"center\",\n BOTTOM: \"bottom\",\n };\n const horzAlign = horzAlignMap[posAttr.horzAlign ?? \"\"];\n const vertAlign = vertAlignMap[posAttr.vertAlign ?? \"\"];\n\n // 오프셋\n const horzOffset = Number(posAttr.horzOffset ?? 0);\n const vertOffset = Number(posAttr.vertOffset ?? 0);\n const xPt = horzOffset !== 0 ? Metric.hwpToPt(horzOffset) : undefined;\n const yPt = vertOffset !== 0 ? Metric.hwpToPt(vertOffset) : undefined;\n\n return { wrap, horzAlign, vertAlign, horzRelTo, vertRelTo, xPt, yPt };\n}\n\n// ─── Table decoding ────────────────────────────────────────\n\nfunction decodeGrid(tbl: any, ctx: DecCtx): GridNode {\n const tblAttr = tbl?._attr ?? {};\n const borderFillId = Number(tblAttr.borderFillIDRef ?? 0);\n const borderFill = ctx.borderFills.get(borderFillId);\n const headerRow = tblAttr.repeatHeader === \"1\";\n\n const gridProps: GridProps = { headerRow: headerRow || undefined };\n if (borderFill?.stroke) gridProps.defaultStroke = borderFill.stroke;\n\n const rowArr = getTag(tbl, \"hp:tr\", \"hp:ROW\");\n\n // Read column widths: first try a row where ALL cells have cs=1\n for (const row of rowArr) {\n const cells = getTag(row, \"hp:tc\", \"hp:CELL\");\n const rowWidths: number[] = [];\n let allSingle = true;\n for (const cell of cells) {\n const cellSpanAttr = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cs = Number(cellSpanAttr.colSpan ?? cell?._attr?.ColSpan ?? 1);\n if (cs> 1) {\n allSingle = false;\n break;\n }\n const szAttr = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const w = Number(szAttr.width ?? 0);\n rowWidths.push(Metric.hwpToPt(w));\n }\n if (allSingle && rowWidths.length> 0 && rowWidths.some((w) => w> 0)) {\n gridProps.colWidths = rowWidths;\n break;\n }\n }\n\n // Fallback: proportional distribution when no all-single row exists\n if (!gridProps.colWidths) {\n // Determine colCount first: max column index reached across all rows\n let detectedCols = 0;\n for (const row of rowArr) {\n let ci = 0;\n for (const cell of getTag(row, \"hp:tc\", \"hp:CELL\")) {\n const csEl = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n ci += Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1);\n }\n if (ci> detectedCols) detectedCols = ci;\n }\n if (detectedCols> 0) {\n const sums = new Float64Array(detectedCols);\n const counts = new Int32Array(detectedCols);\n for (const row of rowArr) {\n let ci = 0;\n for (const cell of getTag(row, \"hp:tc\", \"hp:CELL\")) {\n const csEl = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cs = Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1);\n const szAttr = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const w = Number(szAttr.width ?? 0);\n if (w> 0 && cs> 0) {\n const perCol = w / cs;\n for (let k = 0; k < cs && ci + k < detectedCols; k++) {\n sums[ci + k] += perCol;\n counts[ci + k]++;\n }\n }\n ci += cs;\n }\n }\n const estimated = Array.from(sums).map((s, i) =>\n counts[i]> 0 ? Metric.hwpToPt(s / counts[i]) : 0,\n );\n if (estimated.some((w) => w> 0)) gridProps.colWidths = estimated;\n }\n }\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, \"hp:tc\", \"hp:CELL\");\n const cellNodes = cellArr.map((cell: any) => {\n const ca = cell?._attr ?? {};\n\n // Cell borderFill\n const cellBfId = Number(ca.borderFillIDRef ?? 0);\n const cellBf = ctx.borderFills.get(cellBfId);\n\n const cellProps: CellProps = {\n bg: cellBf?.bgColor ?? safeHex(ca.BgColor),\n };\n\n if (cellBf) {\n // Preserve explicit NONE so it overrides table-level defaultStroke in DOCX tcBorders.\n // Only skip when the side is truly undefined (not specified in borderFill).\n cellProps.top = cellBf.top ?? cellBf.stroke;\n cellProps.bot = cellBf.bottom ?? cellBf.stroke;\n cellProps.left = cellBf.left ?? cellBf.stroke;\n cellProps.right = cellBf.right ?? cellBf.stroke;\n }\n\n // Vertical alignment and cell padding from subList\n const subList = cell?.[\"hp:subList\"]?.[0] ?? cell?.subList?.[0];\n const subAttr = subList?._attr ?? {};\n if (subAttr.vertAlign) {\n const vaMap: Record = {\n TOP: \"top\",\n CENTER: \"mid\",\n BOTTOM: \"bot\",\n };\n cellProps.va = vaMap[subAttr.vertAlign];\n }\n // Cell margins (stored in HWPUNIT on subList attributes)\n const HWPX_DEFAULT_MARGIN_LR = 360; // typical default: 3.6pt\n const HWPX_DEFAULT_MARGIN_TB = 141; // typical default: ~1.4pt\n const mL = Number(subAttr.marginLeft ?? HWPX_DEFAULT_MARGIN_LR);\n const mR = Number(subAttr.marginRight ?? HWPX_DEFAULT_MARGIN_LR);\n const mT = Number(subAttr.marginTop ?? HWPX_DEFAULT_MARGIN_TB);\n const mB = Number(subAttr.marginBottom ?? HWPX_DEFAULT_MARGIN_TB);\n if (mL !== HWPX_DEFAULT_MARGIN_LR) cellProps.padL = Metric.hwpToPt(mL);\n if (mR !== HWPX_DEFAULT_MARGIN_LR) cellProps.padR = Metric.hwpToPt(mR);\n if (mT !== HWPX_DEFAULT_MARGIN_TB) cellProps.padT = Metric.hwpToPt(mT);\n if (mB !== HWPX_DEFAULT_MARGIN_TB) cellProps.padB = Metric.hwpToPt(mB);\n\n // Colspan/rowspan from cellSpan element or attributes\n const cellSpan = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cs = Number(cellSpan.colSpan ?? ca.ColSpan ?? 1);\n const rs = Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1);\n\n // Parse cell content — paragraphs and nested tables (중첩 표)\n const cellKids: (ParaNode | GridNode)[] = [];\n const source = subList ?? cell;\n const sourcePSource = getTag(source, \"hp:p\", \"hp:P\");\n for (const sp of sourcePSource) {\n try {\n // Check if this paragraph contains a nested table in its runs\n const runs = getTag(sp, \"hp:run\", \"hp:RUN\");\n let hasNestedTable = false;\n for (const run of runs) {\n const nestedTbls = getTag(run, \"hp:tbl\", \"hp:TABLE\");\n for (const nestedTbl of nestedTbls) {\n try {\n cellKids.push(decodeGrid(nestedTbl, ctx));\n } catch {\n /* skip malformed nested table */\n }\n hasNestedTable = true;\n }\n }\n if (!hasNestedTable) {\n cellKids.push(decodePara(sp, ctx));\n }\n } catch {\n /* skip corrupted para in cell */\n }\n }\n\n return buildCell(\n cellKids.length> 0 ? cellKids : [buildPara([buildSpan(\"\")])],\n { cs, rs, props: cellProps },\n );\n });\n // Row height: prefer a non-merged cell (rs=1) for accuracy.\n // For merged cells, divide total height by rowSpan to get per-row height.\n let rowHeightPt: number | undefined;\n for (const cell of cellArr) {\n const ca = cell?._attr ?? {};\n const cellSpan = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cellRs = Math.max(1, Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1));\n const hSz = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const hVal = Number(hSz.height ?? 0);\n if (hVal> 0) {\n rowHeightPt = Metric.hwpToPt(hVal) / cellRs;\n if (cellRs === 1) break; // exact match — stop searching\n }\n }\n return buildRow(cellNodes, rowHeightPt);\n });\n return buildGrid(rowNodes, gridProps);\n}\n\nfunction decodeGridSimple(tbl: any, ctx: DecCtx): GridNode {\n const rowArr = getTag(tbl, \"hp:tr\", \"hp:ROW\");\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, \"hp:tc\", \"hp:CELL\");\n return buildRow(\n cellArr.map((cell: any) =>\n buildCell([buildPara([buildSpan(cellText(cell))])]),\n ),\n );\n });\n return buildGrid(rowNodes);\n}\n\nfunction decodeGridFlat(tbl: any): GridNode {\n return buildGrid([\n buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])]),\n ]);\n}\n\nfunction decodeGridText(tbl: any): ParaNode {\n return buildPara([buildSpan(tableText(tbl))]);\n}\n\nfunction cellText(cell: any): string {\n const subList = cell?.[\"hp:subList\"]?.[0] ?? cell?.subList?.[0];\n const source = subList ?? cell;\n return getTag(source, \"hp:p\", \"hp:P\")\n .map((p: any) =>\n getTag(p, \"hp:run\", \"hp:RUN\")\n .map((r: any) =>\n getTag(r, \"hp:t\", \"hp:T\")\n .map((t: any) => {\n const val =\n typeof t === \"string\"\n ? t\n : (t?._text ?? t?._ ?? t?.[\"#text\"] ?? \"\");\n return val.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n })\n .join(\"\"),\n )\n .join(\"\"),\n )\n .join(\" \");\n}\n\nfunction tableText(tbl: any): string {\n return getTag(tbl, \"hp:tr\", \"hp:ROW\")\n .map((row: any) =>\n getTag(row, \"hp:tc\", \"hp:CELL\")\n .map((c: any) => cellText(c))\n .join(\"\\t\"),\n )\n .join(\"\\n\");\n}\n\nfunction toArr(v: any): any[] {\n return v == null ? [] : Array.isArray(v) ? v : [v];\n}\n\n// Auto-register\nregistry.registerDecoder(new HwpxDecoder());\n","/**\n * OLE2 Compound File Binary Format (CFB) parser.\n * Used for legacy HWP 5.0 files.\n */\n\nexport const BinaryKit = {\n readU16LE(buf: Uint8Array, offset: number): number {\n return buf[offset] | (buf[offset + 1] << 8);\n },\n\n readU32LE(buf: Uint8Array, offset: number): number {\n return (\n (buf[offset] | (buf[offset + 1] << 8) | (buf[offset + 2] << 16))>>> 0\n ) + buf[offset + 3] * 0x1000000;\n },\n\n isOle2(data: Uint8Array): boolean {\n return (\n data.length>= 8 &&\n data[0] === 0xD0 && data[1] === 0xCF &&\n data[2] === 0x11 && data[3] === 0xE0 &&\n data[4] === 0xA1 && data[5] === 0xB1 &&\n data[6] === 0x1A && data[7] === 0xE1\n );\n },\n\n parseCfb(data: Uint8Array): Map {\n const streams = new Map();\n\n if (!this.isOle2(data)) {\n throw new Error('Not a valid OLE2 file');\n }\n\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const sectorSize = 1 << view.getUint16(30, true);\n const miniSectorSz = 1 << view.getUint16(32, true);\n const dirFirstSec = view.getUint32(48, true);\n const miniStreamCutoff = view.getUint32(56, true);\n const miniFatFirst = view.getUint32(60, true);\n const miniFatCnt = view.getUint32(64, true);\n const difatFirst = view.getUint32(68, true);\n\n const ENDOFCHAIN = 0xFFFFFFFE;\n const FREESECT = 0xFFFFFFFF;\n\n const sectorAt = (sec: number): Uint8Array =>\n data.subarray(512 + sec * sectorSize, 512 + (sec + 1) * sectorSize);\n\n // Build FAT from DIFAT\n const fatSecNums: number[] = [];\n for (let i = 0; i < 109; i++) {\n const s = view.getUint32(76 + i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n if (difatFirst !== ENDOFCHAIN && difatFirst !== FREESECT) {\n let difSec = difatFirst;\n while (difSec !== ENDOFCHAIN && difSec !== FREESECT) {\n const sec = sectorAt(difSec);\n const sv = new DataView(sec.buffer, sec.byteOffset, sec.byteLength);\n for (let i = 0; i < (sectorSize / 4) - 1; i++) {\n const s = sv.getUint32(i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n difSec = sv.getUint32(sectorSize - 4, true);\n }\n }\n\n const fat: number[] = [];\n for (const sec of fatSecNums) {\n const s = sectorAt(sec);\n const sv = new DataView(s.buffer, s.byteOffset, s.byteLength);\n for (let i = 0; i < sectorSize / 4; i++) {\n fat.push(sv.getUint32(i * 4, true));\n }\n }\n\n const readChain = (startSec: number): Uint8Array => {\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < fat.length) {\n chunks.push(sectorAt(sec));\n sec = fat[sec];\n }\n return concatUint8(chunks);\n };\n\n // Directory entries\n const dirData = readChain(dirFirstSec);\n const dirView = new DataView(dirData.buffer, dirData.byteOffset, dirData.byteLength);\n const dirCount = dirData.length / 128;\n\n interface DirEntry {\n name: string;\n type: number;\n startSec: number;\n size: number;\n childId: number;\n siblingLeftId: number;\n siblingRightId: number;\n }\n\n const dirEntries: DirEntry[] = [];\n for (let i = 0; i < dirCount; i++) {\n const base = i * 128;\n const nameLen = dirView.getUint16(base + 64, true);\n const nameBytes = dirData.subarray(base, base + Math.max(0, nameLen - 2));\n const name = new TextDecoder('utf-16le').decode(nameBytes);\n const type = dirData[base + 66];\n const childId = dirView.getInt32(base + 76, true);\n const sibLeft = dirView.getInt32(base + 68, true);\n const sibRight = dirView.getInt32(base + 72, true);\n const startSec = dirView.getUint32(base + 116, true);\n const size = dirView.getUint32(base + 120, true);\n dirEntries.push({ name, type, startSec, size, childId, siblingLeftId: sibLeft, siblingRightId: sibRight });\n }\n\n // Mini stream\n const rootEntry = dirEntries[0];\n let miniStreamData: Uint8Array | null = null;\n let miniFat: number[] = [];\n\n if (rootEntry && rootEntry.startSec !== ENDOFCHAIN && rootEntry.startSec !== FREESECT) {\n miniStreamData = readChain(rootEntry.startSec);\n }\n\n if (miniFatCnt> 0 && miniFatFirst !== ENDOFCHAIN && miniFatFirst !== FREESECT) {\n const mfData = readChain(miniFatFirst);\n const mfv = new DataView(mfData.buffer, mfData.byteOffset, mfData.byteLength);\n for (let i = 0; i < mfData.length / 4; i++) {\n miniFat.push(mfv.getUint32(i * 4, true));\n }\n }\n\n const readMiniChain = (startSec: number, size: number): Uint8Array => {\n if (!miniStreamData) return new Uint8Array(0);\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n let remaining = size;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < miniFat.length && remaining> 0) {\n const off = sec * miniSectorSz;\n const chunk = miniStreamData.subarray(off, off + Math.min(miniSectorSz, remaining));\n chunks.push(chunk);\n remaining -= chunk.length;\n sec = miniFat[sec];\n }\n return concatUint8(chunks).subarray(0, size);\n };\n\n // DFS traversal\n const visit = (id: number, path: string): void => {\n if (id < 0 || id>= dirEntries.length) return;\n const entry = dirEntries[id];\n const fullPath = path ? `${path}/${entry.name}` : entry.name;\n\n if (entry.type === 2) {\n let streamData: Uint8Array;\n if (entry.size < miniStreamCutoff && miniStreamData) {\n streamData = readMiniChain(entry.startSec, entry.size);\n } else {\n streamData = readChain(entry.startSec).subarray(0, entry.size);\n }\n streams.set(fullPath, streamData);\n streams.set(entry.name, streamData);\n }\n\n if (entry.childId>= 0) visit(entry.childId, fullPath);\n if (entry.siblingLeftId>= 0) visit(entry.siblingLeftId, path);\n if (entry.siblingRightId>= 0) visit(entry.siblingRightId, path);\n };\n\n if (dirEntries.length> 0 && dirEntries[0].childId>= 0) {\n visit(dirEntries[0].childId, '');\n }\n\n return streams;\n },\n};\n\nfunction concatUint8(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const a of arrays) { out.set(a, off); off += a.length; }\n return out;\n}\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, ImgNode, GridNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { Align, Stroke, StrokeKind, PageDims, TextProps, ParaProps, CellProps, GridProps } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildGrid, buildRow, buildCell, buildImg } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { BinaryKit } from '../../toolkit/BinaryKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { Metric, safeHex, safeFont } from '../../safety/StyleBridge';\nimport { registry } from '../../pipeline/registry';\nimport { A4 } from '../../model/doc-props';\nimport pako from 'pako';\n\n/* ═══════════════════════════════════════════════════════════════\n HWP 5.0 Tag Constants\n ═══════════════════════════════════════════════════════════════ */\n\nconst HWPTAG_BEGIN = 16;\n\nconst TAG_FACE_NAME = HWPTAG_BEGIN + 3; // 19\nconst TAG_BORDER_FILL = HWPTAG_BEGIN + 4; // 20\nconst TAG_CHAR_SHAPE = HWPTAG_BEGIN + 5; // 21\nconst TAG_PARA_SHAPE = HWPTAG_BEGIN + 9; // 25\nconst TAG_PARA_HEADER = HWPTAG_BEGIN + 50; // 66\nconst TAG_PARA_TEXT = HWPTAG_BEGIN + 51; // 67\nconst TAG_PARA_CHAR_SHAPE = HWPTAG_BEGIN + 52; // 68\nconst TAG_CTRL_HEADER = HWPTAG_BEGIN + 55; // 71\nconst TAG_PAGE_DEF = HWPTAG_BEGIN + 57; // 73\n\n// TABLE / CELL tags vary by HWP version\nconst TAG_LIST_HEADER = HWPTAG_BEGIN + 56; // 72\nconst TAG_TABLE_A = HWPTAG_BEGIN + 61; // 77\nconst TAG_CELL_A = HWPTAG_BEGIN + 62; // 78\nconst TAG_TABLE_B = HWPTAG_BEGIN + 64; // 80\nconst TAG_CELL_B = HWPTAG_BEGIN + 65; // 81\n\nfunction isTableTag(t: number) { return t === TAG_TABLE_A || t === TAG_TABLE_B; }\nfunction isCellTag(t: number) { return t === TAG_CELL_A || t === TAG_CELL_B || t === TAG_LIST_HEADER; }\n\n// CTRL_HEADER ctrlId values (UINT32-LE as ASCII)\nconst CTRL_TABLE = 0x74626C20; // ' lbt' = 표(table)\nconst CTRL_IMAGE = 0x696D6720; // 'img '\nconst CTRL_OBJ = 0x6F626A20; // 'obj '\nconst CTRL_FIG = 0x66696720; // 'fig '\nconst CTRL_GSO = 0x67736F20; // 'gso ' = 그리기 객체 (drawing object, contains embedded images)\n\n/* ═══════════════════════════════════════════════════════════════\n Types\n ═══════════════════════════════════════════════════════════════ */\n\ninterface HwpRecord {\n tag: number;\n level: number;\n data: Uint8Array;\n}\n\ninterface HwpCharShape {\n faceIds: number[];\n height: number;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikeout: boolean;\n superscript: boolean;\n subscript: boolean;\n textColor: string;\n}\n\ninterface HwpParaShape {\n align: Align;\n spaceBefore: number;\n spaceAfter: number;\n lineSpacing: number;\n leftMargin: number;\n indent: number;\n}\n\ninterface HwpBorderFill {\n borders: { type: number; widthPt: number; color: string }[];\n bgColor?: string;\n}\n\ninterface DocInfo {\n faceNames: string[];\n charShapes: HwpCharShape[];\n paraShapes: HwpParaShape[];\n borderFills: HwpBorderFill[];\n}\n\ninterface ParsedChar { pos: number; ch: string }\ninterface ParsedCtrl { pos: number; ctrlId: number; objId: number; matched: boolean }\ninterface ParaTextResult { chars: ParsedChar[]; controls: ParsedCtrl[] }\n\ninterface OleObject {\n id: number;\n data: Uint8Array;\n mimeType: string;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Low-level record parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseRecords(data: Uint8Array): HwpRecord[] {\n const out: HwpRecord[] = [];\n let off = 0;\n while (off + 4 <= data.length) {\n const hdr = BinaryKit.readU32LE(data, off);\n const tag = hdr & 0x3FF;\n const level = (hdr>> 10) & 0x3FF;\n let size = (hdr>> 20) & 0xFFF;\n off += 4;\n if (size === 0xFFF) {\n if (off + 4> data.length) break;\n size = BinaryKit.readU32LE(data, off);\n off += 4;\n }\n if (off + size> data.length) break;\n out.push({ tag, level, data: data.subarray(off, off + size) });\n off += size;\n }\n return out;\n}\n\nfunction tryInflate(data: Uint8Array): Uint8Array {\n try { return pako.inflate(data); } catch {\n try { return pako.inflateRaw(data); } catch { return data; }\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n FileHeader\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseFileHeader(buf: Uint8Array) {\n if (buf.length < 40) return { compressed: true, encrypted: false };\n const props = BinaryKit.readU32LE(buf, 36);\n return { compressed: (props & 1) !== 0, encrypted: (props & 2) !== 0 };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n DocInfo parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseDocInfo(data: Uint8Array, compressed: boolean): DocInfo {\n const raw = compressed ? tryInflate(data) : data;\n const recs = parseRecords(raw);\n const info: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n\n for (const r of recs) {\n try {\n if (r.tag === TAG_FACE_NAME) info.faceNames.push(parseFaceName(r.data));\n if (r.tag === TAG_CHAR_SHAPE) info.charShapes.push(parseCharShape(r.data));\n if (r.tag === TAG_PARA_SHAPE) info.paraShapes.push(parseParaShape(r.data));\n if (r.tag === TAG_BORDER_FILL) info.borderFills.push(parseBorderFill(r.data));\n } catch { /* skip malformed record */ }\n }\n return info;\n}\n\n/* ── FACE_NAME ──────────────────────────────────────────────── */\n\nfunction parseFaceName(d: Uint8Array): string {\n if (d.length < 3) return '';\n const len = BinaryKit.readU16LE(d, 1); // UTF-16 char count\n if (d.length < 3 + len * 2) return '';\n return new TextDecoder('utf-16le').decode(d.subarray(3, 3 + len * 2));\n}\n\n/* ── CHAR_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 14 faceId[7] (UINT16 ×ばつ 7)\n 14 7 ratio[7]\n 21 7 spacing[7]\n 28 7 relSize[7]\n 35 7 offset[7]\n 42 4 height (UINT32, HWP-units 100 = 1pt)\n 46 4 attr (UINT32, bit flags)\n 50 1 shadowX\n 51 1 shadowY\n 52 4 textColor (COLORREF R,G,B,0) */\n\nfunction parseCharShape(d: Uint8Array): HwpCharShape {\n const faceIds: number[] = [];\n for (let i = 0; i < 7; i++) faceIds.push(d.length>= (i + 1) * 2 ? BinaryKit.readU16LE(d, i * 2) : 0);\n\n const height = d.length>= 46 ? BinaryKit.readU32LE(d, 42) : 1000;\n const attr = d.length>= 50 ? BinaryKit.readU32LE(d, 46) : 0;\n\n // attr bit layout (HWP 5.0 spec Table 35):\n // 0: italic, 1: bold, 2-4: underline type(3), 5-8: underline shape(4),\n // 9-11: outline(3), 12-13: shadow(2), 14: emboss, 15: engrave,\n // 16-17: super/sub(2, 0=none,1=super,2=sub), 18-20: strikeout type(3),\n // 21-24: strikeout shape(4), 25: annotLine, 26-28: annotLine type,\n // 29: useFontSpace, 30: kerning\n const ulType = (attr>> 2) & 0x7; // 3 bits at 2-4\n const skType = (attr>> 18) & 0x7; // 3 bits at 18-20\n const suType = (attr>> 16) & 0x3; // 2 bits at 16-17 (0=none,1=super,2=sub)\n\n return {\n faceIds,\n height: (height> 0 && height < 100000) ? height : 1000,\n italic: (attr & 1) !== 0,\n bold: ((attr>> 1) & 1) !== 0,\n underline: ulType !== 0,\n strikeout: skType !== 0,\n superscript: suType === 1,\n subscript: suType === 2,\n textColor: d.length>= 56 ? colorRef(d, 52) : '000000',\n };\n}\n\n/* ── PARA_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 4 attr1 (bits 0-1 = alignment: 0=justify,1=left,2=right,3=center)\n 4 4 leftMargin (HWPUNIT)\n 8 4 rightMargin\n 12 4 indent\n 16 4 spaceBefore\n 20 4 spaceAfter\n 24 4 lineSpacing */\n\nconst ALIGN_TBL: Record = { 0: 'justify', 1: 'left', 2: 'right', 3: 'center', 4: 'justify' };\n\nfunction parseParaShape(d: Uint8Array): HwpParaShape {\n if (d.length < 4) return { align: 'left', spaceBefore: 0, spaceAfter: 0, lineSpacing: 160, leftMargin: 0, indent: 0 };\n const attr = BinaryKit.readU32LE(d, 0);\n return {\n align: ALIGN_TBL[(attr>> 2) & 0x7] ?? 'left',\n leftMargin: d.length>= 8 ? i32(d, 4) : 0, // offset 4: leftMargin (들여쓰기)\n indent: d.length>= 16 ? i32(d, 12) : 0, // offset 12: first-line indent\n spaceBefore: d.length>= 20 ? i32(d, 16) : 0,\n spaceAfter: d.length>= 24 ? i32(d, 20) : 0,\n lineSpacing: d.length>= 28 ? i32(d, 24) : 160,\n };\n}\n\n/* ── BORDER_FILL ────────────────────────────────────────────── */\n/* [0:2] attr\n For each of 5 borders (left,right,top,bottom,diagonal): 6 bytes\n +0 type(BYTE) +1 widthIdx(BYTE) +2 color(COLORREF)\n [32:4] fillType\n [36:4] faceColor (bgColor for solid fill) */\n\nconst BORDER_W_PT = [0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.70, 1.98, 2.84, 4.25, 5.67, 8.50, 11.34, 14.17];\nconst BORDER_KIND: Record = { 0:'solid',1:'dash',2:'dash',3:'dot',4:'dash',5:'dash',6:'dash',7:'double',8:'double',9:'double',10:'none' };\n\nfunction parseBorderFill(d: Uint8Array): HwpBorderFill {\n // Spec grouped format (표 23):\n // [0:2] attr\n // [2:4] 4 border types (left, right, top, bottom) — 1 byte each\n // [6:4] 4 border widths (left, right, top, bottom) — 1 byte each (index into BORDER_W_PT)\n // [10:16] 4 border colors (left, right, top, bottom) — 4 bytes each (COLORREF)\n // [26:3] diagonal: type(1) + width(1) + color(4) = 6 bytes actually [26:6]\n // [32:4] fillType\n // [36:4] faceColor (bgColor for solid fill)\n const borders: HwpBorderFill['borders'] = [];\n const BASE_TYPE = 2; // 4 type bytes\n const BASE_WIDTH = 6; // 4 width bytes\n const BASE_COLOR = 10; // 4 ×ばつ 4-byte colors\n for (let i = 0; i < 4; i++) {\n const type = BASE_TYPE + i < d.length ? d[BASE_TYPE + i] : 0;\n const widthPt = BASE_WIDTH + i < d.length ? (BORDER_W_PT[d[BASE_WIDTH + i]] ?? 0.5) : 0.5;\n const color = BASE_COLOR + i * 4 + 4 <= d.length ? colorRef(d, BASE_COLOR + i * 4) : '000000';\n borders.push({ type, widthPt, color });\n }\n let bgColor: string | undefined;\n // after attr(2) + 4 types(4) + 4 widths(4) + 4 colors(16) + diagonal(6) = offset 32\n const fOff = 32;\n if (d.length>= fOff + 8) {\n const ft = BinaryKit.readU32LE(d, fOff);\n if (ft & 1) bgColor = colorRef(d, fOff + 4);\n }\n return { borders, bgColor };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Body section parsing\n ═══════════════════════════════════════════════════════════════ */\n\n// gsoCtx: shared mutable counter for 'gso ' drawing objects.\n// Each 'gso ' CTRL_HEADER encountered increments this counter.\n// objectMap is keyed by 0-based gso order = sequential BinData insertion order.\ninterface GsoCtx { count: number }\n\nfunction parseBody(\n raw: Uint8Array, compressed: boolean, di: DocInfo, shield: ShieldedParser, gsoCtx: GsoCtx,\n): { content: ContentNode[]; pageDims?: PageDims } {\n const recs = parseRecords(compressed ? tryInflate(raw) : raw);\n const content: ContentNode[] = [];\n let pageDims: PageDims | undefined;\n\n // Pre-scan for PAGE_DEF at any nesting level (real HWP stores it at level 2 inside section ctrl)\n for (const r of recs) {\n if (r.tag === TAG_PAGE_DEF) {\n pageDims = shield.guard(() => parsePageDef(r.data), A4, 'hwp:pageDef');\n break;\n }\n }\n\n let i = 0;\n while (i < recs.length) {\n if (recs[i].tag === TAG_PAGE_DEF) {\n i++; // already handled above; skip at top level\n } else if (recs[i].tag === TAG_PARA_HEADER) {\n const r = shield.guard(\n () => parseParagraphGroup(recs, i, di, shield, gsoCtx),\n { nodes: [] as ContentNode[], next: i + 1 },\n `hwp:para@${i}`,\n );\n content.push(...r.nodes);\n i = r.next;\n } else {\n i++;\n }\n }\n return { content, pageDims };\n}\n\n/* ── Paragraph group ────────────────────────────────────────── */\n\nfunction parseParagraphGroup(\n recs: HwpRecord[], start: number, di: DocInfo, shield: ShieldedParser, gsoCtx: GsoCtx,\n): { nodes: ContentNode[]; next: number } {\n const hdr = recs[start];\n const lv = hdr.level;\n\n // paraShapeId at offset 8 (UINT16)\n const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n\n let text: ParaTextResult | null = null;\n let csPairs: [number, number][] = [];\n const grids: ContentNode[] = [];\n // imgId: for 'gso' uses sequential gsoCtx.count; for others uses flags-based objId\n const ctrlHeaders: { ctrlId: number; imgId: number; wPt: number; hPt: number }[] = [];\n let i = start + 1;\n\n while (i < recs.length && recs[i].level> lv) {\n const r = recs[i];\n\n if (r.tag === TAG_PARA_TEXT && r.level === lv + 1) {\n text = decodeParaText(r.data);\n i++;\n } else if (r.tag === TAG_PARA_CHAR_SHAPE && r.level === lv + 1) {\n csPairs = parseCharShapePairs(r.data);\n i++;\n } else if (r.tag === TAG_CTRL_HEADER && r.level === lv + 1) {\n if (r.data.length>= 4) {\n const ctrlId = BinaryKit.readU32LE(r.data, 0);\n\n // HWP 5.0 general-object layout:\n // [0:4] ctrlId [4:4] flags [8:4] xOff [12:4] yOff\n // [16:4] width(HWPUNIT) [20:4] height(HWPUNIT)\n const MAX_HWP = 1_000_000;\n const rawW = r.data.length>= 24 ? BinaryKit.readU32LE(r.data, 16) : 0;\n const rawH = r.data.length>= 28 ? BinaryKit.readU32LE(r.data, 20) : 0;\n const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n\n // 'gso ' (그리기 객체) uses sequential counter; others use flags-based id\n const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : (r.data.length>= 6 ? BinaryKit.readU16LE(r.data, 4) : 0);\n ctrlHeaders.push({ ctrlId, imgId, wPt, hPt });\n\n if (ctrlId === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, i, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, i) },\n `hwp:tbl@${i}`,\n );\n if (tr.grid) grids.push(tr.grid);\n i = tr.next;\n } else {\n i = skipKids(recs, i);\n }\n } else {\n i = skipKids(recs, i);\n }\n } else {\n i++;\n }\n }\n\n const nodes: ContentNode[] = [];\n\n // Build paragraph from text and inline controls (images)\n if (text && (text.chars.length> 0 || text.controls.length> 0)) {\n const paraContent: (SpanNode | ContentNode)[] = [];\n\n if (text.chars.length> 0) {\n const spans = resolveCharShapes(text.chars, csPairs, di);\n paraContent.push(...spans);\n }\n\n // Image placeholder spans: only for actual image controls.\n // Non-image controls (footnotes, TOC entries, etc.) are silently skipped.\n if (text.controls.length> 0) {\n for (let ci = 0; ci < text.controls.length; ci++) {\n const ch = ctrlHeaders[ci];\n if (!ch) continue; // anchor-only ctrl (gso is sibling, not inline)\n const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO;\n if (!isImg) continue; // skip footnotes, TOC, page num, etc.\n const dimStr = (ch.wPt> 0 && ch.hPt> 0)\n ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}`\n : '';\n paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`));\n }\n }\n\n if (paraContent.length> 0) {\n nodes.push(buildPara(paraContent as any, buildParaProps(ps)));\n }\n }\n\n nodes.push(...grids);\n return { nodes, next: i };\n}\n\nfunction skipKids(recs: HwpRecord[], idx: number): number {\n const lv = recs[idx].level;\n let i = idx + 1;\n while (i < recs.length && recs[i].level> lv) i++;\n return i;\n}\n\n/* ── PARA_TEXT ───────────────────────────────────────────────── */\n\n// Extended controls: 8 WORDs, associated CTRL_HEADER\nconst EXT_CTRL = new Set([2, 3, 11, 12, 14, 15]);\n// Inline controls: 8 WORDs, no CTRL_HEADER\nconst INL_CTRL = new Set([4, 5, 6, 7, 8]);\n\nfunction decodeParaText(d: Uint8Array): ParaTextResult {\n const chars: ParsedChar[] = [];\n const controls: ParsedCtrl[] = [];\n let i = 0, pos = 0;\n\n while (i + 1 < d.length) {\n const c = d[i] | (d[i + 1] << 8);\n if (c === 0) { i += 2; pos++; continue; }\n if (c === 13) { break; } // paragraph end\n if (c === 10) { chars.push({ pos, ch: '\\n' }); i += 2; pos++; continue; }\n\n if (EXT_CTRL.has(c)) {\n // Extended control: 8 WORDs (16 bytes)\n // WORD 4 contains objId (for images, charts, etc.)\n let objId = 0;\n if (i + 16 <= d.length) {\n objId = BinaryKit.readU16LE(d, i + 8); // 4th WORD (offset 8) contains objId\n }\n controls.push({ pos, ctrlId: 0, objId, matched: false });\n i += 16; pos += 8; continue;\n }\n if (INL_CTRL.has(c)) {\n i += 16; pos += 8; continue;\n }\n if (c === 9) { // tab (inline 8 WORDs)\n chars.push({ pos, ch: '\\t' });\n i += 16; pos += 8; continue;\n }\n if (c>= 1 && c <= 31) { i += 2; pos++; continue; } // other control\n\n chars.push({ pos, ch: String.fromCharCode(c) });\n i += 2; pos++;\n }\n return { chars, controls };\n}\n\n/* ── PARA_CHAR_SHAPE ────────────────────────────────────────── */\n\nfunction parseCharShapePairs(d: Uint8Array): [number, number][] {\n const out: [number, number][] = [];\n for (let i = 0; i + 7 < d.length; i += 8)\n out.push([BinaryKit.readU32LE(d, i), BinaryKit.readU32LE(d, i + 4)]);\n return out;\n}\n\n/* ── Char-shape → SpanNode resolution ───────────────────────── */\n\nfunction resolveCharShapes(chars: ParsedChar[], pairs: [number, number][], di: DocInfo): SpanNode[] {\n if (chars.length === 0) return [buildSpan('')];\n\n const defaultId = pairs.length> 0 ? pairs[0][1] : 0;\n\n function idFor(pos: number): number {\n let id = defaultId;\n for (const [p, sid] of pairs) { if (p <= pos) id = sid; else break; }\n return id;\n }\n\n const spans: SpanNode[] = [];\n let curId = idFor(chars[0].pos);\n let buf = chars[0].ch;\n\n for (let k = 1; k < chars.length; k++) {\n const sid = idFor(chars[k].pos);\n if (sid !== curId) { spans.push(styledSpan(buf, curId, di)); buf = ''; curId = sid; }\n buf += chars[k].ch;\n }\n if (buf) spans.push(styledSpan(buf, curId, di));\n return spans;\n}\n\nfunction styledSpan(text: string, shapeId: number, di: DocInfo): SpanNode {\n const cs = di.charShapes[shapeId];\n if (!cs) return buildSpan(text);\n\n const props: TextProps = {};\n const fid = cs.faceIds[0] ?? 0;\n if (fid < di.faceNames.length && di.faceNames[fid]) props.font = safeFont(di.faceNames[fid]);\n if (cs.height> 0) props.pt = Metric.hwpToPt(cs.height);\n if (cs.bold) props.b = true;\n if (cs.italic) props.i = true;\n if (cs.underline) props.u = true;\n if (cs.strikeout) props.s = true;\n if (cs.superscript) props.sup = true;\n if (cs.subscript) props.sub = true;\n\n const hex = safeHex(cs.textColor);\n if (hex && hex !== '000000') props.color = hex;\n\n return buildSpan(text, props);\n}\n\n/* ── Table control parsing ──────────────────────────────────── */\n\nfunction parseTableCtrl(\n recs: HwpRecord[], ctrlIdx: number, di: DocInfo, shield: ShieldedParser, gsoCtx: GsoCtx,\n): { grid: ContentNode | null; next: number } {\n const ctrlLv = recs[ctrlIdx].level;\n let i = ctrlIdx + 1;\n\n let tblData: Uint8Array | null = null;\n const cells: { data: Uint8Array; tag: number; cStart: number; cEnd: number }[] = [];\n\n // Collect TABLE and cell records within this control's scope\n const tblLevel = ctrlLv + 1;\n\n while (i < recs.length && recs[i].level> ctrlLv) {\n const r = recs[i];\n\n if (isTableTag(r.tag) && r.level === tblLevel) {\n tblData = r.data;\n i++;\n } else if (r.tag === TAG_LIST_HEADER && r.level === tblLevel) {\n // LIST_HEADER as cell: paraCount tells how many paragraphs follow\n const cellData = r.data;\n const paraCount = cellData.length>= 2 ? BinaryKit.readU16LE(cellData, 0) : 0;\n i++;\n const cStart = i;\n // Consume exactly paraCount paragraphs (each with its child records)\n let consumed = 0;\n while (i < recs.length && consumed < paraCount) {\n if (recs[i].tag === TAG_PARA_HEADER && recs[i].level === tblLevel) {\n consumed++;\n i++;\n // Skip child records of this paragraph\n while (i < recs.length && recs[i].level> tblLevel) i++;\n } else if (recs[i].level> tblLevel) {\n i++;\n } else {\n break; // hit next sibling at same level\n }\n }\n cells.push({ data: cellData, tag: TAG_LIST_HEADER, cStart, cEnd: i });\n } else if (isCellTag(r.tag) && r.level === tblLevel) {\n // Full CELL record (with cell-specific fields)\n const cellData = r.data;\n const cellTag = r.tag;\n i++;\n const cStart = i;\n while (i < recs.length && recs[i].level> tblLevel) i++;\n cells.push({ data: cellData, tag: cellTag, cStart, cEnd: i });\n } else {\n i++;\n }\n }\n\n if (!tblData || cells.length === 0) return { grid: null, next: i };\n\n const rowCnt = tblData.length>= 6 ? BinaryKit.readU16LE(tblData, 4) : 1;\n const colCnt = tblData.length>= 8 ? BinaryKit.readU16LE(tblData, 6) : 1;\n\n interface PC { row: number; col: number; cs: number; rs: number; widthHwp: number; heightHwp?: number; props: CellProps; cellChildren: (ParaNode | GridNode)[] }\n const parsed: PC[] = [];\n\n for (let ci = 0; ci < cells.length; ci++) {\n const c = cells[ci];\n const seqIdx = ci;\n const pc = shield.guard(\n () => parseCellRec(c.data, c.tag, recs, c.cStart, c.cEnd, di, shield, seqIdx, colCnt, gsoCtx),\n { row: Math.floor(ci / (colCnt || 1)), col: ci % (colCnt || 1), cs: 1, rs: 1, widthHwp: 0, heightHwp: undefined, props: {}, cellChildren: [buildPara([buildSpan('')])] },\n `hwp:cell@${c.cStart}`,\n );\n parsed.push(pc);\n }\n\n // Determine actual row count from cell data (may exceed rowCnt for merged cells)\n const maxRow = parsed.reduce((m, c) => Math.max(m, c.row + c.rs), 0);\n const actualRowCnt = Math.max(rowCnt, maxRow);\n\n // Validate cell positions; fallback to sequential layout if invalid\n const posValid = parsed.every(c => c.row>= 0 && c.col>= 0 && c.col < colCnt);\n if (!posValid) {\n let idx = 0;\n for (const c of parsed) { c.row = Math.floor(idx / colCnt); c.col = idx % colCnt; idx++; }\n }\n\n // Compute column widths in points from cell widths\n const colWidthsPt: number[] = new Array(colCnt).fill(0);\n // Pass 1: use cells with cs=1 for exact column widths\n for (const c of parsed) {\n if (c.cs === 1 && c.widthHwp> 0) {\n const wPt = Metric.hwpToPt(c.widthHwp);\n if (wPt> colWidthsPt[c.col]) colWidthsPt[c.col] = wPt;\n }\n }\n // Pass 2: for columns still 0, try to derive from multi-span cells\n // Sort by span size ascending so smaller, more precise spans fill widths before larger spans\n const zeroColumns = colWidthsPt.filter(w => w === 0).length;\n if (zeroColumns> 0) {\n const spanCells = parsed.filter(c => c.cs> 1 && c.widthHwp> 0).sort((a, b) => a.cs - b.cs);\n for (const c of spanCells) {\n if (c.cs> 1 && c.widthHwp> 0) {\n // Subtract known column widths from the span\n let known = 0;\n let unknownCols = 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci]> 0) known += colWidthsPt[ci];\n else unknownCols++;\n }\n if (unknownCols> 0) {\n const remaining = Metric.hwpToPt(c.widthHwp) - known;\n const each = remaining> 0 ? remaining / unknownCols : 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci] === 0 && each> 0) colWidthsPt[ci] = each;\n }\n }\n }\n }\n }\n\n // Post-process: clamp near-zero column widths (< 1pt = floating-point artifact) to minimum 1pt\n for (let i = 0; i < colWidthsPt.length; i++) {\n if (colWidthsPt[i]> 0 && colWidthsPt[i] < 1) colWidthsPt[i] = 1;\n }\n\n const rows = [];\n for (let r = 0; r < actualRowCnt; r++) {\n const rc = parsed.filter(c => c.row === r).sort((a, b) => a.col - b.col);\n if (rc.length === 0) continue;\n\n // Calculate row height — prefer rs=1 cells (exact per-row height)\n let rowHeightPt: number | undefined = undefined;\n for (const c of rc) {\n if (c.heightHwp && c.heightHwp> 0 && c.rs === 1) {\n const hPt = Metric.hwpToPt(c.heightHwp);\n if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt;\n }\n }\n // Fallback: all cells span multiple rows → approximate height per row\n if (rowHeightPt == null) {\n for (const c of rc) {\n if (c.heightHwp && c.heightHwp> 0) {\n const hPt = Metric.hwpToPt(c.heightHwp) / c.rs;\n if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt;\n }\n }\n }\n\n rows.push(buildRow(rc.map(c => {\n return buildCell(c.cellChildren, { cs: c.cs, rs: c.rs, props: c.props });\n }), rowHeightPt));\n }\n if (rows.length === 0) return { grid: null, next: i };\n\n // Table-level default stroke\n let defStroke: Stroke | undefined;\n const bfOff = 18 + rowCnt * 2;\n if (tblData.length>= bfOff + 2) {\n const bfId = BinaryKit.readU16LE(tblData, bfOff);\n defStroke = strokeFromBF(bfId, di);\n }\n\n const gp: GridProps = {};\n if (defStroke) gp.defaultStroke = defStroke;\n const hasWidths = colWidthsPt.some(w => w> 0);\n if (hasWidths) gp.colWidths = colWidthsPt;\n return { grid: buildGrid(rows, gp), next: i };\n}\n\n/* ── Cell record ────────────────────────────────────────────── */\n/* LIST_HEADER for cells (HWP 5.0/5.1):\n [0:2] paraCount [2:4] attr (bits 6-7 = vertAlign)\n [6:2] unknown [8:2] rowAddr [10:2] colAddr\n [12:2] rowSpan [14:2] colSpan\n [16:4] width(HWPUNIT) [20:4] height(HWPUNIT)\n [24:8] padding[4] [32:2] borderFillId */\n\nfunction parseCellRec(\n d: Uint8Array, tag: number, recs: HwpRecord[], cStart: number, cEnd: number,\n di: DocInfo, shield: ShieldedParser, seqIdx: number, colCnt: number, gsoCtx: GsoCtx,\n) {\n let col: number, row: number, cs = 1, rs = 1;\n let widthHwp = 0;\n let heightHwp = 0;\n const props: CellProps = {};\n\n const attr = d.length>= 6 ? BinaryKit.readU32LE(d, 2) : 0;\n const va = (attr>> 6) & 0x3;\n if (va === 1) props.va = 'mid';\n else if (va === 2) props.va = 'bot';\n\n const HWP_PAD_LR_DEFAULT = 360;\n const HWP_PAD_TB_DEFAULT = 141;\n\n if (tag === TAG_LIST_HEADER && d.length>= 22) {\n col = BinaryKit.readU16LE(d, 8);\n row = BinaryKit.readU16LE(d, 10);\n cs = Math.max(1, BinaryKit.readU16LE(d, 12));\n rs = Math.max(1, BinaryKit.readU16LE(d, 14));\n widthHwp = BinaryKit.readU32LE(d, 16);\n heightHwp = d.length>= 24 ? BinaryKit.readU32LE(d, 20) : 0;\n if (d.length>= 32) {\n const pL = BinaryKit.readU16LE(d, 24); const pR = BinaryKit.readU16LE(d, 26);\n const pT = BinaryKit.readU16LE(d, 28); const pB = BinaryKit.readU16LE(d, 30);\n if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL);\n if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR);\n if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT);\n if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB);\n }\n const bfId = d.length>= 34 ? BinaryKit.readU16LE(d, 32) : 0;\n if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props);\n } else if (tag !== TAG_LIST_HEADER) {\n col = d.length>= 8 ? BinaryKit.readU16LE(d, 6) : seqIdx % (colCnt || 1);\n row = d.length>= 10 ? BinaryKit.readU16LE(d, 8) : Math.floor(seqIdx / (colCnt || 1));\n cs = d.length>= 12 ? Math.max(1, BinaryKit.readU16LE(d, 10)) : 1;\n rs = d.length>= 14 ? Math.max(1, BinaryKit.readU16LE(d, 12)) : 1;\n widthHwp = d.length>= 18 ? BinaryKit.readU32LE(d, 14) : 0;\n heightHwp = d.length>= 22 ? BinaryKit.readU32LE(d, 18) : 0;\n if (d.length>= 30) {\n const pL = BinaryKit.readU16LE(d, 22); const pR = BinaryKit.readU16LE(d, 24);\n const pT = BinaryKit.readU16LE(d, 26); const pB = BinaryKit.readU16LE(d, 28);\n if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL);\n if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR);\n if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT);\n if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB);\n }\n const bfId = d.length>= 32 ? BinaryKit.readU16LE(d, 30) : 0;\n if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props);\n } else {\n row = Math.floor(seqIdx / (colCnt || 1));\n col = seqIdx % (colCnt || 1);\n }\n\n const cellChildren: (ParaNode | GridNode)[] = [];\n const MAX_HWP = 1_000_000;\n let k = cStart;\n\n while (k < cEnd) {\n if (recs[k].tag === TAG_PARA_HEADER) {\n // Parse paragraph inside cell — also extracts nested tables within the paragraph\n const r = shield.guard(\n () => {\n const hdr = recs[k];\n const lv = hdr.level;\n const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n let txt: ParaTextResult | null = null;\n let csp: [number, number][] = [];\n const ctrlHdrs: { ctrlId: number; imgId: number; wPt: number; hPt: number }[] = [];\n const innerGrids: GridNode[] = [];\n let j = k + 1;\n while (j < cEnd && recs[j].level> lv) {\n if (recs[j].tag === TAG_PARA_TEXT) { txt = decodeParaText(recs[j].data); j++; }\n else if (recs[j].tag === TAG_PARA_CHAR_SHAPE) { csp = parseCharShapePairs(recs[j].data); j++; }\n else if (recs[j].tag === TAG_CTRL_HEADER && recs[j].level === lv + 1) {\n if (recs[j].data.length>= 4) {\n const ctrlId = BinaryKit.readU32LE(recs[j].data, 0);\n if (ctrlId === CTRL_TABLE) {\n // Nested table inside a cell paragraph — recurse into parseTableCtrl\n const nestedTr = shield.guard(\n () => parseTableCtrl(recs, j, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, j) },\n `hwp:innerNestedTbl@${j}`,\n );\n if (nestedTr.grid) innerGrids.push(nestedTr.grid as GridNode);\n j = nestedTr.next;\n } else {\n const rawW = recs[j].data.length>= 24 ? BinaryKit.readU32LE(recs[j].data, 16) : 0;\n const rawH = recs[j].data.length>= 28 ? BinaryKit.readU32LE(recs[j].data, 20) : 0;\n const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : (recs[j].data.length>= 6 ? BinaryKit.readU16LE(recs[j].data, 4) : 0);\n ctrlHdrs.push({ ctrlId, imgId, wPt, hPt });\n j = skipKids(recs, j);\n }\n } else {\n j = skipKids(recs, j);\n }\n }\n else j++;\n }\n const paraContent: (SpanNode | ContentNode)[] = [];\n if (txt && txt.chars.length> 0) paraContent.push(...resolveCharShapes(txt.chars, csp, di));\n if (txt && txt.controls.length> 0) {\n for (let ci = 0; ci < txt.controls.length; ci++) {\n const ch = ctrlHdrs[ci];\n if (!ch) continue;\n const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO;\n if (!isImg) continue;\n const dimStr = (ch.wPt> 0 && ch.hPt> 0) ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}` : '';\n paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`));\n }\n }\n const kids = paraContent.length> 0 ? paraContent as any : [buildSpan('')];\n const items: (ParaNode | GridNode)[] = [buildPara(kids, buildParaProps(ps)), ...innerGrids];\n return { items, next: j };\n },\n { items: [buildPara([buildSpan('')])] as (ParaNode | GridNode)[], next: k + 1 },\n `hwp:cellP@${k}`,\n );\n cellChildren.push(...r.items);\n k = r.next;\n } else if (recs[k].tag === TAG_CTRL_HEADER && recs[k].data.length>= 4) {\n // CTRL_HEADER at cell level (sibling of PARA_HEADER) — anchored 'gso' images and outer-level nested tables\n const cellCtrlId = BinaryKit.readU32LE(recs[k].data, 0);\n if (cellCtrlId === CTRL_GSO) {\n const gsoId = gsoCtx.count++;\n const rawW = recs[k].data.length>= 24 ? BinaryKit.readU32LE(recs[k].data, 16) : 0;\n const rawH = recs[k].data.length>= 28 ? BinaryKit.readU32LE(recs[k].data, 20) : 0;\n const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n const dimStr = (wPt> 0 && hPt> 0) ? `_W${Math.round(wPt)}_H${Math.round(hPt)}` : '';\n cellChildren.push(buildPara([buildSpan(`__EXT_${gsoId}${dimStr}__`)]));\n k = skipKids(recs, k);\n } else if (cellCtrlId === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, k, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, k) },\n `hwp:nestedTbl@${k}`,\n );\n if (tr.grid) cellChildren.push(tr.grid as GridNode);\n k = tr.next;\n } else {\n k = skipKids(recs, k);\n }\n } else { k++; }\n }\n\n return {\n row, col, cs, rs, props, widthHwp,\n heightHwp: heightHwp || undefined,\n cellChildren: cellChildren.length ? cellChildren : [buildPara([buildSpan('')])],\n };\n}\n\n/* ── PAGE_DEF ───────────────────────────────────────────────── */\n/* [0:4] width [4:4] height [8:4] ml [12:4] mr\n [16:4] mt [20:4] mb [36:4] attr (bit0=landscape) */\n\nfunction parsePageDef(d: Uint8Array): PageDims {\n if (d.length < 24) return A4;\n const w = BinaryKit.readU32LE(d, 0);\n const h = BinaryKit.readU32LE(d, 4);\n const ml = BinaryKit.readU32LE(d, 8);\n const mr = BinaryKit.readU32LE(d, 12);\n const mt = BinaryKit.readU32LE(d, 16);\n const mb = BinaryKit.readU32LE(d, 20);\n const at = d.length>= 40 ? BinaryKit.readU32LE(d, 36) : 0;\n return {\n wPt: Metric.hwpToPt(w), hPt: Metric.hwpToPt(h),\n ml: Metric.hwpToPt(ml), mr: Metric.hwpToPt(mr),\n mt: Metric.hwpToPt(mt), mb: Metric.hwpToPt(mb),\n orient: (at & 1) ? 'landscape' : 'portrait',\n };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Helpers\n ═══════════════════════════════════════════════════════════════ */\n\nfunction i32(d: Uint8Array, o: number): number {\n const u = BinaryKit.readU32LE(d, o);\n return u> 0x7FFFFFFF ? u - 0x100000000 : u;\n}\n\nfunction colorRef(d: Uint8Array, o: number): string {\n if (o + 3> d.length) return '000000';\n return ((d[o] << 16) | (d[o + 1] << 8) | d[o + 2]).toString(16).padStart(6, '0').toUpperCase();\n}\n\nfunction toStroke(b: { type: number; widthPt: number; color: string }): Stroke {\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\n// Apply borderFill to CellProps. Preserve explicit NONE so DOCX tcBorders can\n// override the table-level tblBorders. Filtering NONE would let tblBorders bleed through.\nfunction applyCellBorderFill(bf: HwpBorderFill, props: CellProps): void {\n if (bf.borders.length>= 4) {\n props.left = toStroke(bf.borders[0]);\n props.right = toStroke(bf.borders[1]);\n props.top = toStroke(bf.borders[2]);\n props.bot = toStroke(bf.borders[3]);\n }\n if (bf.bgColor && bf.bgColor !== 'FFFFFF') props.bg = bf.bgColor;\n}\n\nfunction strokeFromBF(bfId: number, di: DocInfo): Stroke | undefined {\n if (bfId <= 0 || bfId> di.borderFills.length) return undefined;\n const bf = di.borderFills[bfId - 1];\n if (!bf.borders.length) return undefined;\n const b = bf.borders[0];\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\nfunction buildParaProps(ps?: HwpParaShape): ParaProps {\n if (!ps) return {};\n const p: ParaProps = {};\n if (ps.align && ps.align !== 'left') p.align = ps.align;\n if (ps.spaceBefore> 0) p.spaceBefore = Metric.hwpToPt(ps.spaceBefore);\n if (ps.spaceAfter> 0) p.spaceAfter = Metric.hwpToPt(ps.spaceAfter);\n if (ps.lineSpacing> 0 && ps.lineSpacing !== 160) p.lineHeight = ps.lineSpacing / 100;\n // leftMargin (offset 4) = 문단 몸체 왼쪽 여백 → leftMargin (pt), ensure non-negative\n const leftMarginPt = Math.max(0, Metric.hwpToPt(ps.leftMargin));\n if (leftMarginPt> 0) p.leftMargin = leftMarginPt;\n // indent (offset 12) = 첫 줄 들여쓰기(양수) / 내어쓰기(음수) → firstLineIndentPt\n if (ps.indent !== 0) p.firstLineIndentPt = Metric.hwpToPt(ps.indent);\n return p;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Decoder class\n ═══════════════════════════════════════════════════════════════ */\n\nexport class HwpScanner implements Decoder {\n readonly format = 'hwp';\n readonly aliases = ['application/vnd.hancom.hwp'];\n\n async decode(data: Uint8Array): Promise> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n if (!BinaryKit.isOle2(data)) return fail('HWP: Invalid OLE2 signature');\n const streams = BinaryKit.parseCfb(data);\n\n // FileHeader\n const fh = streams.get('FileHeader');\n const { compressed, encrypted } = fh ? parseFileHeader(fh) : { compressed: true, encrypted: false };\n if (encrypted) return fail('HWP: 암호화된 파일은 지원하지 않습니다');\n\n // DocInfo\n const diRaw = streams.get('DocInfo');\n let di: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n if (diRaw) {\n di = shield.guard(() => parseDocInfo(diRaw, compressed), di, 'hwp:docInfo');\n }\n\n // Extract images from BinData streams.\n // HWP duplicates each BinData entry: once as \"BinData/BIN0001.jpg\" and once as \"BIN0001.jpg\".\n // We keep only the \"BinData/\" prefixed versions, sort by BIN number, then assign 0-based keys\n // matching the order 'gso' CTRL_HEADER records are encountered during body parsing.\n const binEntries: { binNum: number; data: Uint8Array }[] = [];\n for (const [path, streamData] of streams) {\n // Match \"BinData/BIN0001.jpg\" style — the canonical form\n const m = path.match(/^BinData[/\\\\]BIN(\\d+)\\.\\w+$/i);\n if (m) binEntries.push({ binNum: parseInt(m[1], 10), data: streamData });\n }\n // Sort by BIN number (ascending) so BIN0001→idx0, BIN0002→idx1, ...\n binEntries.sort((a, b) => a.binNum - b.binNum);\n\n const objectMap = new Map();\n for (let idx = 0; idx < binEntries.length; idx++) {\n const { data: imgData } = binEntries[idx];\n\n // Determine MIME type from binary signature first, then fall back to extension\n let mimeType: ImgNode['mime'] = 'image/jpeg';\n if (imgData[0] === 0x89 && imgData[1] === 0x50) mimeType = 'image/png';\n else if (imgData[0] === 0x47 && imgData[1] === 0x49) mimeType = 'image/gif';\n else if (imgData[0] === 0x42 && imgData[1] === 0x4D) mimeType = 'image/bmp';\n\n const base64 = TextKit.base64Encode(imgData);\n const { wPt, hPt } = getImageDimsPt(imgData, mimeType);\n objectMap.set(idx, buildImg(base64, mimeType, wPt, hPt));\n }\n\n // gsoCtx tracks sequential 'gso' encounter order — must be shared across all sections\n const gsoCtx: GsoCtx = { count: 0 };\n\n // Body sections\n const allContent: ContentNode[] = [];\n let pageDims: PageDims = A4;\n\n for (let s = 0; s < 100; s++) {\n const sec = streams.get(`BodyText/Section${s}`) ?? streams.get(`Section${s}`);\n if (!sec) {\n if (s === 0) {\n const fb = findBodySection(streams);\n if (fb) {\n const r = parseBody(fb, compressed, di, shield, gsoCtx);\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n }\n break;\n }\n const r = shield.guard(\n () => parseBody(sec, compressed, di, shield, gsoCtx),\n { content: [], pageDims: undefined },\n `hwp:sec${s}`,\n );\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n\n if (objectMap.size> 0) {\n injectImagesIntoContent(allContent, objectMap);\n }\n\n warns.push(...shield.flush());\n const content = allContent.length> 0 ? allContent : [buildPara([buildSpan('')])];\n return succeed(buildRoot({}, [buildSheet(content, pageDims)]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWP decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\nfunction findBodySection(streams: Map): Uint8Array | undefined {\n for (const [k, v] of streams)\n if (k.includes('Section') && !k.includes('Header') && !k.includes('Info')) return v;\n return undefined;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Image dimension extraction from binary headers\n ════════════════════════════════════════════════════════════ */\n\n// Returns { wPt, hPt } by parsing image headers; falls back to { wPt: 72, hPt: 72 } (1-inch)\nfunction getImageDimsPt(data: Uint8Array, mime: string): { wPt: number; hPt: number } {\n const fallback = { wPt: 72, hPt: 72 };\n try {\n if (mime === 'image/png' && data.length>= 24) {\n // PNG IHDR: sig(8) + length(4) + type(4) + width(4) + height(4) — all big-endian\n const w = (data[16] << 24 | data[17] << 16 | data[18] << 8 | data[19])>>> 0;\n const h = (data[20] << 24 | data[21] << 16 | data[22] << 8 | data[23])>>> 0;\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; // 96 DPI → pt\n }\n if (mime === 'image/jpeg') {\n // Scan for SOF markers: FF C0 / C1 / C2 / C3\n let i = 2;\n while (i + 8 < data.length) {\n if (data[i] !== 0xFF) { i++; continue; }\n const marker = data[i + 1];\n if (marker>= 0xC0 && marker <= 0xC3) {\n // SOF: 2-byte marker + 2-byte length + 1-byte precision + 2-byte height + 2-byte width\n const h = (data[i + 5] << 8 | data[i + 6])>>> 0;\n const w = (data[i + 7] << 8 | data[i + 8])>>> 0;\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n const segLen = data[i + 2] << 8 | data[i + 3];\n i += 2 + (segLen> 0 ? segLen : 2);\n }\n }\n if (mime === 'image/bmp' && data.length>= 26) {\n // BMP DIB header: width at 18, height at 22 (signed int32 LE; negative = top-down)\n const w = BinaryKit.readU32LE(data, 18);\n const h = Math.abs(BinaryKit.readU32LE(data, 22) | 0);\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n if (mime === 'image/gif' && data.length>= 10) {\n // GIF: width at 6, height at 8 (uint16 LE)\n const w = data[6] | data[7] << 8;\n const h = data[8] | data[9] << 8;\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n } catch { /* ignore */ }\n return fallback;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n OLE Object extraction (images)\n ════════════════════════════════════════════════════════════ */\n\nfunction extractImagesFromOleObjectLink(data: Uint8Array): OleObject[] {\n const objects: OleObject[] = [];\n let off = 0;\n\n while (off + 8 <= data.length) {\n const objId = BinaryKit.readU32LE(data, off);\n const dataSize = BinaryKit.readU32LE(data, off + 4);\n const reserved = BinaryKit.readU32LE(data, off + 8);\n\n if (objId === 0 || dataSize === 0) break;\n\n const objOff = off + 16;\n if (objOff + dataSize> data.length) break;\n\n const objData = data.subarray(objOff, objOff + dataSize);\n\n // Detect MIME type from signature\n let mimeType = 'application/octet-stream';\n if (objData[0] === 0xFF && objData[1] === 0xD8 && objData[2] === 0xFF) {\n mimeType = 'image/jpeg';\n } else if (objData[0] === 0x89 && objData[1] === 0x50 && objData[2] === 0x4E && objData[3] === 0x47) {\n mimeType = 'image/png';\n } else if (objData[0] === 0x47 && objData[1] === 0x49 && objData[2] === 0x46 && objData[3] === 0x3538) {\n mimeType = 'image/gif';\n } else if (objData[0] === 0x42 && objData[1] === 0x4D) {\n mimeType = 'image/bmp';\n }\n\n objects.push({ id: objId, data: objData, mimeType });\n off = objOff + dataSize;\n }\n\n return objects;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Helper to inject images into paragraph content\n ════════════════════════════════════════════════════════════ */\n\nfunction injectImagesIntoContent(\n content: ContentNode[],\n objectMap: Map\n): void {\n if (objectMap.size === 0) return;\n\n // Helper function to process a list of kids (spans, images, etc.)\n const processKids = (kids: any[]) => {\n for (let i = 0; i < kids.length; i++) {\n const kid = kids[i];\n // Span node structure: { tag: 'span', props, kids: [{ tag: 'txt', content }] }\n if (kid.tag === 'span' && kid.kids && kid.kids[0]?.tag === 'txt') {\n const text = kid.kids[0].content;\n // __EXT_N__ or __EXT_N_W_H__ (with encoded display size)\n // N is the objId that matches the index in objectMap\n const match = text.match?.(/^__(?:IMG|EXT)_(\\d+)(?:_W(\\d+)_H(\\d+))?__$/);\n if (match) {\n const objId = parseInt(match[1], 10);\n const base = objectMap.get(objId);\n if (base) {\n const wPt = match[2] ? parseInt(match[2], 10) : 0;\n const hPt = match[3] ? parseInt(match[3], 10) : 0;\n // Use encoded display size when valid; otherwise keep pixel-based dims\n kids[i] = (wPt> 0 && hPt> 0) ? { ...base, w: wPt, h: hPt } : base;\n }\n }\n }\n }\n };\n\n // Recursively process a grid (table): resolves image placeholders in all cells,\n // including nested grids inside cells.\n const processGridKids = (grid: any) => {\n if (!grid.kids || !Array.isArray(grid.kids)) return;\n\n for (const row of grid.kids) {\n if (!row.kids || !Array.isArray(row.kids)) continue;\n\n for (const cell of row.kids) {\n if (!cell.kids || !Array.isArray(cell.kids)) continue;\n\n for (const cellKid of cell.kids) {\n if (cellKid.tag === 'grid') {\n // Nested table inside cell — recurse\n processGridKids(cellKid);\n } else if (cellKid.tag === 'para' && cellKid.kids) {\n processKids(cellKid.kids);\n }\n }\n }\n }\n };\n\n for (const node of content) {\n if (node.tag === 'para' && node.kids) {\n // Process paragraph kids (spans, images, links, grids)\n processKids(node.kids);\n\n // Also process any nested grids inside the paragraph\n for (const kid of node.kids) {\n if (kid.tag === 'grid') {\n processGridKids(kid);\n }\n }\n } else if (node.tag === 'grid') {\n // Process grid nodes (tables)\n processGridKids(node);\n }\n }\n}\n\nregistry.registerDecoder(new HwpScanner());\n","import type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n LinkNode,\n PageNumNode,\n CellNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n DocMeta,\n PageDims,\n TextProps,\n ParaProps,\n CellProps,\n GridProps,\n TableLook,\n Stroke,\n ImgLayout,\n ImgHorzAlign,\n ImgVertAlign,\n ImgHorzRelTo,\n ImgVertRelTo,\n ImgWrap,\n} from \"../../model/doc-props\";\nimport { A4 } from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport {\n buildRoot,\n buildSheet,\n buildPara,\n buildSpan,\n buildImg,\n buildGrid,\n buildRow,\n buildCell,\n buildPb,\n} from \"../../model/builders\";\nimport { ShieldedParser } from \"../../safety/ShieldedParser\";\nimport {\n Metric,\n safeAlign,\n safeFont,\n safeHex,\n safeStrokeDocx,\n} from \"../../safety/StyleBridge\";\nimport { BaseDecoder } from \"../../core/BaseDecoder\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { XmlKit } from \"../../toolkit/XmlKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\n\nexport class DocxDecoder extends BaseDecoder {\n protected getFormat(): string {\n return \"docx\";\n }\n\n async decode(data: Uint8Array): Promise> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const getFile = (path: string) => {\n const lower = path.toLowerCase();\n for (const [name, data] of files.entries()) {\n if (name.toLowerCase() === lower) return data;\n }\n return undefined;\n };\n\n const docXml = getFile(\"word/document.xml\");\n if (!docXml) return fail(\"DOCX: word/document.xml not found\");\n\n const relsXml = getFile(\"word/_rels/document.xml.rels\");\n const relsMap = relsXml\n ? await parseRels(TextKit.decode(relsXml))\n : new Map();\n\n const coreXml = getFile(\"docProps/core.xml\");\n let meta: DocMeta = {};\n if (coreXml) {\n try {\n meta = await parseCoreProps(TextKit.decode(coreXml));\n } catch {\n // ignore — meta is optional\n }\n }\n\n // Parse numbering.xml for list support\n const numXml = getFile(\"word/numbering.xml\");\n let numMap: NumMap = new Map();\n if (numXml) {\n try {\n numMap = await parseNumbering(TextKit.decode(numXml));\n } catch {\n /* non-fatal */\n }\n }\n\n // Parse styles.xml for table and paragraph/character style defaults\n let stylesMap: StylesMap = new Map();\n let paraStyleMap: ParaStyleMap = new Map();\n const stylesXml = getFile(\"word/styles.xml\");\n if (stylesXml) {\n try {\n const stylesStr = TextKit.decode(stylesXml);\n stylesMap = await parseStylesMap(stylesStr);\n paraStyleMap = await parseParaStyleMap(stylesStr);\n } catch {\n /* non-fatal */\n }\n }\n\n let docStr = TextKit.decode(docXml).trim();\n if (!docStr) {\n warns.push(\n \"DOCX: word/document.xml is empty, using fallback empty document\",\n );\n docStr =\n '';\n }\n const docObj: any = await XmlKit.parseStrict(docStr);\n\n const body = getBody(docObj);\n const dims = extractDims(body) ?? { ...A4 };\n const elements = getBodyElements(body);\n console.log(\n `[DocxDecoder] 파싱된 전체 본문 요소 개수: ${elements.length}`,\n );\n\n const decCtx: DecCtx = {\n relsMap,\n files,\n shield,\n numMap,\n warns,\n stylesMap,\n paraStyleMap,\n };\n\n const kids: ContentNode[] = [];\n for (const el of elements) {\n const nodes = shield.guard(\n () => decodeElement(el, decCtx),\n [buildPara([buildSpan(\"[요소 파싱 실패]\")])],\n \"docx:bodyElement\",\n );\n if (Array.isArray(nodes)) {\n kids.push(...nodes);\n } else {\n kids.push(nodes);\n }\n\n // Inline sectPr in pPr = section break → insert page-break paragraph after\n if (el.type === \"para\") {\n const pPr = el.node?.[\"w:pPr\"]?.[0] ?? el.node?.pPr?.[0] ?? {};\n const inlineSectPr = pPr?.[\"w:sectPr\"]?.[0] ?? pPr?.sectPr?.[0];\n if (inlineSectPr) {\n const typeAttr = inlineSectPr?.[\"w:type\"]?.[0]?._attr;\n const sectType = typeAttr?.[\"w:val\"] ?? typeAttr?.val ?? \"nextPage\";\n if (sectType !== \"continuous\") {\n kids.push(\n buildPara([{ tag: \"span\", props: {}, kids: [buildPb()] }]),\n );\n }\n }\n }\n }\n\n // Decode header/footer\n const headersMap = await decodeHeaderFooter(\n \"header\",\n body,\n relsMap,\n files,\n decCtx,\n );\n const footersMap = await decodeHeaderFooter(\n \"footer\",\n body,\n relsMap,\n files,\n decCtx,\n );\n\n warns.push(...shield.flush());\n const sheet = buildSheet(kids.filter(Boolean) as ContentNode[], dims, {\n headers: headersMap,\n footers: footersMap,\n });\n return succeed(buildRoot(meta, [sheet]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`DOCX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── types ─────────────────────────────────────────────────\n\ninterface TblBorderDef {\n top?: Stroke;\n bottom?: Stroke;\n left?: Stroke;\n right?: Stroke;\n insideH?: Stroke;\n insideV?: Stroke;\n}\n\n/** Parsed tblStyle defaults from styles.xml */\ninterface TblStyleDef {\n tblBorders?: TblBorderDef;\n cellBg?: string; // default cell background\n}\n\n/** Parsed paragraph/character style defaults */\ninterface ParaStyleDef {\n rPr?: {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n pt?: number;\n color?: string;\n font?: string;\n };\n pPr?: {\n align?: string;\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n indentPt?: number;\n indentRightPt?: number;\n firstLineIndentPt?: number;\n };\n basedOn?: string; // parent style id\n}\n\ntype StylesMap = Map; // styleId → table style defaults\ntype ParaStyleMap = Map; // styleId → para/char style defaults\n\ninterface DecCtx {\n relsMap: Map;\n files: Map;\n shield: ShieldedParser;\n numMap: NumMap;\n warns: string[];\n stylesMap: StylesMap;\n paraStyleMap: ParaStyleMap;\n}\n\n// numId → { abstractNumId, levels: Map }\ntype NumMap = Map<\n number,\n { levels: Map }\n>;\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction toArr(v: any): any[] {\n return v == null ? [] : Array.isArray(v) ? v : [v];\n}\n\n/** Resolve DOCX relative paths. e.g. (\"word\", \"../media/image1.png\") → \"word/media/image1.png\" */\nfunction resolveDocxPath(baseDir: string, target: string): string {\n if (target.startsWith(\"/\")) return target.slice(1);\n const parts = (baseDir + \"/\" + target).split(\"/\");\n const stack: string[] = [];\n for (const p of parts) {\n if (p === \"..\") {\n stack.pop();\n } else if (p !== \".\") {\n stack.push(p);\n }\n }\n return stack.join(\"/\");\n}\n\nasync function parseRels(xml: string): Promise
            > {\n const map = new Map();\n const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\n for (const rel of toArr(obj?.Relationships?.[0]?.Relationship)) {\n const a = rel?._attr ?? {};\n if (a.Id && a.Target) map.set(a.Id, a.Target);\n }\n } catch {\n /* ignore */\n }\n return map;\n}\n\nasync function parseCoreProps(xml: string): Promise {\n const trimmed = xml.trim();\n if (!trimmed) return {};\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\n const c = obj?.[\"cp:coreProperties\"]?.[0] ?? obj?.coreProperties?.[0] ?? {};\n return {\n title: c?.[\"dc:title\"]?.[0]?._text ?? undefined,\n author: c?.[\"dc:creator\"]?.[0]?._text ?? undefined,\n subject: c?.[\"dc:subject\"]?.[0]?._text ?? undefined,\n created: c?.[\"dcterms:created\"]?.[0]?._text ?? undefined,\n modified: c?.[\"dcterms:modified\"]?.[0]?._text ?? undefined,\n };\n } catch {\n return {};\n }\n}\n\nasync function parseNumbering(xml: string): Promise {\n const map: NumMap = new Map();\n const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\n const root = obj?.[\"w:numbering\"]?.[0] ?? obj?.numbering?.[0] ?? obj;\n\n // Parse abstractNums\n const absMap = new Map<\n number,\n Map\n>();\n for (const abs of toArr(root?.[\"w:abstractNum\"] ?? root?.abstractNum)) {\n const absId = Number(\n abs?._attr?.[\"w:abstractNumId\"] ?? abs?._attr?.abstractNumId ?? 0,\n );\n const levels = new Map();\n for (const lvl of toArr(abs?.[\"w:lvl\"] ?? abs?.lvl)) {\n const ilvl = Number(lvl?._attr?.[\"w:ilvl\"] ?? lvl?._attr?.ilvl ?? 0);\n const fmtNode =\n lvl?.[\"w:numFmt\"]?.[0]?._attr ?? lvl?.numFmt?.[0]?._attr ?? {};\n const fmt = fmtNode?.[\"w:val\"] ?? fmtNode?.val ?? \"decimal\";\n levels.set(ilvl, { fmt, isOrdered: fmt !== \"bullet\" });\n }\n absMap.set(absId, levels);\n }\n\n // Parse nums\n for (const num of toArr(root?.[\"w:num\"] ?? root?.num)) {\n const numId = Number(num?._attr?.[\"w:numId\"] ?? num?._attr?.numId ?? 0);\n const absRef =\n num?.[\"w:abstractNumId\"]?.[0]?._attr ??\n num?.abstractNumId?.[0]?._attr ??\n {};\n const absId = Number(absRef?.[\"w:val\"] ?? absRef?.val ?? 0);\n const levels = absMap.get(absId) ?? new Map();\n map.set(numId, { levels });\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction getBody(obj: any): any {\n // XML 파서에 따라 w:document 또는 document 형태일 수 있음\n const doc = obj?.[\"w:document\"]?.[0] ?? obj?.document?.[0] ?? obj;\n const body = doc?.[\"w:body\"]?.[0] ?? doc?.body?.[0] ?? doc;\n\n if (!body) {\n console.error(\"[DocxDecoder] 본문(body)을 찾을 수 없습니다.\");\n }\n return body;\n}\n\nfunction extractDims(body: any): PageDims | null {\n try {\n const sp = body?.[\"w:sectPr\"]?.[0] ?? body?.sectPr?.[0];\n if (!sp) return null;\n const sz = sp?.[\"w:pgSz\"]?.[0]?._attr ?? sp?.pgSz?.[0]?._attr;\n const mar = sp?.[\"w:pgMar\"]?.[0]?._attr ?? sp?.pgMar?.[0]?._attr;\n if (!sz) return null;\n const headerDxa = Number(mar?.[\"w:header\"] ?? mar?.header ?? 0);\n const footerDxa = Number(mar?.[\"w:footer\"] ?? mar?.footer ?? 0);\n return {\n wPt: Metric.dxaToPt(Number(sz[\"w:w\"] ?? sz.w ?? 11906)),\n hPt: Metric.dxaToPt(Number(sz[\"w:h\"] ?? sz.h ?? 16838)),\n mt: Metric.dxaToPt(Number(mar?.[\"w:top\"] ?? mar?.top ?? 1440)),\n mb: Metric.dxaToPt(Number(mar?.[\"w:bottom\"] ?? mar?.bottom ?? 1440)),\n ml: Metric.dxaToPt(Number(mar?.[\"w:left\"] ?? mar?.left ?? 1800)),\n mr: Metric.dxaToPt(Number(mar?.[\"w:right\"] ?? mar?.right ?? 1800)),\n orient:\n (sz[\"w:orient\"] ?? sz.orient) === \"landscape\"\n ? \"landscape\"\n : \"portrait\",\n headerPt: headerDxa> 0 ? Metric.dxaToPt(headerDxa) : undefined,\n footerPt: footerDxa> 0 ? Metric.dxaToPt(footerDxa) : undefined,\n };\n } catch {\n return null;\n }\n}\n\nfunction getBodyElements(body: any): { type: string; node: any }[] {\n const paras = toArr(body?.[\"w:p\"] ?? body?.p);\n const tables = toArr(body?.[\"w:tbl\"] ?? body?.tbl);\n const sdts = toArr(body?.[\"w:sdt\"] ?? body?.sdt);\n\n const childOrder = body?.[\"_childOrder\"] as string[] | undefined;\n if (Array.isArray(childOrder)) {\n const items: { type: string; node: any }[] = [];\n let pi = 0,\n ti = 0,\n si = 0;\n for (const tag of childOrder) {\n if ((tag === \"w:p\" || tag === \"p\") && pi < paras.length) {\n items.push({ type: \"para\", node: paras[pi++] });\n } else if ((tag === \"w:tbl\" || tag === \"tbl\") && ti < tables.length) {\n items.push({ type: \"table\", node: tables[ti++] });\n } else if ((tag === \"w:sdt\" || tag === \"sdt\") && si < sdts.length) {\n items.push({ type: \"sdt\", node: sdts[si++] });\n }\n }\n // Append any remainders\n while (pi < paras.length) items.push({ type: \"para\", node: paras[pi++] });\n while (ti < tables.length)\n items.push({ type: \"table\", node: tables[ti++] });\n while (si < sdts.length) items.push({ type: \"sdt\", node: sdts[si++] });\n return items;\n }\n\n // Fallback: paragraphs, then tables, then sdts\n return [\n ...paras.map((n: any) => ({ type: \"para\", node: n })),\n ...tables.map((n: any) => ({ type: \"table\", node: n })),\n ...sdts.map((n: any) => ({ type: \"sdt\", node: n })),\n ];\n}\n\n// ─── Header/Footer decoding ────────────────────────────────\n\nasync function decodeHeaderFooter(\n kind: \"header\" | \"footer\",\n body: any,\n relsMap: Map, // document.xml.rels (기존)\n files: Map,\n ctx: DecCtx,\n): Promise | undefined> {\n try {\n const sp = body?.[\"w:sectPr\"]?.[0] ?? body?.sectPr?.[0];\n if (!sp) return undefined;\n\n const refTag =\n kind === \"header\" ? \"w:headerReference\" : \"w:footerReference\";\n const refs = toArr(sp?.[refTag] ?? sp?.[refTag.replace(\"w:\", \"\")]);\n if (refs.length === 0) return undefined;\n\n const result: Record = {};\n\n for (const ref of refs) {\n const type = ref._attr?.[\"w:type\"] ?? ref._attr?.type ?? \"default\";\n const rId = ref._attr?.[\"r:id\"] ?? ref._attr?.[\"r:Id\"] ?? ref._attr?.id;\n if (!rId) continue;\n\n const target = relsMap.get(rId);\n if (!target) continue;\n\n const filePath = resolveDocxPath(\"word\", target);\n const fileData = files.get(filePath);\n if (!fileData) continue;\n\n // ★ 핵심 수정: 헤더/풋터 전용 rels 파일 로드\n const hfFileName = filePath.split(\"/\").pop() ?? \"\";\n const hfRelsPath = `word/_rels/${hfFileName}.rels`;\n const hfRelsData = files.get(hfRelsPath);\n // 헤더/풋터 rels를 document rels와 병합\n let hfRelsMap = relsMap;\n if (hfRelsData) {\n const hfRelsStr = TextKit.decode(hfRelsData).trim();\n const parsed = hfRelsStr\n ? await parseRels(hfRelsStr)\n : new Map();\n // 병합 (헤더/풋터 rels 우선)\n hfRelsMap = new Map([...relsMap, ...parsed]);\n }\n\n const xmlStr = TextKit.decode(fileData).trim();\n if (!xmlStr) continue;\n\n const watermark = extractWatermark(xmlStr);\n if (watermark) {\n result[type] = [\n buildPara([\n buildSpan(watermark, { pt: 80, color: \"CCCCCC\", b: true }),\n ]),\n ];\n continue;\n }\n\n try {\n const obj: any = await XmlKit.parseStrict(xmlStr);\n const rootTag = kind === \"header\" ? \"w:hdr\" : \"w:ftr\";\n const root =\n obj?.[rootTag]?.[0] ?? obj?.[rootTag.replace(\"w:\", \"\")]?.[0] ?? obj;\n\n // ctx에 hfRelsMap 임시 적용\n const origRelsMap = ctx.relsMap;\n (ctx as any).relsMap = hfRelsMap;\n const paras = toArr(root?.[\"w:p\"] ?? root?.p);\n result[type] = paras.map((p: any) => decodePara(p, ctx));\n (ctx as any).relsMap = origRelsMap;\n } catch (err) {\n console.warn(`[DocxDecoder] ${kind} (${type}) XML 파싱 실패:`, err);\n continue;\n }\n }\n\n return Object.keys(result).length> 0 ? result : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** 워터마크 텍스트 추출 (VML v:textpath 기반) */\nfunction extractWatermark(xml: string): string | null {\n if (!xml.includes(\"v:textpath\")) return null;\n const m = xml.match(/string=\"([^\"]+)\"/);\n return m ? m[1] : null;\n}\n\n// ─── Element decoding ──────────────────────────────────────\n\n//만약에 drawing 태그가 안에 있으면 true 반환\nfunction hasDrawingDeep(node: any): boolean {\n if (!node || typeof node !== \"object\") return false;\n\n if (node[\"w:drawing\"] || node[\"w:pict\"]) return true;\n\n return Object.values(node).some((v) => {\n if (Array.isArray(v)) return v.some(hasDrawingDeep);\n return hasDrawingDeep(v);\n });\n}\n\nfunction decodeElement(\n el: { type: string; node: any },\n ctx: DecCtx,\n): ContentNode | ContentNode[] {\n if (el.type === \"table\") {\n const { value } = ctx.shield.guardGrid(\n el.node,\n (n) => decodeGrid(n as any, ctx),\n (n) => decodeGridSimple(n as any),\n (n) => decodeGridFlat(n as any),\n (n) => decodeGridText(n as any) as unknown as GridNode,\n \"docx:table\",\n );\n return value;\n } else if (el.type === \"sdt\") {\n return decodeSdt(el.node, ctx);\n }\n return decodePara(el.node, ctx);\n}\n\nfunction decodeSdt(sdt: any, ctx: DecCtx): ContentNode[] {\n const content = sdt?.[\"w:sdtContent\"]?.[0] ?? sdt?.sdtContent?.[0];\n if (!content) return [];\n const elements = getBodyElements(content);\n const kids: ContentNode[] = [];\n for (const el of elements) {\n const res = decodeElement(el, ctx);\n if (Array.isArray(res)) kids.push(...res);\n else kids.push(res);\n }\n return kids;\n}\n\nfunction decodePara(p: any, ctx: DecCtx): ParaNode {\n const pPr = p?.[\"w:pPr\"]?.[0] ?? {};\n const alignVal =\n pPr?.[\"w:jc\"]?.[0]?._attr?.[\"w:val\"] ?? pPr?.[\"w:jc\"]?.[0]?._attr?.val;\n const headStyle =\n pPr?.[\"w:pStyle\"]?.[0]?._attr?.[\"w:val\"] ??\n pPr?.[\"w:pStyle\"]?.[0]?._attr?.val ??\n \"\";\n\n // Resolve paragraph style inheritance chain\n const styleInherited = resolveParaStyle(\n headStyle || undefined,\n ctx.paraStyleMap,\n );\n\n const props: ParaProps = {\n align: safeAlign(alignVal),\n heading: parseHeading(headStyle),\n styleId: headStyle || undefined,\n };\n\n // Spacing (before/after/line height) — inline pPr wins over style\n const spacingAttr =\n pPr?.[\"w:spacing\"]?.[0]?._attr ?? pPr?.spacing?.[0]?._attr ?? {};\n const beforeVal = Number(\n spacingAttr?.[\"w:before\"] ?? spacingAttr?.before ?? 0,\n );\n const afterVal = Number(spacingAttr?.[\"w:after\"] ?? spacingAttr?.after ?? 0);\n const lineVal = Number(spacingAttr?.[\"w:line\"] ?? spacingAttr?.line ?? 0);\n const lineRule =\n spacingAttr?.[\"w:lineRule\"] ?? spacingAttr?.lineRule ?? \"auto\";\n if (beforeVal> 0) props.spaceBefore = Metric.dxaToPt(beforeVal);\n else if (styleInherited.pPr?.spaceBefore)\n props.spaceBefore = styleInherited.pPr.spaceBefore;\n if (afterVal> 0) props.spaceAfter = Metric.dxaToPt(afterVal);\n else if (styleInherited.pPr?.spaceAfter)\n props.spaceAfter = styleInherited.pPr.spaceAfter;\n if (lineVal> 0 && lineRule === \"auto\") props.lineHeight = lineVal / 240;\n else if (styleInherited.pPr?.lineHeight)\n props.lineHeight = styleInherited.pPr.lineHeight;\n\n // Indentation\n const indAttr = pPr?.[\"w:ind\"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {};\n const leftVal = Number(indAttr?.[\"w:left\"] ?? indAttr?.left ?? 0);\n const rightVal = Number(indAttr?.[\"w:right\"] ?? indAttr?.right ?? 0);\n const firstLineVal = Number(\n indAttr?.[\"w:firstLine\"] ?? indAttr?.firstLine ?? 0,\n );\n const hangingVal = Number(indAttr?.[\"w:hanging\"] ?? indAttr?.hanging ?? 0);\n if (leftVal> 0) props.indentPt = Metric.dxaToPt(leftVal);\n else if (styleInherited.pPr?.indentPt)\n props.indentPt = styleInherited.pPr.indentPt;\n if (rightVal> 0) props.indentRightPt = Metric.dxaToPt(rightVal);\n else if (styleInherited.pPr?.indentRightPt)\n props.indentRightPt = styleInherited.pPr.indentRightPt;\n if (firstLineVal> 0) props.firstLineIndentPt = Metric.dxaToPt(firstLineVal);\n else if (hangingVal> 0)\n props.firstLineIndentPt = -Metric.dxaToPt(hangingVal);\n else if (styleInherited.pPr?.firstLineIndentPt)\n props.firstLineIndentPt = styleInherited.pPr.firstLineIndentPt;\n\n // Alignment from style if not set inline\n if (!alignVal && styleInherited.pPr?.align)\n props.align = safeAlign(styleInherited.pPr.align);\n\n // List/numbering\n const numPr = pPr?.[\"w:numPr\"]?.[0] ?? pPr?.numPr?.[0];\n if (numPr) {\n const ilvlNode =\n numPr?.[\"w:ilvl\"]?.[0]?._attr ?? numPr?.ilvl?.[0]?._attr ?? {};\n const numIdNode =\n numPr?.[\"w:numId\"]?.[0]?._attr ?? numPr?.numId?.[0]?._attr ?? {};\n const ilvl = Number(ilvlNode?.[\"w:val\"] ?? ilvlNode?.val ?? 0);\n const numId = Number(numIdNode?.[\"w:val\"] ?? numIdNode?.val ?? 0);\n\n props.listLv = ilvl;\n const numEntry = ctx.numMap.get(numId);\n if (numEntry) {\n const lvlInfo = numEntry.levels.get(ilvl) ?? numEntry.levels.get(0);\n props.listOrd = lvlInfo?.isOrdered ?? false;\n } else {\n // Fallback: numId=1 is typically bullet, numId=2 is numbered\n props.listOrd = numId>= 2;\n }\n }\n\n // pageBreakBefore: paragraph always starts on a new page\n const pbBeforeNode =\n pPr?.[\"w:pageBreakBefore\"]?.[0] ?? pPr?.pageBreakBefore?.[0];\n const hasPageBreakBefore =\n pbBeforeNode != null &&\n (pbBeforeNode?._attr?.[\"w:val\"] ?? pbBeforeNode?._attr?.val ?? \"1\") !== \"0\";\n\n // Resolve all children (runs AND hyperlinks) in document order\n const children = p?.[\"_childOrder\"] as string[] | undefined;\n const kids: (SpanNode | ImgNode | LinkNode)[] = [];\n\n if (Array.isArray(children)) {\n const runsArr = toArr(p?.[\"w:r\"] ?? p?.r);\n const hlArr = toArr(p?.[\"w:hyperlink\"] ?? p?.hyperlink);\n const sdtArr = toArr(p?.[\"w:sdt\"] ?? p?.sdt);\n let ri = 0;\n let hi = 0;\n let si = 0;\n\n for (const tag of children) {\n if (tag === \"w:r\" || tag === \"r\") {\n const run = runsArr[ri++];\n if (run) {\n kids.push(\n ctx.shield.guard(\n () =>\n hasDrawingDeep(run)\n ? decodeRunOrImage(run, ctx)\n : decodeRun(run, ctx, styleInherited.rPr),\n buildSpan(\"\"),\n \"docx:run\",\n ),\n );\n }\n } else if (tag === \"w:hyperlink\" || tag === \"hyperlink\") {\n const hl = hlArr[hi++];\n if (hl) {\n const rId = hl?._attr?.[\"r:id\"] ?? hl?._attr?.id;\n const url = rId ? ctx.relsMap.get(rId) : \"\";\n const hlRuns = toArr(hl?.[\"w:r\"] ?? hl?.r);\n const hlKids = hlRuns.map((r: any) =>\n decodeRun(r, ctx, {\n ...styleInherited.rPr,\n u: true,\n color: \"0000FF\",\n }),\n );\n kids.push({\n tag: \"link\",\n href: url || \"\",\n kids: hlKids,\n });\n }\n } else if (tag === \"w:sdt\" || tag === \"sdt\") {\n const sdt = sdtArr[si++];\n if (sdt) {\n const sdtContent = sdt?.[\"w:sdtContent\"]?.[0] ?? sdt?.sdtContent?.[0];\n if (sdtContent) {\n const innerRuns = toArr(sdtContent?.[\"w:r\"] ?? sdtContent?.r);\n for (const ir of innerRuns) {\n kids.push(\n ctx.shield.guard(\n () =>\n hasDrawingDeep(ir)\n ? decodeRunOrImage(ir, ctx)\n : decodeRun(ir, ctx, styleInherited.rPr),\n buildSpan(\"\"),\n \"docx:run\",\n ),\n );\n }\n }\n }\n }\n }\n } else {\n // Fallback if _childOrder is missing\n const runs = toArr(p?.[\"w:r\"] ?? p?.r);\n const legacyKids: (SpanNode | ImgNode)[] = ctx.shield.guardAll(\n runs,\n (run: any) =>\n hasDrawingDeep(run)\n ? decodeRunOrImage(run, ctx)\n : decodeRun(run, ctx, styleInherited.rPr),\n () => buildSpan(\"\"),\n \"docx:run\",\n );\n kids.push(...legacyKids);\n }\n\n const filteredKids = kids.filter(Boolean) as ParaNode[\"kids\"];\n\n // Prepend pb span when pageBreakBefore is set\n if (hasPageBreakBefore) {\n filteredKids.unshift({ tag: \"span\", props: {}, kids: [buildPb()] });\n }\n\n return buildPara(filteredKids, props);\n}\n\n// 3/28 코드 수정\nfunction decodeRunOrImage(run: any, ctx: DecCtx): SpanNode | ImgNode {\n function findFirstDrawing(node: any): any | null {\n if (!node || typeof node !== \"object\") return null;\n\n if (node[\"w:drawing\"]) return node[\"w:drawing\"][0];\n if (node[\"w:pict\"]) return node[\"w:pict\"][0];\n\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n const found = findFirstDrawing(v);\n if (found) return found;\n }\n } else {\n const found = findFirstDrawing(value);\n if (found) return found;\n }\n }\n\n return null;\n }\n\n const drawing = findFirstDrawing(run);\n\n if (drawing) {\n const img = decodeDrawing(drawing, ctx);\n if (img) return img;\n }\n\n return decodeRun(run, ctx);\n}\n/** Decode image layout from anchor element */\nfunction decodeImageLayout(anchor: any): ImgLayout {\n const wrap = anchor?.[\"wp:wrapTop\"]?.[0] ?? anchor?.wrapTop?.[0];\n const anchorPos =\n anchor?.[\"wp:anchorPos\"]?.[0]?._attr ?? anchor?.anchorPos?.[0]?._attr ?? {};\n\n const layout: ImgLayout = {\n wrap: \"square\",\n horzAlign: \"left\",\n vertAlign: \"top\",\n horzRelTo: \"page\",\n vertRelTo: \"page\",\n xPt: Number(anchorPos?.x ?? 0) / 12700, // emu to pt\n yPt: Number(anchorPos?.y ?? 0) / 12700, // emu to pt\n };\n\n // Parse wrap type\n if (wrap?.[\"wp:none\"]) layout.wrap = \"none\";\n else if (wrap?.[\"wp:square\"]) layout.wrap = \"square\";\n else if (wrap?.[\"wp:tight\"]) layout.wrap = \"tight\";\n else if (wrap?.[\"wp:through\"]) layout.wrap = \"through\";\n else if (wrap?.[\"wp:behind\"]) layout.wrap = \"behind\";\n else if (wrap?.[\"wp:inFront\"]) layout.wrap = \"front\";\n\n return layout;\n}\n\nfunction decodeDrawing(drawing: any, ctx: DecCtx): ImgNode | null {\n try {\n const inline = drawing?.[\"wp:inline\"]?.[0] ?? drawing?.inline?.[0];\n const anchor = drawing?.[\"wp:anchor\"]?.[0] ?? drawing?.anchor?.[0];\n const container = inline ?? anchor;\n if (!container) return null;\n\n // Get dimensions\n const extent =\n container?.[\"wp:extent\"]?.[0]?._attr ??\n container?.extent?.[0]?._attr ??\n {};\n const cx = Number(extent?.cx ?? 0);\n const cy = Number(extent?.cy ?? 0);\n const wPt = Metric.emuToPt(cx);\n const hPt = Metric.emuToPt(cy);\n\n // Get alt text\n const docPr =\n container?.[\"wp:docPr\"]?.[0]?._attr ?? container?.docPr?.[0]?._attr ?? {};\n const alt = docPr?.descr ?? docPr?.name ?? \"\";\n\n // Navigate to blip\n const graphic = container?.[\"a:graphic\"]?.[0] ?? container?.graphic?.[0];\n const graphicData =\n graphic?.[\"a:graphicData\"]?.[0] ?? graphic?.graphicData?.[0];\n\n // 1. 차트 감지\n if (graphicData?.[\"c:chart\"] || graphicData?.chart) {\n return {\n tag: \"img\",\n b64: \"\", // 플레이스홀더\n mime: \"image/png\",\n w: wPt,\n h: hPt,\n alt: `[차트: ${alt || \"차트\"}]`,\n layout: decodeImageLayout(anchor),\n };\n }\n\n const pic = graphicData?.[\"pic:pic\"]?.[0] ?? graphicData?.pic?.[0];\n const blipFill = pic?.[\"pic:blipFill\"]?.[0] ?? pic?.blipFill?.[0];\n const blip =\n blipFill?.[\"a:blip\"]?.[0]?._attr ?? blipFill?.blip?.[0]?._attr ?? {};\n const rId = blip?.[\"r:embed\"] ?? blip?.embed;\n\n if (!rId) return null;\n\n const target = ctx.relsMap.get(rId);\n if (!target) return null;\n\n let filePath = resolveDocxPath(\"word\", target);\n let fileData = ctx.files.get(filePath);\n\n if (!fileData) {\n filePath = resolveDocxPath(\"word/_rels\", target);\n fileData = ctx.files.get(filePath);\n }\n\n if (!fileData) {\n const fileName = target.split(\"/\").pop() ?? \"\";\n for (const [k, v] of ctx.files) {\n if (fileName && (k.endsWith(\"/\" + fileName) || k === fileName)) {\n fileData = v;\n filePath = k;\n break;\n }\n }\n }\n\n if (!fileData) {\n console.warn(`[DocxDecoder] image not found: \"${target}\"`);\n return null;\n }\n\n const ext = target.split(\".\").pop()?.toLowerCase() ?? \"png\";\n const mimeMap: Record = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n const mime = mimeMap[ext] ?? \"image/png\";\n console.log(\n `[DocxDecoder] image loaded: ${filePath} (${mime}, ${fileData.length} bytes)`,\n );\n\n // ── layout 추출 ──────────────────────────────────────────\n const layout: ImgLayout = inline\n ? { wrap: \"inline\" }\n : extractAnchorLayout(anchor);\n\n return buildImg(\n TextKit.base64Encode(fileData),\n mime,\n wPt,\n hPt,\n alt || undefined,\n layout,\n );\n } catch {\n return null;\n }\n}\n\n/** w:highlight val → hex 색상 매핑 (OOXML 명세) */\nconst HIGHLIGHT_COLOR_MAP: Record = {\n yellow: \"FFFF00\",\n green: \"00FF00\",\n cyan: \"00FFFF\",\n magenta: \"FF00FF\",\n blue: \"0000FF\",\n red: \"FF0000\",\n darkBlue: \"00008B\",\n darkCyan: \"008B8B\",\n darkGreen: \"006400\",\n darkMagenta: \"8B008B\",\n darkRed: \"8B0000\",\n darkYellow: \"808000\",\n darkGray: \"A9A9A9\",\n lightGray: \"D3D3D3\",\n black: \"000000\",\n white: \"FFFFFF\",\n};\n\nfunction decodeRun(\n run: any,\n ctx: DecCtx,\n styleRpr?: ParaStyleDef[\"rPr\"],\n): SpanNode {\n const rPr = run?.[\"w:rPr\"]?.[0] ?? run?.rPr?.[0] ?? {};\n\n // w:vanish — 숨긴 텍스트: run 전체 건너뜀 (빈 span 반환)\n const vanishNode = rPr?.[\"w:vanish\"]?.[0] ?? rPr?.vanish?.[0];\n if (vanishNode != null) {\n const vanishVal =\n vanishNode?._attr?.[\"w:val\"] ?? vanishNode?._attr?.val ?? \"1\";\n if (vanishVal !== \"0\") return buildSpan(\"\");\n }\n\n // w:sz → 없으면 w:szCs 로 fallback (한글 글꼴 크기)\n const szAttr = rPr?.[\"w:sz\"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {};\n const szVal = szAttr?.[\"w:val\"] ?? szAttr?.val;\n const szCsAttr = rPr?.[\"w:szCs\"]?.[0]?._attr ?? rPr?.szCs?.[0]?._attr ?? {};\n const szCsVal = szCsAttr?.[\"w:val\"] ?? szCsAttr?.val;\n const effectiveSzVal = szVal ?? szCsVal;\n\n const colorAttr =\n rPr?.[\"w:color\"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {};\n const colorVal = colorAttr?.[\"w:val\"] ?? colorAttr?.val;\n\n const fontAttr =\n rPr?.[\"w:rFonts\"]?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {};\n const fontName =\n fontAttr?.[\"w:ascii\"] ??\n fontAttr?.ascii ??\n fontAttr?.[\"w:hAnsi\"] ??\n fontAttr?.hAnsi ??\n fontAttr?.[\"w:eastAsia\"] ??\n fontAttr?.eastAsia;\n\n const underVal =\n rPr?.[\"w:u\"]?.[0]?._attr?.[\"w:val\"] ?? rPr?.[\"w:u\"]?.[0]?._attr?.val;\n\n // w:shd — 배경색 (낮은 우선순위)\n const shdAttr = rPr?.[\"w:shd\"]?.[0]?._attr ?? rPr?.shd?.[0]?._attr ?? {};\n const shdBg = safeHex(shdAttr?.[\"w:fill\"] ?? shdAttr?.fill);\n\n // w:highlight — 형광펜 색상 (w:shd보다 우선)\n const hlAttr =\n rPr?.[\"w:highlight\"]?.[0]?._attr ?? rPr?.highlight?.[0]?._attr ?? {};\n const hlVal = hlAttr?.[\"w:val\"] ?? hlAttr?.val;\n const bgVal = (hlVal ? HIGHLIGHT_COLOR_MAP[hlVal] : undefined) ?? shdBg;\n\n // w:vertAlign — superscript / subscript\n const vertAlignVal =\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.[\"w:val\"] ??\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.val;\n\n // w:position — 글자 상하 이동 (half-point, 양수=위, 음수=아래)\n // vertAlign이 없을 때 보조 판단: ±4 half-pt(≈2pt) 이상이면 sup/sub\n const posAttr =\n rPr?.[\"w:position\"]?.[0]?._attr ?? rPr?.position?.[0]?._attr ?? {};\n const posVal = Number(posAttr?.[\"w:val\"] ?? posAttr?.val ?? 0);\n let isSup = vertAlignVal === \"superscript\";\n let isSub = vertAlignVal === \"subscript\";\n if (!isSup && !isSub && posVal !== 0) {\n if (posVal>= 4) isSup = true;\n else if (posVal <= -4) isSub = true;\n }\n\n // Check bold/italic/strike — val=\"0\" means explicitly OFF\n const bNode = rPr?.[\"w:b\"]?.[0] ?? rPr?.b?.[0];\n const isBold =\n bNode != null &&\n (bNode?._attr?.[\"w:val\"] ?? bNode?._attr?.val ?? \"1\") !== \"0\";\n const iNode = rPr?.[\"w:i\"]?.[0] ?? rPr?.i?.[0];\n const isItalic =\n iNode != null &&\n (iNode?._attr?.[\"w:val\"] ?? iNode?._attr?.val ?? \"1\") !== \"0\";\n const sNode = rPr?.[\"w:strike\"]?.[0] ?? rPr?.strike?.[0];\n const isStrike =\n sNode != null &&\n (sNode?._attr?.[\"w:val\"] ?? sNode?._attr?.val ?? \"1\") !== \"0\";\n\n // Run-level properties: run wins, then fall back to paragraph style inheritance\n const props: TextProps = {\n b: (bNode != null ? isBold : styleRpr?.b) || undefined,\n i: (iNode != null ? isItalic : styleRpr?.i) || undefined,\n u: (underVal ? underVal !== \"none\" : styleRpr?.u) || undefined,\n s: (sNode != null ? isStrike : styleRpr?.s) || undefined,\n sup: isSup || undefined,\n sub: isSub || undefined,\n pt: effectiveSzVal\n ? Metric.halfPtToPt(Number(effectiveSzVal))\n : styleRpr?.pt,\n color: safeHex(colorVal) ?? styleRpr?.color,\n font: fontName ? safeFont(fontName) : styleRpr?.font,\n bg: bgVal,\n };\n\n // Check for field codes (PAGE number)\n const fldChar = run?.[\"w:fldChar\"]?.[0]?._attr ?? run?.fldChar?.[0]?._attr;\n const instrText = run?.[\"w:instrText\"]?.[0];\n\n // Page break: \n const brNodes = toArr(run?.[\"w:br\"] ?? run?.br ?? []);\n for (const br of brNodes) {\n const brType = br?._attr?.[\"w:type\"] ?? br?._attr?.type;\n if (brType === \"page\") {\n return { tag: \"span\", props, kids: [buildPb()] };\n }\n }\n\n const textNodes = toArr(run?.[\"w:t\"] ?? run?.t);\n const content = textNodes\n .map((t: any) => (typeof t === \"string\" ? t : (t?._ ?? t?._text ?? \"\")))\n .join(\"\");\n\n // Handle page number field in instrText\n if (instrText) {\n const instrStr =\n typeof instrText === \"string\" ? instrText : (instrText?._text ?? \"\");\n if (instrStr.trim().toUpperCase() === \"PAGE\") {\n const pageNum: PageNumNode = { tag: \"pagenum\", format: \"decimal\" };\n return { tag: \"span\", props, kids: [pageNum] };\n }\n }\n\n return buildSpan(content, props);\n}\n\n/** Parse all 6 border sides from a w:tblBorders or w:tcBorders node */\nfunction parseBorderDef(bdrNode: any): TblBorderDef {\n const sides: [string, keyof TblBorderDef][] = [\n [\"top\", \"top\"],\n [\"bottom\", \"bottom\"],\n [\"left\", \"left\"],\n [\"right\", \"right\"],\n [\"insideH\", \"insideH\"],\n [\"insideV\", \"insideV\"],\n ];\n const result: TblBorderDef = {};\n for (const [xml, prop] of sides) {\n const bdr = bdrNode?.[\"w:\" + xml]?.[0]?._attr ?? bdrNode?.[xml]?.[0]?._attr;\n if (!bdr) continue;\n const val = bdr?.[\"w:val\"] ?? bdr?.val;\n if (val === \"none\" || val === \"nil\") continue; // explicit none → skip (no border)\n result[prop] = safeStrokeDocx(\n val,\n Number(bdr?.[\"w:sz\"] ?? bdr?.sz ?? 4),\n bdr?.[\"w:color\"] ?? bdr?.color,\n );\n }\n return result;\n}\n\n/** Parse styles.xml and build a map of tblStyle defaults */\nasync function parseStylesMap(xml: string): Promise\\n\\n\\n
            \\n${bodyParts.join('\\n')}\\n
            \\n\\n`;\n\n return succeed(this.stringToBytes(html), warns);\n } catch (e: any) {\n return fail(`HTML encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\nconst BASE_CSS = `\nbody { margin: 0; padding: 0; background: #f0f0f0; }\n.hwp-doc { max-width: 800px; margin: 0 auto; background: #fff; padding: 40px 60px; box-shadow: 0 0 8px rgba(0,0,0,0.15); }\n.hwp-header, .hwp-footer { color: #666; font-size: 0.9em; border-bottom: 1px solid #ddd; margin-bottom: 8px; padding-bottom: 4px; }\n.hwp-footer { border-top: 1px solid #ddd; border-bottom: none; margin-top: 8px; padding-top: 4px; }\np { margin: 0; padding: 0; line-height: 1; }\ntable { border-collapse: collapse; width: 100%; margin: 8px 0; }\ntd, th { border: 1px solid #ccc; padding: 4px 8px; vertical-align: top; }\nimg { max-width: 100%; height: auto; }\n`.trim();\n\nfunction encodeContent(node: ContentNode, warns: string[]): string {\n return node.tag === 'grid' ? encodeGrid(node, warns) : encodePara(node, warns);\n}\n\nfunction encodePara(para: ParaNode, warns: string[]): string {\n const kids = para.kids.map((k): string => {\n if (k.tag === 'span') return encodeSpan(k, warns);\n if (k.tag === 'img') return encodeImage(k);\n if (k.tag === 'link') {\n const link = k as LinkNode;\n const inner = link.kids.map(s => encodeSpan(s, warns)).join('');\n return `${inner}`;\n }\n return '';\n }).join('');\n\n // Heading\n if (para.props.heading) {\n const tag = `h${para.props.heading}`;\n return `<${tag}>${kids}\\n`;\n }\n\n // List\n if (para.props.listOrd !== undefined) {\n const indent = (para.props.listLv ?? 0) * 20;\n const style = indent> 0 ? ` style=\"margin-left:${indent}px\"` : '';\n const marker = para.props.listOrd ? `1. ` : ``;\n return `${marker}${kids}

            \\n`;\n }\n\n // Alignment\n const align = para.props.align;\n const styleAttrs: string[] = [];\n if (align && align !== 'left') styleAttrs.push(`text-align:${align}`);\n if (para.props.indentPt) styleAttrs.push(`margin-left:${para.props.indentPt.toFixed(1)}pt`);\n if (para.props.spaceBefore) styleAttrs.push(`margin-top:${para.props.spaceBefore.toFixed(1)}pt`);\n if (para.props.spaceAfter) styleAttrs.push(`margin-bottom:${para.props.spaceAfter.toFixed(1)}pt`);\n if (para.props.lineHeight) styleAttrs.push(`line-height:${para.props.lineHeight}`);\n\n const styleAttr = styleAttrs.length> 0 ? ` style=\"${styleAttrs.join(';')}\"` : '';\n return `${kids || ' '}

            \\n`;\n}\n\nfunction encodeSpan(span: SpanNode, warns: string[]): string {\n const parts: string[] = [];\n let hasPageNum = false;\n\n for (const kid of span.kids) {\n if (kid.tag === 'txt') {\n // __EXT_N__ 또는 __EXT_N_W_H__ 자리표시자 제거\n const content = kid.content.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, '');\n if (content) parts.push(TextKit.escapeXml(content));\n } else if (kid.tag === 'br') {\n parts.push('
            ');\n } else if (kid.tag === 'pb') {\n parts.push('');\n } else if (kid.tag === 'pagenum') {\n hasPageNum = true;\n warns.push('[SHIELD] HTML: 페이지 번호 — 정적 값으로 대체됨');\n parts.push('[페이지]');\n }\n }\n\n let text = parts.join('');\n if (hasPageNum && text.trim() === '[페이지]') {\n // keep as-is\n }\n\n const p = span.props;\n const css: string[] = [];\n if (p.font) css.push(`font-family:${TextKit.escapeXml(p.font)}`);\n if (p.pt) css.push(`font-size:${p.pt}pt`);\n if (p.color) css.push(`color:#${p.color}`);\n if (p.bg) css.push(`background-color:#${p.bg}`);\n if (p.b) css.push('font-weight:bold');\n if (p.i) css.push('font-style:italic');\n\n const decorations: string[] = [];\n if (p.u) decorations.push('underline');\n if (p.s) decorations.push('line-through');\n if (decorations.length> 0) css.push(`text-decoration:${decorations.join(' ')}`);\n\n if (p.sup) return `${text}`;\n if (p.sub) return `${text}`;\n if (css.length> 0) return `${text}`;\n return text;\n}\n\nfunction encodeImage(img: ImgNode): string {\n const wStyle = img.w ? ` width=\"${Math.round(img.w / 72 * 96)}px\"` : '';\n const hStyle = img.h ? ` height=\"${Math.round(img.h / 72 * 96)}px\"` : '';\n const alt = TextKit.escapeXml(img.alt ?? '');\n return `\`;\n}\n\nfunction encodeGrid(grid: GridNode, warns: string[]): string {\n if (grid.kids.length === 0) return '';\n\n // Build occupancy map for rowspan\n const rowCount = grid.kids.length;\n const occupancy: Set[] = Array.from({ length: rowCount }, () => new Set());\n let colCount = 0;\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let ci = 0;\n for (const cell of row.kids) {\n while (occupancy[ri].has(ci)) ci++;\n if (cell.rs> 1) {\n for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) {\n for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c);\n }\n }\n ci += cell.cs;\n }\n while (occupancy[ri].has(ci)) ci++;\n if (ci> colCount) colCount = ci;\n }\n\n let rows = '';\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let cells = '';\n let ci = 0;\n for (const cell of row.kids) {\n while (occupancy[ri].has(ci)) ci++;\n\n const isHeader = cell.props.isHeader || (grid.props.headerRow && ri === 0);\n const tag = isHeader ? 'th' : 'td';\n\n const cs = cell.cs> 1 ? ` colspan=\"${cell.cs}\"` : '';\n const rs = cell.rs> 1 ? ` rowspan=\"${cell.rs}\"` : '';\n\n const styleAttrs: string[] = [];\n if (cell.props.bg) styleAttrs.push(`background-color:#${cell.props.bg}`);\n const va = cell.props.va;\n if (va === 'mid') styleAttrs.push('vertical-align:middle');\n else if (va === 'bot') styleAttrs.push('vertical-align:bottom');\n const styleAttr = styleAttrs.length> 0 ? ` style=\"${styleAttrs.join(';')}\"` : '';\n\n const content = cell.kids.map(p => p.tag === 'para' ? encodePara(p, warns) : encodeGrid(p, warns)).join('');\n cells += `<${tag}${cs}${rs}${styleattr}>${content}`;\n ci += cell.cs;\n }\n rows += `
            ${cells}
            \\n`;\n }\n\n return `\\n\\n${rows}\\n\\n`;\n}\n\nregistry.registerEncoder(new HtmlEncoder());\n","/**\n * HwpEncoder — DocRoot → HWP 5.0 바이너리 (OLE2/CFB 컨테이너)\n *\n * ANYTOHWP에서 영감받은 개선 사항:\n * 1. HwpStyleBank — 7개 언어 그룹 독립 폰트 레지스트리 (HANGUL/LATIN/HANJA/...)\n * 2. readPixelDims — PNG/JPEG 바이너리 헤더에서 픽셀 치수 추출 → 정확한 HWPUNIT 변환\n * 3. mkIdMappings — 언어별 폰트 카운트를 개별 기록\n * 4. mkCharShape — 언어별 faceId[7] 사용\n *\n * OLE2 레이아웃:\n * FileHeader (stream) — 256-byte HWP 시그니처 + 플래그\n * DocInfo (stream) — zlib 압축된 FACE_NAME / CHAR_SHAPE / PARA_SHAPE 레코드\n * BodyText (storage)\n * Section0 (stream) — zlib 압축된 PAGE_DEF + 문단/표 레코드\n */\n\nimport type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n LinkNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n TextProps,\n ParaProps,\n Stroke,\n PageDims,\n Align,\n} from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport { Metric, safeFontToKr } from \"../../safety/StyleBridge\";\nimport { registry } from \"../../pipeline/registry\";\nimport { A4 } from \"../../model/doc-props\";\nimport pako from \"pako\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { BaseEncoder } from \"../../core/BaseEncoder\";\n\n// ─── HWP 5.0 태그 ID ────────────────────────────────────────\nconst T = 16; // HWPTAG_BEGIN\n\n// DocInfo 태그\nconst TAG_DOCUMENT_PROPERTIES = T + 0; // 16\nconst TAG_ID_MAPPINGS = T + 1; // 17\nconst TAG_BIN_DATA = T + 2; // 18\nconst TAG_FACE_NAME = T + 3; // 19\nconst TAG_BORDER_FILL = T + 4; // 20\nconst TAG_CHAR_SHAPE = T + 5; // 21\nconst TAG_PARA_SHAPE = T + 9; // 25\nconst TAG_STYLE = T + 10; // 26\n\n// BodyText 태그\nconst TAG_PARA_HEADER = T + 50; // 66\nconst TAG_PARA_TEXT = T + 51; // 67\nconst TAG_PARA_CHAR_SHAPE = T + 52; // 68\nconst TAG_PARA_LINE_SEG = T + 53; // 69\nconst TAG_CTRL_HEADER = T + 55; // 71\nconst TAG_LIST_HEADER = T + 56; // 72\nconst TAG_PAGE_DEF = T + 57; // 73\nconst TAG_FOOTNOTE_SHAPE = T + 58; // 74\nconst TAG_TABLE = T + 61; // 77\nconst TAG_SHAPE_COMPONENT_PICTURE = T + 69; // 85\n\n// Control ID (LE UINT32)\nconst CTRL_TABLE = 0x74626c20; // 'tbl '\nconst CTRL_SECD = 0x73656364; // 'secd'\nconst CTRL_PIC = 0x24706963; // '$pic'\nconst CTRL_FIELD_BEGIN = 0x646c6625; // '%fld'\nconst CTRL_FIELD_END = 0x646c665c; // '\\fld'\n\n/** 테두리선 굵기 인덱스 테이블 (pt) */\nconst BORDER_W_PT = [\n 0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.7, 1.98, 2.84, 4.25, 5.67,\n 8.5, 11.34, 14.17,\n];\n\nconst BORDER_KIND_IDX: Record = {\n solid: 0,\n dot: 1,\n dash: 2,\n double: 7,\n triple: 8,\n none: 0,\n};\n\nconst ALIGN_CODE: Record = {\n justify: 0,\n left: 1,\n right: 2,\n center: 3,\n distribute: 4,\n};\n\n// ─── 바이너리 버퍼 라이터 ────────────────────────────────────\n\nclass BufWriter {\n private chunks: Uint8Array[] = [];\n private _sz = 0;\n get size() {\n return this._sz;\n }\n\n u8(v: number): this {\n this.chunks.push(new Uint8Array([v & 0xff]));\n this._sz++;\n return this;\n }\n u16(v: number): this {\n this.chunks.push(new Uint8Array([v & 0xff, (v>> 8) & 0xff]));\n this._sz += 2;\n return this;\n }\n u32(v: number): this {\n const b = new Uint8Array(4);\n b[0] = v & 0xff;\n b[1] = (v>>> 8) & 0xff;\n b[2] = (v>>> 16) & 0xff;\n b[3] = (v>>> 24) & 0xff;\n this.chunks.push(b);\n this._sz += 4;\n return this;\n }\n i32(v: number): this {\n return this.u32(v < 0 ? v + 0x100000000 : v);\n }\n i16(v: number): this {\n return this.u16(v < 0 ? v + 0x10000 : v);\n }\n bytes(d: Uint8Array): this {\n this.chunks.push(d);\n this._sz += d.length;\n return this;\n }\n zeros(n: number): this {\n this.chunks.push(new Uint8Array(n));\n this._sz += n;\n return this;\n }\n utf16(s: string): this {\n for (let i = 0; i < s.length; i++) this.u16(s.charCodeAt(i));\n return this;\n }\n colorRef(hex: string): this {\n const h = (hex || \"000000\").replace(\"#\", \"\").padStart(6, \"0\");\n return this.u8(parseInt(h.slice(0, 2), 16))\n .u8(parseInt(h.slice(2, 4), 16))\n .u8(parseInt(h.slice(4, 6), 16))\n .u8(0);\n }\n build(): Uint8Array {\n const out = new Uint8Array(this._sz);\n let off = 0;\n for (const c of this.chunks) {\n out.set(c, off);\n off += c.length;\n }\n return out;\n }\n}\n\n// ─── HWP 레코드 빌더 ─────────────────────────────────────────\n\nfunction mkRec(tag: number, level: number, data: Uint8Array): Uint8Array {\n const sz = data.length;\n const enc = Math.min(sz, 0xfff);\n const hdr = (enc << 20) | ((level & 0x3ff) << 10) | (tag & 0x3ff);\n const w = new BufWriter().u32(hdr);\n if (enc>= 0xfff) w.u32(sz);\n w.bytes(data);\n return w.build();\n}\n\n// ─── ANYTOHWP 영감: PNG/JPEG 바이너리 헤더에서 픽셀 치수 추출\nfunction readPixelDims(\n data: Uint8Array,\n mime: string,\n): { w: number; h: number } | null {\n try {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n if (mime.includes(\"png\")) {\n if (\n data.length>= 24 &&\n view.getUint32(0) === 0x89504e47 &&\n view.getUint32(4) === 0x0d0a1a0a\n ) {\n return { w: view.getUint32(16), h: view.getUint32(20) };\n }\n } else if (mime.includes(\"jpeg\") || mime.includes(\"jpg\")) {\n let off = 2;\n while (off < data.length - 4) {\n const marker = view.getUint16(off);\n off += 2;\n if (marker === 0xffc0 || marker === 0xffc2) {\n return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) };\n }\n if ((marker & 0xff00) !== 0xff00) break;\n off += view.getUint16(off);\n }\n }\n } catch {\n /* 무시 */\n }\n return null;\n}\n\n// ─── ANYTOHWP 영감: HwpStyleBank — 7개 언어 그룹 독립 폰트 레지스트리\n// StyleCollector를 대체하는 새로운 스타일 수집기\n\nconst LANG_GROUPS = [\n \"HANGUL\",\n \"LATIN\",\n \"HANJA\",\n \"JAPANESE\",\n \"OTHER\",\n \"SYMBOL\",\n \"USER\",\n] as const;\ntype LangGroup = (typeof LANG_GROUPS)[number];\n\n/** 한글 폰트 여부 판별 */\nfunction isKoreanFont(face: string): boolean {\n return (\n /[\\uAC00-\\uD7A3\\u3131-\\u318E]/.test(face) ||\n [\"맑은\", \"나눔\", \"굴림\", \"돋움\", \"바탕\", \"함초롬\", \"한컴\", \"HY\"].some((k) =>\n face.includes(k),\n )\n );\n}\n\nclass HwpStyleBank {\n readonly DEF_STROKE: Stroke = { kind: \"solid\", pt: 0.5, color: \"000000\" };\n\n // 언어별 독립 폰트 목록 (ANYTOHWP langFontFaces)\n private langFonts = new Map(\n LANG_GROUPS.map((g) => [g, []]),\n );\n private langFontIdx = new Map>(\n LANG_GROUPS.map((g) => [g, new Map()]),\n );\n\n // charShape, parShape, borderFill 레지스트리\n readonly csProps: TextProps[] = [{}];\n private csIdx = new Map([[csKey({}), 0]]);\n\n readonly psProps: ParaProps[] = [{}];\n private psIdx = new Map([[psKey({}), 0]]);\n\n readonly bfData: BfEntry[] = [];\n private bfIdx = new Map();\n\n // charShape마다 언어별 fontId를 기록\n readonly csFontIds: number[][] = [[0, 0, 0, 0, 0, 0, 0]]; // id=0 → 모두 0\n\n constructor() {\n // 기본 폰트 등록 (ANYTOHWP: 함초롬바탕)\n for (const g of LANG_GROUPS) this._registerLangFont(g, \"함초롬바탕\");\n this.addBorderFill(this.DEF_STROKE); // bfId=1\n }\n\n private _registerLangFont(lang: LangGroup, face: string): number {\n const idx = this.langFontIdx.get(lang)!;\n if (idx.has(face)) return idx.get(face)!;\n const id = this.langFonts.get(lang)!.length;\n this.langFonts.get(lang)!.push(face);\n idx.set(face, id);\n return id;\n }\n\n /** 폰트 이름 → 언어별 7개 ID 반환 (ANYTOHWP 방식) */\n registerFontForLangs(rawFace: string): number[] {\n const face = safeFontToKr(rawFace) || \"함초롬바탕\";\n const isKor = isKoreanFont(face);\n const hangulFace = isKor ? face : \"함초롬바탕\";\n const latinFace = isKor ? \"함초롬바탕\" : face;\n\n const ids: number[] = [];\n for (const lang of LANG_GROUPS) {\n const f = lang === \"LATIN\" ? latinFace : hangulFace;\n ids.push(this._registerLangFont(lang, f));\n }\n return ids; // [hangulId, latinId, hanjaId, japaneseId, otherId, symbolId, userId]\n }\n\n /** 언어별 폰트 목록 반환 */\n getFontsForLang(lang: LangGroup): string[] {\n return [...(this.langFonts.get(lang) ?? [])];\n }\n\n /** 폰트 수 반환 (mkIdMappings용) */\n getFontCount(lang: LangGroup): number {\n return this.langFonts.get(lang)?.length ?? 0;\n }\n\n addCharShape(p: TextProps): number {\n const k = csKey(p);\n if (this.csIdx.has(k)) return this.csIdx.get(k)!;\n const id = this.csProps.length;\n const fIds = p.font\n ? this.registerFontForLangs(p.font)\n : [0, 0, 0, 0, 0, 0, 0];\n this.csProps.push(p);\n this.csFontIds.push(fIds);\n this.csIdx.set(k, id);\n return id;\n }\n\n addParaShape(p: ParaProps): number {\n const k = psKey(p);\n if (this.psIdx.has(k)) return this.psIdx.get(k)!;\n const id = this.psProps.length;\n this.psProps.push(p);\n this.psIdx.set(k, id);\n return id;\n }\n\n addBorderFill(s: Stroke, bg?: string): number {\n const k = bfKey(s, bg);\n if (this.bfIdx.has(k)) return this.bfIdx.get(k)!;\n const id = this.bfData.length + 1;\n this.bfData.push({ uniform: true, s, bg });\n this.bfIdx.set(k, id);\n return id;\n }\n\n addBorderFillPerSide(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n ): number {\n const k = bfPerSideKey(l, r, t, b, bg);\n if (this.bfIdx.has(k)) return this.bfIdx.get(k)!;\n const id = this.bfData.length + 1;\n this.bfData.push({ uniform: false, l, r, t, b, bg });\n this.bfIdx.set(k, id);\n return id;\n }\n}\n\n// ─── 키 함수 ────────────────────────────────────────────────\n\nfunction csKey(p: TextProps): string {\n return [\n p.font ?? \"\",\n p.pt ?? 10,\n p.b ? 1 : 0,\n p.i ? 1 : 0,\n p.u ? 1 : 0,\n p.s ? 1 : 0,\n p.sup ? 1 : 0,\n p.sub ? 1 : 0,\n p.color ?? \"000000\",\n ].join(\"|\");\n}\n\nfunction psKey(p: ParaProps): string {\n return [\n p.align ?? \"left\",\n p.indentPt ?? 0,\n p.firstLineIndentPt ?? 0,\n p.spaceBefore ?? 0,\n p.spaceAfter ?? 0,\n p.lineHeight ?? 1,\n ].join(\"|\");\n}\n\nfunction bfKey(s: Stroke, bg?: string): string {\n return `${s.kind}|${s.pt}|${s.color}|${bg ?? \"\"}`;\n}\n\nfunction bfPerSideKey(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n): string {\n return `${bfKey(l)}/${bfKey(r)}/${bfKey(t)}/${bfKey(b)}/${bg ?? \"\"}`;\n}\n\ntype BfEntry =\n | { uniform: true; s: Stroke; bg?: string }\n | { uniform: false; l: Stroke; r: Stroke; t: Stroke; b: Stroke; bg?: string };\n\n// ─── Pre-scan: 스타일 수집 ──────────────────────────────────\n\nfunction collectNode(node: ContentNode, bank: HwpStyleBank): void {\n if (node.tag === \"para\") {\n bank.addParaShape(node.props);\n for (const kid of node.kids) {\n if (kid.tag === \"span\") bank.addCharShape((kid as SpanNode).props);\n }\n } else if (node.tag === \"grid\") {\n if (node.props.defaultStroke) bank.addBorderFill(node.props.defaultStroke);\n for (const row of node.kids) {\n for (const cell of row.kids) {\n const defStroke = node.props.defaultStroke ?? bank.DEF_STROKE;\n const cp = cell.props;\n if (cp.top || cp.bot || cp.left || cp.right) {\n bank.addBorderFillPerSide(\n cp.left ?? defStroke,\n cp.right ?? defStroke,\n cp.top ?? defStroke,\n cp.bot ?? defStroke,\n cp.bg,\n );\n } else {\n bank.addBorderFill(defStroke, cp.bg);\n }\n for (const para of cell.kids) collectNode(para, bank);\n }\n }\n }\n}\n\n// ─── DocInfo 레코드 빌더 ─────────────────────────────────────\n\nfunction mkDocumentProperties(): Uint8Array {\n return new BufWriter()\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1) // ×ばつ UINT16 카운터\n .u32(0)\n .u32(0)\n .u32(0) // 캐럿 위치\n .build(); // 26 bytes\n}\n\n/**\n * HWPTAG_ID_MAPPINGS (72 bytes = 18 ×ばつ INT32)\n * [0]=binData, [1-7]=7개 언어별 글꼴 수 (ANYTOHWP 방식으로 언어별 독립),\n * [8]=테두리/배경, [9]=글자모양, [10]=탭, [11]=번호, [12]=글머리,\n * [13]=문단모양, [14]=스타일, [15-17]=메모/변경추적\n */\nfunction mkIdMappings(bank: HwpStyleBank, nBinData = 0): Uint8Array {\n const w = new BufWriter();\n w.u32(nBinData);\n // [1-7]: 언어별 폰트 수 (ANYTOHWP: langFontFaces별 크기)\n for (const lang of LANG_GROUPS) w.u32(bank.getFontCount(lang));\n w.u32(bank.bfData.length); // [8]\n w.u32(bank.csProps.length); // [9]\n w.u32(0); // [10] tabDef\n w.u32(0); // [11] numbering\n w.u32(0); // [12] bullet\n w.u32(bank.psProps.length); // [13]\n w.u32(1); // [14] style (바탕글 1개)\n w.u32(0); // [15]\n w.u32(0); // [16]\n w.u32(0); // [17]\n return w.build(); // 18 ×ばつ 4 = 72 bytes\n}\n\nfunction mkStyle(\n name: string,\n engName: string,\n paraPrId: number,\n charPrId: number,\n): Uint8Array {\n return new BufWriter()\n .u16(name.length)\n .utf16(name)\n .u16(engName.length)\n .utf16(engName)\n .u16(paraPrId)\n .u16(charPrId)\n .u16(0)\n .u16(1042)\n .u16(0)\n .build();\n}\n\nfunction mkFaceName(name: string): Uint8Array {\n return new BufWriter()\n .u8(0)\n .u16(name.length)\n .utf16(name)\n .u8(0)\n .u16(0)\n .zeros(10)\n .u16(0)\n .build();\n}\n\nfunction borderWidthIdx(pt: number): number {\n let best = 0;\n for (let i = 0; i < BORDER_W_PT.length; i++) {\n if (Math.abs(BORDER_W_PT[i] - pt) < Math.abs(BORDER_W_PT[best] - pt))\n best = i;\n }\n return best;\n}\n\nfunction mkBorderFill(s: Stroke, bg?: string): Uint8Array {\n const w = new BufWriter();\n const t = BORDER_KIND_IDX[s.kind] ?? 0;\n const wi = borderWidthIdx(s.pt);\n const col = s.color || \"000000\";\n w.u16(0);\n for (let i = 0; i < 4; i++) w.u8(t);\n for (let i = 0; i < 4; i++) w.u8(wi);\n for (let i = 0; i < 4; i++) w.colorRef(col);\n w.u8(0).u8(0).colorRef(\"000000\");\n if (bg) {\n w.u32(1).colorRef(bg).colorRef(\"FFFFFF\").u32(0);\n } else {\n w.u32(0);\n }\n return w.build();\n}\n\nfunction mkBorderFillPerSide(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n): Uint8Array {\n const w = new BufWriter();\n w.u16(0);\n w.u8(BORDER_KIND_IDX[l.kind] ?? 0)\n .u8(BORDER_KIND_IDX[r.kind] ?? 0)\n .u8(BORDER_KIND_IDX[t.kind] ?? 0)\n .u8(BORDER_KIND_IDX[b.kind] ?? 0);\n w.u8(borderWidthIdx(l.pt))\n .u8(borderWidthIdx(r.pt))\n .u8(borderWidthIdx(t.pt))\n .u8(borderWidthIdx(b.pt));\n w.colorRef(l.color || \"000000\")\n .colorRef(r.color || \"000000\")\n .colorRef(t.color || \"000000\")\n .colorRef(b.color || \"000000\");\n w.u8(0).u8(0).colorRef(\"000000\");\n if (bg) {\n w.u32(1).colorRef(bg).colorRef(\"FFFFFF\").u32(0);\n } else {\n w.u32(0);\n }\n return w.build();\n}\n\n/**\n * HWPTAG_CHAR_SHAPE (74 bytes)\n * ANYTOHWP 개선: faceId[7]에 언어별 ID를 개별 기록\n */\nfunction mkCharShape(fontIds: number[], p: TextProps): Uint8Array {\n const height = Math.round((p.pt ?? 10) * 100);\n let attr = 0;\n if (p.i) attr |= 1 << 0;\n if (p.b) attr |= 1 << 1;\n if (p.u) attr |= 1 << 2;\n if (p.s) attr |= 1 << 18;\n if (p.sup) attr |= 1 << 16;\n if (p.sub) attr |= 2 << 16;\n\n const w = new BufWriter();\n // faceId[7]: 언어별 독립 ID (ANYTOHWP 핵심 개선)\n for (const id of fontIds) w.u16(id);\n for (let i = 0; i < 7; i++) w.u8(100); // ratio\n for (let i = 0; i < 7; i++) w.u8(0); // spacing\n for (let i = 0; i < 7; i++) w.u8(100); // relSize\n for (let i = 0; i < 7; i++) w.u8(0); // offset\n w.i32(height).u32(attr).u8(0).u8(0);\n w.colorRef(p.color ?? \"000000\");\n w.colorRef(\"000000\"); // underlineColor\n w.colorRef(p.bg ?? \"FFFFFF\"); // shadeColor\n w.colorRef(\"000000\"); // shadowColor\n w.u16(0); // borderFillId\n w.colorRef(\"000000\"); // strikeColor\n return w.build(); // 74 bytes\n}\n\nfunction mkParaShape(p: ParaProps): Uint8Array {\n const alignVal = ALIGN_CODE[p.align ?? \"left\"] ?? 1;\n const attr1 = (alignVal & 0x7) << 2;\n const lineSpacePct = p.lineHeight ? Math.round(p.lineHeight * 100) : 160;\n return new BufWriter()\n .u32(attr1)\n .i32(Metric.ptToHwp(p.indentPt ?? 0))\n .i32(Metric.ptToHwp(p.indentRightPt ?? 0))\n .i32(Metric.ptToHwp(p.firstLineIndentPt ?? 0))\n .i32(Metric.ptToHwp(p.spaceBefore ?? 0))\n .i32(Metric.ptToHwp(p.spaceAfter ?? 0))\n .i32(lineSpacePct)\n .u16(0)\n .u16(0)\n .u16(0)\n .i16(0)\n .i16(0)\n .i16(0)\n .i16(0)\n .u32(0)\n .u32(4)\n .u32(lineSpacePct)\n .build(); // 54 bytes\n}\n\nfunction mkBinData(id: number, ext: string): Uint8Array {\n return new BufWriter().u16(0x0002).u16(id).u16(ext.length).utf16(ext).build();\n}\n\ninterface BinImage {\n id: number;\n ext: string;\n data: Uint8Array;\n}\n\n/**\n * DocInfo 스트림 빌더\n * ANYTOHWP 개선: 언어별 폰트 목록을 순서대로 독립 기록\n */\nfunction buildDocInfoStream(\n bank: HwpStyleBank,\n images: BinImage[] = [],\n): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n chunks.push(mkRec(TAG_DOCUMENT_PROPERTIES, 0, mkDocumentProperties()));\n chunks.push(mkRec(TAG_ID_MAPPINGS, 1, mkIdMappings(bank, images.length)));\n\n for (const img of images) {\n chunks.push(mkRec(TAG_BIN_DATA, 1, mkBinData(img.id, img.ext)));\n }\n\n // ANYTOHWP 방식: 언어 그룹별로 독립된 FACE_NAME 레코드 직렬화\n for (const lang of LANG_GROUPS) {\n for (const face of bank.getFontsForLang(lang)) {\n chunks.push(mkRec(TAG_FACE_NAME, 1, mkFaceName(face)));\n }\n }\n\n for (const entry of bank.bfData) {\n chunks.push(\n mkRec(\n TAG_BORDER_FILL,\n 1,\n entry.uniform\n ? mkBorderFill(entry.s, entry.bg)\n : mkBorderFillPerSide(entry.l, entry.r, entry.t, entry.b, entry.bg),\n ),\n );\n }\n\n // charShape — 언어별 fontId 배열 사용\n for (let i = 0; i < bank.csProps.length; i++) {\n chunks.push(\n mkRec(TAG_CHAR_SHAPE, 1, mkCharShape(bank.csFontIds[i], bank.csProps[i])),\n );\n }\n\n for (const p of bank.psProps) {\n chunks.push(mkRec(TAG_PARA_SHAPE, 1, mkParaShape(p)));\n }\n\n chunks.push(mkRec(TAG_STYLE, 1, mkStyle(\"바탕글\", \"Normal\", 0, 0)));\n\n return concatU8(chunks);\n}\n\n// ─── BodyText 레코드 빌더 ────────────────────────────────────\n\nfunction mkPageDef(dims: PageDims): Uint8Array {\n return new BufWriter()\n .u32(Metric.ptToHwp(dims.wPt))\n .u32(Metric.ptToHwp(dims.hPt))\n .u32(Metric.ptToHwp(dims.ml))\n .u32(Metric.ptToHwp(dims.mr))\n .u32(Metric.ptToHwp(dims.mt))\n .u32(Metric.ptToHwp(dims.mb))\n .zeros(12)\n .u32(dims.orient === \"landscape\" ? 1 : 0)\n .build(); // 40 bytes\n}\n\nfunction mkParaHeader(\n nchars: number,\n ctrlMask: number,\n psId: number,\n csCount: number,\n lineAlignCount = 0,\n instanceId = 0,\n): Uint8Array {\n return new BufWriter()\n .u32(nchars)\n .u32(ctrlMask)\n .u16(psId)\n .u8(0)\n .u8(0)\n .u16(csCount)\n .u16(0)\n .u16(lineAlignCount)\n .u32(instanceId)\n .u16(0)\n .build(); // 24 bytes\n}\n\nfunction mkParaText(text: string): Uint8Array {\n const w = new BufWriter();\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i);\n // 0x09(탭), 0x0A(줄바꿈), 0x03(필드시작), 0x04(필드종료) 등 허용\n w.u16(c);\n }\n w.u16(13); // 문단 종결자\n return w.build();\n}\n\nfunction mkParaCharShape(pairs: [pos: number, id: number][]): Uint8Array {\n const w = new BufWriter();\n for (const [pos, id] of pairs) w.u32(pos).u32(id);\n return w.build();\n}\n\n/**\n * 5가지 LineSpacing(줄 간격) 타입에 따른 height 계산 로직\n */\nfunction calcLineHeight(\n type: number,\n value: number,\n textHeight: number,\n): number {\n switch (type) {\n case 0:\n return Math.floor((textHeight * value) / 100);\n case 1:\n return value;\n case 2:\n return Math.max(textHeight, value);\n case 3:\n return textHeight + value;\n case 4:\n return Math.floor(textHeight * value);\n default:\n return Math.floor((textHeight * value) / 100);\n }\n}\n\n/**\n * LineSeg 36바이트 구조체 (HWP 5.0 공식 규격)\n */\nfunction mkLineSeg(\n textStartPos: number,\n vertPos: number,\n vertSize: number,\n textHeight: number,\n baseline: number,\n spacing: number,\n horzPos: number,\n horzSize: number,\n flags: number,\n): Uint8Array {\n return new BufWriter()\n .u32(textStartPos)\n .i32(vertPos)\n .i32(vertSize)\n .i32(textHeight)\n .i32(baseline)\n .i32(spacing)\n .i32(horzPos)\n .i32(horzSize)\n .u32(flags)\n .build(); // 36 bytes\n}\n\nfunction buildDefaultLineSeg(\n availWidthHwp: number,\n fontHwp: number,\n nchars: number,\n paraProps?: ParaProps,\n vertPos = 0,\n): Uint8Array {\n const ratio = paraProps?.lineHeight\n ? Math.round(paraProps.lineHeight * 100)\n : 160;\n const vertSize = calcLineHeight(0, ratio, fontHwp);\n const baseline = Math.round(fontHwp * 0.85);\n const spacing = vertSize - fontHwp;\n // flags: bit 0 (페이지 첫 줄), bit 1 (컬럼 첫 줄)\n const flags = 3;\n\n return mkLineSeg(\n 0,\n vertPos,\n vertSize,\n fontHwp,\n baseline,\n spacing,\n 0,\n availWidthHwp,\n flags,\n );\n}\n\nfunction mkSecdParaText(): Uint8Array {\n const lo = CTRL_SECD & 0xffff;\n const hi = (CTRL_SECD>>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x0002)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x0002)\n .u16(0x000d)\n .build();\n}\n\nfunction mkTableParaText(): Uint8Array {\n const lo = CTRL_TABLE & 0xffff;\n const hi = (CTRL_TABLE>>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x000b)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x000b)\n .u16(0x000d)\n .build();\n}\n\nfunction mkPicParaText(): Uint8Array {\n const lo = CTRL_PIC & 0xffff;\n const hi = (CTRL_PIC>>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x000b)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x000b)\n .u16(0x000d)\n .build();\n}\n\n// ─── 이미지 관련 레코드 (ANYTOHWP 영감: 픽셀 치수 우선 사용)\n\ninterface ImgLayout {\n wrap?: string;\n xPt?: number;\n yPt?: number;\n zOrder?: number;\n distL?: number;\n distR?: number;\n distT?: number;\n distB?: number;\n}\n\nfunction mkShapeComponentPicture(\n binDataId: number,\n wHwp: number,\n hHwp: number,\n): Uint8Array {\n const w = new BufWriter();\n w.u32(CTRL_PIC).zeros(15);\n w.u32(0).u32(0).u32(wHwp).u32(hHwp);\n w.u32(0).u32(0).u32(wHwp).u32(hHwp);\n w.zeros(36);\n w.u16(binDataId).u8(0).u8(0).u8(0).zeros(5);\n return w.build();\n}\n\nfunction mkObjectCtrl(\n ctrlId: number,\n wHwp: number,\n hHwp: number,\n instanceId: number,\n layout?: ImgLayout,\n): Uint8Array {\n let attr = 0x082a2210;\n if (layout?.wrap === \"inline\") attr |= 1 << 3;\n return new BufWriter()\n .u32(ctrlId)\n .u32(attr)\n .i32(layout?.yPt ? Metric.ptToHwp(layout.yPt) : 0)\n .i32(layout?.xPt ? Metric.ptToHwp(layout.xPt) : 0)\n .u32(wHwp)\n .u32(hHwp)\n .i32(layout?.zOrder ?? 0)\n .u16(layout?.distL ? Metric.ptToHwp(layout.distL) : 0)\n .u16(layout?.distR ? Metric.ptToHwp(layout.distR) : 0)\n .u16(layout?.distT ? Metric.ptToHwp(layout.distT) : 0)\n .u16(layout?.distB ? Metric.ptToHwp(layout.distB) : 0)\n .u32(instanceId)\n .i32(0)\n .u16(0)\n .build(); // 46 bytes\n}\n\nfunction mkFieldBeginCtrl(instanceId: number): Uint8Array {\n // 46-byte Object Control Header for Field\n return new BufWriter()\n .u32(CTRL_FIELD_BEGIN)\n .u32(0x00000002) // 필드 플래그\n .zeros(28) // xy/size 등 불필요 (필드는 비가시)\n .u32(instanceId)\n .zeros(6)\n .build();\n}\n\nfunction mkFieldEndCtrl(beginId: number): Uint8Array {\n return new BufWriter()\n .u32(CTRL_FIELD_END)\n .u32(0)\n .zeros(28)\n .u32(beginId)\n .zeros(6)\n .build();\n}\n\n/**\n * 이미지 단락 인코딩\n * ANYTOHWP 개선: PNG/JPEG 픽셀 치수에서 HWPUNIT 계산\n */\nfunction encodePicPara(\n imgNode: ImgNode,\n binDataId: number,\n bank: HwpStyleBank,\n lv: number,\n idGen: () => number,\n availWidthHwp: number,\n): Uint8Array[] {\n // ANYTOHWP 방식: 픽셀 치수 추출 시도 → 실패 시 pt 기반으로 폴백\n const rawData = TextKit.base64Decode(imgNode.b64);\n const pixDims = readPixelDims(rawData, imgNode.mime);\n\n let wHwp: number, hHwp: number;\n if (pixDims && pixDims.w> 0 && pixDims.h> 0) {\n wHwp = Metric.ptToHwp((pixDims.w * 72) / 96); // px → pt(96dpi) → hwpunit\n hHwp = Metric.ptToHwp((pixDims.h * 72) / 96);\n } else {\n wHwp = Metric.ptToHwp(imgNode.w);\n hHwp = Metric.ptToHwp(imgNode.h);\n }\n\n // 가용 너비 초과 방지\n if (wHwp> availWidthHwp) {\n hHwp = Math.round((hHwp * availWidthHwp) / wHwp);\n wHwp = availWidthHwp;\n }\n\n const CTRL_MASK = 1 << 11;\n const instanceId = idGen();\n const psId = bank.addParaShape({});\n\n return [\n mkRec(\n TAG_PARA_HEADER,\n lv,\n mkParaHeader(9, CTRL_MASK, psId, 1, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, lv + 1, mkPicParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape([[0, 0]])),\n mkRec(\n TAG_PARA_LINE_SEG,\n lv + 1,\n buildDefaultLineSeg(availWidthHwp, hHwp, 9),\n ),\n mkRec(\n TAG_CTRL_HEADER,\n lv + 1,\n mkObjectCtrl(CTRL_PIC, wHwp, hHwp, idGen(), imgNode.layout),\n ),\n mkRec(\n TAG_SHAPE_COMPONENT_PICTURE,\n lv + 2,\n mkShapeComponentPicture(binDataId, wHwp, hHwp),\n ),\n ];\n}\n\n// ─── 문단 인코딩 ─────────────────────────────────────────────\n\nfunction encodePara(\n para: ParaNode,\n bank: HwpStyleBank,\n lv: number,\n instanceId: number,\n availWidthHwp: number,\n mask = 0,\n vertPos = 0,\n): Uint8Array[] {\n let text = \"\";\n const csPairs: [number, number][] = [];\n let pos = 0;\n let fontHwp = 1000;\n const ctrlRecords: Uint8Array[] = [];\n\n for (const kid of para.kids) {\n if (\n kid.tag === \"span\" &&\n (kid as SpanNode).props.pt &&\n ((kid as SpanNode).props.pt as number)> 0\n ) {\n fontHwp = Metric.ptToHwp((kid as SpanNode).props.pt as number);\n break;\n }\n }\n\n // 내부적으로 사용되는 ID 생성기 (단락 내에서 로컬하게 사용)\n let localIdCounter = 10000;\n const localIdGen = () => localIdCounter++;\n\n function processKids(kids: any[]): void {\n for (const kid of kids) {\n if (kid.tag === \"span\") {\n const span = kid as SpanNode;\n const csId = bank.addCharShape(span.props);\n if (!csPairs.length || csPairs[csPairs.length - 1][1] !== csId) {\n csPairs.push([pos, csId]);\n }\n for (const t of span.kids) {\n if (t.tag === \"txt\") {\n text += t.content;\n pos += t.content.length;\n }\n }\n } else if (kid.tag === \"link\") {\n const link = kid as LinkNode;\n mask |= 1 << 11; // 하이퍼링크 마스크\n\n const fieldBeginId = localIdGen();\n // 1. 시작 제어 문자 (0x03)\n text += String.fromCharCode(3);\n pos += 1;\n ctrlRecords.push(\n mkRec(TAG_CTRL_HEADER, lv + 1, mkFieldBeginCtrl(fieldBeginId)),\n );\n\n // 2. 내용 처리\n processKids(link.kids);\n\n // 3. 종료 제어 문자 (0x04)\n text += String.fromCharCode(4);\n pos += 1;\n ctrlRecords.push(\n mkRec(TAG_CTRL_HEADER, lv + 1, mkFieldEndCtrl(fieldBeginId)),\n );\n }\n }\n }\n processKids(para.kids);\n if (!csPairs.length) csPairs.push([0, 0]);\n\n const psId = bank.addParaShape(para.props);\n const nchars = text.length + 1;\n\n return [\n mkRec(\n TAG_PARA_HEADER,\n lv,\n mkParaHeader(nchars, mask, psId, csPairs.length, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, lv + 1, mkParaText(text)),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape(csPairs)),\n mkRec(\n TAG_PARA_LINE_SEG,\n lv + 1,\n buildDefaultLineSeg(availWidthHwp, fontHwp, nchars, para.props, vertPos),\n ),\n ...ctrlRecords,\n ];\n}\n\n// ─── 표 인코딩 ───────────────────────────────────────────────\n\nfunction mkTableCtrl(\n wHwp: number,\n hHwp: number,\n instanceId: number,\n align: Align = \"left\",\n): Uint8Array {\n // 표 정렬 속성 플래그 (HWP 표 제어 문자)\n // offset 20-21: 속성 플래그 (align: left=0, center=1, right=2, justify=3)\n const alignFlags = { left: 0, center: 1, right: 2, justify: 3 }[align] ?? 0;\n return new BufWriter()\n .u32(CTRL_TABLE)\n .u32(0x082a2211)\n .i32(0)\n .i32(0)\n .u32(wHwp)\n .u32(hHwp)\n .i32(7)\n .u16(140)\n .u16(140)\n .u16(140)\n .u16(140)\n .u32(instanceId)\n .i32(alignFlags)\n .u16(0)\n .build(); // 46 bytes\n}\n\nfunction mkTableRecord(\n rowCnt: number,\n colCnt: number,\n rowHwp: number[],\n bfId: number,\n): Uint8Array {\n const w = new BufWriter();\n w.u32(0x04000006).u16(rowCnt).u16(colCnt).u16(0);\n w.u16(510).u16(510).u16(141).u16(141);\n for (const h of rowHwp) w.u16(Math.max(1, h & 0xffff));\n w.u16(bfId).u16(0);\n return w.build();\n}\n\nfunction mkCellListHeader(\n paraCount: number,\n row: number,\n col: number,\n rs: number,\n cs: number,\n wHwp: number,\n hHwp: number,\n bfId: number,\n padL = 141,\n padR = 141,\n padT = 141,\n padB = 141,\n): Uint8Array {\n return new BufWriter()\n .u16(paraCount)\n .u32(0)\n .u16(0)\n .u16(col)\n .u16(row)\n .u16(rs)\n .u16(cs)\n .u32(wHwp)\n .u32(hHwp)\n .u16(padL)\n .u16(padR)\n .u16(padT)\n .u16(padB)\n .u16(bfId)\n .zeros(13)\n .build(); // 47 bytes\n}\n\nconst DEFAULT_ROW_HEIGHT_PT = 14;\n\nfunction encodeGrid(\n grid: GridNode,\n bank: HwpStyleBank,\n lv: number,\n idGen: () => number,\n availWidthHwp: number,\n): Uint8Array[] {\n const records: Uint8Array[] = [];\n const rowCnt = grid.kids.length;\n const colCnt = Math.max(1, grid.kids[0]?.kids.length ?? 1);\n\n const cwPt = (grid.props as any).colWidths ?? [];\n const totalPt = cwPt.reduce((s: number, w: number) => s + w, 0) || 453;\n const defColPt = totalPt / colCnt;\n const defStroke = grid.props.defaultStroke ?? bank.DEF_STROKE;\n const defBfId = bank.addBorderFill(defStroke);\n\n const rowHwp = grid.kids.map((row: any) =>\n row.heightPt != null && row.heightPt> 0\n ? Metric.ptToHwp(row.heightPt)\n : Metric.ptToHwp(DEFAULT_ROW_HEIGHT_PT),\n );\n\n const tblWPt =\n cwPt.length> 0 ? cwPt.reduce((s: number, w: number) => s + w, 0) : totalPt;\n const tblHPt = grid.kids.reduce(\n (s: number, row: any) =>\n s +\n (row.heightPt != null && row.heightPt> 0\n ? row.heightPt\n : DEFAULT_ROW_HEIGHT_PT),\n 0,\n );\n const tblInstanceId = idGen();\n const tblAlign = grid.props.align ?? \"left\";\n\n records.push(\n mkRec(\n TAG_CTRL_HEADER,\n lv,\n mkTableCtrl(\n Metric.ptToHwp(tblWPt),\n Metric.ptToHwp(tblHPt),\n tblInstanceId,\n tblAlign,\n ),\n ),\n );\n records.push(\n mkRec(TAG_TABLE, lv + 1, mkTableRecord(rowCnt, colCnt, rowHwp, defBfId)),\n );\n\n for (let r = 0; r < grid.kids.length; r++) {\n for (let c = 0; c < grid.kids[r].kids.length; c++) {\n const cell = grid.kids[r].kids[c];\n const wHwp = Metric.ptToHwp(cwPt[c] ?? defColPt);\n const hHwp = rowHwp[r];\n const cp = cell.props;\n const hasPerSide = cp.top || cp.bot || cp.left || cp.right;\n const bfId = hasPerSide\n ? bank.addBorderFillPerSide(\n cp.left ?? defStroke,\n cp.right ?? defStroke,\n cp.top ?? defStroke,\n cp.bot ?? defStroke,\n cp.bg,\n )\n : bank.addBorderFill(defStroke, cp.bg);\n\n const paras =\n cell.kids.length> 0\n ? cell.kids\n : [{ tag: \"para\" as const, props: {}, kids: [] }];\n\n const padL = cp.padL !== undefined ? Metric.ptToHwp(cp.padL) : 510;\n const padR = cp.padR !== undefined ? Metric.ptToHwp(cp.padR) : 510;\n const padT = cp.padT !== undefined ? Metric.ptToHwp(cp.padT) : 141;\n const padB = cp.padB !== undefined ? Metric.ptToHwp(cp.padB) : 141;\n\n records.push(\n mkRec(\n TAG_LIST_HEADER,\n lv + 1,\n mkCellListHeader(\n paras.length,\n r,\n c,\n cell.rs,\n cell.cs,\n wHwp,\n hHwp,\n bfId,\n padL,\n padR,\n padT,\n padB,\n ),\n ),\n );\n\n const cellWidthHwp = Metric.ptToHwp(cwPt[c] ?? defColPt);\n for (const para of paras) {\n records.push(\n ...encodePara(para as ParaNode, bank, lv + 2, idGen(), cellWidthHwp),\n );\n }\n }\n }\n return records;\n}\n\nfunction mkSectionCtrl(): Uint8Array {\n return new BufWriter()\n .u32(CTRL_SECD)\n .u32(0)\n .u32(1134)\n .u16(0x4000)\n .u16(0x001f)\n .zeros(31)\n .build(); // 47 bytes\n}\n\nfunction buildSectionParagraph(\n dims: PageDims,\n instanceId: number,\n): Uint8Array[] {\n const SECD_CTRL_MASK = 1 << 2;\n const nchars = 9;\n const availWidthHwp = Math.max(\n 1000,\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(dims.ml) -\n Metric.ptToHwp(dims.mr),\n );\n return [\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(nchars, SECD_CTRL_MASK, 0, 1, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, 1, mkSecdParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])),\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, nchars),\n ),\n mkRec(TAG_CTRL_HEADER, 1, mkSectionCtrl()),\n mkRec(TAG_PAGE_DEF, 2, mkPageDef(dims)),\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)),\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)),\n ];\n}\n\n// ─── BodyText 스트림 빌더 ─────────────────────────────────────\n\nfunction flatImgNodes(kids: any[]): any[] {\n const result: any[] = [];\n for (const kid of kids) {\n if (kid.tag === \"img\") result.push(kid);\n else if (kid.tag === \"link\" && Array.isArray(kid.kids))\n result.push(...flatImgNodes(kid.kids));\n }\n return result;\n}\n\nfunction b64Matches(binImg: BinImage, b64: string): boolean {\n const a = TextKit.base64Encode(binImg.data).replace(/\\s/g, \"\");\n const b = b64.replace(/\\s/g, \"\");\n return a === b;\n}\n\nfunction buildBodyTextStream(\n doc: DocRoot,\n bank: HwpStyleBank,\n images: BinImage[],\n): Uint8Array {\n const chunks: Uint8Array[] = [];\n const dims = doc.kids[0]?.dims ?? A4;\n let instanceIdCounter = 1;\n const idGen = () => instanceIdCounter++;\n const availWidthHwp = Math.max(\n 1000,\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(dims.ml) -\n Metric.ptToHwp(dims.mr),\n );\n\n for (const r of buildSectionParagraph(dims, idGen())) chunks.push(r);\n\n const TABLE_CTRL_MASK = 1 << 11;\n let vertPos = 0; // 단락 간격 추적\n\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) {\n if (node.tag === \"para\") {\n const para = node as ParaNode;\n\n const hasPageBreak = para.kids.some(\n (k) => k.tag === \"span\" && k.kids.some((c) => c.tag === \"pb\"),\n );\n let paraMask = hasPageBreak ? 1 << 2 : 0;\n\n // 코드 블록 감지 → ×ばつ1 표로 감싸기\n const hasCourier = (kids: any[]): boolean =>\n kids.some(\n (k) =>\n (k.tag === \"span\" &&\n k.props.font?.toLowerCase().includes(\"courier\")) ||\n (k.tag === \"link\" && hasCourier(k.kids)),\n );\n const isCode =\n para.props.styleId?.toLowerCase().includes(\"code\") ||\n hasCourier(para.kids);\n\n if (isCode) {\n const gridNode: GridNode = {\n tag: \"grid\",\n props: {\n colWidths: [Metric.hwpToPt(availWidthHwp)],\n defaultStroke: { kind: \"solid\", pt: 0.5, color: \"aaaaaa\" },\n },\n kids: [\n {\n tag: \"row\",\n kids: [\n {\n tag: \"cell\",\n rs: 1,\n cs: 1,\n props: { bg: \"f4f4f4\" },\n kids: [para],\n },\n ],\n },\n ],\n };\n chunks.push(\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(9, TABLE_CTRL_MASK | paraMask, 0, 1, 1, idGen()),\n ),\n );\n chunks.push(mkRec(TAG_PARA_TEXT, 1, mkTableParaText()));\n chunks.push(mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])));\n chunks.push(\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, 9, undefined, vertPos),\n ),\n );\n vertPos += Metric.ptToHwp(20); // 코드 블록 후 간격\n for (const r of encodeGrid(gridNode, bank, 1, idGen, availWidthHwp))\n chunks.push(r);\n continue;\n }\n\n const imgNodes = flatImgNodes(para.kids);\n if (imgNodes.length> 0) {\n for (const img of imgNodes) {\n const binImg = images.find((b) => b64Matches(b, img.b64));\n if (binImg) {\n for (const r of encodePicPara(\n img,\n binImg.id,\n bank,\n 0,\n idGen,\n availWidthHwp,\n )) {\n // 첫 레코드가 PARA_HEADER인 경우 페이지 브레이크 마스크 적용\n chunks.push(r);\n }\n vertPos += Metric.ptToHwp(img.h ?? 100); // 이미지 높이 추가\n }\n }\n const textKids = para.kids.filter(\n (k: any) => k.tag !== \"img\" && k.tag !== \"link\",\n );\n if (textKids.length> 0) {\n const textPara: ParaNode = {\n tag: \"para\",\n props: para.props,\n kids: textKids as any,\n };\n for (const r of encodePara(\n textPara,\n bank,\n 0,\n idGen(),\n availWidthHwp,\n paraMask,\n vertPos,\n )) {\n // PARA_HEADER 레코드(목록의 첫 번째)에 마스크 적용\n if (r[0] === (TAG_PARA_HEADER & 0xff)) {\n // 레코드 헤더 수정은 복잡하므로 encodePara 내부에서 처리하는 것이 안전하지만\n // 여기서는 간단히 구현하기 위해 encodePara의 인자로 mask를 넘기도록 구조를 변경하는 것이 좋습니다.\n }\n chunks.push(r);\n }\n // 단락 높이 계산 및 vertPos 업데이트 (이미지/텍스트 혼합)\n const fontHwp_img = (\n textKids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n )?.props.pt\n ? Metric.ptToHwp(\n (\n textKids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n ).props.pt as number,\n )\n : 1000;\n const lineSpacePct_img = Math.round((para.props.lineHeight ?? 1.6) * 100);\n vertPos += Math.round((fontHwp_img * lineSpacePct_img) / 100);\n }\n } else {\n for (const r of encodePara(\n para,\n bank,\n 0,\n idGen(),\n availWidthHwp,\n paraMask,\n vertPos,\n ))\n chunks.push(r);\n // 단락 높이 계산 및 vertPos 업데이트 (일반 단락)\n const fontHwp_para = (\n para.kids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n )?.props.pt\n ? Metric.ptToHwp(\n (\n para.kids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n ).props.pt as number,\n )\n : 1000;\n const lineSpacePct_para = para.props.lineHeight\n ? Math.round(para.props.lineHeight * 100)\n : 160;\n vertPos += Math.round((fontHwp_para * lineSpacePct_para) / 100);\n }\n } else if (node.tag === \"grid\") {\n chunks.push(\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(9, TABLE_CTRL_MASK, 0, 1, 1, idGen()),\n ),\n );\n chunks.push(mkRec(TAG_PARA_TEXT, 1, mkTableParaText()));\n chunks.push(mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])));\n chunks.push(\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, 9, undefined, vertPos),\n ),\n );\n vertPos += Metric.ptToHwp(20); // 표 후 간격\n for (const r of encodeGrid(\n node as GridNode,\n bank,\n 1,\n idGen,\n availWidthHwp,\n ))\n chunks.push(r);\n }\n }\n }\n\n return concatU8(chunks);\n}\n\n// ─── HWP FileHeader ─────────────────────────────────────────\n/**\n * HWP 5.0 FileHeader 를 생성합니다.\n *\n * 구조:\n * 0-15: 시그니처 \"HWP Document File\" (16 바이트)\n * 16-31: reserved (16 바이트)\n * 32-35: version (4 바이트, Little-Endian) - 0x05000300 = 5.0.3.0\n * 36-39: flags (4 바이트, Little-Endian) - bit 0 = compressed, bit 1 = encrypted\n * 40-255: reserved (216 바이트)\n *\n * 총 256 바이트\n */\nfunction buildHwpFileHeader(): Uint8Array {\n const SIZE = 256;\n const buf = new Uint8Array(SIZE);\n const dv = new DataView(buf.buffer);\n\n // 0-15: 시그니처 \"HWP Document File\" (16 바이트)\n const sig = \"HWP Document File\";\n for (let i = 0; i < sig.length; i++) {\n buf[i] = sig.charCodeAt(i);\n }\n\n // 16-31: reserved (0 으로 초기화됨)\n\n // 32-35: version (4 바이트, Little-Endian) - 0x05000300 = 5.0.3.0\n dv.setUint32(32, 0x05000300, true);\n\n // 36-39: flags (4 바이트, Little-Endian)\n // bit 0 = 1: compressed (압축됨)\n // bit 1 = 0: not encrypted (암호화 안됨)\n dv.setUint32(36, 0x00000001, true);\n\n // 40-255: reserved (0 으로 초기화됨)\n\n // 검증\n if (buf.length !== SIZE) {\n throw new Error(`FileHeader 크기 오류: ${buf.length} (기대: ${SIZE})`);\n }\n if (new TextDecoder().decode(buf.subarray(0, sig.length)) !== sig) {\n throw new Error(\"FileHeader 시그니처 오류\");\n }\n if (dv.getUint32(32, true) !== 0x05000300) {\n throw new Error(\"FileHeader 버전 오류\");\n }\n\n return buf;\n}\n\n// ─── OLE2/CFB 컨테이너 빌더 ─────────────────────────────────\n\nfunction buildHwpOle2(\n fileHeaderData: Uint8Array,\n docInfoData: Uint8Array,\n section0Data: Uint8Array,\n binImages: BinImage[] = [],\n): Uint8Array {\n const SS = 512;\n const ENDOFCHAIN = 0xfffffffe;\n const FREESECT = 0xffffffff;\n const FATSECT = 0xfffffffd;\n\n // FileHeader 크기 검증\n if (fileHeaderData.length < 256) {\n throw new Error(\n `FileHeader 크기 부족: ${fileHeaderData.length} (최소 256)`,\n );\n }\n\n function padSector(d: Uint8Array): Uint8Array {\n const n = Math.ceil(Math.max(d.length, 1) / SS) * SS;\n if (d.length === n) return d;\n const out = new Uint8Array(n);\n out.set(d);\n return out;\n }\n\n const fhPad = padSector(fileHeaderData);\n const diPad = padSector(docInfoData);\n const s0Pad = padSector(section0Data);\n const imgPads = binImages.map((img) => padSector(img.data));\n\n const fhN = fhPad.length / SS;\n const diN = diPad.length / SS;\n const s0N = s0Pad.length / SS;\n const imgNs = imgPads.map((p) => p.length / SS);\n const totalImgN = imgNs.reduce((s, n) => s + n, 0);\n\n const numDirEntries = 5 + (binImages.length> 0 ? 1 + binImages.length : 0);\n const dirN = Math.max(2, Math.ceil(numDirEntries / 4));\n\n let fatN = 1;\n for (let iter = 0; iter < 10; iter++) {\n const total = fatN + dirN + fhN + diN + s0N + totalImgN;\n const needed = Math.ceil(total / 128);\n if (needed <= fatN) break;\n fatN = needed;\n }\n\n const dir1Sec = fatN;\n const fhSec = dir1Sec + dirN;\n const diSec = fhSec + fhN;\n const s0Sec = diSec + diN;\n\n const imgSecs: number[] = [];\n let curSec = s0Sec + s0N;\n for (const n of imgNs) {\n imgSecs.push(curSec);\n curSec += n;\n }\n const totalSec = curSec;\n\n const fatBuf = new Uint8Array(fatN * SS).fill(0xff);\n const setFat = (i: number, v: number) => {\n fatBuf[i * 4] = v & 0xff;\n fatBuf[i * 4 + 1] = (v>>> 8) & 0xff;\n fatBuf[i * 4 + 2] = (v>>> 16) & 0xff;\n fatBuf[i * 4 + 3] = (v>>> 24) & 0xff;\n };\n\n for (let i = 0; i < fatN; i++) setFat(i, FATSECT);\n for (let i = 0; i < dirN; i++)\n setFat(dir1Sec + i, i + 1 < dirN ? dir1Sec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < fhN; i++)\n setFat(fhSec + i, i + 1 < fhN ? fhSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < diN; i++)\n setFat(diSec + i, i + 1 < diN ? diSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < s0N; i++)\n setFat(s0Sec + i, i + 1 < s0N ? s0Sec + i + 1 : ENDOFCHAIN);\n for (let ii = 0; ii < imgNs.length; ii++) {\n const start = imgSecs[ii];\n const n = imgNs[ii];\n for (let i = 0; i < n; i++)\n setFat(start + i, i + 1 < n ? start + i + 1 : ENDOFCHAIN);\n }\n\n const dirBuf = new Uint8Array(dirN * SS);\n const dv = new DataView(dirBuf.buffer);\n\n function writeDirEntry(\n idx: number,\n name: string,\n type: number,\n left: number,\n right: number,\n child: number,\n startSec: number,\n size: number,\n ): void {\n const base = idx * 128;\n const nl = name.length;\n // OLE2: 이름은 UTF-16LE, (글자수+1)*2 바이트가 길이 필드에 기록됨\n for (let i = 0; i < nl; i++)\n dv.setUint16(base + i * 2, name.charCodeAt(i), true);\n dv.setUint16(base + 64, (nl + 1) * 2, true);\n dirBuf[base + 66] = type;\n dirBuf[base + 67] = 1; // DE_NODE\n dv.setInt32(base + 68, left, true);\n dv.setInt32(base + 72, right, true);\n dv.setInt32(base + 76, child, true);\n dv.setUint32(base + 116, startSec>>> 0, true);\n dv.setUint32(base + 120, size>>> 0, true);\n }\n\n // 초기값 -1 (NOSTREAM)\n for (let i = 0; i < dirN * 4; i++) {\n const base = i * 128;\n dv.setInt32(base + 68, -1, true);\n dv.setInt32(base + 72, -1, true);\n dv.setInt32(base + 76, -1, true);\n }\n\n /**\n * 트리 구조 설계:\n * 0: Root Entry (child -> 1)\n * 1: FileHeader (left -> -1, right -> 2)\n * 2: DocInfo (left -> -1, right -> 3)\n * 3: BodyText (left -> -1, right -> 5, child -> 4)\n * 4: Section0 (left -> -1, right -> -1)\n * 5: BinData (left -> -1, right -> -1, child -> 6...)\n */\n\n if (binImages.length> 0) {\n writeDirEntry(0, \"Root Entry\", 5, -1, -1, 1, ENDOFCHAIN, 0);\n writeDirEntry(1, \"FileHeader\", 2, -1, 2, -1, fhSec, fileHeaderData.length);\n writeDirEntry(2, \"DocInfo\", 2, -1, 3, -1, diSec, docInfoData.length);\n writeDirEntry(3, \"BodyText\", 1, -1, 5, 4, ENDOFCHAIN, 0);\n writeDirEntry(4, \"Section0\", 2, -1, -1, -1, s0Sec, section0Data.length);\n writeDirEntry(5, \"BinData\", 1, -1, -1, 6, ENDOFCHAIN, 0);\n for (let ii = 0; ii < binImages.length; ii++) {\n const img = binImages[ii];\n const streamName = `BIN${String(img.id).padStart(4, \"0\")}.${img.ext}`;\n const sibling = ii + 1 < binImages.length ? 7 + ii : -1;\n writeDirEntry(\n 6 + ii,\n streamName,\n 2,\n -1,\n sibling,\n -1,\n imgSecs[ii],\n img.data.length,\n );\n }\n } else {\n writeDirEntry(0, \"Root Entry\", 5, -1, -1, 1, ENDOFCHAIN, 0);\n writeDirEntry(1, \"FileHeader\", 2, -1, 2, -1, fhSec, fileHeaderData.length);\n writeDirEntry(2, \"DocInfo\", 2, -1, 3, -1, diSec, docInfoData.length);\n writeDirEntry(3, \"BodyText\", 1, -1, -1, 4, ENDOFCHAIN, 0);\n writeDirEntry(4, \"Section0\", 2, -1, -1, -1, s0Sec, section0Data.length);\n }\n\n // HWP Root Entry CLSID\n const HWP_CLSID = [\n 0x20, 0xe9, 0xe3, 0xc0, 0x46, 0x35, 0xcf, 0x11, 0x8d, 0x81, 0x00, 0xaa,\n 0x00, 0x38, 0x9b, 0x71,\n ];\n for (let i = 0; i < 16; i++) dirBuf[80 + i] = HWP_CLSID[i];\n\n const hdr = new Uint8Array(SS);\n const hdv = new DataView(hdr.buffer);\n\n // OLE2/CFB 헤더 구조:\n // 0-7: Magic number (D0 CF 11 E0 A1 B1 1A E1)\n // 8-23: CLSID (16 bytes)\n // 24-25: Minor version (0x003E = 62)\n // 26-27: Major version (0x0003 = 3)\n // 28-29: Byte order (0x00FE = Little-Endian)\n // 30-31: Sector size exponent (0x0009 = 2^9 = 512)\n // 32-33: Mini sector size exponent (0x0006 = 2^6 = 64)\n // 34-39: Reserved (6 bytes)\n // 40-43: Number of FAT sectors\n // 44-47: Directory start sector location\n // 48-51: Transaction signature number\n // 52-55: Mini stream cutoff size (0x1000 = 4096)\n // 56-59: Mini FAT start sector location\n // 60-63: Number of mini FAT sectors\n // 64-67: FAT start sector location\n // 68-71: Number of backup FAT sectors\n // 72-75: Backup FAT start sector location\n // 76-511: Sector bitmap (109 sectors worth)\n\n // Magic number\n const MAGIC = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];\n MAGIC.forEach((b, i) => {\n hdr[i] = b;\n });\n\n // CLSID is already set in dirBuf[0][80:96] for Root Entry\n\n // Version\n hdv.setUint16(24, 0x003e, true); // Minor version\n hdv.setUint16(26, 0x0003, true); // Major version\n\n // Byte order\n hdv.setUint16(28, 0x00fe, true); // Little-Endian\n\n // Sector size exponent (2^9 = 512)\n hdv.setUint16(30, 0x0009, true);\n\n // Mini sector size exponent (2^6 = 64)\n hdv.setUint16(32, 0x0006, true);\n\n // Reserved (34-39, 6 bytes) - already zero\n\n // Number of FAT sectors\n hdv.setUint32(40, fatN, true);\n\n // Directory start sector location\n hdv.setUint32(44, dir1Sec, true);\n\n // Transaction signature number\n hdv.setUint32(48, 0, true);\n\n // Mini stream cutoff size\n hdv.setUint32(52, 0x1000, true);\n\n // Mini FAT start sector location\n hdv.setUint32(56, ENDOFCHAIN, true);\n\n // Number of mini FAT sectors\n hdv.setUint32(60, 0, true);\n\n // FAT start sector location\n hdv.setUint32(64, ENDOFCHAIN, true);\n\n // Number of backup FAT sectors\n hdv.setUint32(68, 0, true);\n\n // Backup FAT start sector location\n hdv.setUint32(72, 0, true);\n\n // Sector bitmap (76-511)\n for (let i = 0; i < 109; i++) {\n hdv.setUint32(76 + i * 4, i < fatN ? i : FREESECT, true);\n }\n\n const out = new Uint8Array(SS + totalSec * SS);\n out.set(hdr, 0);\n for (let i = 0; i < fatN; i++)\n out.set(fatBuf.subarray(i * SS, (i + 1) * SS), SS + i * SS);\n for (let i = 0; i < dirN; i++)\n out.set(dirBuf.subarray(i * SS, (i + 1) * SS), SS + (dir1Sec + i) * SS);\n out.set(fhPad, SS + fhSec * SS);\n out.set(diPad, SS + diSec * SS);\n out.set(s0Pad, SS + s0Sec * SS);\n for (let ii = 0; ii < imgPads.length; ii++)\n out.set(imgPads[ii], SS + imgSecs[ii] * SS);\n return out;\n}\n\n// ─── 유틸리티 ────────────────────────────────────────────────\n\nfunction concatU8(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const a of arrays) {\n out.set(a, off);\n off += a.length;\n }\n return out;\n}\n\n// ─── OLE2 검증 ──────────────────────────────────────────────\n\nfunction validateOle2Magic(hwp: Uint8Array): boolean {\n const OLE_MAGIC = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];\n return OLE_MAGIC.every((b, i) => hwp[i] === b);\n}\n\n// ─── Encoder 진입점 ──────────────────────────────────────────\n\nexport class HwpEncoder extends BaseEncoder {\n protected getFormat(): string {\n return \"hwp\";\n }\n protected getAliases(): string[] {\n return [\"application/vnd.hancom.hwp\"];\n }\n\n async encode(doc: DocRoot): Promise> {\n try {\n // 패스 1: 스타일 수집 (HwpStyleBank — ANYTOHWP 방식 언어별 폰트)\n const bank = new HwpStyleBank();\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectNode(node, bank);\n }\n\n // 이미지 수집 (ANYTOHWP 개선: 픽셀 치수는 encodePicPara에서 추출)\n const images: BinImage[] = [];\n const seenB64 = new Set();\n let binIdCounter = 1;\n\n function registerImg(img: any): void {\n const key = img.b64.substring(0, 50);\n if (seenB64.has(key)) return;\n seenB64.add(key);\n const raw = TextKit.base64Decode(img.b64);\n const ext =\n img.mime === \"image/png\"\n ? \"png\"\n : img.mime === \"image/gif\"\n ? \"gif\"\n : img.mime === \"image/bmp\"\n ? \"bmp\"\n : \"jpg\";\n images.push({ id: binIdCounter++, ext, data: new Uint8Array(raw) });\n }\n\n function collectImages(node: any): void {\n if (node.tag === \"para\") {\n for (const img of flatImgNodes(node.kids)) registerImg(img);\n } else if (node.tag === \"grid\") {\n for (const row of node.kids)\n for (const cell of row.kids)\n for (const para of cell.kids) collectImages(para);\n }\n }\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectImages(node);\n }\n\n // 패스 2: 스트림 빌드\n const docInfoRaw = buildDocInfoStream(bank, images);\n const bodyRaw = buildBodyTextStream(doc, bank, images);\n\n // HWP 5.0: Zlib 헤더 없는 Raw Deflate\n const docInfoCmp = pako.deflateRaw(docInfoRaw);\n const bodyCmp = pako.deflateRaw(bodyRaw);\n\n const fileHdr = buildHwpFileHeader();\n\n // FileHeader 검증\n if (fileHdr.length !== 256) {\n return fail(\n `HwpEncoder: FileHeader 크기 오류 - ${fileHdr.length} bytes (기대: 256 bytes)`,\n );\n }\n\n const hwp = buildHwpOle2(fileHdr, docInfoCmp, bodyCmp, images);\n\n if (!validateOle2Magic(hwp)) {\n return fail(\"HwpEncoder: OLE2 매직 바이트 오류\");\n }\n\n // HWP 파일 크기 검증 (최소 512 바이트 - OLE2 헤더 1 섹터)\n if (hwp.length < 512) {\n return fail(\n `HwpEncoder: HWP 파일 크기 부족 - ${hwp.length} bytes (최소 512 bytes)`,\n );\n }\n\n return succeed(hwp);\n } catch (e: any) {\n return fail(`HwpEncoder: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n}\n\nregistry.registerEncoder(new HwpEncoder());\n","import type { DocRoot } from '../model/doc-tree';\nimport type { Outcome } from '../contract/result';\nimport type { EncoderOptions } from '../contract/encoder';\nimport { succeed, fail } from '../contract/result';\nimport { registry } from './registry';\n\n// Side-effect imports: auto-register all decoders and encoders\nimport '../decoders/hwpx/HwpxDecoder';\nimport '../decoders/hwp/HwpScanner';\nimport '../decoders/docx/DocxDecoder';\nimport '../decoders/md/MdDecoder';\nimport '../decoders/html/HtmlDecoder';\nimport '../encoders/hwpx/HwpxEncoder';\nimport '../encoders/docx/DocxEncoder';\nimport '../encoders/md/MdEncoder';\nimport '../encoders/html/HtmlEncoder';\nimport '../encoders/hwp/HwpEncoder';\n\nexport class Pipeline {\n private constructor(private raw: Uint8Array, private srcFmt: string) {}\n\n /** 파일을 열고 포맷을 자동 감지하거나 명시 */\n static open(input: Uint8Array | string, fmt?: string): Pipeline {\n if (typeof input === 'string') {\n return new Pipeline(new TextEncoder().encode(input), fmt ?? 'md');\n }\n return new Pipeline(input, fmt ?? detectFormat(input));\n }\n\n /** File/Blob 비동기 입력 */\n static async openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise {\n if (input instanceof Uint8Array || typeof input === 'string') {\n return Pipeline.open(input, fmt);\n }\n const buf = await input.arrayBuffer();\n const data = new Uint8Array(buf);\n const detectedFmt = fmt ?? (input instanceof File ? getExt(input.name) : undefined) ?? detectFormat(data);\n return new Pipeline(data, detectedFmt);\n }\n\n /** 목표 포맷으로 변환 */\n async to(targetFmt: string, options?: EncoderOptions): Promise> {\n const decoder = registry.getDecoder(this.srcFmt);\n const encoder = registry.getEncoder(targetFmt);\n\n if (!decoder) return fail(`지원하지 않는 입력 포맷: ${this.srcFmt}`);\n if (!encoder) return fail(`지원하지 않는 출력 포맷: ${targetFmt}`);\n\n const docResult = await decoder.decode(this.raw);\n if (!docResult.ok) return docResult;\n\n const encResult = await encoder.encode(docResult.data, options);\n if (!encResult.ok) return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n\n return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n }\n\n /** DocRoot만 추출 (인코딩 없이) */\n async inspect(): Promise> {\n const decoder = registry.getDecoder(this.srcFmt);\n if (!decoder) return fail(`디코더 없음: ${this.srcFmt}`);\n return decoder.decode(this.raw);\n }\n}\n\nfunction detectFormat(data: Uint8Array): string {\n // HWP 파일 (OLE Compound Document)\n if (data[0] === 0xD0 && data[1] === 0xCF && data[2] === 0x11 && data[3] === 0xE0) return 'hwp';\n\n // ZIP 기반 파일 (DOCX, HWPX)\n if (data[0] === 0x50 && data[1] === 0x4B) {\n // DOCX 는 [Content_Types].xml 에 application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml 이 있음\n // HWPX 는 application/ha-xml-core-document\n const str = new TextDecoder('utf-8', { fatal: false }).decode(data.slice(0, 4096));\n if (str.includes('wordprocessingml')) return 'docx';\n if (str.includes('ha-xml')) return 'hwpx';\n if (str.includes('hwpml/')) return 'hwpx';\n if (str.includes('word/')) return 'docx';\n return 'hwpx'; // 기본값\n }\n\n return 'md';\n}\n\nfunction getExt(name: string): string | undefined {\n const parts = name.split('.');\n return parts.length> 1 ? parts[parts.length - 1].toLowerCase() : undefined;\n}\n","import type { AnyNode, DocRoot } from '../model/doc-tree';\n\nexport type WalkCallback = (node: AnyNode, parent: AnyNode | null, depth: number) => void | 'stop';\n\nexport function walkNode(\n node: AnyNode,\n cb: WalkCallback,\n parent: AnyNode | null = null,\n depth = 0,\n): boolean {\n const result = cb(node, parent, depth);\n if (result === 'stop') return false;\n\n if ('kids' in node && Array.isArray((node as any).kids)) {\n for (const kid of (node as any).kids) {\n if (!walkNode(kid as AnyNode, cb, node, depth + 1)) return false;\n }\n }\n return true;\n}\n\nexport class TreeWalker {\n walk(root: DocRoot, cb: WalkCallback): void {\n walkNode(root, cb);\n }\n\n findAll(root: DocRoot, predicate: (n: AnyNode) => n is T): T[] {\n const results: T[] = [];\n walkNode(root, (n) => { if (predicate(n)) results.push(n); });\n return results;\n }\n\n extractText(root: DocRoot): string {\n const parts: string[] = [];\n walkNode(root, (n) => {\n if (n.tag === 'txt') parts.push(n.content);\n if (n.tag === 'br') parts.push('\\n');\n if (n.tag === 'pb') parts.push('\\n\\n');\n });\n return parts.join('');\n }\n}\n","import type { DocRoot, GridNode } from '../model/doc-tree';\nimport { walkNode } from './TreeWalker';\n\nexport function countNodes(root: DocRoot): Record {\n const counts: Record = {};\n walkNode(root, (n) => { counts[n.tag] = (counts[n.tag] ?? 0) + 1; });\n return counts;\n}\n\nexport function validateRoot(root: DocRoot): string[] {\n const errors: string[] = [];\n if (root.tag !== 'root') errors.push('Root node must have tag \"root\"');\n if (!Array.isArray(root.kids)) errors.push('Root.kids must be an array');\n if (root.kids.length === 0) errors.push('Document has no sheets');\n\n walkNode(root, (n) => {\n if (n.tag === 'cell' && n.kids.length === 0) {\n errors.push('CellNode must have at least one ParaNode child');\n }\n if (n.tag === 'grid' && (n as GridNode).kids.length === 0) {\n errors.push('GridNode must have at least one RowNode');\n }\n });\n\n return errors;\n}\n"],"mappings":"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","names":["pako","import_pako","pako","i","r","data","coreXml","stylesXml","extractDims","decodeHeaderFooter","toArr","decodePara","decodeGrid","decodeGridSimple","decodeGridFlat","decodeGridText","cellText","tableText","end","t","paraKids","stylesXml","mimeToExt","registerImage","esc","encodeImage","encodeContent","encodeGrid","encodeImage","encodePara","encodeContent","encodeGrid","encodeSpan","encodeImage","import_pako","TAG_FACE_NAME","TAG_BORDER_FILL","TAG_CHAR_SHAPE","TAG_PARA_SHAPE","TAG_PARA_HEADER","TAG_PARA_TEXT","TAG_PARA_CHAR_SHAPE","TAG_CTRL_HEADER","TAG_LIST_HEADER","TAG_PAGE_DEF","CTRL_TABLE","BORDER_W_PT","readPixelDims","LANG_GROUPS","encodePara","encodeGrid","out","registerImg","collectImages","pako"]} \ No newline at end of file diff --git a/hwpkit-extension/index.mjs b/hwpkit-extension/index.mjs new file mode 100644 index 000000000..77d78461d --- /dev/null +++ b/hwpkit-extension/index.mjs @@ -0,0 +1,7762 @@ +// src/contract/result.ts +function succeed(data, warns = []) { + return { ok: true, data, warns }; +} +function fail(error, warns = []) { + return { ok: false, error, warns }; +} + +// src/pipeline/registry.ts +var FormatRegistry = class { + constructor() { + this.decoders = /* @__PURE__ */ new Map(); + this.encoders = /* @__PURE__ */ new Map(); + } + registerDecoder(d) { + this.decoders.set(d.format, d); + if (d.aliases) { + for (const alias of d.aliases) this.decoders.set(alias, d); + } + } + registerEncoder(e) { + this.encoders.set(e.format, e); + if (e.aliases) { + for (const alias of e.aliases) this.encoders.set(alias, e); + } + } + getDecoder(fmt) { + return this.decoders.get(fmt); + } + getEncoder(fmt) { + return this.encoders.get(fmt); + } + supportedInputs() { + return [...this.decoders.keys()]; + } + supportedOutputs() { + return [...this.encoders.keys()]; + } +}; +var registry = new FormatRegistry(); + +// src/model/doc-props.ts +var A4 = { + wPt: 595.28, + hPt: 841.89, + mt: 56.69, + mb: 56.69, + ml: 70.87, + mr: 70.87, + orient: "portrait" +}; +var A4_LANDSCAPE = { + wPt: 841.89, + hPt: 595.28, + mt: 56.69, + mb: 56.69, + ml: 70.87, + mr: 70.87, + orient: "landscape" +}; +function normalizeDims(dims) { + const orient = dims.orient ?? "portrait"; + if (orient === "landscape" && dims.wPt < dims.hPt) { + return { ...dims, wPt: dims.hPt, hPt: dims.wPt }; + } + if (orient === "portrait" && dims.wPt> dims.hPt) { + return { ...dims, wPt: dims.hPt, hPt: dims.wPt }; + } + return dims; +} +var DEFAULT_STROKE = { kind: "solid", pt: 0.5, color: "000000" }; + +// src/model/builders.ts +function buildRoot(meta = {}, kids = []) { + return { tag: "root", meta, kids }; +} +function buildSheet(kids = [], dims = A4, opts) { + const node = { tag: "sheet", dims, kids }; + if (opts?.headers) node.headers = opts.headers; + if (opts?.footers) node.footers = opts.footers; + return node; +} +function buildPageNum(format) { + return { tag: "pagenum", format }; +} +function buildBr() { + return { tag: "br" }; +} +function buildPb() { + return { tag: "pb" }; +} +function buildPara(kids = [], props = {}) { + return { tag: "para", props, kids }; +} +function buildSpan(content, props = {}) { + const txt = { tag: "txt", content }; + return { tag: "span", props, kids: [txt] }; +} +function buildImg(b64, mime, w, h, alt, layout) { + const node = { tag: "img", b64, mime, w, h }; + if (alt) node.alt = alt; + if (layout) node.layout = layout; + return node; +} +function buildGrid(kids, props = {}) { + return { tag: "grid", props, kids }; +} +function buildRow(kids, heightPt) { + const node = { tag: "row", kids }; + if (heightPt != null) node.heightPt = heightPt; + return node; +} +function buildCell(kids, opts = {}) { + return { tag: "cell", cs: opts.cs ?? 1, rs: opts.rs ?? 1, props: opts.props ?? {}, kids }; +} + +// src/safety/ShieldedParser.ts +var ShieldedParser = class { + constructor() { + this.log = []; + } + /** 단일 요소 안전 파싱 */ + guard(fn, fallback, label) { + try { + const v = fn(); + if (v == null) { + this.warn(label, "returned null/undefined"); + return fallback; + } + return v; + } catch (e) { + this.warn(label, e?.message ?? String(e)); + return fallback; + } + } + /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */ + guardAll(items, fn, fb, label) { + return items.map( + (x, i) => this.guard(() => fn(x, i), fb(x, i), `${label}[${i}]`) + ); + } + /** + * 표 전용 4단계 폴백 + * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text + */ + guardGrid(node, lv1Full, lv2Grid, lv3Flat, lv4Text, label) { + const levels = [ + [lv1Full, 1], + [lv2Grid, 2], + [lv3Flat, 3], + [lv4Text, 4] + ]; + for (const [fn, lv] of levels) { + try { + const v = fn(node); + if (v != null) { + if (lv> 1) this.warn(label, `degraded to level ${lv}`); + return { value: v, level: lv }; + } + } catch (e) { + this.warn(label, `Lv${lv} failed: ${e?.message ?? String(e)}`); + } + } + this.warn(label, "ALL LEVELS FAILED \u2014 returning lv4Text forced"); + return { value: lv4Text(null), level: 4 }; + } + /** 이미지 안전 파싱 */ + guardImg(node, fn, placeholder, label) { + try { + const v = fn(node); + if (v != null) return v; + } catch (e) { + this.warn(label, e?.message ?? String(e)); + } + this.warn(label, "using placeholder image"); + return placeholder(`[\uC774\uBBF8\uC9C0 \uB85C\uB4DC \uC2E4\uD328: ${label}]`); + } + warn(label, msg) { + const w = `[SHIELD] ${label}: ${msg}`; + console.warn(w); + this.log.push(w); + } + flush() { + const r = [...this.log]; + this.log = []; + return r; + } +}; + +// src/safety/StyleBridge.ts +var Metric = { + // HWP 세계 (1 inch = 7200 HWPUNIT) + hwpToPt: (v) => v / 100, + ptToHwp: (v) => Math.round(v * 100), + hwpToDxa: (v) => Math.round(v / 5), + dxaToHwp: (v) => Math.round(v * 5), + hwpToEmu: (v) => Math.round(v * 127), + emuToHwp: (v) => Math.round(v / 127), + // DOCX 세계 (1 inch = 1440 dxa, 1 pt = 20 dxa) + dxaToPt: (v) => v / 20, + ptToDxa: (v) => Math.round(v * 20), + dxaToEmu: (v) => Math.round(v * 635), + emuToDxa: (v) => Math.round(v / 635), + emuToPt: (v) => v / 12700, + ptToEmu: (v) => Math.round(v * 12700), + // HWPX charPr height: 1000 = 10pt + hHeightToPt: (v) => v / 100, + ptToHHeight: (v) => Math.round(v * 100), + // DOCX half-point: 24 = 12pt + halfPtToPt: (v) => v / 2, + ptToHalfPt: (v) => Math.round(v * 2) +}; +function safeHex(raw) { + if (raw == null) return void 0; + if (typeof raw === "number") { + if (raw <= 0) return "000000"; + if (raw>= 16777215) return void 0; + return raw.toString(16).padStart(6, "0").toUpperCase(); + } + let s = String(raw).replace(/^#/, "").toUpperCase(); + if (/^[0-9A-F]{3}$/.test(s)) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2]; + if (/^[0-9A-F]{6}$/.test(s)) return s; + if (s === "AUTO" || s === "NONE" || s === "TRANSPARENT") return void 0; + return void 0; +} +var ALIGN_MAP = { + LEFT: "left", + CENTER: "center", + RIGHT: "right", + JUSTIFY: "justify", + BOTH: "justify", + DISTRIBUTE: "justify", + left: "left", + center: "center", + right: "right", + both: "justify", + start: "left", + end: "right" +}; +function safeAlign(raw) { + return ALIGN_MAP[raw ?? ""] ?? "left"; +} +var HWPX_STROKE = { + SOLID: "solid", + NONE: "none", + DASH: "dash", + DOT: "dot", + DOUBLE: "double", + LONG_DASH: "dash", + DASH_DOT: "dashDot", + DASH_DOT_DOT: "dashDotDot", + THICK_THIN: "double", + THIN_THICK: "double", + TRIPLE: "double" +}; +var DOCX_STROKE = { + single: "solid", + none: "none", + nil: "none", + dashed: "dash", + dotted: "dot", + double: "double", + dotDash: "dashDot", + dotDotDash: "dashDotDot", + thickThin: "double", + thinThick: "double", + triple: "double", + wave: "wave", + dashDotStroked: "dashDot", + threeDEmboss: "solid", + threeDEngrave: "solid" +}; +function safeStrokeHwpx(type, w, c) { + return { + kind: HWPX_STROKE[type ?? ""] ?? "solid", + pt: w != null ? Metric.hwpToPt(w) : 0.5, + color: safeHex(c) ?? "000000" + }; +} +function safeStrokeDocx(val, sz, c) { + return { + kind: DOCX_STROKE[val ?? ""] ?? "solid", + pt: sz != null ? sz / 8 : 0.5, + color: safeHex(c) ?? "000000" + }; +} +var FONT_MAP = { + // 맑은 고딕 계열 + "\uB9D1\uC740 \uACE0\uB515": "Malgun Gothic", + "\uB9D1\uC740\uACE0\uB515": "Malgun Gothic", + // 바탕 계열 (serif) + "\uBC14\uD0D5": "Batang", + "\uBC14\uD0D5\uCCB4": "BatangChe", + "\uD55C\uCEF4\uBC14\uD0D5": "Batang", + "\uD568\uCD08\uB86C\uBC14\uD0D5": "Batang", + "HY\uC2E0\uBA85\uC870": "Batang", + "HY\uACAC\uBA85\uC870": "Batang", + "HY\uADF8\uB798\uD53D": "Batang", + "\uAD81\uC11C": "Gungsuh", + "\uAD81\uC11C\uCCB4": "GungsuhChe", + // 고딕 계열 (sans-serif) + "\uB3CB\uC6C0": "Dotum", + "\uB3CB\uC6C0\uCCB4": "DotumChe", + "\uAD74\uB9BC": "Gulim", + "\uAD74\uB9BC\uCCB4": "GulimChe", + "\uD55C\uCEF4\uB3CB\uC6C0": "Malgun Gothic", + "\uD568\uCD08\uB86C\uB3CB\uC6C0": "Malgun Gothic", + "HY\uACAC\uACE0\uB515": "Malgun Gothic", + "HY\uC911\uACE0\uB515": "Malgun Gothic", + "HY\uD5E4\uB4DC\uB77C\uC778M": "Malgun Gothic", + "HY\uAC15B": "Malgun Gothic", + "HY\uB098\uBB34M": "Malgun Gothic", + "HY\uBAA9\uAC01\uD30C\uC784B": "Malgun Gothic", + "HY\uC5FD\uC11CM": "Malgun Gothic", + "HY\uC5FD\uC11CL": "Malgun Gothic", + // 나눔 계열 + "\uB098\uB214\uACE0\uB515": "Malgun Gothic", + "\uB098\uB214\uBA85\uC870": "Batang" +}; +function safeFont(raw) { + return FONT_MAP[raw ?? ""] ?? raw ?? "Malgun Gothic"; +} +var FONT_MAP_KR = { + "Malgun Gothic": "\uB9D1\uC740 \uACE0\uB515", + "Batang": "\uBC14\uD0D5", + "Dotum": "\uB3CB\uC6C0", + "Gulim": "\uAD74\uB9BC" +}; +function safeFontToKr(raw) { + return FONT_MAP_KR[raw ?? ""] ?? raw ?? "\uB9D1\uC740 \uACE0\uB515"; +} + +// src/toolkit/ArchiveKit.ts +import pako from "pako"; +var ArchiveKit = { + async inflate(compressed) { + return pako.inflate(compressed); + }, + async deflate(data) { + return pako.deflate(data, { level: 6 }); + }, + async unzip(zipData) { + const files = /* @__PURE__ */ new Map(); + const view = new DataView(zipData.buffer, zipData.byteOffset, zipData.byteLength); + let eocdOffset = -1; + const searchStart = Math.max(0, zipData.length - 65558); + for (let i = zipData.length - 22; i>= searchStart; i--) { + if (view.getUint32(i, true) === 101010256) { + eocdOffset = i; + break; + } + } + if (eocdOffset !== -1) { + const entryCount = view.getUint16(eocdOffset + 10, true); + const centralDirOffset = view.getUint32(eocdOffset + 16, true); + let cdOffset = centralDirOffset; + for (let i = 0; i < entryCount; i++) { + if (cdOffset + 46> zipData.length) break; + if (view.getUint32(cdOffset, true) !== 33639248) break; + const compressionMethod = view.getUint16(cdOffset + 10, true); + const compressedSize = view.getUint32(cdOffset + 20, true); + const uncompressedSize = view.getUint32(cdOffset + 24, true); + const fileNameLength = view.getUint16(cdOffset + 28, true); + const extraLength = view.getUint16(cdOffset + 30, true); + const commentLength = view.getUint16(cdOffset + 32, true); + const localHeaderOffset = view.getUint32(cdOffset + 42, true); + const nameBytes = zipData.subarray(cdOffset + 46, cdOffset + 46 + fileNameLength); + const name = new TextDecoder("utf-8").decode(nameBytes); + cdOffset += 46 + fileNameLength + extraLength + commentLength; + if (name.endsWith("/")) continue; + const localFnLen = view.getUint16(localHeaderOffset + 26, true); + const localExtraLen = view.getUint16(localHeaderOffset + 28, true); + const dataOffset = localHeaderOffset + 30 + localFnLen + localExtraLen; + let fileData; + if (compressionMethod === 0) { + fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize); + } else if (compressionMethod === 8) { + const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize); + fileData = pako.inflateRaw(compressed); + } else { + throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`); + } + files.set(name, new Uint8Array(fileData)); + } + return files; + } + let offset = 0; + while (offset < zipData.length - 4) { + const sig = view.getUint32(offset, true); + if (sig === 67324752) { + const compressionMethod = view.getUint16(offset + 8, true); + const compressedSize = view.getUint32(offset + 18, true); + const uncompressedSize = view.getUint32(offset + 22, true); + const fileNameLength = view.getUint16(offset + 26, true); + const extraLength = view.getUint16(offset + 28, true); + const nameBytes = zipData.subarray(offset + 30, offset + 30 + fileNameLength); + const name = new TextDecoder("utf-8").decode(nameBytes); + const dataOffset = offset + 30 + fileNameLength + extraLength; + let fileData; + if (compressionMethod === 0) { + fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize); + } else if (compressionMethod === 8) { + const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize); + fileData = pako.inflateRaw(compressed); + } else { + throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`); + } + files.set(name, new Uint8Array(fileData)); + offset = dataOffset + compressedSize; + } else if (sig === 33639248 || sig === 101010256) { + break; + } else { + offset++; + } + } + return files; + }, + async zip(entries) { + const localHeaders = []; + const centralHeaders = []; + let localOffset = 0; + for (const entry of entries) { + const nameBytes = new TextEncoder().encode(entry.name); + const crc = crc32(entry.data); + const store = entry.name === "mimetype" || entry.name === "version.xml"; + const method = store ? 0 : 8; + const payload = store ? entry.data : pako.deflateRaw(entry.data, { level: 6 }); + const local = new Uint8Array(30 + nameBytes.length + payload.length); + const lv = new DataView(local.buffer); + lv.setUint32(0, 67324752, true); + lv.setUint16(4, 20, true); + lv.setUint16(6, 0, true); + lv.setUint16(8, method, true); + lv.setUint16(10, 0, true); + lv.setUint16(12, 33, true); + lv.setUint32(14, crc, true); + lv.setUint32(18, payload.length, true); + lv.setUint32(22, entry.data.length, true); + lv.setUint16(26, nameBytes.length, true); + lv.setUint16(28, 0, true); + local.set(nameBytes, 30); + local.set(payload, 30 + nameBytes.length); + const central = new Uint8Array(46 + nameBytes.length); + const cv = new DataView(central.buffer); + cv.setUint32(0, 33639248, true); + cv.setUint16(4, 20, true); + cv.setUint16(6, 20, true); + cv.setUint16(8, 0, true); + cv.setUint16(10, method, true); + cv.setUint16(12, 0, true); + cv.setUint16(14, 33, true); + cv.setUint32(16, crc, true); + cv.setUint32(20, payload.length, true); + cv.setUint32(24, entry.data.length, true); + cv.setUint16(28, nameBytes.length, true); + cv.setUint16(30, 0, true); + cv.setUint16(32, 0, true); + cv.setUint16(34, 0, true); + cv.setUint16(36, 0, true); + cv.setUint32(38, 0, true); + cv.setUint32(42, localOffset, true); + central.set(nameBytes, 46); + localHeaders.push(local); + centralHeaders.push(central); + localOffset += local.length; + } + const centralDir = concat(centralHeaders); + const eocd = new Uint8Array(22); + const ev = new DataView(eocd.buffer); + ev.setUint32(0, 101010256, true); + ev.setUint16(4, 0, true); + ev.setUint16(6, 0, true); + ev.setUint16(8, entries.length, true); + ev.setUint16(10, entries.length, true); + ev.setUint32(12, centralDir.length, true); + ev.setUint32(16, localOffset, true); + ev.setUint16(20, 0, true); + return concat([...localHeaders, centralDir, eocd]); + } +}; +function concat(arrays) { + const total = arrays.reduce((s, a) => s + a.length, 0); + const out = new Uint8Array(total); + let offset = 0; + for (const a of arrays) { + out.set(a, offset); + offset += a.length; + } + return out; +} +function crc32(data) { + let crc = 4294967295; + for (const byte of data) { + crc ^= byte; + for (let i = 0; i < 8; i++) { + crc = crc & 1 ? crc>>> 1 ^ 3988292384 : crc>>> 1; + } + } + return (crc ^ 4294967295)>>> 0; +} + +// src/toolkit/XmlKit.ts +import { SaxesParser } from "saxes"; +function parseXmlStrict(xml) { + return new Promise((resolve, reject) => { + const parser = new SaxesParser({ xmlns: false }); + const stack = []; + let result = null; + parser.on("error", (err) => reject(err)); + parser.on("opentag", (node) => { + const obj = {}; + const attrs = node.attributes; + if (attrs && Object.keys(attrs).length> 0) { + obj["_attr"] = { ...attrs }; + } + stack.push({ tag: node.name, obj }); + }); + const appendText = (text) => { + if (stack.length> 0 && text) { + const frame = stack[stack.length - 1]; + const cur = frame.obj["_text"]; + frame.obj["_text"] = typeof cur === "string" ? cur + text : text; + } + }; + parser.on("text", (text) => appendText(text)); + parser.on("cdata", (cdata) => appendText(cdata)); + parser.on("closetag", () => { + const frame = stack.pop(); + if (!frame) return; + const { tag, obj } = frame; + if (stack.length === 0) { + result = { [tag]: [obj] }; + } else { + const parent = stack[stack.length - 1].obj; + const existing = parent[tag]; + if (Array.isArray(existing)) { + existing.push(obj); + } else { + parent[tag] = [obj]; + } + if (!parent["_childOrder"]) parent["_childOrder"] = []; + parent["_childOrder"].push(tag); + } + }); + try { + parser.write(xml).close(); + resolve(result); + } catch (e) { + reject(e); + } + }); +} +var XmlKit = { + /** @deprecated Use parseStrict instead */ + async parse(xml) { + return parseXmlStrict(xml); + }, + async parseStrict(xml) { + return parseXmlStrict(xml); + }, + attr(node, key) { + const a = node["_attr"]; + return a?.[key]; + }, + text(node) { + if (node == null) return ""; + if (typeof node === "string") return node; + const t = node["_text"]; + return typeof t === "string" ? t : ""; + } +}; + +// src/toolkit/TextKit.ts +var TextKit = { + decode(data, encoding = "utf-8") { + try { + return new TextDecoder(encoding, { fatal: true }).decode(data); + } catch { + return new TextDecoder("utf-8", { fatal: false }).decode(data); + } + }, + encode(text) { + return new TextEncoder().encode(text); + }, + escapeXml(s) { + return s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + }, + unescapeXml(s) { + return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'"); + }, + normalizeWhitespace(s) { + return s.replace(/\s+/g, " ").trim(); + }, + stripControl(s) { + return s.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ""); + }, + base64Encode(data) { + let binary = ""; + for (let i = 0; i < data.length; i++) { + binary += String.fromCharCode(data[i]); + } + return btoa(binary); + }, + base64Decode(b64) { + const binary = atob(b64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytes; + } +}; + +// src/core/BaseDecoder.ts +var BaseDecoder = class { + constructor() { + this.format = this.getFormat(); + this.aliases = this.getAliases(); + } + /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */ + getAliases() { + return []; + } + // ─── 공통 유틸리티 메서드 ────────────────────────── + /** 바이트를 UTF-8 문자열로 변환 */ + bytesToString(data) { + return TextKit.decode(data); + } + /** 문자열을 UTF-8 바이트로 변환 */ + stringToBytes(s) { + return TextKit.encode(s); + } + /** XML 이스케이프 */ + escapeXml(s) { + return TextKit.escapeXml(s); + } + /** XML 언이스케이프 */ + unescapeXml(s) { + return TextKit.unescapeXml(s); + } + /** base64 문자열을 Uint8Array 로 변환 */ + base64ToBytes(b64) { + return TextKit.base64Decode(b64); + } + /** Uint8Array 를 base64 문자열로 변환 */ + bytesToBase64(data) { + return TextKit.base64Encode(data); + } + /** ZIP 해제 */ + async unzip(data) { + return ArchiveKit.unzip(data); + } + /** ZIP 압축 */ + async zip(entries) { + return ArchiveKit.zip(entries); + } + /** inflate 해제 */ + async inflate(data) { + return ArchiveKit.inflate(data); + } + /** deflate 압축 */ + async deflate(data) { + return ArchiveKit.deflate(data); + } + /** 제어 문자 제거 */ + stripControl(s) { + return TextKit.stripControl(s); + } + /** 공백 정규화 */ + normalizeWhitespace(s) { + return TextKit.normalizeWhitespace(s); + } + /** XML 파싱 (DOMParser 사용) */ + parseXml(xmlString) { + const parser = new DOMParser(); + return parser.parseFromString(xmlString, "text/xml"); + } + /** XML 요소에서 텍스트 내용 추출 */ + getTextContent(element) { + if (!element) return ""; + return element.textContent ?? ""; + } + /** XML 요소의 속성 값 추출 */ + getAttr(element, name) { + return element?.getAttribute(name) ?? null; + } + /** XML 요소의 자식 요소 찾기 */ + getChild(element, tagName) { + if (!element) return null; + return element.querySelector(`>${tagName}`) ?? null; + } + /** XML 요소의 모든 자식 요소 찾기 */ + getChildren(element, tagName) { + if (!element) return []; + return Array.from(element.querySelectorAll(`>${tagName}`)); + } +}; + +// src/encoders/hwpx/constants.ts +var HWPX_MIME_TYPE = "application/hwp+zip"; +var NAMESPACES = { + /** Hancom 문서 네임스페이스 */ + HANCOM: "http://www.hancom.co.kr/hwp/xml", + /** Hancom 공통 네임스페이스 */ + HANCOM_COMMON: "http://www.hancom.co.kr/hwp/xml/common", + /** Hancom 버전 네임스페이스 */ + HANCOM_VERSION: "http://www.hancom.co.kr/hwp/xml/version", + /** Hancom 속성 네임스페이스 */ + HANCOM_PROP: "http://www.hancom.co.kr/hwp/xml/property" +}; +var NAMESPACE_DECLARATIONS = { + HEAD: `xmlns:hh="${NAMESPACES.HANCOM}" xmlns:hc="${NAMESPACES.HANCOM_COMMON}" xmlns:hv="${NAMESPACES.HANCOM_VERSION}" xmlns:hp="${NAMESPACES.HANCOM_PROP}"`, + SECTION: `xmlns:hs="${NAMESPACES.HANCOM}" xmlns:hp="${NAMESPACES.HANCOM_PROP}"` +}; +var PT_PER_INCH = 72; +var PIXELS_PER_INCH = 96; +var PT_PER_PIXEL = PT_PER_INCH / PIXELS_PER_INCH; + +// src/decoders/hwpx/HwpxDecoder.ts +var HwpxDecoder = class extends BaseDecoder { + getFormat() { + return "hwpx"; + } + getAliases() { + return [HWPX_MIME_TYPE, "application/hwp+zip"]; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const files = await ArchiveKit.unzip(data); + const sectionFiles = []; + for (let i = 0; ; i++) { + const sec = files.get(`Contents/section${i}.xml`) ?? files.get(`section${i}.xml`); + if (!sec) break; + sectionFiles.push(sec); + } + if (sectionFiles.length === 0) { + const fallback = findSectionFile(files); + if (fallback) sectionFiles.push(fallback); + } + if (sectionFiles.length === 0) + return fail("HWPX: No section files found"); + const headXml = files.get("Contents/header.xml") ?? files.get("header.xml"); + let meta = {}; + let dims = { ...A4 }; + let borderFills = /* @__PURE__ */ new Map(); + let charPrs = /* @__PURE__ */ new Map(); + let paraPrs = /* @__PURE__ */ new Map(); + if (headXml) { + try { + const headStr = TextKit.decode(headXml); + const headObj = await XmlKit.parseStrict(headStr); + if (headObj) { + meta = extractMeta(headObj); + dims = extractDims(headObj) ?? dims; + borderFills = extractBorderFills(headObj); + charPrs = extractCharPrs(headObj); + paraPrs = extractParaPrs(headObj); + } + } catch { + } + } + const ctx = { + files, + shield, + borderFills, + charPrs, + paraPrs, + warns + }; + const allSections = []; + for (const secFile of sectionFiles) { + const bodyStr = TextKit.decode(secFile); + const bodyObj = await XmlKit.parseStrict(bodyStr); + allSections.push(...normalizeSections(bodyObj)); + } + const kids = shield.guardAll( + allSections, + (sec) => decodeSection(sec, dims, ctx), + () => buildSheet([buildPara([buildSpan("[\uC139\uC158 \uD30C\uC2F1 \uC2E4\uD328]")])], dims), + "hwpx:section" + ); + warns.push(...shield.flush()); + return succeed(buildRoot(meta, kids), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`HWPX decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function findSectionFile(files) { + for (const [key, val] of files) { + if (key.toLowerCase().includes("section") && key.endsWith(".xml")) + return val; + } + return void 0; +} +function normalizeSections(bodyObj) { + if (bodyObj?.["hs:sec"]) return toArr(bodyObj["hs:sec"]); + if (bodyObj?.["hp:SEC"]) return toArr(bodyObj["hp:SEC"]); + const root = bodyObj?.["hp:HWPML"] ?? bodyObj?.HWPML ?? bodyObj; + const body = root?.["hp:BODY"]?.[0] ?? root?.BODY?.[0] ?? root?.["hp:BODY"] ?? root?.BODY; + if (!body) return [bodyObj]; + const sections = body?.["hp:SECTION"] ?? body?.SECTION ?? []; + return Array.isArray(sections) ? sections : [sections]; +} +function getTag(obj, ...names) { + for (const n of names) { + const v = obj?.[n]; + if (v != null) return toArr(v); + } + return []; +} +function extractMeta(headObj) { + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const info = root?.["hh:DOCSUMMARY"]?.[0] ?? root?.DOCSUMMARY?.[0]; + if (!info) return {}; + const a = (k) => info?.[`hh:${k}`]?.[0]?._text ?? info?.[k]?.[0]?._text ?? ""; + return { + title: a("TITLE") || void 0, + author: a("AUTHOR") || void 0, + subject: a("SUBJECT") || void 0 + }; + } catch { + return {}; + } +} +function extractDims(headObj) { + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return null; + const secPrList = refList?.["hh:SECPRLST"]?.[0]?.["hh:SECPR"] ?? refList?.SECPRLST?.[0]?.SECPR; + const sec = Array.isArray(secPrList) ? secPrList[0] : secPrList; + if (!sec) return null; + const pa = sec?.["hh:PAGEPROPERTY"]?.[0]?._attr ?? sec?.PAGEPROPERTY?.[0]?._attr; + if (!pa) return null; + const ew = Number(pa.Width ?? 59528); + const eh = Number(pa.Height ?? 84188); + return { + wPt: Metric.hwpToPt(ew), + hPt: Metric.hwpToPt(eh), + mt: Metric.hwpToPt(Number(pa.TopMargin ?? 5670)), + mb: Metric.hwpToPt(Number(pa.BottomMargin ?? 4252)), + ml: Metric.hwpToPt(Number(pa.LeftMargin ?? 8504)), + mr: Metric.hwpToPt(Number(pa.RightMargin ?? 8504)), + orient: ew> eh ? "landscape" : "portrait" + }; + } catch { + return null; + } +} +function extractBorderFills(headObj) { + const map = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return map; + const bfList = refList?.["hh:borderFills"]?.[0] ?? refList?.["hh:BORDERFILLLIST"]?.[0] ?? refList?.BORDERFILLLIST?.[0]; + if (!bfList) return map; + const bfs = getTag(bfList, "hh:borderFill", "hh:BORDERFILL"); + for (const bf of bfs) { + const attr = bf?._attr ?? {}; + const id = Number(attr.id ?? 0); + if (id === 0) continue; + const info = {}; + const parseBorderEl = (el) => { + if (!el) return void 0; + const a = el?._attr ?? {}; + const mmVal = parseFloat(a.width) || void 0; + const hwpVal = mmVal != null ? mmVal * 2.835 * 100 : void 0; + return safeStrokeHwpx(a.type, hwpVal, a.color); + }; + const topEl = bf?.["hh:topBorder"]?.[0] ?? bf?.["hh:top"]?.[0] ?? bf?.top?.[0]; + const rightEl = bf?.["hh:rightBorder"]?.[0] ?? bf?.["hh:right"]?.[0] ?? bf?.right?.[0]; + const bottomEl = bf?.["hh:bottomBorder"]?.[0] ?? bf?.["hh:bottom"]?.[0] ?? bf?.bottom?.[0]; + const leftEl = bf?.["hh:leftBorder"]?.[0] ?? bf?.["hh:left"]?.[0] ?? bf?.left?.[0]; + info.top = parseBorderEl(topEl); + info.right = parseBorderEl(rightEl); + info.bottom = parseBorderEl(bottomEl); + info.left = parseBorderEl(leftEl); + info.stroke = info.top ?? info.left ?? info.right ?? info.bottom; + const fillBrush = bf?.["hc:fillBrush"]?.[0] ?? bf?.["hh:fillBrush"]?.[0] ?? bf?.["hh:fill"]?.[0] ?? bf?.fill?.[0] ?? bf?.fillBrush?.[0]; + if (fillBrush) { + const winBrush = fillBrush?.["hc:winBrush"]?.[0]?._attr ?? fillBrush?.["hh:winBrush"]?.[0]?._attr ?? fillBrush?.winBrush?.[0]?._attr; + if (winBrush?.faceColor && winBrush.faceColor !== "none") { + info.bgColor = safeHex(winBrush.faceColor); + } + } + map.set(id, info); + } + } catch { + } + return map; +} +function buildFontIdMap(headObj) { + const fontMap = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return fontMap; + const fontfaces = refList?.["hh:fontfaces"]?.[0] ?? refList?.["hh:FONTFACES"]?.[0]; + if (!fontfaces) return fontMap; + const ffGroups = getTag(fontfaces, "hh:fontface", "hh:FONTFACE"); + for (const ff of ffGroups) { + const fonts = getTag(ff, "hh:font", "hh:FONT"); + for (const font of fonts) { + const fa = font?._attr ?? {}; + const fid = Number(fa.id ?? -1); + const name = fa.face ?? fa.name ?? fa.Face ?? ""; + if (fid>= 0 && name && !fontMap.has(fid)) fontMap.set(fid, name); + } + if (fontMap.size> 0) break; + } + } catch { + } + return fontMap; +} +function extractCharPrs(headObj) { + const map = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return map; + const fontIdMap = buildFontIdMap(headObj); + const cpList = refList?.["hh:charProperties"]?.[0] ?? refList?.["hh:CHARPROPERTIES"]?.[0]; + if (!cpList) return map; + const cps = getTag(cpList, "hh:charPr", "hh:CHARPR"); + for (const cp of cps) { + const attr = cp?._attr ?? {}; + const id = Number(attr.id ?? -1); + if (id < 0) continue; + const info = {}; + if (attr.height) info.pt = Metric.hHeightToPt(Number(attr.height)); + if (attr.textColor) info.color = safeHex(attr.textColor); + if (cp?.["hh:bold"]?.[0] != null) info.b = true; + if (cp?.["hh:italic"]?.[0] != null) info.i = true; + const ulAttr = cp?.["hh:underline"]?.[0]?._attr; + if (ulAttr?.type && ulAttr.type !== "NONE") info.u = true; + const stAttr = cp?.["hh:strikeout"]?.[0]?._attr; + if (stAttr?.shape && stAttr.shape !== "NONE" && stAttr.shape !== "3D") + info.s = true; + const fontRefAttr = cp?.["hh:fontRef"]?.[0]?._attr ?? cp?.["hh:FONTREF"]?.[0]?._attr; + if (fontRefAttr) { + const fid = Number( + fontRefAttr.hangul ?? fontRefAttr.latin ?? fontRefAttr.Hangul ?? 0 + ); + const name = fontIdMap.get(fid); + if (name) info.font = safeFont(name); + } + map.set(id, info); + } + } catch { + } + return map; +} +function extractParaPrs(headObj) { + const map = /* @__PURE__ */ new Map(); + try { + const root = headObj?.["hh:head"]?.[0] ?? headObj?.["hh:HEAD"]?.[0] ?? headObj?.HEAD?.[0] ?? headObj; + const refList = root?.["hh:refList"]?.[0] ?? root?.["hh:REFLIST"]?.[0] ?? root?.REFLIST?.[0]; + if (!refList) return map; + const ppList = refList?.["hh:paraProperties"]?.[0] ?? refList?.["hh:PARAPROPERTIES"]?.[0]; + if (!ppList) return map; + const pps = getTag(ppList, "hh:paraPr", "hh:PARAPR"); + for (const pp of pps) { + const attr = pp?._attr ?? {}; + const id = Number(attr.id ?? -1); + if (id < 0) continue; + const alignNode = pp?.["hh:align"]?.[0]?._attr ?? pp?.["hh:ALIGN"]?.[0]?._attr; + const align = alignNode?.horizontal ?? alignNode?.Horizontal; + let marginEl = pp?.["hh:margin"]?.[0] ?? null; + let lineSpEl = pp?.["hh:lineSpacing"]?.[0] ?? null; + if (!marginEl) { + const sw = pp?.["hp:switch"]?.[0]; + const container = sw?.["hp:default"]?.[0] ?? sw?.["hp:case"]?.[0]; + marginEl = container?.["hh:margin"]?.[0] ?? null; + lineSpEl = lineSpEl ?? container?.["hh:lineSpacing"]?.[0] ?? null; + } + let indentPt; + let indentRightPt; + let firstLineIndentPt; + let spaceBefore; + let spaceAfter; + let lineHeight; + let lineHeightFixed; + if (marginEl) { + const leftEl = marginEl?.["hc:left"]?.[0]; + const rightEl = marginEl?.["hc:right"]?.[0]; + const indentEl = marginEl?.["hc:intent"]?.[0] ?? marginEl?.["hc:indent"]?.[0]; + const prevEl = marginEl?.["hc:prev"]?.[0]; + const nextEl = marginEl?.["hc:next"]?.[0]; + const leftVal = Number(leftEl?._attr?.value ?? 0); + const rightVal = Number(rightEl?._attr?.value ?? 0); + const indentVal = Number(indentEl?._attr?.value ?? 0); + const prevVal = Number(prevEl?._attr?.value ?? 0); + const nextVal = Number(nextEl?._attr?.value ?? 0); + if (leftVal !== 0) indentPt = Metric.hwpToPt(leftVal); + if (rightVal !== 0) indentRightPt = Metric.hwpToPt(rightVal); + if (indentVal !== 0) firstLineIndentPt = Metric.hwpToPt(indentVal); + if (prevVal> 0) spaceBefore = Metric.hwpToPt(prevVal); + if (nextVal> 0) spaceAfter = Metric.hwpToPt(nextVal); + } + if (lineSpEl) { + const lsAttr = lineSpEl._attr ?? {}; + const lsType = lsAttr.type ?? "PERCENT"; + const lsVal = Number(lsAttr.value ?? 160); + if (lsType === "PERCENT" && lsVal> 0 && lsVal !== 160) { + lineHeight = lsVal / 100; + } else if (lsType === "FIXED" && lsVal> 0) { + lineHeightFixed = Metric.hwpToPt(lsVal); + } + } + map.set(id, { + align, + indentPt, + indentRightPt, + firstLineIndentPt, + spaceBefore, + spaceAfter, + lineHeight, + lineHeightFixed + }); + } + } catch { + } + return map; +} +function addParaItems(p, items) { + const runs = getTag(p, "hp:run", "hp:RUN"); + let hasTable = false; + for (const run of runs) { + const tbls = getTag(run, "hp:tbl", "hp:TABLE"); + if (tbls.length> 0) { + for (const tbl of tbls) { + items.push({ type: "table", node: tbl }); + } + hasTable = true; + } + } + if (!hasTable) { + items.push({ type: "para", node: p }); + } +} +function decodeSection(sec, dims, ctx) { + const firstParas = getTag(sec, "hp:p", "hp:P"); + const pageDims = extractSecPrDims(firstParas[0]) ?? dims; + const items = []; + const paras = getTag(sec, "hp:p", "hp:P"); + const tbls = getTag(sec, "hp:tbl", "hp:TABLE"); + const childOrder = sec?.["_childOrder"]; + if (Array.isArray(childOrder)) { + let pi = 0; + let ti = 0; + for (const tag of childOrder) { + if ((tag === "hp:p" || tag === "hp:P") && pi < paras.length) { + addParaItems(paras[pi++], items); + } else if ((tag === "hp:tbl" || tag === "hp:TABLE") && ti < tbls.length) { + items.push({ type: "table", node: tbls[ti++] }); + } + } + while (pi < paras.length) addParaItems(paras[pi++], items); + while (ti < tbls.length) items.push({ type: "table", node: tbls[ti++] }); + } else { + for (const p of paras) addParaItems(p, items); + for (const t of tbls) items.push({ type: "table", node: t }); + } + const kids = ctx.shield.guardAll( + items, + (item) => { + if (item.type === "table") { + try { + const { value } = ctx.shield.guardGrid( + item.node, + (n) => decodeGrid(n, ctx), + (n) => decodeGridSimple(n, ctx), + (n) => decodeGridFlat(n), + (n) => decodeGridText(n), + "hwpx:table" + ); + return value; + } catch { + return buildPara([buildSpan("[\uD45C \uD30C\uC2F1 \uC2E4\uD328]")]); + } + } + return decodePara(item.node, ctx); + }, + () => buildPara([buildSpan("[\uD30C\uC2F1 \uC2E4\uD328]")]), + "hwpx:content" + ); + const headerParas = decodeHeaderFooter(sec, "header", ctx); + const footerParas = decodeHeaderFooter(sec, "footer", ctx); + return buildSheet(kids.filter(Boolean), pageDims, { + headers: { default: headerParas }, + footers: { default: footerParas } + }); +} +function parseSecPrDims(secPr) { + const pagePr = secPr?.["hp:pagePr"]?.[0]?._attr ?? secPr?.["hp:PAGEPR"]?.[0]?._attr; + if (!pagePr) return null; + const margin = secPr?.["hp:pagePr"]?.[0]?.["hp:margin"]?.[0]?._attr ?? secPr?.["hp:PAGEPR"]?.[0]?.["hp:MARGIN"]?.[0]?._attr ?? {}; + const pw = Number(pagePr.width ?? 59528); + const ph = Number(pagePr.height ?? 84188); + return { + wPt: Metric.hwpToPt(pw), + hPt: Metric.hwpToPt(ph), + mt: Metric.hwpToPt(Number(margin.top ?? 5670)), + mb: Metric.hwpToPt(Number(margin.bottom ?? 4252)), + ml: Metric.hwpToPt(Number(margin.left ?? 8504)), + mr: Metric.hwpToPt(Number(margin.right ?? 8504)), + orient: pw> ph ? "landscape" : "portrait" + }; +} +function extractSecPrDims(p) { + if (!p) return null; + try { + const secPrDirect = p?.["hp:secPr"]?.[0] ?? p?.["hp:SECPR"]?.[0]; + if (secPrDirect) { + const dims = parseSecPrDims(secPrDirect); + if (dims) return dims; + } + const runs = getTag(p, "hp:run", "hp:RUN"); + for (const run of runs) { + const secPr = run?.["hp:secPr"]?.[0] ?? run?.["hp:SECPR"]?.[0]; + if (!secPr) continue; + const dims = parseSecPrDims(secPr); + if (dims) return dims; + } + } catch { + } + return null; +} +function decodeHeaderFooter(sec, kind, ctx) { + try { + const hf = sec?.["hp:headerFooter"]?.[0] ?? sec?.["hp:HEADERFOOTER"]?.[0] ?? sec?.headerFooter?.[0] ?? sec?.HEADERFOOTER?.[0]; + if (!hf) return void 0; + const part = hf?.["hp:" + kind]?.[0] ?? hf?.["hp:" + kind.toUpperCase()]?.[0] ?? hf?.[kind]?.[0] ?? hf?.[kind.toUpperCase()]?.[0]; + if (!part) return void 0; + const paras = getTag(part, "hp:p", "hp:P"); + if (paras.length === 0) return void 0; + return paras.map((p) => decodePara(p, ctx)); + } catch { + return void 0; + } +} +function decodePara(p, ctx) { + const pAttr = p?._attr ?? {}; + const paraPrIdRef = Number(pAttr.paraPrIDRef ?? -1); + let align; + const paraPrDef = ctx.paraPrs.get(paraPrIdRef); + if (paraPrDef?.align) align = paraPrDef.align; + const inlineParaPr = p?.["hp:PARAPR"]?.[0] ?? p?.["hp:paraPr"]?.[0] ?? p?.PARAPR?.[0]; + if (inlineParaPr) { + const alignNode = inlineParaPr?.["hp:ALIGN"]?.[0]?._attr ?? inlineParaPr?.["hp:align"]?.[0]?._attr ?? inlineParaPr?.ALIGN?.[0]?._attr; + if (alignNode?.Type) align = alignNode.Type; + if (alignNode?.horizontal) align = alignNode.horizontal; + } + const inlineAttr = inlineParaPr?._attr ?? {}; + const props = { align: safeAlign(align) }; + if (paraPrDef) { + if (paraPrDef.indentPt !== void 0) props.indentPt = paraPrDef.indentPt; + if (paraPrDef.indentRightPt !== void 0) + props.indentRightPt = paraPrDef.indentRightPt; + if (paraPrDef.firstLineIndentPt !== void 0) + props.firstLineIndentPt = paraPrDef.firstLineIndentPt; + if (paraPrDef.spaceBefore !== void 0) + props.spaceBefore = paraPrDef.spaceBefore; + if (paraPrDef.spaceAfter !== void 0) + props.spaceAfter = paraPrDef.spaceAfter; + if (paraPrDef.lineHeight !== void 0) + props.lineHeight = paraPrDef.lineHeight; + if (paraPrDef.lineHeightFixed !== void 0) + props.lineHeightFixed = paraPrDef.lineHeightFixed; + } + if (inlineAttr.listType) { + props.listOrd = inlineAttr.listType === "DIGIT" || inlineAttr.listType === "DECIMAL"; + props.listLv = Number(inlineAttr.listLevel ?? 0); + } + const runs = getTag(p, "hp:run", "hp:RUN"); + const kids = []; + const collectPics = (container) => { + const direct = getTag(container, "hp:pic", "hp:PIC"); + const ctrls = getTag(container, "hp:ctrl", "hp:CTRL"); + const nested = ctrls.flatMap((c) => getTag(c, "hp:pic", "hp:PIC")); + return [...direct, ...nested]; + }; + for (const pic of collectPics(p)) { + const img = decodePic(pic, ctx); + if (img) kids.push(img); + } + for (const run of runs) { + for (const pic of collectPics(run)) { + const img = decodePic(pic, ctx); + if (img) kids.push(img); + } + const pageNums = getTag(run, "hp:pageNum", "hp:PAGENUM"); + if (pageNums.length> 0) { + const pn = pageNums[0]?._attr ?? {}; + const fmt = pn.formatType === "ROMAN_LOWER" ? "roman" : pn.formatType === "ROMAN_UPPER" ? "romanCaps" : "decimal"; + const pageNumNode = { tag: "pagenum", format: fmt }; + const spanProps = resolveCharPr(run, ctx); + kids.push({ tag: "span", props: spanProps, kids: [pageNumNode] }); + continue; + } + const runPics = collectPics(run); + const textNodes = getTag(run, "hp:t", "hp:T", "hp:CHAR"); + const content = textNodes.map((t) => { + const val = typeof t === "string" ? t : t?._text ?? t?._ ?? t?.["#text"] ?? ""; + return val.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + }).join(""); + if (content === "" && (run?.["hp:secPr"]?.[0] || run?.["hp:SECPR"]?.[0]) && runPics.length === 0 && pageNums.length === 0) + continue; + if (content !== "" || runPics.length === 0 && pageNums.length === 0) { + const spanProps = resolveCharPr(run, ctx); + kids.push(buildSpan(content, spanProps)); + } + } + if (pAttr.pageBreak === "1") { + kids.unshift({ tag: "span", props: {}, kids: [buildPb()] }); + } + return buildPara(kids.filter(Boolean), props); +} +function resolveCharPr(run, ctx) { + const runAttr = run?._attr ?? {}; + const charPrIdRef = Number(runAttr.charPrIDRef ?? runAttr.CharPrIDRef ?? -1); + const def = ctx.charPrs.get(charPrIdRef); + if (def) { + return { + b: def.b, + i: def.i, + u: def.u, + s: def.s, + pt: def.pt, + color: def.color, + font: def.font, + bg: def.bg + }; + } + const inlinePr = run?.["hp:CHARPR"]?.[0] ?? run?.["hp:charPr"]?.[0] ?? run?.CHARPR?.[0] ?? run?.charPr?.[0]; + const ca = inlinePr?._attr ?? {}; + const bVal = ca.Bold ?? ca.bold ?? ca.B ?? ""; + const iVal = ca.Italic ?? ca.italic ?? ca.I ?? ""; + const uVal = ca.Underline ?? ca.underline ?? ""; + const sVal = ca.Strikeout ?? ca.strikeout ?? ""; + const fontName = ca.FontName ?? ca.fontName ?? ca.FaceNameHangul ?? ca.faceNameHangul ?? ""; + const heightVal = ca.Height ?? ca.height ?? ""; + return { + b: bVal === "1" || bVal === "true" || bVal === "True" || void 0, + i: iVal === "1" || iVal === "true" || iVal === "True" || void 0, + u: uVal && uVal !== "NONE" ? true : void 0, + s: sVal && sVal !== "NONE" && sVal !== "3D" ? true : void 0, + font: fontName ? safeFont(fontName) : void 0, + pt: heightVal ? Metric.hHeightToPt(Number(heightVal)) : void 0, + color: safeHex(ca.TextColor ?? ca.textColor), + bg: safeHex(ca.BgColor ?? ca.bgColor) + }; +} +function decodePic(pic, ctx) { + try { + const szAttr = pic?.["hp:sz"]?.[0]?._attr ?? pic?.sz?.[0]?._attr ?? {}; + const w = Metric.hwpToPt(Number(szAttr.width ?? 0)); + const h = Metric.hwpToPt(Number(szAttr.height ?? 0)); + const imgNode = pic?.["hp:img"]?.[0]?._attr ?? pic?.["hc:img"]?.[0]?._attr ?? pic?.img?.[0]?._attr ?? {}; + const binRef = imgNode.binaryItemIDRef ?? imgNode.BinaryItemIDRef; + if (!binRef) return null; + let imgData; + for (const [key, val] of ctx.files) { + if (key.includes(binRef) || key.toLowerCase().includes(binRef.toLowerCase())) { + imgData = val; + break; + } + } + if (!imgData) return null; + const ext = binRef.split(".").pop()?.toLowerCase() ?? "png"; + const mimeMap = { + png: "image/png", + jpg: "image/jpeg", + jpeg: "image/jpeg", + gif: "image/gif", + bmp: "image/bmp" + }; + const posAttr = pic?.["hp:pos"]?.[0]?._attr ?? pic?.pos?.[0]?._attr ?? {}; + const layout = extractHwpxLayout(posAttr, pic); + return buildImg( + TextKit.base64Encode(imgData), + mimeMap[ext] ?? "image/png", + w, + h, + void 0, + layout + ); + } catch { + return null; + } +} +function extractHwpxLayout(posAttr, pic) { + const treatAsChar = posAttr.treatAsChar === "1" || posAttr.treatAsChar === "true"; + if (treatAsChar) return { wrap: "inline" }; + const textWrap = pic?._attr?.textWrap ?? pic?.pic?.[0]?._attr?.textWrap ?? "TOP_AND_BOTTOM"; + const wrapMap = { + TOP_AND_BOTTOM: "topAndBottom", + // float, 위아래 텍스트 흐름 + SQUARE: "square", + BOTH_SIDES: "tight", + LEFT: "tight", + RIGHT: "tight", + LARGER_ONLY: "tight", + SMALLER_ONLY: "tight", + LARGEST_ONLY: "tight", + BEHIND_TEXT: "behind", + FRONT_TEXT: "front" + }; + const wrap = wrapMap[textWrap] ?? "square"; + const horzRelToMap = { + PARA: "para", + MARGIN: "margin", + PAGE: "page", + COLUMN: "column" + }; + const vertRelToMap = { + PARA: "para", + MARGIN: "margin", + PAGE: "page", + PAPER: "page", + LINE: "line" + }; + const horzRelTo = horzRelToMap[posAttr.horzRelTo ?? ""] ?? "para"; + const vertRelTo = vertRelToMap[posAttr.vertRelTo ?? ""] ?? "para"; + const horzAlignMap = { + LEFT: "left", + CENTER: "center", + RIGHT: "right" + }; + const vertAlignMap = { + TOP: "top", + CENTER: "center", + BOTTOM: "bottom" + }; + const horzAlign = horzAlignMap[posAttr.horzAlign ?? ""]; + const vertAlign = vertAlignMap[posAttr.vertAlign ?? ""]; + const horzOffset = Number(posAttr.horzOffset ?? 0); + const vertOffset = Number(posAttr.vertOffset ?? 0); + const xPt = horzOffset !== 0 ? Metric.hwpToPt(horzOffset) : void 0; + const yPt = vertOffset !== 0 ? Metric.hwpToPt(vertOffset) : void 0; + return { wrap, horzAlign, vertAlign, horzRelTo, vertRelTo, xPt, yPt }; +} +function decodeGrid(tbl, ctx) { + const tblAttr = tbl?._attr ?? {}; + const borderFillId = Number(tblAttr.borderFillIDRef ?? 0); + const borderFill = ctx.borderFills.get(borderFillId); + const headerRow = tblAttr.repeatHeader === "1"; + const gridProps = { headerRow: headerRow || void 0 }; + if (borderFill?.stroke) gridProps.defaultStroke = borderFill.stroke; + const rowArr = getTag(tbl, "hp:tr", "hp:ROW"); + for (const row of rowArr) { + const cells = getTag(row, "hp:tc", "hp:CELL"); + const rowWidths = []; + let allSingle = true; + for (const cell of cells) { + const cellSpanAttr = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cs = Number(cellSpanAttr.colSpan ?? cell?._attr?.ColSpan ?? 1); + if (cs> 1) { + allSingle = false; + break; + } + const szAttr = cell?.["hp:cellSz"]?.[0]?._attr ?? {}; + const w = Number(szAttr.width ?? 0); + rowWidths.push(Metric.hwpToPt(w)); + } + if (allSingle && rowWidths.length> 0 && rowWidths.some((w) => w> 0)) { + gridProps.colWidths = rowWidths; + break; + } + } + if (!gridProps.colWidths) { + let detectedCols = 0; + for (const row of rowArr) { + let ci = 0; + for (const cell of getTag(row, "hp:tc", "hp:CELL")) { + const csEl = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + ci += Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1); + } + if (ci> detectedCols) detectedCols = ci; + } + if (detectedCols> 0) { + const sums = new Float64Array(detectedCols); + const counts = new Int32Array(detectedCols); + for (const row of rowArr) { + let ci = 0; + for (const cell of getTag(row, "hp:tc", "hp:CELL")) { + const csEl = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cs = Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1); + const szAttr = cell?.["hp:cellSz"]?.[0]?._attr ?? {}; + const w = Number(szAttr.width ?? 0); + if (w> 0 && cs> 0) { + const perCol = w / cs; + for (let k = 0; k < cs && ci + k < detectedCols; k++) { + sums[ci + k] += perCol; + counts[ci + k]++; + } + } + ci += cs; + } + } + const estimated = Array.from(sums).map( + (s, i) => counts[i]> 0 ? Metric.hwpToPt(s / counts[i]) : 0 + ); + if (estimated.some((w) => w> 0)) gridProps.colWidths = estimated; + } + } + const rowNodes = rowArr.map((row) => { + const cellArr = getTag(row, "hp:tc", "hp:CELL"); + const cellNodes = cellArr.map((cell) => { + const ca = cell?._attr ?? {}; + const cellBfId = Number(ca.borderFillIDRef ?? 0); + const cellBf = ctx.borderFills.get(cellBfId); + const cellProps = { + bg: cellBf?.bgColor ?? safeHex(ca.BgColor) + }; + if (cellBf) { + cellProps.top = cellBf.top ?? cellBf.stroke; + cellProps.bot = cellBf.bottom ?? cellBf.stroke; + cellProps.left = cellBf.left ?? cellBf.stroke; + cellProps.right = cellBf.right ?? cellBf.stroke; + } + const subList = cell?.["hp:subList"]?.[0] ?? cell?.subList?.[0]; + const subAttr = subList?._attr ?? {}; + if (subAttr.vertAlign) { + const vaMap = { + TOP: "top", + CENTER: "mid", + BOTTOM: "bot" + }; + cellProps.va = vaMap[subAttr.vertAlign]; + } + const HWPX_DEFAULT_MARGIN_LR = 360; + const HWPX_DEFAULT_MARGIN_TB = 141; + const mL = Number(subAttr.marginLeft ?? HWPX_DEFAULT_MARGIN_LR); + const mR = Number(subAttr.marginRight ?? HWPX_DEFAULT_MARGIN_LR); + const mT = Number(subAttr.marginTop ?? HWPX_DEFAULT_MARGIN_TB); + const mB = Number(subAttr.marginBottom ?? HWPX_DEFAULT_MARGIN_TB); + if (mL !== HWPX_DEFAULT_MARGIN_LR) cellProps.padL = Metric.hwpToPt(mL); + if (mR !== HWPX_DEFAULT_MARGIN_LR) cellProps.padR = Metric.hwpToPt(mR); + if (mT !== HWPX_DEFAULT_MARGIN_TB) cellProps.padT = Metric.hwpToPt(mT); + if (mB !== HWPX_DEFAULT_MARGIN_TB) cellProps.padB = Metric.hwpToPt(mB); + const cellSpan = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cs = Number(cellSpan.colSpan ?? ca.ColSpan ?? 1); + const rs = Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1); + const cellKids = []; + const source = subList ?? cell; + const sourcePSource = getTag(source, "hp:p", "hp:P"); + for (const sp of sourcePSource) { + try { + const runs = getTag(sp, "hp:run", "hp:RUN"); + let hasNestedTable = false; + for (const run of runs) { + const nestedTbls = getTag(run, "hp:tbl", "hp:TABLE"); + for (const nestedTbl of nestedTbls) { + try { + cellKids.push(decodeGrid(nestedTbl, ctx)); + } catch { + } + hasNestedTable = true; + } + } + if (!hasNestedTable) { + cellKids.push(decodePara(sp, ctx)); + } + } catch { + } + } + return buildCell( + cellKids.length> 0 ? cellKids : [buildPara([buildSpan("")])], + { cs, rs, props: cellProps } + ); + }); + let rowHeightPt; + for (const cell of cellArr) { + const ca = cell?._attr ?? {}; + const cellSpan = cell?.["hp:cellSpan"]?.[0]?._attr ?? {}; + const cellRs = Math.max(1, Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1)); + const hSz = cell?.["hp:cellSz"]?.[0]?._attr ?? {}; + const hVal = Number(hSz.height ?? 0); + if (hVal> 0) { + rowHeightPt = Metric.hwpToPt(hVal) / cellRs; + if (cellRs === 1) break; + } + } + return buildRow(cellNodes, rowHeightPt); + }); + return buildGrid(rowNodes, gridProps); +} +function decodeGridSimple(tbl, ctx) { + const rowArr = getTag(tbl, "hp:tr", "hp:ROW"); + const rowNodes = rowArr.map((row) => { + const cellArr = getTag(row, "hp:tc", "hp:CELL"); + return buildRow( + cellArr.map( + (cell) => buildCell([buildPara([buildSpan(cellText(cell))])]) + ) + ); + }); + return buildGrid(rowNodes); +} +function decodeGridFlat(tbl) { + return buildGrid([ + buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])]) + ]); +} +function decodeGridText(tbl) { + return buildPara([buildSpan(tableText(tbl))]); +} +function cellText(cell) { + const subList = cell?.["hp:subList"]?.[0] ?? cell?.subList?.[0]; + const source = subList ?? cell; + return getTag(source, "hp:p", "hp:P").map( + (p) => getTag(p, "hp:run", "hp:RUN").map( + (r) => getTag(r, "hp:t", "hp:T").map((t) => { + const val = typeof t === "string" ? t : t?._text ?? t?._ ?? t?.["#text"] ?? ""; + return val.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + }).join("") + ).join("") + ).join(" "); +} +function tableText(tbl) { + return getTag(tbl, "hp:tr", "hp:ROW").map( + (row) => getTag(row, "hp:tc", "hp:CELL").map((c) => cellText(c)).join(" ") + ).join("\n"); +} +function toArr(v) { + return v == null ? [] : Array.isArray(v) ? v : [v]; +} +registry.registerDecoder(new HwpxDecoder()); + +// src/toolkit/BinaryKit.ts +var BinaryKit = { + readU16LE(buf, offset) { + return buf[offset] | buf[offset + 1] << 8; + }, + readU32LE(buf, offset) { + return ((buf[offset] | buf[offset + 1] << 8 | buf[offset + 2] << 16)>>> 0) + buf[offset + 3] * 16777216; + }, + isOle2(data) { + return data.length>= 8 && data[0] === 208 && data[1] === 207 && data[2] === 17 && data[3] === 224 && data[4] === 161 && data[5] === 177 && data[6] === 26 && data[7] === 225; + }, + parseCfb(data) { + const streams = /* @__PURE__ */ new Map(); + if (!this.isOle2(data)) { + throw new Error("Not a valid OLE2 file"); + } + const view = new DataView(data.buffer, data.byteOffset, data.byteLength); + const sectorSize = 1 << view.getUint16(30, true); + const miniSectorSz = 1 << view.getUint16(32, true); + const dirFirstSec = view.getUint32(48, true); + const miniStreamCutoff = view.getUint32(56, true); + const miniFatFirst = view.getUint32(60, true); + const miniFatCnt = view.getUint32(64, true); + const difatFirst = view.getUint32(68, true); + const ENDOFCHAIN = 4294967294; + const FREESECT = 4294967295; + const sectorAt = (sec) => data.subarray(512 + sec * sectorSize, 512 + (sec + 1) * sectorSize); + const fatSecNums = []; + for (let i = 0; i < 109; i++) { + const s = view.getUint32(76 + i * 4, true); + if (s === FREESECT || s === ENDOFCHAIN) break; + fatSecNums.push(s); + } + if (difatFirst !== ENDOFCHAIN && difatFirst !== FREESECT) { + let difSec = difatFirst; + while (difSec !== ENDOFCHAIN && difSec !== FREESECT) { + const sec = sectorAt(difSec); + const sv = new DataView(sec.buffer, sec.byteOffset, sec.byteLength); + for (let i = 0; i < sectorSize / 4 - 1; i++) { + const s = sv.getUint32(i * 4, true); + if (s === FREESECT || s === ENDOFCHAIN) break; + fatSecNums.push(s); + } + difSec = sv.getUint32(sectorSize - 4, true); + } + } + const fat = []; + for (const sec of fatSecNums) { + const s = sectorAt(sec); + const sv = new DataView(s.buffer, s.byteOffset, s.byteLength); + for (let i = 0; i < sectorSize / 4; i++) { + fat.push(sv.getUint32(i * 4, true)); + } + } + const readChain = (startSec) => { + const chunks = []; + let sec = startSec; + while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < fat.length) { + chunks.push(sectorAt(sec)); + sec = fat[sec]; + } + return concatUint8(chunks); + }; + const dirData = readChain(dirFirstSec); + const dirView = new DataView(dirData.buffer, dirData.byteOffset, dirData.byteLength); + const dirCount = dirData.length / 128; + const dirEntries = []; + for (let i = 0; i < dirCount; i++) { + const base = i * 128; + const nameLen = dirView.getUint16(base + 64, true); + const nameBytes = dirData.subarray(base, base + Math.max(0, nameLen - 2)); + const name = new TextDecoder("utf-16le").decode(nameBytes); + const type = dirData[base + 66]; + const childId = dirView.getInt32(base + 76, true); + const sibLeft = dirView.getInt32(base + 68, true); + const sibRight = dirView.getInt32(base + 72, true); + const startSec = dirView.getUint32(base + 116, true); + const size = dirView.getUint32(base + 120, true); + dirEntries.push({ name, type, startSec, size, childId, siblingLeftId: sibLeft, siblingRightId: sibRight }); + } + const rootEntry = dirEntries[0]; + let miniStreamData = null; + let miniFat = []; + if (rootEntry && rootEntry.startSec !== ENDOFCHAIN && rootEntry.startSec !== FREESECT) { + miniStreamData = readChain(rootEntry.startSec); + } + if (miniFatCnt> 0 && miniFatFirst !== ENDOFCHAIN && miniFatFirst !== FREESECT) { + const mfData = readChain(miniFatFirst); + const mfv = new DataView(mfData.buffer, mfData.byteOffset, mfData.byteLength); + for (let i = 0; i < mfData.length / 4; i++) { + miniFat.push(mfv.getUint32(i * 4, true)); + } + } + const readMiniChain = (startSec, size) => { + if (!miniStreamData) return new Uint8Array(0); + const chunks = []; + let sec = startSec; + let remaining = size; + while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < miniFat.length && remaining> 0) { + const off = sec * miniSectorSz; + const chunk = miniStreamData.subarray(off, off + Math.min(miniSectorSz, remaining)); + chunks.push(chunk); + remaining -= chunk.length; + sec = miniFat[sec]; + } + return concatUint8(chunks).subarray(0, size); + }; + const visit = (id, path) => { + if (id < 0 || id>= dirEntries.length) return; + const entry = dirEntries[id]; + const fullPath = path ? `${path}/${entry.name}` : entry.name; + if (entry.type === 2) { + let streamData; + if (entry.size < miniStreamCutoff && miniStreamData) { + streamData = readMiniChain(entry.startSec, entry.size); + } else { + streamData = readChain(entry.startSec).subarray(0, entry.size); + } + streams.set(fullPath, streamData); + streams.set(entry.name, streamData); + } + if (entry.childId>= 0) visit(entry.childId, fullPath); + if (entry.siblingLeftId>= 0) visit(entry.siblingLeftId, path); + if (entry.siblingRightId>= 0) visit(entry.siblingRightId, path); + }; + if (dirEntries.length> 0 && dirEntries[0].childId>= 0) { + visit(dirEntries[0].childId, ""); + } + return streams; + } +}; +function concatUint8(arrays) { + const total = arrays.reduce((s, a) => s + a.length, 0); + const out = new Uint8Array(total); + let off = 0; + for (const a of arrays) { + out.set(a, off); + off += a.length; + } + return out; +} + +// src/decoders/hwp/HwpScanner.ts +import pako2 from "pako"; +var HWPTAG_BEGIN = 16; +var TAG_FACE_NAME = HWPTAG_BEGIN + 3; +var TAG_BORDER_FILL = HWPTAG_BEGIN + 4; +var TAG_CHAR_SHAPE = HWPTAG_BEGIN + 5; +var TAG_PARA_SHAPE = HWPTAG_BEGIN + 9; +var TAG_PARA_HEADER = HWPTAG_BEGIN + 50; +var TAG_PARA_TEXT = HWPTAG_BEGIN + 51; +var TAG_PARA_CHAR_SHAPE = HWPTAG_BEGIN + 52; +var TAG_CTRL_HEADER = HWPTAG_BEGIN + 55; +var TAG_PAGE_DEF = HWPTAG_BEGIN + 57; +var TAG_LIST_HEADER = HWPTAG_BEGIN + 56; +var TAG_TABLE_A = HWPTAG_BEGIN + 61; +var TAG_CELL_A = HWPTAG_BEGIN + 62; +var TAG_TABLE_B = HWPTAG_BEGIN + 64; +var TAG_CELL_B = HWPTAG_BEGIN + 65; +function isTableTag(t) { + return t === TAG_TABLE_A || t === TAG_TABLE_B; +} +function isCellTag(t) { + return t === TAG_CELL_A || t === TAG_CELL_B || t === TAG_LIST_HEADER; +} +var CTRL_TABLE = 1952607264; +var CTRL_IMAGE = 1768777504; +var CTRL_OBJ = 1868720672; +var CTRL_FIG = 1718183712; +var CTRL_GSO = 1735618336; +function parseRecords(data) { + const out = []; + let off = 0; + while (off + 4 <= data.length) { + const hdr = BinaryKit.readU32LE(data, off); + const tag = hdr & 1023; + const level = hdr>> 10 & 1023; + let size = hdr>> 20 & 4095; + off += 4; + if (size === 4095) { + if (off + 4> data.length) break; + size = BinaryKit.readU32LE(data, off); + off += 4; + } + if (off + size> data.length) break; + out.push({ tag, level, data: data.subarray(off, off + size) }); + off += size; + } + return out; +} +function tryInflate(data) { + try { + return pako2.inflate(data); + } catch { + try { + return pako2.inflateRaw(data); + } catch { + return data; + } + } +} +function parseFileHeader(buf) { + if (buf.length < 40) return { compressed: true, encrypted: false }; + const props = BinaryKit.readU32LE(buf, 36); + return { compressed: (props & 1) !== 0, encrypted: (props & 2) !== 0 }; +} +function parseDocInfo(data, compressed) { + const raw = compressed ? tryInflate(data) : data; + const recs = parseRecords(raw); + const info = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] }; + for (const r of recs) { + try { + if (r.tag === TAG_FACE_NAME) info.faceNames.push(parseFaceName(r.data)); + if (r.tag === TAG_CHAR_SHAPE) info.charShapes.push(parseCharShape(r.data)); + if (r.tag === TAG_PARA_SHAPE) info.paraShapes.push(parseParaShape(r.data)); + if (r.tag === TAG_BORDER_FILL) info.borderFills.push(parseBorderFill(r.data)); + } catch { + } + } + return info; +} +function parseFaceName(d) { + if (d.length < 3) return ""; + const len = BinaryKit.readU16LE(d, 1); + if (d.length < 3 + len * 2) return ""; + return new TextDecoder("utf-16le").decode(d.subarray(3, 3 + len * 2)); +} +function parseCharShape(d) { + const faceIds = []; + for (let i = 0; i < 7; i++) faceIds.push(d.length>= (i + 1) * 2 ? BinaryKit.readU16LE(d, i * 2) : 0); + const height = d.length>= 46 ? BinaryKit.readU32LE(d, 42) : 1e3; + const attr = d.length>= 50 ? BinaryKit.readU32LE(d, 46) : 0; + const ulType = attr>> 2 & 7; + const skType = attr>> 18 & 7; + const suType = attr>> 16 & 3; + return { + faceIds, + height: height> 0 && height < 1e5 ? height : 1e3, + italic: (attr & 1) !== 0, + bold: (attr>> 1 & 1) !== 0, + underline: ulType !== 0, + strikeout: skType !== 0, + superscript: suType === 1, + subscript: suType === 2, + textColor: d.length>= 56 ? colorRef(d, 52) : "000000" + }; +} +var ALIGN_TBL = { 0: "justify", 1: "left", 2: "right", 3: "center", 4: "justify" }; +function parseParaShape(d) { + if (d.length < 4) return { align: "left", spaceBefore: 0, spaceAfter: 0, lineSpacing: 160, leftMargin: 0, indent: 0 }; + const attr = BinaryKit.readU32LE(d, 0); + return { + align: ALIGN_TBL[attr>> 2 & 7] ?? "left", + leftMargin: d.length>= 8 ? i32(d, 4) : 0, + // offset 4: leftMargin (들여쓰기) + indent: d.length>= 16 ? i32(d, 12) : 0, + // offset 12: first-line indent + spaceBefore: d.length>= 20 ? i32(d, 16) : 0, + spaceAfter: d.length>= 24 ? i32(d, 20) : 0, + lineSpacing: d.length>= 28 ? i32(d, 24) : 160 + }; +} +var BORDER_W_PT = [0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.7, 1.98, 2.84, 4.25, 5.67, 8.5, 11.34, 14.17]; +var BORDER_KIND = { 0: "solid", 1: "dash", 2: "dash", 3: "dot", 4: "dash", 5: "dash", 6: "dash", 7: "double", 8: "double", 9: "double", 10: "none" }; +function parseBorderFill(d) { + const borders = []; + const BASE_TYPE = 2; + const BASE_WIDTH = 6; + const BASE_COLOR = 10; + for (let i = 0; i < 4; i++) { + const type = BASE_TYPE + i < d.length ? d[BASE_TYPE + i] : 0; + const widthPt = BASE_WIDTH + i < d.length ? BORDER_W_PT[d[BASE_WIDTH + i]] ?? 0.5 : 0.5; + const color = BASE_COLOR + i * 4 + 4 <= d.length ? colorRef(d, BASE_COLOR + i * 4) : "000000"; + borders.push({ type, widthPt, color }); + } + let bgColor; + const fOff = 32; + if (d.length>= fOff + 8) { + const ft = BinaryKit.readU32LE(d, fOff); + if (ft & 1) bgColor = colorRef(d, fOff + 4); + } + return { borders, bgColor }; +} +function parseBody(raw, compressed, di, shield, gsoCtx) { + const recs = parseRecords(compressed ? tryInflate(raw) : raw); + const content = []; + let pageDims; + for (const r of recs) { + if (r.tag === TAG_PAGE_DEF) { + pageDims = shield.guard(() => parsePageDef(r.data), A4, "hwp:pageDef"); + break; + } + } + let i = 0; + while (i < recs.length) { + if (recs[i].tag === TAG_PAGE_DEF) { + i++; + } else if (recs[i].tag === TAG_PARA_HEADER) { + const r = shield.guard( + () => parseParagraphGroup(recs, i, di, shield, gsoCtx), + { nodes: [], next: i + 1 }, + `hwp:para@${i}` + ); + content.push(...r.nodes); + i = r.next; + } else { + i++; + } + } + return { content, pageDims }; +} +function parseParagraphGroup(recs, start, di, shield, gsoCtx) { + const hdr = recs[start]; + const lv = hdr.level; + const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0; + const ps = di.paraShapes[psId]; + let text = null; + let csPairs = []; + const grids = []; + const ctrlHeaders = []; + let i = start + 1; + while (i < recs.length && recs[i].level> lv) { + const r = recs[i]; + if (r.tag === TAG_PARA_TEXT && r.level === lv + 1) { + text = decodeParaText(r.data); + i++; + } else if (r.tag === TAG_PARA_CHAR_SHAPE && r.level === lv + 1) { + csPairs = parseCharShapePairs(r.data); + i++; + } else if (r.tag === TAG_CTRL_HEADER && r.level === lv + 1) { + if (r.data.length>= 4) { + const ctrlId = BinaryKit.readU32LE(r.data, 0); + const MAX_HWP = 1e6; + const rawW = r.data.length>= 24 ? BinaryKit.readU32LE(r.data, 16) : 0; + const rawH = r.data.length>= 28 ? BinaryKit.readU32LE(r.data, 20) : 0; + const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0; + const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0; + const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : r.data.length>= 6 ? BinaryKit.readU16LE(r.data, 4) : 0; + ctrlHeaders.push({ ctrlId, imgId, wPt, hPt }); + if (ctrlId === CTRL_TABLE) { + const tr = shield.guard( + () => parseTableCtrl(recs, i, di, shield, gsoCtx), + { grid: null, next: skipKids(recs, i) }, + `hwp:tbl@${i}` + ); + if (tr.grid) grids.push(tr.grid); + i = tr.next; + } else { + i = skipKids(recs, i); + } + } else { + i = skipKids(recs, i); + } + } else { + i++; + } + } + const nodes = []; + if (text && (text.chars.length> 0 || text.controls.length> 0)) { + const paraContent = []; + if (text.chars.length> 0) { + const spans = resolveCharShapes(text.chars, csPairs, di); + paraContent.push(...spans); + } + if (text.controls.length> 0) { + for (let ci = 0; ci < text.controls.length; ci++) { + const ch = ctrlHeaders[ci]; + if (!ch) continue; + const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO; + if (!isImg) continue; + const dimStr = ch.wPt> 0 && ch.hPt> 0 ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}` : ""; + paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`)); + } + } + if (paraContent.length> 0) { + nodes.push(buildPara(paraContent, buildParaProps(ps))); + } + } + nodes.push(...grids); + return { nodes, next: i }; +} +function skipKids(recs, idx) { + const lv = recs[idx].level; + let i = idx + 1; + while (i < recs.length && recs[i].level> lv) i++; + return i; +} +var EXT_CTRL = /* @__PURE__ */ new Set([2, 3, 11, 12, 14, 15]); +var INL_CTRL = /* @__PURE__ */ new Set([4, 5, 6, 7, 8]); +function decodeParaText(d) { + const chars = []; + const controls = []; + let i = 0, pos = 0; + while (i + 1 < d.length) { + const c = d[i] | d[i + 1] << 8; + if (c === 0) { + i += 2; + pos++; + continue; + } + if (c === 13) { + break; + } + if (c === 10) { + chars.push({ pos, ch: "\n" }); + i += 2; + pos++; + continue; + } + if (EXT_CTRL.has(c)) { + let objId = 0; + if (i + 16 <= d.length) { + objId = BinaryKit.readU16LE(d, i + 8); + } + controls.push({ pos, ctrlId: 0, objId, matched: false }); + i += 16; + pos += 8; + continue; + } + if (INL_CTRL.has(c)) { + i += 16; + pos += 8; + continue; + } + if (c === 9) { + chars.push({ pos, ch: " " }); + i += 16; + pos += 8; + continue; + } + if (c>= 1 && c <= 31) { + i += 2; + pos++; + continue; + } + chars.push({ pos, ch: String.fromCharCode(c) }); + i += 2; + pos++; + } + return { chars, controls }; +} +function parseCharShapePairs(d) { + const out = []; + for (let i = 0; i + 7 < d.length; i += 8) + out.push([BinaryKit.readU32LE(d, i), BinaryKit.readU32LE(d, i + 4)]); + return out; +} +function resolveCharShapes(chars, pairs, di) { + if (chars.length === 0) return [buildSpan("")]; + const defaultId = pairs.length> 0 ? pairs[0][1] : 0; + function idFor(pos) { + let id = defaultId; + for (const [p, sid] of pairs) { + if (p <= pos) id = sid; + else break; + } + return id; + } + const spans = []; + let curId = idFor(chars[0].pos); + let buf = chars[0].ch; + for (let k = 1; k < chars.length; k++) { + const sid = idFor(chars[k].pos); + if (sid !== curId) { + spans.push(styledSpan(buf, curId, di)); + buf = ""; + curId = sid; + } + buf += chars[k].ch; + } + if (buf) spans.push(styledSpan(buf, curId, di)); + return spans; +} +function styledSpan(text, shapeId, di) { + const cs = di.charShapes[shapeId]; + if (!cs) return buildSpan(text); + const props = {}; + const fid = cs.faceIds[0] ?? 0; + if (fid < di.faceNames.length && di.faceNames[fid]) props.font = safeFont(di.faceNames[fid]); + if (cs.height> 0) props.pt = Metric.hwpToPt(cs.height); + if (cs.bold) props.b = true; + if (cs.italic) props.i = true; + if (cs.underline) props.u = true; + if (cs.strikeout) props.s = true; + if (cs.superscript) props.sup = true; + if (cs.subscript) props.sub = true; + const hex = safeHex(cs.textColor); + if (hex && hex !== "000000") props.color = hex; + return buildSpan(text, props); +} +function parseTableCtrl(recs, ctrlIdx, di, shield, gsoCtx) { + const ctrlLv = recs[ctrlIdx].level; + let i = ctrlIdx + 1; + let tblData = null; + const cells = []; + const tblLevel = ctrlLv + 1; + while (i < recs.length && recs[i].level> ctrlLv) { + const r = recs[i]; + if (isTableTag(r.tag) && r.level === tblLevel) { + tblData = r.data; + i++; + } else if (r.tag === TAG_LIST_HEADER && r.level === tblLevel) { + const cellData = r.data; + const paraCount = cellData.length>= 2 ? BinaryKit.readU16LE(cellData, 0) : 0; + i++; + const cStart = i; + let consumed = 0; + while (i < recs.length && consumed < paraCount) { + if (recs[i].tag === TAG_PARA_HEADER && recs[i].level === tblLevel) { + consumed++; + i++; + while (i < recs.length && recs[i].level> tblLevel) i++; + } else if (recs[i].level> tblLevel) { + i++; + } else { + break; + } + } + cells.push({ data: cellData, tag: TAG_LIST_HEADER, cStart, cEnd: i }); + } else if (isCellTag(r.tag) && r.level === tblLevel) { + const cellData = r.data; + const cellTag = r.tag; + i++; + const cStart = i; + while (i < recs.length && recs[i].level> tblLevel) i++; + cells.push({ data: cellData, tag: cellTag, cStart, cEnd: i }); + } else { + i++; + } + } + if (!tblData || cells.length === 0) return { grid: null, next: i }; + const rowCnt = tblData.length>= 6 ? BinaryKit.readU16LE(tblData, 4) : 1; + const colCnt = tblData.length>= 8 ? BinaryKit.readU16LE(tblData, 6) : 1; + const parsed = []; + for (let ci = 0; ci < cells.length; ci++) { + const c = cells[ci]; + const seqIdx = ci; + const pc = shield.guard( + () => parseCellRec(c.data, c.tag, recs, c.cStart, c.cEnd, di, shield, seqIdx, colCnt, gsoCtx), + { row: Math.floor(ci / (colCnt || 1)), col: ci % (colCnt || 1), cs: 1, rs: 1, widthHwp: 0, heightHwp: void 0, props: {}, cellChildren: [buildPara([buildSpan("")])] }, + `hwp:cell@${c.cStart}` + ); + parsed.push(pc); + } + const maxRow = parsed.reduce((m, c) => Math.max(m, c.row + c.rs), 0); + const actualRowCnt = Math.max(rowCnt, maxRow); + const posValid = parsed.every((c) => c.row>= 0 && c.col>= 0 && c.col < colCnt); + if (!posValid) { + let idx = 0; + for (const c of parsed) { + c.row = Math.floor(idx / colCnt); + c.col = idx % colCnt; + idx++; + } + } + const colWidthsPt = new Array(colCnt).fill(0); + for (const c of parsed) { + if (c.cs === 1 && c.widthHwp> 0) { + const wPt = Metric.hwpToPt(c.widthHwp); + if (wPt> colWidthsPt[c.col]) colWidthsPt[c.col] = wPt; + } + } + const zeroColumns = colWidthsPt.filter((w) => w === 0).length; + if (zeroColumns> 0) { + const spanCells = parsed.filter((c) => c.cs> 1 && c.widthHwp> 0).sort((a, b) => a.cs - b.cs); + for (const c of spanCells) { + if (c.cs> 1 && c.widthHwp> 0) { + let known = 0; + let unknownCols = 0; + for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) { + if (colWidthsPt[ci]> 0) known += colWidthsPt[ci]; + else unknownCols++; + } + if (unknownCols> 0) { + const remaining = Metric.hwpToPt(c.widthHwp) - known; + const each = remaining> 0 ? remaining / unknownCols : 0; + for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) { + if (colWidthsPt[ci] === 0 && each> 0) colWidthsPt[ci] = each; + } + } + } + } + } + for (let i2 = 0; i2 < colWidthsPt.length; i2++) { + if (colWidthsPt[i2]> 0 && colWidthsPt[i2] < 1) colWidthsPt[i2] = 1; + } + const rows = []; + for (let r = 0; r < actualRowCnt; r++) { + const rc = parsed.filter((c) => c.row === r).sort((a, b) => a.col - b.col); + if (rc.length === 0) continue; + let rowHeightPt = void 0; + for (const c of rc) { + if (c.heightHwp && c.heightHwp> 0 && c.rs === 1) { + const hPt = Metric.hwpToPt(c.heightHwp); + if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt; + } + } + if (rowHeightPt == null) { + for (const c of rc) { + if (c.heightHwp && c.heightHwp> 0) { + const hPt = Metric.hwpToPt(c.heightHwp) / c.rs; + if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt; + } + } + } + rows.push(buildRow(rc.map((c) => { + return buildCell(c.cellChildren, { cs: c.cs, rs: c.rs, props: c.props }); + }), rowHeightPt)); + } + if (rows.length === 0) return { grid: null, next: i }; + let defStroke; + const bfOff = 18 + rowCnt * 2; + if (tblData.length>= bfOff + 2) { + const bfId = BinaryKit.readU16LE(tblData, bfOff); + defStroke = strokeFromBF(bfId, di); + } + const gp = {}; + if (defStroke) gp.defaultStroke = defStroke; + const hasWidths = colWidthsPt.some((w) => w> 0); + if (hasWidths) gp.colWidths = colWidthsPt; + return { grid: buildGrid(rows, gp), next: i }; +} +function parseCellRec(d, tag, recs, cStart, cEnd, di, shield, seqIdx, colCnt, gsoCtx) { + let col, row, cs = 1, rs = 1; + let widthHwp = 0; + let heightHwp = 0; + const props = {}; + const attr = d.length>= 6 ? BinaryKit.readU32LE(d, 2) : 0; + const va = attr>> 6 & 3; + if (va === 1) props.va = "mid"; + else if (va === 2) props.va = "bot"; + const HWP_PAD_LR_DEFAULT = 360; + const HWP_PAD_TB_DEFAULT = 141; + if (tag === TAG_LIST_HEADER && d.length>= 22) { + col = BinaryKit.readU16LE(d, 8); + row = BinaryKit.readU16LE(d, 10); + cs = Math.max(1, BinaryKit.readU16LE(d, 12)); + rs = Math.max(1, BinaryKit.readU16LE(d, 14)); + widthHwp = BinaryKit.readU32LE(d, 16); + heightHwp = d.length>= 24 ? BinaryKit.readU32LE(d, 20) : 0; + if (d.length>= 32) { + const pL = BinaryKit.readU16LE(d, 24); + const pR = BinaryKit.readU16LE(d, 26); + const pT = BinaryKit.readU16LE(d, 28); + const pB = BinaryKit.readU16LE(d, 30); + if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL); + if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR); + if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT); + if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB); + } + const bfId = d.length>= 34 ? BinaryKit.readU16LE(d, 32) : 0; + if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props); + } else if (tag !== TAG_LIST_HEADER) { + col = d.length>= 8 ? BinaryKit.readU16LE(d, 6) : seqIdx % (colCnt || 1); + row = d.length>= 10 ? BinaryKit.readU16LE(d, 8) : Math.floor(seqIdx / (colCnt || 1)); + cs = d.length>= 12 ? Math.max(1, BinaryKit.readU16LE(d, 10)) : 1; + rs = d.length>= 14 ? Math.max(1, BinaryKit.readU16LE(d, 12)) : 1; + widthHwp = d.length>= 18 ? BinaryKit.readU32LE(d, 14) : 0; + heightHwp = d.length>= 22 ? BinaryKit.readU32LE(d, 18) : 0; + if (d.length>= 30) { + const pL = BinaryKit.readU16LE(d, 22); + const pR = BinaryKit.readU16LE(d, 24); + const pT = BinaryKit.readU16LE(d, 26); + const pB = BinaryKit.readU16LE(d, 28); + if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL); + if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR); + if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT); + if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB); + } + const bfId = d.length>= 32 ? BinaryKit.readU16LE(d, 30) : 0; + if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props); + } else { + row = Math.floor(seqIdx / (colCnt || 1)); + col = seqIdx % (colCnt || 1); + } + const cellChildren = []; + const MAX_HWP = 1e6; + let k = cStart; + while (k < cEnd) { + if (recs[k].tag === TAG_PARA_HEADER) { + const r = shield.guard( + () => { + const hdr = recs[k]; + const lv = hdr.level; + const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0; + const ps = di.paraShapes[psId]; + let txt = null; + let csp = []; + const ctrlHdrs = []; + const innerGrids = []; + let j = k + 1; + while (j < cEnd && recs[j].level> lv) { + if (recs[j].tag === TAG_PARA_TEXT) { + txt = decodeParaText(recs[j].data); + j++; + } else if (recs[j].tag === TAG_PARA_CHAR_SHAPE) { + csp = parseCharShapePairs(recs[j].data); + j++; + } else if (recs[j].tag === TAG_CTRL_HEADER && recs[j].level === lv + 1) { + if (recs[j].data.length>= 4) { + const ctrlId = BinaryKit.readU32LE(recs[j].data, 0); + if (ctrlId === CTRL_TABLE) { + const nestedTr = shield.guard( + () => parseTableCtrl(recs, j, di, shield, gsoCtx), + { grid: null, next: skipKids(recs, j) }, + `hwp:innerNestedTbl@${j}` + ); + if (nestedTr.grid) innerGrids.push(nestedTr.grid); + j = nestedTr.next; + } else { + const rawW = recs[j].data.length>= 24 ? BinaryKit.readU32LE(recs[j].data, 16) : 0; + const rawH = recs[j].data.length>= 28 ? BinaryKit.readU32LE(recs[j].data, 20) : 0; + const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0; + const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0; + const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : recs[j].data.length>= 6 ? BinaryKit.readU16LE(recs[j].data, 4) : 0; + ctrlHdrs.push({ ctrlId, imgId, wPt, hPt }); + j = skipKids(recs, j); + } + } else { + j = skipKids(recs, j); + } + } else j++; + } + const paraContent = []; + if (txt && txt.chars.length> 0) paraContent.push(...resolveCharShapes(txt.chars, csp, di)); + if (txt && txt.controls.length> 0) { + for (let ci = 0; ci < txt.controls.length; ci++) { + const ch = ctrlHdrs[ci]; + if (!ch) continue; + const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO; + if (!isImg) continue; + const dimStr = ch.wPt> 0 && ch.hPt> 0 ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}` : ""; + paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`)); + } + } + const kids = paraContent.length> 0 ? paraContent : [buildSpan("")]; + const items = [buildPara(kids, buildParaProps(ps)), ...innerGrids]; + return { items, next: j }; + }, + { items: [buildPara([buildSpan("")])], next: k + 1 }, + `hwp:cellP@${k}` + ); + cellChildren.push(...r.items); + k = r.next; + } else if (recs[k].tag === TAG_CTRL_HEADER && recs[k].data.length>= 4) { + const cellCtrlId = BinaryKit.readU32LE(recs[k].data, 0); + if (cellCtrlId === CTRL_GSO) { + const gsoId = gsoCtx.count++; + const rawW = recs[k].data.length>= 24 ? BinaryKit.readU32LE(recs[k].data, 16) : 0; + const rawH = recs[k].data.length>= 28 ? BinaryKit.readU32LE(recs[k].data, 20) : 0; + const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0; + const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0; + const dimStr = wPt> 0 && hPt> 0 ? `_W${Math.round(wPt)}_H${Math.round(hPt)}` : ""; + cellChildren.push(buildPara([buildSpan(`__EXT_${gsoId}${dimStr}__`)])); + k = skipKids(recs, k); + } else if (cellCtrlId === CTRL_TABLE) { + const tr = shield.guard( + () => parseTableCtrl(recs, k, di, shield, gsoCtx), + { grid: null, next: skipKids(recs, k) }, + `hwp:nestedTbl@${k}` + ); + if (tr.grid) cellChildren.push(tr.grid); + k = tr.next; + } else { + k = skipKids(recs, k); + } + } else { + k++; + } + } + return { + row, + col, + cs, + rs, + props, + widthHwp, + heightHwp: heightHwp || void 0, + cellChildren: cellChildren.length ? cellChildren : [buildPara([buildSpan("")])] + }; +} +function parsePageDef(d) { + if (d.length < 24) return A4; + const w = BinaryKit.readU32LE(d, 0); + const h = BinaryKit.readU32LE(d, 4); + const ml = BinaryKit.readU32LE(d, 8); + const mr = BinaryKit.readU32LE(d, 12); + const mt = BinaryKit.readU32LE(d, 16); + const mb = BinaryKit.readU32LE(d, 20); + const at = d.length>= 40 ? BinaryKit.readU32LE(d, 36) : 0; + return { + wPt: Metric.hwpToPt(w), + hPt: Metric.hwpToPt(h), + ml: Metric.hwpToPt(ml), + mr: Metric.hwpToPt(mr), + mt: Metric.hwpToPt(mt), + mb: Metric.hwpToPt(mb), + orient: at & 1 ? "landscape" : "portrait" + }; +} +function i32(d, o) { + const u = BinaryKit.readU32LE(d, o); + return u> 2147483647 ? u - 4294967296 : u; +} +function colorRef(d, o) { + if (o + 3> d.length) return "000000"; + return (d[o] << 16 | d[o + 1] << 8 | d[o + 2]).toString(16).padStart(6, "0").toUpperCase(); +} +function toStroke(b) { + return { kind: BORDER_KIND[b.type] ?? "solid", pt: b.widthPt, color: b.color }; +} +function applyCellBorderFill(bf, props) { + if (bf.borders.length>= 4) { + props.left = toStroke(bf.borders[0]); + props.right = toStroke(bf.borders[1]); + props.top = toStroke(bf.borders[2]); + props.bot = toStroke(bf.borders[3]); + } + if (bf.bgColor && bf.bgColor !== "FFFFFF") props.bg = bf.bgColor; +} +function strokeFromBF(bfId, di) { + if (bfId <= 0 || bfId> di.borderFills.length) return void 0; + const bf = di.borderFills[bfId - 1]; + if (!bf.borders.length) return void 0; + const b = bf.borders[0]; + return { kind: BORDER_KIND[b.type] ?? "solid", pt: b.widthPt, color: b.color }; +} +function buildParaProps(ps) { + if (!ps) return {}; + const p = {}; + if (ps.align && ps.align !== "left") p.align = ps.align; + if (ps.spaceBefore> 0) p.spaceBefore = Metric.hwpToPt(ps.spaceBefore); + if (ps.spaceAfter> 0) p.spaceAfter = Metric.hwpToPt(ps.spaceAfter); + if (ps.lineSpacing> 0 && ps.lineSpacing !== 160) p.lineHeight = ps.lineSpacing / 100; + const leftMarginPt = Math.max(0, Metric.hwpToPt(ps.leftMargin)); + if (leftMarginPt> 0) p.leftMargin = leftMarginPt; + if (ps.indent !== 0) p.firstLineIndentPt = Metric.hwpToPt(ps.indent); + return p; +} +var HwpScanner = class { + constructor() { + this.format = "hwp"; + this.aliases = ["application/vnd.hancom.hwp"]; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + if (!BinaryKit.isOle2(data)) return fail("HWP: Invalid OLE2 signature"); + const streams = BinaryKit.parseCfb(data); + const fh = streams.get("FileHeader"); + const { compressed, encrypted } = fh ? parseFileHeader(fh) : { compressed: true, encrypted: false }; + if (encrypted) return fail("HWP: \uC554\uD638\uD654\uB41C \uD30C\uC77C\uC740 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4"); + const diRaw = streams.get("DocInfo"); + let di = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] }; + if (diRaw) { + di = shield.guard(() => parseDocInfo(diRaw, compressed), di, "hwp:docInfo"); + } + const binEntries = []; + for (const [path, streamData] of streams) { + const m = path.match(/^BinData[/\\]BIN(\d+)\.\w+$/i); + if (m) binEntries.push({ binNum: parseInt(m[1], 10), data: streamData }); + } + binEntries.sort((a, b) => a.binNum - b.binNum); + const objectMap = /* @__PURE__ */ new Map(); + for (let idx = 0; idx < binEntries.length; idx++) { + const { data: imgData } = binEntries[idx]; + let mimeType = "image/jpeg"; + if (imgData[0] === 137 && imgData[1] === 80) mimeType = "image/png"; + else if (imgData[0] === 71 && imgData[1] === 73) mimeType = "image/gif"; + else if (imgData[0] === 66 && imgData[1] === 77) mimeType = "image/bmp"; + const base64 = TextKit.base64Encode(imgData); + const { wPt, hPt } = getImageDimsPt(imgData, mimeType); + objectMap.set(idx, buildImg(base64, mimeType, wPt, hPt)); + } + const gsoCtx = { count: 0 }; + const allContent = []; + let pageDims = A4; + for (let s = 0; s < 100; s++) { + const sec = streams.get(`BodyText/Section${s}`) ?? streams.get(`Section${s}`); + if (!sec) { + if (s === 0) { + const fb = findBodySection(streams); + if (fb) { + const r2 = parseBody(fb, compressed, di, shield, gsoCtx); + allContent.push(...r2.content); + if (r2.pageDims) pageDims = r2.pageDims; + } + } + break; + } + const r = shield.guard( + () => parseBody(sec, compressed, di, shield, gsoCtx), + { content: [], pageDims: void 0 }, + `hwp:sec${s}` + ); + allContent.push(...r.content); + if (r.pageDims) pageDims = r.pageDims; + } + if (objectMap.size> 0) { + injectImagesIntoContent(allContent, objectMap); + } + warns.push(...shield.flush()); + const content = allContent.length> 0 ? allContent : [buildPara([buildSpan("")])]; + return succeed(buildRoot({}, [buildSheet(content, pageDims)]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`HWP decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function findBodySection(streams) { + for (const [k, v] of streams) + if (k.includes("Section") && !k.includes("Header") && !k.includes("Info")) return v; + return void 0; +} +function getImageDimsPt(data, mime) { + const fallback = { wPt: 72, hPt: 72 }; + try { + if (mime === "image/png" && data.length>= 24) { + const w = (data[16] << 24 | data[17] << 16 | data[18] << 8 | data[19])>>> 0; + const h = (data[20] << 24 | data[21] << 16 | data[22] << 8 | data[23])>>> 0; + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + if (mime === "image/jpeg") { + let i = 2; + while (i + 8 < data.length) { + if (data[i] !== 255) { + i++; + continue; + } + const marker = data[i + 1]; + if (marker>= 192 && marker <= 195) { + const h = (data[i + 5] << 8 | data[i + 6])>>> 0; + const w = (data[i + 7] << 8 | data[i + 8])>>> 0; + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + const segLen = data[i + 2] << 8 | data[i + 3]; + i += 2 + (segLen> 0 ? segLen : 2); + } + } + if (mime === "image/bmp" && data.length>= 26) { + const w = BinaryKit.readU32LE(data, 18); + const h = Math.abs(BinaryKit.readU32LE(data, 22) | 0); + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + if (mime === "image/gif" && data.length>= 10) { + const w = data[6] | data[7] << 8; + const h = data[8] | data[9] << 8; + if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; + } + } catch { + } + return fallback; +} +function injectImagesIntoContent(content, objectMap) { + if (objectMap.size === 0) return; + const processKids = (kids) => { + for (let i = 0; i < kids.length; i++) { + const kid = kids[i]; + if (kid.tag === "span" && kid.kids && kid.kids[0]?.tag === "txt") { + const text = kid.kids[0].content; + const match = text.match?.(/^__(?:IMG|EXT)_(\d+)(?:_W(\d+)_H(\d+))?__$/); + if (match) { + const objId = parseInt(match[1], 10); + const base = objectMap.get(objId); + if (base) { + const wPt = match[2] ? parseInt(match[2], 10) : 0; + const hPt = match[3] ? parseInt(match[3], 10) : 0; + kids[i] = wPt> 0 && hPt> 0 ? { ...base, w: wPt, h: hPt } : base; + } + } + } + } + }; + const processGridKids = (grid) => { + if (!grid.kids || !Array.isArray(grid.kids)) return; + for (const row of grid.kids) { + if (!row.kids || !Array.isArray(row.kids)) continue; + for (const cell of row.kids) { + if (!cell.kids || !Array.isArray(cell.kids)) continue; + for (const cellKid of cell.kids) { + if (cellKid.tag === "grid") { + processGridKids(cellKid); + } else if (cellKid.tag === "para" && cellKid.kids) { + processKids(cellKid.kids); + } + } + } + } + }; + for (const node of content) { + if (node.tag === "para" && node.kids) { + processKids(node.kids); + for (const kid of node.kids) { + if (kid.tag === "grid") { + processGridKids(kid); + } + } + } else if (node.tag === "grid") { + processGridKids(node); + } + } +} +registry.registerDecoder(new HwpScanner()); + +// src/decoders/docx/DocxDecoder.ts +var DocxDecoder = class extends BaseDecoder { + getFormat() { + return "docx"; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const files = await ArchiveKit.unzip(data); + const getFile = (path) => { + const lower = path.toLowerCase(); + for (const [name, data2] of files.entries()) { + if (name.toLowerCase() === lower) return data2; + } + return void 0; + }; + const docXml = getFile("word/document.xml"); + if (!docXml) return fail("DOCX: word/document.xml not found"); + const relsXml = getFile("word/_rels/document.xml.rels"); + const relsMap = relsXml ? await parseRels(TextKit.decode(relsXml)) : /* @__PURE__ */ new Map(); + const coreXml2 = getFile("docProps/core.xml"); + let meta = {}; + if (coreXml2) { + try { + meta = await parseCoreProps(TextKit.decode(coreXml2)); + } catch { + } + } + const numXml = getFile("word/numbering.xml"); + let numMap = /* @__PURE__ */ new Map(); + if (numXml) { + try { + numMap = await parseNumbering(TextKit.decode(numXml)); + } catch { + } + } + let stylesMap = /* @__PURE__ */ new Map(); + let paraStyleMap = /* @__PURE__ */ new Map(); + const stylesXml2 = getFile("word/styles.xml"); + if (stylesXml2) { + try { + const stylesStr = TextKit.decode(stylesXml2); + stylesMap = await parseStylesMap(stylesStr); + paraStyleMap = await parseParaStyleMap(stylesStr); + } catch { + } + } + let docStr = TextKit.decode(docXml).trim(); + if (!docStr) { + warns.push( + "DOCX: word/document.xml is empty, using fallback empty document" + ); + docStr = ''; + } + const docObj = await XmlKit.parseStrict(docStr); + const body = getBody(docObj); + const dims = extractDims2(body) ?? { ...A4 }; + const elements = getBodyElements(body); + console.log( + `[DocxDecoder] \uD30C\uC2F1\uB41C \uC804\uCCB4 \uBCF8\uBB38 \uC694\uC18C \uAC1C\uC218: ${elements.length}` + ); + const decCtx = { + relsMap, + files, + shield, + numMap, + warns, + stylesMap, + paraStyleMap + }; + const kids = []; + for (const el of elements) { + const nodes = shield.guard( + () => decodeElement(el, decCtx), + [buildPara([buildSpan("[\uC694\uC18C \uD30C\uC2F1 \uC2E4\uD328]")])], + "docx:bodyElement" + ); + if (Array.isArray(nodes)) { + kids.push(...nodes); + } else { + kids.push(nodes); + } + if (el.type === "para") { + const pPr = el.node?.["w:pPr"]?.[0] ?? el.node?.pPr?.[0] ?? {}; + const inlineSectPr = pPr?.["w:sectPr"]?.[0] ?? pPr?.sectPr?.[0]; + if (inlineSectPr) { + const typeAttr = inlineSectPr?.["w:type"]?.[0]?._attr; + const sectType = typeAttr?.["w:val"] ?? typeAttr?.val ?? "nextPage"; + if (sectType !== "continuous") { + kids.push( + buildPara([{ tag: "span", props: {}, kids: [buildPb()] }]) + ); + } + } + } + } + const headersMap = await decodeHeaderFooter2( + "header", + body, + relsMap, + files, + decCtx + ); + const footersMap = await decodeHeaderFooter2( + "footer", + body, + relsMap, + files, + decCtx + ); + warns.push(...shield.flush()); + const sheet = buildSheet(kids.filter(Boolean), dims, { + headers: headersMap, + footers: footersMap + }); + return succeed(buildRoot(meta, [sheet]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`DOCX decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function toArr2(v) { + return v == null ? [] : Array.isArray(v) ? v : [v]; +} +function resolveDocxPath(baseDir, target) { + if (target.startsWith("/")) return target.slice(1); + const parts = (baseDir + "/" + target).split("/"); + const stack = []; + for (const p of parts) { + if (p === "..") { + stack.pop(); + } else if (p !== ".") { + stack.push(p); + } + } + return stack.join("/"); +} +async function parseRels(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + for (const rel of toArr2(obj?.Relationships?.[0]?.Relationship)) { + const a = rel?._attr ?? {}; + if (a.Id && a.Target) map.set(a.Id, a.Target); + } + } catch { + } + return map; +} +async function parseCoreProps(xml) { + const trimmed = xml.trim(); + if (!trimmed) return {}; + try { + const obj = await XmlKit.parseStrict(trimmed); + const c = obj?.["cp:coreProperties"]?.[0] ?? obj?.coreProperties?.[0] ?? {}; + return { + title: c?.["dc:title"]?.[0]?._text ?? void 0, + author: c?.["dc:creator"]?.[0]?._text ?? void 0, + subject: c?.["dc:subject"]?.[0]?._text ?? void 0, + created: c?.["dcterms:created"]?.[0]?._text ?? void 0, + modified: c?.["dcterms:modified"]?.[0]?._text ?? void 0 + }; + } catch { + return {}; + } +} +async function parseNumbering(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + const root = obj?.["w:numbering"]?.[0] ?? obj?.numbering?.[0] ?? obj; + const absMap = /* @__PURE__ */ new Map(); + for (const abs of toArr2(root?.["w:abstractNum"] ?? root?.abstractNum)) { + const absId = Number( + abs?._attr?.["w:abstractNumId"] ?? abs?._attr?.abstractNumId ?? 0 + ); + const levels = /* @__PURE__ */ new Map(); + for (const lvl of toArr2(abs?.["w:lvl"] ?? abs?.lvl)) { + const ilvl = Number(lvl?._attr?.["w:ilvl"] ?? lvl?._attr?.ilvl ?? 0); + const fmtNode = lvl?.["w:numFmt"]?.[0]?._attr ?? lvl?.numFmt?.[0]?._attr ?? {}; + const fmt = fmtNode?.["w:val"] ?? fmtNode?.val ?? "decimal"; + levels.set(ilvl, { fmt, isOrdered: fmt !== "bullet" }); + } + absMap.set(absId, levels); + } + for (const num of toArr2(root?.["w:num"] ?? root?.num)) { + const numId = Number(num?._attr?.["w:numId"] ?? num?._attr?.numId ?? 0); + const absRef = num?.["w:abstractNumId"]?.[0]?._attr ?? num?.abstractNumId?.[0]?._attr ?? {}; + const absId = Number(absRef?.["w:val"] ?? absRef?.val ?? 0); + const levels = absMap.get(absId) ?? /* @__PURE__ */ new Map(); + map.set(numId, { levels }); + } + } catch { + } + return map; +} +function getBody(obj) { + const doc = obj?.["w:document"]?.[0] ?? obj?.document?.[0] ?? obj; + const body = doc?.["w:body"]?.[0] ?? doc?.body?.[0] ?? doc; + if (!body) { + console.error("[DocxDecoder] \uBCF8\uBB38(body)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."); + } + return body; +} +function extractDims2(body) { + try { + const sp = body?.["w:sectPr"]?.[0] ?? body?.sectPr?.[0]; + if (!sp) return null; + const sz = sp?.["w:pgSz"]?.[0]?._attr ?? sp?.pgSz?.[0]?._attr; + const mar = sp?.["w:pgMar"]?.[0]?._attr ?? sp?.pgMar?.[0]?._attr; + if (!sz) return null; + const headerDxa = Number(mar?.["w:header"] ?? mar?.header ?? 0); + const footerDxa = Number(mar?.["w:footer"] ?? mar?.footer ?? 0); + return { + wPt: Metric.dxaToPt(Number(sz["w:w"] ?? sz.w ?? 11906)), + hPt: Metric.dxaToPt(Number(sz["w:h"] ?? sz.h ?? 16838)), + mt: Metric.dxaToPt(Number(mar?.["w:top"] ?? mar?.top ?? 1440)), + mb: Metric.dxaToPt(Number(mar?.["w:bottom"] ?? mar?.bottom ?? 1440)), + ml: Metric.dxaToPt(Number(mar?.["w:left"] ?? mar?.left ?? 1800)), + mr: Metric.dxaToPt(Number(mar?.["w:right"] ?? mar?.right ?? 1800)), + orient: (sz["w:orient"] ?? sz.orient) === "landscape" ? "landscape" : "portrait", + headerPt: headerDxa> 0 ? Metric.dxaToPt(headerDxa) : void 0, + footerPt: footerDxa> 0 ? Metric.dxaToPt(footerDxa) : void 0 + }; + } catch { + return null; + } +} +function getBodyElements(body) { + const paras = toArr2(body?.["w:p"] ?? body?.p); + const tables = toArr2(body?.["w:tbl"] ?? body?.tbl); + const sdts = toArr2(body?.["w:sdt"] ?? body?.sdt); + const childOrder = body?.["_childOrder"]; + if (Array.isArray(childOrder)) { + const items = []; + let pi = 0, ti = 0, si = 0; + for (const tag of childOrder) { + if ((tag === "w:p" || tag === "p") && pi < paras.length) { + items.push({ type: "para", node: paras[pi++] }); + } else if ((tag === "w:tbl" || tag === "tbl") && ti < tables.length) { + items.push({ type: "table", node: tables[ti++] }); + } else if ((tag === "w:sdt" || tag === "sdt") && si < sdts.length) { + items.push({ type: "sdt", node: sdts[si++] }); + } + } + while (pi < paras.length) items.push({ type: "para", node: paras[pi++] }); + while (ti < tables.length) + items.push({ type: "table", node: tables[ti++] }); + while (si < sdts.length) items.push({ type: "sdt", node: sdts[si++] }); + return items; + } + return [ + ...paras.map((n) => ({ type: "para", node: n })), + ...tables.map((n) => ({ type: "table", node: n })), + ...sdts.map((n) => ({ type: "sdt", node: n })) + ]; +} +async function decodeHeaderFooter2(kind, body, relsMap, files, ctx) { + try { + const sp = body?.["w:sectPr"]?.[0] ?? body?.sectPr?.[0]; + if (!sp) return void 0; + const refTag = kind === "header" ? "w:headerReference" : "w:footerReference"; + const refs = toArr2(sp?.[refTag] ?? sp?.[refTag.replace("w:", "")]); + if (refs.length === 0) return void 0; + const result = {}; + for (const ref of refs) { + const type = ref._attr?.["w:type"] ?? ref._attr?.type ?? "default"; + const rId = ref._attr?.["r:id"] ?? ref._attr?.["r:Id"] ?? ref._attr?.id; + if (!rId) continue; + const target = relsMap.get(rId); + if (!target) continue; + const filePath = resolveDocxPath("word", target); + const fileData = files.get(filePath); + if (!fileData) continue; + const hfFileName = filePath.split("/").pop() ?? ""; + const hfRelsPath = `word/_rels/${hfFileName}.rels`; + const hfRelsData = files.get(hfRelsPath); + let hfRelsMap = relsMap; + if (hfRelsData) { + const hfRelsStr = TextKit.decode(hfRelsData).trim(); + const parsed = hfRelsStr ? await parseRels(hfRelsStr) : /* @__PURE__ */ new Map(); + hfRelsMap = new Map([...relsMap, ...parsed]); + } + const xmlStr = TextKit.decode(fileData).trim(); + if (!xmlStr) continue; + const watermark = extractWatermark(xmlStr); + if (watermark) { + result[type] = [ + buildPara([ + buildSpan(watermark, { pt: 80, color: "CCCCCC", b: true }) + ]) + ]; + continue; + } + try { + const obj = await XmlKit.parseStrict(xmlStr); + const rootTag = kind === "header" ? "w:hdr" : "w:ftr"; + const root = obj?.[rootTag]?.[0] ?? obj?.[rootTag.replace("w:", "")]?.[0] ?? obj; + const origRelsMap = ctx.relsMap; + ctx.relsMap = hfRelsMap; + const paras = toArr2(root?.["w:p"] ?? root?.p); + result[type] = paras.map((p) => decodePara2(p, ctx)); + ctx.relsMap = origRelsMap; + } catch (err) { + console.warn(`[DocxDecoder] ${kind} (${type}) XML \uD30C\uC2F1 \uC2E4\uD328:`, err); + continue; + } + } + return Object.keys(result).length> 0 ? result : void 0; + } catch { + return void 0; + } +} +function extractWatermark(xml) { + if (!xml.includes("v:textpath")) return null; + const m = xml.match(/string="([^"]+)"/); + return m ? m[1] : null; +} +function hasDrawingDeep(node) { + if (!node || typeof node !== "object") return false; + if (node["w:drawing"] || node["w:pict"]) return true; + return Object.values(node).some((v) => { + if (Array.isArray(v)) return v.some(hasDrawingDeep); + return hasDrawingDeep(v); + }); +} +function decodeElement(el, ctx) { + if (el.type === "table") { + const { value } = ctx.shield.guardGrid( + el.node, + (n) => decodeGrid2(n, ctx), + (n) => decodeGridSimple2(n), + (n) => decodeGridFlat2(n), + (n) => decodeGridText2(n), + "docx:table" + ); + return value; + } else if (el.type === "sdt") { + return decodeSdt(el.node, ctx); + } + return decodePara2(el.node, ctx); +} +function decodeSdt(sdt, ctx) { + const content = sdt?.["w:sdtContent"]?.[0] ?? sdt?.sdtContent?.[0]; + if (!content) return []; + const elements = getBodyElements(content); + const kids = []; + for (const el of elements) { + const res = decodeElement(el, ctx); + if (Array.isArray(res)) kids.push(...res); + else kids.push(res); + } + return kids; +} +function decodePara2(p, ctx) { + const pPr = p?.["w:pPr"]?.[0] ?? {}; + const alignVal = pPr?.["w:jc"]?.[0]?._attr?.["w:val"] ?? pPr?.["w:jc"]?.[0]?._attr?.val; + const headStyle = pPr?.["w:pStyle"]?.[0]?._attr?.["w:val"] ?? pPr?.["w:pStyle"]?.[0]?._attr?.val ?? ""; + const styleInherited = resolveParaStyle( + headStyle || void 0, + ctx.paraStyleMap + ); + const props = { + align: safeAlign(alignVal), + heading: parseHeading(headStyle), + styleId: headStyle || void 0 + }; + const spacingAttr = pPr?.["w:spacing"]?.[0]?._attr ?? pPr?.spacing?.[0]?._attr ?? {}; + const beforeVal = Number( + spacingAttr?.["w:before"] ?? spacingAttr?.before ?? 0 + ); + const afterVal = Number(spacingAttr?.["w:after"] ?? spacingAttr?.after ?? 0); + const lineVal = Number(spacingAttr?.["w:line"] ?? spacingAttr?.line ?? 0); + const lineRule = spacingAttr?.["w:lineRule"] ?? spacingAttr?.lineRule ?? "auto"; + if (beforeVal> 0) props.spaceBefore = Metric.dxaToPt(beforeVal); + else if (styleInherited.pPr?.spaceBefore) + props.spaceBefore = styleInherited.pPr.spaceBefore; + if (afterVal> 0) props.spaceAfter = Metric.dxaToPt(afterVal); + else if (styleInherited.pPr?.spaceAfter) + props.spaceAfter = styleInherited.pPr.spaceAfter; + if (lineVal> 0 && lineRule === "auto") props.lineHeight = lineVal / 240; + else if (styleInherited.pPr?.lineHeight) + props.lineHeight = styleInherited.pPr.lineHeight; + const indAttr = pPr?.["w:ind"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {}; + const leftVal = Number(indAttr?.["w:left"] ?? indAttr?.left ?? 0); + const rightVal = Number(indAttr?.["w:right"] ?? indAttr?.right ?? 0); + const firstLineVal = Number( + indAttr?.["w:firstLine"] ?? indAttr?.firstLine ?? 0 + ); + const hangingVal = Number(indAttr?.["w:hanging"] ?? indAttr?.hanging ?? 0); + if (leftVal> 0) props.indentPt = Metric.dxaToPt(leftVal); + else if (styleInherited.pPr?.indentPt) + props.indentPt = styleInherited.pPr.indentPt; + if (rightVal> 0) props.indentRightPt = Metric.dxaToPt(rightVal); + else if (styleInherited.pPr?.indentRightPt) + props.indentRightPt = styleInherited.pPr.indentRightPt; + if (firstLineVal> 0) props.firstLineIndentPt = Metric.dxaToPt(firstLineVal); + else if (hangingVal> 0) + props.firstLineIndentPt = -Metric.dxaToPt(hangingVal); + else if (styleInherited.pPr?.firstLineIndentPt) + props.firstLineIndentPt = styleInherited.pPr.firstLineIndentPt; + if (!alignVal && styleInherited.pPr?.align) + props.align = safeAlign(styleInherited.pPr.align); + const numPr = pPr?.["w:numPr"]?.[0] ?? pPr?.numPr?.[0]; + if (numPr) { + const ilvlNode = numPr?.["w:ilvl"]?.[0]?._attr ?? numPr?.ilvl?.[0]?._attr ?? {}; + const numIdNode = numPr?.["w:numId"]?.[0]?._attr ?? numPr?.numId?.[0]?._attr ?? {}; + const ilvl = Number(ilvlNode?.["w:val"] ?? ilvlNode?.val ?? 0); + const numId = Number(numIdNode?.["w:val"] ?? numIdNode?.val ?? 0); + props.listLv = ilvl; + const numEntry = ctx.numMap.get(numId); + if (numEntry) { + const lvlInfo = numEntry.levels.get(ilvl) ?? numEntry.levels.get(0); + props.listOrd = lvlInfo?.isOrdered ?? false; + } else { + props.listOrd = numId>= 2; + } + } + const pbBeforeNode = pPr?.["w:pageBreakBefore"]?.[0] ?? pPr?.pageBreakBefore?.[0]; + const hasPageBreakBefore = pbBeforeNode != null && (pbBeforeNode?._attr?.["w:val"] ?? pbBeforeNode?._attr?.val ?? "1") !== "0"; + const children = p?.["_childOrder"]; + const kids = []; + if (Array.isArray(children)) { + const runsArr = toArr2(p?.["w:r"] ?? p?.r); + const hlArr = toArr2(p?.["w:hyperlink"] ?? p?.hyperlink); + const sdtArr = toArr2(p?.["w:sdt"] ?? p?.sdt); + let ri = 0; + let hi = 0; + let si = 0; + for (const tag of children) { + if (tag === "w:r" || tag === "r") { + const run = runsArr[ri++]; + if (run) { + kids.push( + ctx.shield.guard( + () => hasDrawingDeep(run) ? decodeRunOrImage(run, ctx) : decodeRun(run, ctx, styleInherited.rPr), + buildSpan(""), + "docx:run" + ) + ); + } + } else if (tag === "w:hyperlink" || tag === "hyperlink") { + const hl = hlArr[hi++]; + if (hl) { + const rId = hl?._attr?.["r:id"] ?? hl?._attr?.id; + const url = rId ? ctx.relsMap.get(rId) : ""; + const hlRuns = toArr2(hl?.["w:r"] ?? hl?.r); + const hlKids = hlRuns.map( + (r) => decodeRun(r, ctx, { + ...styleInherited.rPr, + u: true, + color: "0000FF" + }) + ); + kids.push({ + tag: "link", + href: url || "", + kids: hlKids + }); + } + } else if (tag === "w:sdt" || tag === "sdt") { + const sdt = sdtArr[si++]; + if (sdt) { + const sdtContent = sdt?.["w:sdtContent"]?.[0] ?? sdt?.sdtContent?.[0]; + if (sdtContent) { + const innerRuns = toArr2(sdtContent?.["w:r"] ?? sdtContent?.r); + for (const ir of innerRuns) { + kids.push( + ctx.shield.guard( + () => hasDrawingDeep(ir) ? decodeRunOrImage(ir, ctx) : decodeRun(ir, ctx, styleInherited.rPr), + buildSpan(""), + "docx:run" + ) + ); + } + } + } + } + } + } else { + const runs = toArr2(p?.["w:r"] ?? p?.r); + const legacyKids = ctx.shield.guardAll( + runs, + (run) => hasDrawingDeep(run) ? decodeRunOrImage(run, ctx) : decodeRun(run, ctx, styleInherited.rPr), + () => buildSpan(""), + "docx:run" + ); + kids.push(...legacyKids); + } + const filteredKids = kids.filter(Boolean); + if (hasPageBreakBefore) { + filteredKids.unshift({ tag: "span", props: {}, kids: [buildPb()] }); + } + return buildPara(filteredKids, props); +} +function decodeRunOrImage(run, ctx) { + function findFirstDrawing(node) { + if (!node || typeof node !== "object") return null; + if (node["w:drawing"]) return node["w:drawing"][0]; + if (node["w:pict"]) return node["w:pict"][0]; + for (const value of Object.values(node)) { + if (Array.isArray(value)) { + for (const v of value) { + const found = findFirstDrawing(v); + if (found) return found; + } + } else { + const found = findFirstDrawing(value); + if (found) return found; + } + } + return null; + } + const drawing = findFirstDrawing(run); + if (drawing) { + const img = decodeDrawing(drawing, ctx); + if (img) return img; + } + return decodeRun(run, ctx); +} +function decodeImageLayout(anchor) { + const wrap = anchor?.["wp:wrapTop"]?.[0] ?? anchor?.wrapTop?.[0]; + const anchorPos = anchor?.["wp:anchorPos"]?.[0]?._attr ?? anchor?.anchorPos?.[0]?._attr ?? {}; + const layout = { + wrap: "square", + horzAlign: "left", + vertAlign: "top", + horzRelTo: "page", + vertRelTo: "page", + xPt: Number(anchorPos?.x ?? 0) / 12700, + // emu to pt + yPt: Number(anchorPos?.y ?? 0) / 12700 + // emu to pt + }; + if (wrap?.["wp:none"]) layout.wrap = "none"; + else if (wrap?.["wp:square"]) layout.wrap = "square"; + else if (wrap?.["wp:tight"]) layout.wrap = "tight"; + else if (wrap?.["wp:through"]) layout.wrap = "through"; + else if (wrap?.["wp:behind"]) layout.wrap = "behind"; + else if (wrap?.["wp:inFront"]) layout.wrap = "front"; + return layout; +} +function decodeDrawing(drawing, ctx) { + try { + const inline = drawing?.["wp:inline"]?.[0] ?? drawing?.inline?.[0]; + const anchor = drawing?.["wp:anchor"]?.[0] ?? drawing?.anchor?.[0]; + const container = inline ?? anchor; + if (!container) return null; + const extent = container?.["wp:extent"]?.[0]?._attr ?? container?.extent?.[0]?._attr ?? {}; + const cx = Number(extent?.cx ?? 0); + const cy = Number(extent?.cy ?? 0); + const wPt = Metric.emuToPt(cx); + const hPt = Metric.emuToPt(cy); + const docPr = container?.["wp:docPr"]?.[0]?._attr ?? container?.docPr?.[0]?._attr ?? {}; + const alt = docPr?.descr ?? docPr?.name ?? ""; + const graphic = container?.["a:graphic"]?.[0] ?? container?.graphic?.[0]; + const graphicData = graphic?.["a:graphicData"]?.[0] ?? graphic?.graphicData?.[0]; + if (graphicData?.["c:chart"] || graphicData?.chart) { + return { + tag: "img", + b64: "", + // 플레이스홀더 + mime: "image/png", + w: wPt, + h: hPt, + alt: `[\uCC28\uD2B8: ${alt || "\uCC28\uD2B8"}]`, + layout: decodeImageLayout(anchor) + }; + } + const pic = graphicData?.["pic:pic"]?.[0] ?? graphicData?.pic?.[0]; + const blipFill = pic?.["pic:blipFill"]?.[0] ?? pic?.blipFill?.[0]; + const blip = blipFill?.["a:blip"]?.[0]?._attr ?? blipFill?.blip?.[0]?._attr ?? {}; + const rId = blip?.["r:embed"] ?? blip?.embed; + if (!rId) return null; + const target = ctx.relsMap.get(rId); + if (!target) return null; + let filePath = resolveDocxPath("word", target); + let fileData = ctx.files.get(filePath); + if (!fileData) { + filePath = resolveDocxPath("word/_rels", target); + fileData = ctx.files.get(filePath); + } + if (!fileData) { + const fileName = target.split("/").pop() ?? ""; + for (const [k, v] of ctx.files) { + if (fileName && (k.endsWith("/" + fileName) || k === fileName)) { + fileData = v; + filePath = k; + break; + } + } + } + if (!fileData) { + console.warn(`[DocxDecoder] image not found: "${target}"`); + return null; + } + const ext = target.split(".").pop()?.toLowerCase() ?? "png"; + const mimeMap = { + png: "image/png", + jpg: "image/jpeg", + jpeg: "image/jpeg", + gif: "image/gif", + bmp: "image/bmp" + }; + const mime = mimeMap[ext] ?? "image/png"; + console.log( + `[DocxDecoder] image loaded: ${filePath} (${mime}, ${fileData.length} bytes)` + ); + const layout = inline ? { wrap: "inline" } : extractAnchorLayout(anchor); + return buildImg( + TextKit.base64Encode(fileData), + mime, + wPt, + hPt, + alt || void 0, + layout + ); + } catch { + return null; + } +} +var HIGHLIGHT_COLOR_MAP = { + yellow: "FFFF00", + green: "00FF00", + cyan: "00FFFF", + magenta: "FF00FF", + blue: "0000FF", + red: "FF0000", + darkBlue: "00008B", + darkCyan: "008B8B", + darkGreen: "006400", + darkMagenta: "8B008B", + darkRed: "8B0000", + darkYellow: "808000", + darkGray: "A9A9A9", + lightGray: "D3D3D3", + black: "000000", + white: "FFFFFF" +}; +function decodeRun(run, ctx, styleRpr) { + const rPr = run?.["w:rPr"]?.[0] ?? run?.rPr?.[0] ?? {}; + const vanishNode = rPr?.["w:vanish"]?.[0] ?? rPr?.vanish?.[0]; + if (vanishNode != null) { + const vanishVal = vanishNode?._attr?.["w:val"] ?? vanishNode?._attr?.val ?? "1"; + if (vanishVal !== "0") return buildSpan(""); + } + const szAttr = rPr?.["w:sz"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {}; + const szVal = szAttr?.["w:val"] ?? szAttr?.val; + const szCsAttr = rPr?.["w:szCs"]?.[0]?._attr ?? rPr?.szCs?.[0]?._attr ?? {}; + const szCsVal = szCsAttr?.["w:val"] ?? szCsAttr?.val; + const effectiveSzVal = szVal ?? szCsVal; + const colorAttr = rPr?.["w:color"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {}; + const colorVal = colorAttr?.["w:val"] ?? colorAttr?.val; + const fontAttr = rPr?.["w:rFonts"]?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {}; + const fontName = fontAttr?.["w:ascii"] ?? fontAttr?.ascii ?? fontAttr?.["w:hAnsi"] ?? fontAttr?.hAnsi ?? fontAttr?.["w:eastAsia"] ?? fontAttr?.eastAsia; + const underVal = rPr?.["w:u"]?.[0]?._attr?.["w:val"] ?? rPr?.["w:u"]?.[0]?._attr?.val; + const shdAttr = rPr?.["w:shd"]?.[0]?._attr ?? rPr?.shd?.[0]?._attr ?? {}; + const shdBg = safeHex(shdAttr?.["w:fill"] ?? shdAttr?.fill); + const hlAttr = rPr?.["w:highlight"]?.[0]?._attr ?? rPr?.highlight?.[0]?._attr ?? {}; + const hlVal = hlAttr?.["w:val"] ?? hlAttr?.val; + const bgVal = (hlVal ? HIGHLIGHT_COLOR_MAP[hlVal] : void 0) ?? shdBg; + const vertAlignVal = rPr?.["w:vertAlign"]?.[0]?._attr?.["w:val"] ?? rPr?.["w:vertAlign"]?.[0]?._attr?.val; + const posAttr = rPr?.["w:position"]?.[0]?._attr ?? rPr?.position?.[0]?._attr ?? {}; + const posVal = Number(posAttr?.["w:val"] ?? posAttr?.val ?? 0); + let isSup = vertAlignVal === "superscript"; + let isSub = vertAlignVal === "subscript"; + if (!isSup && !isSub && posVal !== 0) { + if (posVal>= 4) isSup = true; + else if (posVal <= -4) isSub = true; + } + const bNode = rPr?.["w:b"]?.[0] ?? rPr?.b?.[0]; + const isBold = bNode != null && (bNode?._attr?.["w:val"] ?? bNode?._attr?.val ?? "1") !== "0"; + const iNode = rPr?.["w:i"]?.[0] ?? rPr?.i?.[0]; + const isItalic = iNode != null && (iNode?._attr?.["w:val"] ?? iNode?._attr?.val ?? "1") !== "0"; + const sNode = rPr?.["w:strike"]?.[0] ?? rPr?.strike?.[0]; + const isStrike = sNode != null && (sNode?._attr?.["w:val"] ?? sNode?._attr?.val ?? "1") !== "0"; + const props = { + b: (bNode != null ? isBold : styleRpr?.b) || void 0, + i: (iNode != null ? isItalic : styleRpr?.i) || void 0, + u: (underVal ? underVal !== "none" : styleRpr?.u) || void 0, + s: (sNode != null ? isStrike : styleRpr?.s) || void 0, + sup: isSup || void 0, + sub: isSub || void 0, + pt: effectiveSzVal ? Metric.halfPtToPt(Number(effectiveSzVal)) : styleRpr?.pt, + color: safeHex(colorVal) ?? styleRpr?.color, + font: fontName ? safeFont(fontName) : styleRpr?.font, + bg: bgVal + }; + const fldChar = run?.["w:fldChar"]?.[0]?._attr ?? run?.fldChar?.[0]?._attr; + const instrText = run?.["w:instrText"]?.[0]; + const brNodes = toArr2(run?.["w:br"] ?? run?.br ?? []); + for (const br of brNodes) { + const brType = br?._attr?.["w:type"] ?? br?._attr?.type; + if (brType === "page") { + return { tag: "span", props, kids: [buildPb()] }; + } + } + const textNodes = toArr2(run?.["w:t"] ?? run?.t); + const content = textNodes.map((t) => typeof t === "string" ? t : t?._ ?? t?._text ?? "").join(""); + if (instrText) { + const instrStr = typeof instrText === "string" ? instrText : instrText?._text ?? ""; + if (instrStr.trim().toUpperCase() === "PAGE") { + const pageNum = { tag: "pagenum", format: "decimal" }; + return { tag: "span", props, kids: [pageNum] }; + } + } + return buildSpan(content, props); +} +function parseBorderDef(bdrNode) { + const sides = [ + ["top", "top"], + ["bottom", "bottom"], + ["left", "left"], + ["right", "right"], + ["insideH", "insideH"], + ["insideV", "insideV"] + ]; + const result = {}; + for (const [xml, prop] of sides) { + const bdr = bdrNode?.["w:" + xml]?.[0]?._attr ?? bdrNode?.[xml]?.[0]?._attr; + if (!bdr) continue; + const val = bdr?.["w:val"] ?? bdr?.val; + if (val === "none" || val === "nil") continue; + result[prop] = safeStrokeDocx( + val, + Number(bdr?.["w:sz"] ?? bdr?.sz ?? 4), + bdr?.["w:color"] ?? bdr?.color + ); + } + return result; +} +async function parseStylesMap(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + const stylesRoot = obj?.["w:styles"]?.[0] ?? obj?.styles?.[0] ?? obj; + const styleArr = toArr2(stylesRoot?.["w:style"] ?? stylesRoot?.style); + for (const style of styleArr) { + const attr = style?._attr ?? {}; + const type = attr?.["w:type"] ?? attr?.type; + if (type !== "table") continue; + const id = attr?.["w:styleId"] ?? attr?.styleId; + if (!id) continue; + const tblPr = style?.["w:tblPr"]?.[0] ?? style?.tblPr?.[0]; + const tblBdrNode = tblPr?.["w:tblBorders"]?.[0] ?? tblPr?.tblBorders?.[0]; + const tblBorders = tblBdrNode ? parseBorderDef(tblBdrNode) : void 0; + const tcStyle = style?.["w:tcStyle"]?.[0] ?? style?.tcStyle?.[0]; + const tcBdrNode = tcStyle?.["w:tcBdr"]?.[0] ?? tcStyle?.tcBdr?.[0]; + if (tcBdrNode) { + const cellDef = parseBorderDef(tcBdrNode); + if (!tblBorders) { + map.set(id, { tblBorders: cellDef }); + } else { + map.set(id, { tblBorders: { ...cellDef, ...tblBorders } }); + } + } else if (tblBorders) { + map.set(id, { tblBorders }); + } + } + } catch { + } + return map; +} +async function parseParaStyleMap(xml) { + const map = /* @__PURE__ */ new Map(); + const trimmed = xml.trim(); + if (!trimmed) return map; + try { + const obj = await XmlKit.parseStrict(trimmed); + const stylesRoot = obj?.["w:styles"]?.[0] ?? obj?.styles?.[0] ?? obj; + const styleArr = toArr2(stylesRoot?.["w:style"] ?? stylesRoot?.style); + for (const style of styleArr) { + const attr = style?._attr ?? {}; + const type = attr?.["w:type"] ?? attr?.type; + if (type !== "paragraph" && type !== "character") continue; + const id = attr?.["w:styleId"] ?? attr?.styleId; + if (!id) continue; + const basedOn = (style?.["w:basedOn"]?.[0]?._attr ?? style?.basedOn?.[0]?._attr)?.["w:val"]; + const def = { basedOn }; + const rPr = style?.["w:rPr"]?.[0] ?? style?.rPr?.[0]; + if (rPr) { + const szAttr = rPr?.["w:sz"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {}; + const szVal = szAttr?.["w:val"] ?? szAttr?.val; + const colorAttr = rPr?.["w:color"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {}; + const colorVal = colorAttr?.["w:val"] ?? colorAttr?.val; + const fontAttr = rPr?.["w:rFonts"]?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {}; + const fontName = fontAttr?.["w:ascii"] ?? fontAttr?.ascii ?? fontAttr?.["w:eastAsia"] ?? fontAttr?.eastAsia; + const bNode = rPr?.["w:b"]?.[0] ?? rPr?.b?.[0]; + const isBold = bNode != null && (bNode?._attr?.["w:val"] ?? bNode?._attr?.val ?? "1") !== "0"; + const iNode = rPr?.["w:i"]?.[0] ?? rPr?.i?.[0]; + const isItalic = iNode != null && (iNode?._attr?.["w:val"] ?? iNode?._attr?.val ?? "1") !== "0"; + const underVal = rPr?.["w:u"]?.[0]?._attr?.["w:val"] ?? rPr?.["w:u"]?.[0]?._attr?.val; + const sNode = rPr?.["w:strike"]?.[0] ?? rPr?.strike?.[0]; + const isStrike = sNode != null && (sNode?._attr?.["w:val"] ?? sNode?._attr?.val ?? "1") !== "0"; + def.rPr = { + b: isBold || void 0, + i: isItalic || void 0, + u: underVal && underVal !== "none" ? true : void 0, + s: isStrike || void 0, + pt: szVal ? Metric.halfPtToPt(Number(szVal)) : void 0, + color: safeHex(colorVal), + font: fontName ? safeFont(fontName) : void 0 + }; + } + const pPr = style?.["w:pPr"]?.[0] ?? style?.pPr?.[0]; + if (pPr) { + const spacingAttr = pPr?.["w:spacing"]?.[0]?._attr ?? pPr?.spacing?.[0]?._attr ?? {}; + const beforeVal = Number( + spacingAttr?.["w:before"] ?? spacingAttr?.before ?? 0 + ); + const afterVal = Number( + spacingAttr?.["w:after"] ?? spacingAttr?.after ?? 0 + ); + const lineVal = Number( + spacingAttr?.["w:line"] ?? spacingAttr?.line ?? 0 + ); + const lineRule = spacingAttr?.["w:lineRule"] ?? spacingAttr?.lineRule ?? "auto"; + const indAttr = pPr?.["w:ind"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {}; + const leftVal = Number(indAttr?.["w:left"] ?? indAttr?.left ?? 0); + const rightVal = Number(indAttr?.["w:right"] ?? indAttr?.right ?? 0); + const firstLineVal = Number( + indAttr?.["w:firstLine"] ?? indAttr?.firstLine ?? 0 + ); + const hangingVal = Number( + indAttr?.["w:hanging"] ?? indAttr?.hanging ?? 0 + ); + const alignVal = pPr?.["w:jc"]?.[0]?._attr?.["w:val"] ?? pPr?.["w:jc"]?.[0]?._attr?.val; + def.pPr = { + align: alignVal, + spaceBefore: beforeVal> 0 ? Metric.dxaToPt(beforeVal) : void 0, + spaceAfter: afterVal> 0 ? Metric.dxaToPt(afterVal) : void 0, + lineHeight: lineVal> 0 && lineRule === "auto" ? lineVal / 240 : void 0, + indentPt: leftVal> 0 ? Metric.dxaToPt(leftVal) : void 0, + indentRightPt: rightVal> 0 ? Metric.dxaToPt(rightVal) : void 0, + firstLineIndentPt: firstLineVal> 0 ? Metric.dxaToPt(firstLineVal) : hangingVal> 0 ? -Metric.dxaToPt(hangingVal) : void 0 + }; + } + map.set(id, def); + } + } catch { + } + return map; +} +function resolveParaStyle(styleId, map) { + let merged = {}; + const visited = /* @__PURE__ */ new Set(); + let cur = styleId; + while (cur && !visited.has(cur)) { + visited.add(cur); + const def = map.get(cur); + if (!def) break; + if (def.rPr) { + merged.rPr = { ...def.rPr, ...merged.rPr }; + } + if (def.pPr) { + merged.pPr = { ...def.pPr, ...merged.pPr }; + } + cur = def.basedOn; + } + return merged; +} +function resolveCellBorders(cp, ri, ci, rs, cs, rowCount, colCount, tblBdr) { + const isTopEdge = ri === 0; + const isBottomEdge = ri + rs>= rowCount; + const isLeftEdge = ci === 0; + const isRightEdge = ci + cs>= colCount; + const resolved = { ...cp }; + if (!resolved.top) resolved.top = isTopEdge ? tblBdr.top : tblBdr.insideH; + if (!resolved.bot) + resolved.bot = isBottomEdge ? tblBdr.bottom : tblBdr.insideH; + if (!resolved.left) resolved.left = isLeftEdge ? tblBdr.left : tblBdr.insideV; + if (!resolved.right) + resolved.right = isRightEdge ? tblBdr.right : tblBdr.insideV; + return resolved; +} +function decodeGrid2(tbl, ctx) { + const tblPr = tbl?.["w:tblPr"]?.[0] ?? tbl?.tblPr?.[0] ?? {}; + const tblLookAttr = tblPr?.["w:tblLook"]?.[0]?._attr ?? tblPr?.tblLook?.[0]?._attr ?? {}; + const look = { + firstRow: tblLookAttr?.["w:firstRow"] === "1" || void 0, + lastRow: tblLookAttr?.["w:lastRow"] === "1" || void 0, + firstCol: tblLookAttr?.["w:firstColumn"] === "1" || tblLookAttr?.["w:firstCol"] === "1" || void 0, + lastCol: tblLookAttr?.["w:lastColumn"] === "1" || tblLookAttr?.["w:lastCol"] === "1" || void 0, + bandedRows: tblLookAttr?.["w:noHBand"] === "0" || void 0, + bandedCols: tblLookAttr?.["w:noVBand"] === "0" || void 0 + }; + const tblStyleId = (tblPr?.["w:tblStyle"]?.[0]?._attr ?? tblPr?.tblStyle?.[0]?._attr)?.["w:val"]; + const styleDef = tblStyleId ? ctx.stylesMap.get(tblStyleId) : void 0; + let tblBdr = styleDef?.tblBorders ?? {}; + const tblBordersNode = tblPr?.["w:tblBorders"]?.[0] ?? tblPr?.tblBorders?.[0]; + if (tblBordersNode) { + const parsed = parseBorderDef(tblBordersNode); + tblBdr = { ...tblBdr, ...parsed }; + } + const defaultStroke = tblBdr.insideH ?? tblBdr.top; + const gridProps = { look, defaultStroke }; + const tblGrid = tbl?.["w:tblGrid"]?.[0] ?? tbl?.tblGrid?.[0]; + if (tblGrid) { + const gridCols = toArr2(tblGrid?.["w:gridCol"] ?? tblGrid?.gridCol ?? []); + const colWidthsPt = gridCols.map( + (gc) => Metric.dxaToPt(Number(gc?._attr?.["w:w"] ?? gc?._attr?.w ?? 0)) + ).filter((w) => w> 0); + if (colWidthsPt.length> 0) gridProps.colWidths = colWidthsPt; + } + const rowArr = toArr2(tbl?.["w:tr"] ?? tbl?.tr); + const rawGrid = rowArr.map((row) => { + const cellArr = toArr2(row?.["w:tc"] ?? row?.tc); + return cellArr.map((cell) => { + const tcPr = cell?.["w:tcPr"]?.[0] ?? {}; + const gridSpan = Number(tcPr?.["w:gridSpan"]?.[0]?._attr?.["w:val"] ?? 1); + const vMergeNode = tcPr?.["w:vMerge"]?.[0]; + const vMergeVal = vMergeNode?._attr?.["w:val"] ?? vMergeNode?._attr?.val; + const vMergeRestart = vMergeVal === "restart"; + const vMergeContinue = vMergeNode != null && !vMergeRestart; + return { cell, gridSpan, vMergeRestart, vMergeContinue }; + }); + }); + const rsMap = /* @__PURE__ */ new Map(); + for (let ri = 0; ri < rawGrid.length; ri++) { + let gridCol = 0; + for (let ci = 0; ci < rawGrid[ri].length; ci++) { + const rc = rawGrid[ri][ci]; + if (rc.vMergeRestart) { + let span = 1; + for (let nr = ri + 1; nr < rawGrid.length; nr++) { + let col = 0; + let found = false; + for (const nc of rawGrid[nr]) { + if (col === gridCol && nc.vMergeContinue) { + span++; + found = true; + break; + } + col += nc.gridSpan; + } + if (!found) break; + } + rsMap.set(`${ri},${ci}`, span); + } + gridCol += rc.gridSpan; + } + } + const rowNodes = rawGrid.map((rawRow, ri) => { + const row = rowArr[ri]; + const trPr = row?.["w:trPr"]?.[0] ?? row?.trPr?.[0] ?? {}; + const isHeaderRow = trPr?.["w:tblHeader"]?.[0] != null || trPr?.tblHeader?.[0] != null; + if (ri === 0 && isHeaderRow) gridProps.headerRow = true; + let rowHeightPt; + const trHAttr = trPr?.["w:trHeight"]?.[0]?._attr ?? trPr?.trHeight?.[0]?._attr; + if (trHAttr) { + const hDxa = Number(trHAttr?.["w:val"] ?? trHAttr?.val ?? 0); + if (hDxa> 0) rowHeightPt = Metric.dxaToPt(hDxa); + } + const cellNodes = []; + for (let ci = 0; ci < rawRow.length; ci++) { + const rc = rawRow[ci]; + if (rc.vMergeContinue) continue; + const cell = rc.cell; + const tcPr = cell?.["w:tcPr"]?.[0] ?? {}; + const bgAttr = tcPr?.["w:shd"]?.[0]?._attr ?? {}; + const bg = safeHex(bgAttr?.["w:fill"] ?? bgAttr?.fill); + const tcBordersNode = tcPr?.["w:tcBorders"]?.[0] ?? tcPr?.tcBorders?.[0]; + const cp = { bg, isHeader: isHeaderRow || void 0 }; + if (tcBordersNode) { + const dirs = [ + ["top", "top"], + ["bottom", "bot"], + ["left", "left"], + ["right", "right"] + ]; + for (const [xmlTag, propKey] of dirs) { + const bdr = tcBordersNode?.["w:" + xmlTag]?.[0]?._attr ?? tcBordersNode?.[xmlTag]?.[0]?._attr; + if (!bdr) continue; + const val = bdr?.["w:val"] ?? bdr?.val; + if (val === "none" || val === "nil") { + } else { + cp[propKey] = safeStrokeDocx( + val, + Number(bdr?.["w:sz"] ?? bdr?.sz ?? 4), + bdr?.["w:color"] ?? bdr?.color + ); + } + } + } + const vaAttr = tcPr?.["w:vAlign"]?.[0]?._attr ?? tcPr?.vAlign?.[0]?._attr ?? {}; + const vaVal = vaAttr?.["w:val"] ?? vaAttr?.val; + if (vaVal) { + const vaMap = { + top: "top", + center: "mid", + bottom: "bot" + }; + cp.va = vaMap[vaVal]; + } + const tcMar = tcPr?.["w:tcMar"]?.[0] ?? tcPr?.tcMar?.[0]; + if (tcMar) { + const top = tcMar?.["w:top"]?.[0]?._attr ?? tcMar?.top?.[0]?._attr; + const bot = tcMar?.["w:bottom"]?.[0]?._attr ?? tcMar?.bottom?.[0]?._attr; + const left = tcMar?.["w:left"]?.[0]?._attr ?? tcMar?.left?.[0]?._attr; + const right = tcMar?.["w:right"]?.[0]?._attr ?? tcMar?.right?.[0]?._attr; + if (top) cp.padT = Metric.dxaToPt(Number(top?.["w:w"] ?? top?.w ?? 0)); + if (bot) cp.padB = Metric.dxaToPt(Number(bot?.["w:w"] ?? bot?.w ?? 0)); + if (left) + cp.padL = Metric.dxaToPt(Number(left?.["w:w"] ?? left?.w ?? 0)); + if (right) + cp.padR = Metric.dxaToPt(Number(right?.["w:w"] ?? right?.w ?? 0)); + } + const rs = rsMap.get(`${ri},${ci}`) ?? 1; + let gridColIdx = 0; + for (let prevCi = 0; prevCi < ci; prevCi++) { + if (!rawRow[prevCi].vMergeContinue) + gridColIdx += rawRow[prevCi].gridSpan; + } + const colCount = gridProps.colWidths?.length ?? rawGrid[0]?.reduce((s, c) => s + c.gridSpan, 0) ?? 1; + const resolvedCp = resolveCellBorders( + cp, + ri, + gridColIdx, + rs, + rc.gridSpan, + rawGrid.length, + colCount, + tblBdr + ); + const paras = toArr2(cell?.["w:p"] ?? cell?.p).map( + (p) => decodePara2(p, ctx) + ); + cellNodes.push( + buildCell(paras.length> 0 ? paras : [buildPara([buildSpan("")])], { + cs: rc.gridSpan, + rs, + props: resolvedCp + }) + ); + } + return buildRow(cellNodes, rowHeightPt); + }); + return buildGrid(rowNodes, gridProps); +} +function decodeGridSimple2(tbl) { + const rowArr = toArr2(tbl?.["w:tr"] ?? tbl?.tr); + const rowNodes = rowArr.map((row) => { + const cellArr = toArr2(row?.["w:tc"] ?? row?.tc); + return buildRow( + cellArr.map((c) => buildCell([buildPara([buildSpan(cellText2(c))])])) + ); + }); + return buildGrid(rowNodes); +} +function decodeGridFlat2(tbl) { + return buildGrid([ + buildRow([buildCell([buildPara([buildSpan(tableText2(tbl))])])]) + ]); +} +function decodeGridText2(tbl) { + return buildPara([buildSpan(tableText2(tbl))]); +} +function cellText2(cell) { + return toArr2(cell?.["w:p"] ?? cell?.p).map( + (p) => toArr2(p?.["w:r"] ?? p?.r).map( + (r) => toArr2(r?.["w:t"] ?? r?.t).map((t) => typeof t === "string" ? t : t?._ ?? "").join("") + ).join("") + ).join(" "); +} +function tableText2(tbl) { + return toArr2(tbl?.["w:tr"] ?? tbl?.tr).map( + (row) => toArr2(row?.["w:tc"] ?? row?.tc).map((c) => cellText2(c)).join(" ") + ).join("\n"); +} +function parseHeading(style) { + if (!style) return void 0; + const m = style.match(/[Hh]eading(\d)/); + if (m) { + const n = Number(m[1]); + if (n>= 1 && n <= 6) return n; + } + return void 0; +} +registry.registerDecoder(new DocxDecoder()); +function extractAnchorLayout(anchor) { + const attr = anchor?._attr ?? {}; + const behindDoc = attr.behindDoc === "1"; + let wrap = "square"; + if (anchor?.["wp:wrapNone"]?.[0] != null) + wrap = behindDoc ? "behind" : "none"; + else if (anchor?.["wp:wrapTight"]?.[0] != null) wrap = "tight"; + else if (anchor?.["wp:wrapThrough"]?.[0] != null) wrap = "through"; + else if (anchor?.["wp:wrapSquare"]?.[0] != null) wrap = "square"; + else if (anchor?.["wp:wrapTopAndBottom"]?.[0] != null) wrap = "square"; + else if (anchor?.["wp:wrapBehind"]?.[0] != null || behindDoc) wrap = "behind"; + const posH = anchor?.["wp:positionH"]?.[0]; + const horzRelTo = parseHorzRelTo(posH?._attr?.relativeFrom); + const horzAlignTxt = posH?.["wp:align"]?.[0]?._text; + const horzOffsetTxt = posH?.["wp:posOffset"]?.[0]?._text; + const horzAlign = horzAlignTxt ? parseHorzAlign(horzAlignTxt) : void 0; + const xPt = horzOffsetTxt && !horzAlignTxt ? Metric.emuToPt(Number(horzOffsetTxt)) : void 0; + const posV = anchor?.["wp:positionV"]?.[0]; + const vertRelTo = parseVertRelTo(posV?._attr?.relativeFrom); + const vertAlignTxt = posV?.["wp:align"]?.[0]?._text; + const vertOffsetTxt = posV?.["wp:posOffset"]?.[0]?._text; + const vertAlign = vertAlignTxt ? parseVertAlign(vertAlignTxt) : void 0; + const yPt = vertOffsetTxt && !vertAlignTxt ? Metric.emuToPt(Number(vertOffsetTxt)) : void 0; + const distT = attr.distT ? Metric.emuToPt(Number(attr.distT)) : void 0; + const distB = attr.distB ? Metric.emuToPt(Number(attr.distB)) : void 0; + const distL = attr.distL ? Metric.emuToPt(Number(attr.distL)) : void 0; + const distR = attr.distR ? Metric.emuToPt(Number(attr.distR)) : void 0; + const zOrder = attr.relativeHeight ? Number(attr.relativeHeight) : void 0; + return { + wrap, + horzAlign, + vertAlign, + horzRelTo, + vertRelTo, + xPt, + yPt, + distT, + distB, + distL, + distR, + behindDoc, + zOrder + }; +} +var HORZ_RELTO_MAP = { + margin: "margin", + leftMargin: "margin", + rightMargin: "margin", + insideMargin: "margin", + outsideMargin: "margin", + column: "column", + page: "page", + character: "para", + paragraph: "para" +}; +var VERT_RELTO_MAP = { + margin: "margin", + topMargin: "margin", + bottomMargin: "margin", + insideMargin: "margin", + outsideMargin: "margin", + line: "line", + page: "page", + paragraph: "para" +}; +var HORZ_ALIGN_MAP = { + left: "left", + center: "center", + right: "right", + inside: "left", + outside: "right" +}; +var VERT_ALIGN_MAP = { + top: "top", + center: "center", + bottom: "bottom", + inside: "top", + outside: "bottom" +}; +function parseHorzRelTo(v) { + return HORZ_RELTO_MAP[v ?? ""] ?? "column"; +} +function parseVertRelTo(v) { + return VERT_RELTO_MAP[v ?? ""] ?? "para"; +} +function parseHorzAlign(v) { + return HORZ_ALIGN_MAP[v ?? ""]; +} +function parseVertAlign(v) { + return VERT_ALIGN_MAP[v ?? ""]; +} + +// src/decoders/md/MdDecoder.ts +var MdDecoder = class extends BaseDecoder { + getFormat() { + return "md"; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const text = this.bytesToString(data); + const lines = text.split(/\r?\n/); + const kids = []; + let i = 0; + while (i < lines.length) { + const line = lines[i]; + const headingMatch = line.match(/^(#{1,6})\s+(.+)$/); + if (headingMatch) { + const level = headingMatch[1].length; + kids.push(buildPara([buildSpan(headingMatch[2], { b: level <= 2 })], { heading: level })); + i++; + continue; + } + if (line.includes("|") && i + 1 < lines.length && lines[i + 1].match(/^\s*\|?\s*[-:]+\s*\|/)) { + const tableResult = shield.guard(() => parseMdTable(lines, i), null, `md:table@${i}`); + if (tableResult) { + kids.push(tableResult.node); + i = tableResult.nextLine; + continue; + } + } + if (line.match(/^[-*_]{3,}$/)) { + kids.push(buildPara([buildSpan("")], {})); + i++; + continue; + } + const listMatch = line.match(/^(\s*)([-*+]|\d+\.)\s+(.+)$/); + if (listMatch) { + kids.push(buildPara(parseInline(listMatch[3]), { + listLv: Math.floor(listMatch[1].length / 2), + listOrd: /\d+\./.test(listMatch[2]) + })); + i++; + continue; + } + const bqMatch = line.match(/^>\s*(.*)$/); + if (bqMatch) { + kids.push(buildPara([buildSpan(bqMatch[1])], { indentPt: 28 })); + i++; + continue; + } + if (line.startsWith("```")) { + const codeLines = []; + i++; + while (i < lines.length && !lines[i].startsWith("```")) { + codeLines.push(lines[i]); + i++; + } + i++; + kids.push(buildPara([buildSpan(codeLines.join("\n"), { font: "Courier New" })], {})); + continue; + } + if (line.trim() === "") { + i++; + continue; + } + const alignMatch = line.match(/^(.*?)<\/div>$/i); + if (alignMatch) { + const align = alignMatch[1].toLowerCase(); + kids.push(buildPara(parseInline(alignMatch[2]), { align })); + i++; + continue; + } + kids.push(buildPara(parseInline(line), {})); + i++; + } + warns.push(...shield.flush()); + const sheet = buildSheet(kids.length> 0 ? kids : [buildPara([buildSpan("")])], A4); + return succeed(buildRoot({}, [sheet]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`MD decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function parseInline(text) { + const result = []; + let rem = text; + while (rem.length> 0) { + let m = rem.match(/^(.*?)!\[([^\]]*)\]\((data:([^;]+);base64,([^)]+))\)(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + const mime = m[4]; + const validMimes = ["image/png", "image/jpeg", "image/gif", "image/bmp"]; + result.push(buildImg(m[5], validMimes.includes(mime) ? mime : "image/png", 100, 100, m[2] || void 0)); + rem = m[6]; + continue; + } + m = rem.match(/^(.*?)!\[([^\]]*)\]\(([^)]+)\)(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(`[\uC774\uBBF8\uC9C0: ${m[2] || m[3]}]`)); + rem = m[4]; + continue; + } + m = rem.match(/^(.*?)\*\*\*(.+?)\*\*\*(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { b: true, i: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)\*\*(.+?)\*\*(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { b: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)\*(.+?)\*(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { i: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)~~(.+?)~~(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { s: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)(.+?)<\/u>(.*)/si); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { u: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)(.+?)<\/sup>(.*)/si); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { sup: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)(.+?)<\/sub>(.*)/si); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { sub: true })); + rem = m[3]; + continue; + } + m = rem.match(/^(.*?)`(.+?)`(.*)/s); + if (m) { + if (m[1]) result.push(buildSpan(m[1])); + result.push(buildSpan(m[2], { font: "Courier New" })); + rem = m[3]; + continue; + } + result.push(buildSpan(rem)); + break; + } + return result.length> 0 ? result : [buildSpan(text)]; +} +function parseMdTable(lines, startLine) { + const parse = (line) => line.split("|").map((c) => c.trim()).filter((c, i, arr) => i> 0 || c !== ""); + const headers = parse(lines[startLine]); + let cur = startLine + 2; + const rows = []; + while (cur < lines.length) { + if (!lines[cur].includes("|")) break; + const cells = parse(lines[cur]); + if (cells.length === 0) break; + rows.push(cells); + cur++; + } + const allRows = [headers, ...rows]; + const gridRows = allRows.map( + (row, ri) => buildRow(row.map((cell) => buildCell([buildPara([buildSpan(cell, ri === 0 ? { b: true } : {})])]))) + ); + return { node: buildGrid(gridRows), nextLine: cur }; +} +registry.registerDecoder(new MdDecoder()); + +// src/decoders/html/HtmlDecoder.ts +var HtmlDecoder = class extends BaseDecoder { + getFormat() { + return "html"; + } + async decode(data) { + const shield = new ShieldedParser(); + const warns = []; + try { + const html = this.bytesToString(data); + const tokens = shield.guard(() => tokenize(html), [], "html:tokenize"); + const kids = shield.guard(() => parseTokens(tokens), [], "html:parse"); + warns.push(...shield.flush()); + const sheet = buildSheet(kids.length> 0 ? kids : [buildPara([buildSpan("")])], A4); + return succeed(buildRoot({}, [sheet]), warns); + } catch (e) { + warns.push(...shield.flush()); + return fail(`HTML decode error: ${e?.message ?? String(e)}`, warns); + } + } +}; +function tokenize(html) { + const tokens = []; + let i = 0; + while (i < html.length) { + if (html[i] === "<") { + if (html[i + 1] === "!") { + const end2 = html.indexOf(">", i); + i = end2 + 1; + continue; + } + const isClose = html[i + 1] === "/"; + const start = isClose ? i + 2 : i + 1; + const end = html.indexOf(">", i); + if (end === -1) break; + const tagContent = html.slice(start, end).trim(); + const spaceIdx = tagContent.search(/\s/); + const name = spaceIdx> 0 ? tagContent.slice(0, spaceIdx) : tagContent; + const attrsStr = spaceIdx> 0 ? tagContent.slice(spaceIdx + 1).trim() : ""; + const attrs = {}; + if (attrsStr) { + const attrRegex = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=`]+)))?/g; + let m; + while ((m = attrRegex.exec(attrsStr)) !== null) { + attrs[m[1].toLowerCase()] = m[2] ?? m[3] ?? m[4] ?? ""; + } + } + tokens.push({ + type: "tag", + name: name.toLowerCase(), + attrs, + selfClose: html[end - 1] === "/", + close: isClose + }); + i = end + 1; + } else { + const end = html.indexOf("<", i); + const text = end === -1 ? html.slice(i) : html.slice(i, end); + if (text.trim()) { + tokens.push({ type: "text", content: text }); + } + i = end === -1 ? html.length : end; + } + } + return tokens; +} +function parseTokens(tokens) { + const kids = []; + let i = 0; + while (i < tokens.length) { + const t = tokens[i]; + if (t.type === "tag" && !t.close) { + switch (t.name) { + case "html": + i++; + let bodyStart = -1; + let depth = 1; + while (i < tokens.length && depth> 0) { + if (tokens[i].type === "tag" && !tokens[i].close && tokens[i].name === "html") depth++; + else if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === "html") depth--; + else if (tokens[i].type === "tag" && !tokens[i].close && tokens[i].name === "body") { + bodyStart = i + 1; + } + i++; + } + if (bodyStart> 0) { + let bodyEnd = bodyStart; + let bodyDepth = 1; + while (bodyEnd < tokens.length && bodyDepth> 0) { + if (tokens[bodyEnd].type === "tag" && !tokens[bodyEnd].close && tokens[bodyEnd].name === "body") bodyDepth++; + else if (tokens[bodyEnd].type === "tag" && tokens[bodyEnd].close && tokens[bodyEnd].name === "body") bodyDepth--; + bodyEnd++; + } + bodyEnd--; + const bodyTokens = tokens.slice(bodyStart, bodyEnd); + const bodyKids = parseTokens(bodyTokens); + kids.push(...bodyKids); + } + continue; + case "head": + case "style": + case "script": + i = skipBlock(tokens, i, t.name); + continue; + case "body": + case "div": + case "section": + case "article": + case "main": + const start = i + 1; + let end = start; + let divDepth = 1; + while (end < tokens.length && divDepth> 0) { + const t2 = tokens[end]; + if (t2.type === "tag" && !t2.close) { + if (["html", "head", "body", "div", "section", "article", "main"].includes(t2.name ?? "")) divDepth++; + } else if (t2.type === "tag" && t2.close) { + if (["html", "head", "body", "div", "section", "article", "main"].includes(t2.name ?? "")) divDepth--; + } + end++; + } + end--; + const subTokens = tokens.slice(start, end); + const subKids = parseTokens(subTokens); + kids.push(...subKids); + i = end + 1; + continue; + case "p": + i++; + const paraKids = collectInline(tokens, i, ["p", "div", "br"]); + i = paraKids.nextI; + const align = t.attrs?.style?.includes("text-align: center") ? "center" : t.attrs?.style?.includes("text-align: right") ? "right" : t.attrs?.style?.includes("text-align: left") ? "left" : void 0; + kids.push(buildPara(paraKids.nodes, { align })); + continue; + case "br": + kids.push(buildPara([buildSpan("")], {})); + i++; + continue; + case "img": + i++; + const src = t.attrs?.src; + const alt = t.attrs?.alt || ""; + if (src?.startsWith("data:")) { + const match = src.match(/^data:([^;]+);base64,(.+)$/); + if (match) { + kids.push(buildPara([buildImg(match[2], match[1], 100, 100, alt)], {})); + } + } + continue; + case "table": + i++; + const rows = []; + while (i < tokens.length) { + if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === "table") { + i++; + break; + } + if (tokens[i].type === "tag" && tokens[i].name === "tr" && !tokens[i].close) { + i++; + const cells = []; + while (i < tokens.length) { + if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === "tr") { + i++; + break; + } + if (tokens[i].type === "tag" && (tokens[i].name === "td" || tokens[i].name === "th") && !tokens[i].close) { + i++; + const cellKids = collectInline(tokens, i, ["td", "th", "tr"]); + i = cellKids.nextI; + const isHeader = tokens[i - 2]?.name === "th"; + const paraKids2 = cellKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, b: isHeader } } : n); + cells.push(buildCell([buildPara(paraKids2, {})])); + } else if (tokens[i].type === "text" && tokens[i].content?.trim()) { + cells.push(buildCell([buildPara([buildSpan(tokens[i].content.trim())])])); + i++; + } else { + i++; + } + } + if (cells.length> 0) rows.push(buildRow(cells)); + } else { + i++; + } + } + if (rows.length> 0) kids.push(buildGrid(rows)); + continue; + case "ul": + case "ol": + i++; + const isOrdered = t.name === "ol"; + while (i < tokens.length) { + if (tokens[i].type === "tag" && tokens[i].close && tokens[i].name === t.name) { + i++; + break; + } + if (tokens[i].type === "tag" && tokens[i].name === "li" && !tokens[i].close) { + i++; + const liKids = collectInline(tokens, i, ["li", "ul", "ol"]); + i = liKids.nextI; + kids.push(buildPara(liKids.nodes, { listOrd: isOrdered })); + } else { + i++; + } + } + continue; + default: + i++; + } + } else if (t.type === "text" && t.content?.trim()) { + kids.push(buildPara([buildSpan(t.content.trim())], {})); + i++; + } else { + i++; + } + } + return kids; +} +function collectInline(tokens, start, stopTags) { + const nodes = []; + let i = start; + while (i < tokens.length) { + const t = tokens[i]; + if (t.type === "tag" && !t.close) { + if (t.name && stopTags.includes(t.name)) { + break; + } + switch (t.name) { + case "b": + case "strong": + i++; + const boldKids = collectInline(tokens, i, ["b", "strong", ...stopTags]); + i = boldKids.nextI; + nodes.push(...boldKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, b: true } } : n)); + continue; + case "i": + case "em": + i++; + const italicKids = collectInline(tokens, i, ["i", "em", ...stopTags]); + i = italicKids.nextI; + nodes.push(...italicKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, i: true } } : n)); + continue; + case "u": + i++; + const underlineKids = collectInline(tokens, i, ["u", ...stopTags]); + i = underlineKids.nextI; + nodes.push(...underlineKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, u: true } } : n)); + continue; + case "s": + case "strike": + i++; + const strikeKids = collectInline(tokens, i, ["s", "strike", ...stopTags]); + i = strikeKids.nextI; + nodes.push(...strikeKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, s: true } } : n)); + continue; + case "span": + i++; + const spanKids = collectInline(tokens, i, ["span", ...stopTags]); + i = spanKids.nextI; + const color = t.attrs?.style?.match(/color:\s*([^;]+)/)?.[1]; + nodes.push(...spanKids.nodes.map((n) => n.tag === "span" ? { ...n, props: { ...n.props, color: color || n.props.color } } : n)); + continue; + case "img": + const src = t.attrs?.src; + const alt = t.attrs?.alt || ""; + if (src?.startsWith("data:")) { + const match = src.match(/^data:([^;]+);base64,(.+)$/); + if (match) { + nodes.push(buildImg(match[2], match[1], 100, 100, alt)); + } + } + i++; + continue; + default: + i++; + } + } else if (t.type === "text") { + if (t.content?.trim()) { + nodes.push(buildSpan(t.content.trim())); + } + i++; + } else { + i++; + } + } + return { nodes: nodes.length> 0 ? nodes : [buildSpan("")], nextI: i }; +} +function skipBlock(tokens, start, name) { + let i = start + 1; + let depth = 1; + while (i < tokens.length && depth> 0) { + if (tokens[i].type === "tag") { + if (!tokens[i].close && tokens[i].name === name) depth++; + if (tokens[i].close && tokens[i].name === name) depth--; + } + i++; + } + return i; +} +registry.registerDecoder(new HtmlDecoder()); + +// src/core/BaseEncoder.ts +var BaseEncoder = class { + constructor() { + this.format = this.getFormat(); + this.aliases = this.getAliases(); + } + /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */ + getAliases() { + return []; + } + // ─── 공통 유틸리티 메서드 ─────────────────────────── + /** 문서 내 모든 이미지 노드 수집 */ + collectImages(doc) { + const images = []; + this.collectImagesRecursive(doc, images); + return images; + } + /** 재귀적으로 이미지 수집 */ + collectImagesRecursive(node, images) { + if (node.tag === "img") { + images.push(node); + return; + } + const children = this.getChildren(node); + for (const child of children) { + this.collectImagesRecursive(child, images); + } + } + /** 노드의 자식 노드 반환 */ + getChildren(node) { + switch (node.tag) { + case "root": + return node.kids; + case "sheet": + return [...node.kids, ...node.headers?.default ?? [], ...node.footers?.default ?? []]; + case "para": + return node.kids; + case "span": + return node.kids; + case "link": + return node.kids; + case "row": + return node.kids; + case "cell": + return node.kids; + case "grid": + return node.kids; + default: + return []; + } + } + /** base64 문자열을 Uint8Array 로 변환 */ + base64ToBytes(b64) { + return TextKit.base64Decode(b64); + } + /** Uint8Array 를 base64 문자열로 변환 */ + bytesToBase64(data) { + return TextKit.base64Encode(data); + } + /** XML 이스케이프 */ + escapeXml(s) { + return TextKit.escapeXml(s); + } + /** XML 언이스케이프 */ + unescapeXml(s) { + return TextKit.unescapeXml(s); + } + /** 문자열을 UTF-8 바이트로 변환 */ + stringToBytes(s) { + return TextKit.encode(s); + } + /** 바이트를 UTF-8 문자열로 변환 */ + bytesToString(data) { + return TextKit.decode(data); + } + /** ZIP 압축 */ + async zip(entries) { + return ArchiveKit.zip(entries); + } + /** ZIP 해제 */ + async unzip(data) { + return ArchiveKit.unzip(data); + } + /** deflate 압축 */ + async deflate(data) { + return ArchiveKit.deflate(data); + } + /** inflate 해제 */ + async inflate(data) { + return ArchiveKit.inflate(data); + } + /** 제어 문자 제거 */ + stripControl(s) { + return TextKit.stripControl(s); + } + /** 공백 정규화 */ + normalizeWhitespace(s) { + return TextKit.normalizeWhitespace(s); + } +}; + +// src/encoders/hwpx/HwpxEncoder.ts +var NS = [ + 'xmlns:ha="http://www.hancom.co.kr/hwpml/2011/app"', + 'xmlns:hp="http://www.hancom.co.kr/hwpml/2011/paragraph"', + 'xmlns:hp10="http://www.hancom.co.kr/hwpml/2016/paragraph"', + 'xmlns:hs="http://www.hancom.co.kr/hwpml/2011/section"', + 'xmlns:hc="http://www.hancom.co.kr/hwpml/2011/core"', + 'xmlns:hh="http://www.hancom.co.kr/hwpml/2011/head"', + 'xmlns:hhs="http://www.hancom.co.kr/hwpml/2011/history"', + 'xmlns:hm="http://www.hancom.co.kr/hwpml/2011/master-page"', + 'xmlns:hpf="http://www.hancom.co.kr/schema/2011/hpf"', + 'xmlns:dc="http://purl.org/dc/elements/1.1/"', + 'xmlns:opf="http://www.idpf.org/2007/opf"', + 'xmlns:ooxmlchart="http://www.hancom.co.kr/hwpml/2016/ooxmlchart"', + 'xmlns:epub="http://www.idpf.org/2007/ops"', + 'xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"' +].join(" "); +var LINESEG_FLAGS_FIRST = 1441792; +var LINESEG_FLAGS_OTHER = 393216; +var LANG_GROUPS = [ + "HANGUL", + "LATIN", + "HANJA", + "JAPANESE", + "OTHER", + "SYMBOL", + "USER" +]; +var LangFontBank = class { + constructor() { + // 언어 그룹별 독립 폰트 맵: face → localId (0-based) + this.maps = new Map( + LANG_GROUPS.map((g) => [g, /* @__PURE__ */ new Map()]) + ); + this.registerAll("\uD568\uCD08\uB86C\uBC14\uD0D5"); + } + /** 모든 언어 그룹에 동일 폰트 등록 */ + registerAll(face) { + for (const g of LANG_GROUPS) { + const m = this.maps.get(g); + if (!m.has(face)) m.set(face, m.size); + } + } + /** 특정 언어 그룹에 폰트 등록, 이미 있으면 기존 ID 반환 */ + register(lang, face) { + const m = this.maps.get(lang); + if (m.has(face)) return m.get(face); + const id = m.size; + m.set(face, id); + return id; + } + /** 폰트 이름 → 한글 폰트 여부 판별 (ANYTOHWP 방식) */ + isKorean(face) { + return /[\uAC00-\uD7A3\u3131-\u318E]/.test(face) || ["\uB9D1\uC740", "\uB098\uB214", "\uAD74\uB9BC", "\uB3CB\uC6C0", "\uBC14\uD0D5", "\uD568\uCD08\uB86C", "\uD55C\uCEF4", "HY"].some( + (k) => face.includes(k) + ); + } + /** TextProps.font 문자열에서 적절한 HANGUL/LATIN 그룹에 등록 */ + registerFont(rawFace) { + const face = safeFontToKr(rawFace) || "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const isKor = this.isKorean(face); + const hangulId = this.register("HANGUL", isKor ? face : "\uD568\uCD08\uB86C\uBC14\uD0D5"); + const latinId = this.register("LATIN", isKor ? "\uD568\uCD08\uB86C\uBC14\uD0D5" : face); + for (const g of [ + "HANJA", + "JAPANESE", + "OTHER", + "SYMBOL", + "USER" + ]) { + this.register(g, isKor ? face : "\uD568\uCD08\uB86C\uBC14\uD0D5"); + } + return { hangulId, latinId }; + } + /** 언어 그룹별 폰트 목록 반환 */ + getFaces(lang) { + return [...this.maps.get(lang).keys()]; + } + getId(lang, face) { + return this.maps.get(lang).get(face) ?? 0; + } + /** hh:fontfaces XML 생성 */ + toXml() { + let xml = ``; + for (const lang of LANG_GROUPS) { + const faces = this.getFaces(lang); + xml += ``; + faces.forEach((face, i) => { + xml += ``; + }); + xml += ``; + } + return xml + ``; + } +}; +var KIND_MAP = { + solid: "SOLID", + dash: "DASH", + dot: "DOT", + double: "DOUBLE", + none: "NONE", + dash_dot: "DASH_DOT", + dash_dot_dot: "DASH_DOT_DOT" +}; +var BorderFillBank = class { + constructor() { + this.fills = []; + this.keyMap = /* @__PURE__ */ new Map(); + this._addXml( + this._buildXml(void 0, void 0, void 0, void 0, void 0) + ); + const defS = { kind: "solid", pt: 0.5, color: "000000" }; + this._addXml(this._buildXml(defS, defS, defS, defS, void 0)); + } + _strokeXml(tag, s) { + const type = s && s.kind !== "none" ? KIND_MAP[s.kind] ?? "SOLID" : "NONE"; + const w = s && s.kind !== "none" ? `${(s.pt * 0.3528).toFixed(2)} mm` : "0.12 mm"; + const c = s ? s.color.startsWith("#") ? s.color : `#${s.color}` : "#000000"; + return ``; + } + _buildXml(top, right, bottom, left, bg) { + const fill = bg ? `` : ""; + return `` + this._strokeXml("leftBorder", left) + this._strokeXml("rightBorder", right) + this._strokeXml("topBorder", top) + this._strokeXml("bottomBorder", bottom) + `` + fill + ``; + } + _addXml(xml) { + const id = this.fills.length + 1; + this.fills.push({ id, xml: xml.replace("__ID__", String(id)) }); + return id; + } + _key(top, right, bottom, left, bg) { + const sk = (s) => s ? `${s.kind}:${s.pt.toFixed(2)}:${s.color}` : "none"; + return `${sk(top)}|${sk(right)}|${sk(bottom)}|${sk(left)}|${bg ?? ""}`; + } + /** 균일 테두리 등록 */ + addUniform(s, bg) { + const key = this._key(s, s, s, s, bg); + if (this.keyMap.has(key)) return this.keyMap.get(key); + const id = this._addXml(this._buildXml(s, s, s, s, bg)); + this.keyMap.set(key, id); + return id; + } + /** 방향별 테두리 등록 */ + addPerSide(top, right, bottom, left, bg) { + const key = this._key(top, right, bottom, left, bg); + if (this.keyMap.has(key)) return this.keyMap.get(key); + const id = this._addXml(this._buildXml(top, right, bottom, left, bg)); + this.keyMap.set(key, id); + return id; + } + /** CellProps에서 적절한 borderFill ID 계산 (하드코딩 "1" 완전 제거) */ + addFromCellProps(cp, defStroke) { + const d = defStroke ?? DEFAULT_STROKE; + const top = cp.top ?? d; + const right = cp.right ?? d; + const bottom = cp.bot ?? d; + const left = cp.left ?? d; + const bg = cp.bg; + const uniform = top.kind === right.kind && top.kind === bottom.kind && top.kind === left.kind && top.pt === right.pt && top.pt === bottom.pt && top.pt === left.pt && top.color === right.color && top.color === bottom.color && top.color === left.color; + return uniform ? this.addUniform(top, bg) : this.addPerSide(top, right, bottom, left, bg); + } + toXml() { + return `${this.fills.map((f) => f.xml).join("")}`; + } +}; +function readPixelDims(b64, mime) { + try { + const raw = TextKit.base64Decode(b64); + const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); + if (mime.includes("png")) { + if (raw.length>= 24 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) { + return { w: view.getUint32(16), h: view.getUint32(20) }; + } + } else if (mime.includes("jpeg") || mime.includes("jpg")) { + let off = 2; + while (off < raw.length - 4) { + const marker = view.getUint16(off); + off += 2; + if (marker === 65472 || marker === 65474) { + return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) }; + } + if ((marker & 65280) !== 65280) break; + const segLen = view.getUint16(off); + off += segLen; + } + } + } catch { + } + return null; +} +function charPrKey(p) { + return `${p.b ? 1 : 0}|${p.i ? 1 : 0}|${p.u ? 1 : 0}|${p.s ? 1 : 0}|${p.pt ?? 10}|${p.color ?? "000000"}|${p.font ?? ""}|${p.bg ?? ""}`; +} +function paraPrKey(p) { + return `${p.align ?? "left"}|${p.listOrd ?? ""}|${p.listLv ?? 0}|${p.indentPt ?? 0}|${p.firstLineIndentPt ?? 0}|${p.spaceBefore ?? 0}|${p.spaceAfter ?? 0}|${p.lineHeight ?? 0}|${p.styleId ?? ""}`; +} +function registerCharPr(props, ctx) { + const key = charPrKey(props); + const existing = ctx.charPrMap.get(key); + if (existing !== void 0) return existing; + const rawFont = props.font ?? "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const { hangulId, latinId } = ctx.fontBank.registerFont(rawFont); + const id = ctx.charPrs.length; + ctx.charPrs.push({ + id, + height: Metric.ptToHHeight(props.pt ?? 10), + bold: !!props.b, + italic: !!props.i, + underline: props.u ? "BOTTOM" : "NONE", + strikeout: props.s ? "SOLID" : "NONE", + textColor: props.color ? `#${props.color}` : "#000000", + hangulId, + latinId, + bg: props.bg + }); + ctx.charPrMap.set(key, id); + return id; +} +function registerParaPr(props, ctx) { + const key = paraPrKey(props); + const existing = ctx.paraPrMap.get(key); + if (existing !== void 0) return existing; + const id = ctx.paraPrs.length; + const def = { + id, + align: (props.align ?? "left").toUpperCase(), + leftHwp: Metric.ptToHwp(props.indentPt ?? 0), + rightHwp: Metric.ptToHwp(props.indentRightPt ?? 0), + intentHwp: Metric.ptToHwp(props.firstLineIndentPt ?? 0), + prevHwp: Metric.ptToHwp(props.spaceBefore ?? 0), + nextHwp: Metric.ptToHwp(props.spaceAfter ?? 0), + lineSpacing: props.lineHeight ? Math.round(props.lineHeight * 100) : 160 + }; + if (props.listOrd !== void 0) { + def.listType = props.listOrd ? "DIGIT" : "BULLET"; + def.listLevel = props.listLv ?? 0; + } + ctx.paraPrs.push(def); + ctx.paraPrMap.set(key, id); + return id; +} +function mimeToExt(mime) { + if (mime.includes("jpeg")) return "jpg"; + if (mime.includes("gif")) return "gif"; + if (mime.includes("bmp")) return "bmp"; + return "png"; +} +function registerImage(img, ctx) { + if (ctx.imgMap.has(img)) return; + const ext = mimeToExt(img.mime); + const id = `BIN${String(ctx.nextBinNum).padStart(4, "0")}`; + const name = `${id}.${ext}`; + ctx.nextBinNum++; + const data = TextKit.base64Decode(img.b64); + ctx.bins.push({ id, name, data }); + ctx.imgMap.set(img, id); +} +var STYLE_NAME_MAP = { + Normal: "\uBC14\uD0D5\uAE00", + "Heading 1": "\uAC1C\uC694 1", + "Heading 2": "\uAC1C\uC694 2", + "Heading 3": "\uAC1C\uC694 3", + "Heading 4": "\uAC1C\uC694 4", + "Heading 5": "\uAC1C\uC694 5", + "Heading 6": "\uAC1C\uC694 6", + "Body Text": "\uBCF8\uBB38" +}; +function registerStyle(styleId, paraPrId, charPrId, ctx) { + if (!styleId || ctx.styleIdToHwpxId.has(styleId)) return; + if (styleId === "Normal") { + ctx.styleIdToHwpxId.set(styleId, 0); + return; + } + const hwpxId = ctx.hwpxStyles.length; + ctx.styleIdToHwpxId.set(styleId, hwpxId); + ctx.hwpxStyles.push({ + id: hwpxId, + name: STYLE_NAME_MAP[styleId] ?? styleId, + engName: "", + paraPrIDRef: paraPrId, + charPrIDRef: charPrId + }); +} +function scanPara(para, ctx) { + const paraPrId = registerParaPr(para.props, ctx); + let firstCharPrId = 0; + let hasFirstSpan = false; + function scanKids(kids) { + for (const kid of kids) { + if (kid.tag === "span") { + const cId = registerCharPr(kid.props, ctx); + if (!hasFirstSpan) { + firstCharPrId = cId; + hasFirstSpan = true; + } + } else if (kid.tag === "img") { + registerImage(kid, ctx); + } else if (kid.tag === "link") { + scanKids(kid.kids); + } + } + } + scanKids(para.kids); + if (para.props.styleId) + registerStyle(para.props.styleId, paraPrId, firstCharPrId, ctx); +} +function scanGrid(grid, ctx) { + const defStroke = grid.props.defaultStroke ?? DEFAULT_STROKE; + ctx.borderFillBank.addUniform(defStroke); + for (const row of grid.kids) { + for (const cell of row.kids) { + ctx.borderFillBank.addFromCellProps(cell.props, defStroke); + for (const p of cell.kids) { + if (p.tag === "grid") scanGrid(p, ctx); + else scanPara(p, ctx); + } + } + } +} +function scanContent(kids, ctx) { + for (const kid of kids) { + if (kid.tag === "para") scanPara(kid, ctx); + else if (kid.tag === "grid") scanGrid(kid, ctx); + } +} +var HwpxEncoder = class extends BaseEncoder { + getFormat() { + return "hwpx"; + } + getAliases() { + return [HWPX_MIME_TYPE, "application/hwp+zip"]; + } + async encode(doc) { + try { + const sheet = doc.kids[0]; + const dims = normalizeDims(sheet?.dims ?? A4); + const safeML = dims.ml> 0 ? dims.ml : 70.87; + const safeMR = dims.mr> 0 ? dims.mr : 70.87; + const availableWidth = Math.round( + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(safeML) - Metric.ptToHwp(safeMR) + ); + const ctx = { + fontBank: new LangFontBank(), + // ANYTOHWP 방식 언어별 폰트 + borderFillBank: new BorderFillBank(), + // 하드코딩 없는 테두리 관리 + charPrs: [], + charPrMap: /* @__PURE__ */ new Map(), + paraPrs: [], + paraPrMap: /* @__PURE__ */ new Map(), + bins: [], + nextBinNum: 1, + nextElementId: 1e4, + availableWidth, + imgMap: /* @__PURE__ */ new WeakMap(), + nextZOrder: 0, + styleIdToHwpxId: /* @__PURE__ */ new Map(), + hwpxStyles: [] + }; + registerCharPr({}, ctx); + registerParaPr({}, ctx); + ctx.hwpxStyles.push({ + id: 0, + name: "\uBC14\uD0D5\uAE00", + engName: "Normal", + paraPrIDRef: 0, + charPrIDRef: 0 + }); + ctx.styleIdToHwpxId.set("Normal", 0); + scanContent(sheet?.kids ?? [], ctx); + if (sheet?.headers?.default) for (const p of sheet.headers.default) scanPara(p, ctx); + if (sheet?.footers?.default) for (const p of sheet.footers.default) scanPara(p, ctx); + const sectionData = this.stringToBytes(buildSectionXml(sheet, dims, ctx)); + const headerData = this.stringToBytes(buildHeaderXml(dims, doc.meta, ctx)); + const previewText = extractPreviewText(sheet); + const entries = [ + { + name: "mimetype", + data: new TextEncoder().encode(HWPX_MIME_TYPE), + compression: "STORE", + mime: "" + }, + { + name: "version.xml", + data: this.stringToBytes(VERSION_XML), + mime: "application/xml" + }, + { + name: "META-INF/container.xml", + data: this.stringToBytes(CONTAINER_XML), + mime: "application/xml" + }, + { + name: "META-INF/container.rdf", + data: this.stringToBytes(CONTAINER_RDF), + mime: "application/rdf+xml" + }, + { + name: "Contents/content.hpf", + data: this.stringToBytes(buildContentHpf(ctx, doc.meta)), + mime: "application/hwpml-package+xml" + }, + { + name: "Contents/header.xml", + data: headerData, + mime: "application/xml" + }, + { + name: "Contents/section0.xml", + data: sectionData, + mime: "application/xml" + }, + { + name: "Preview/PrvText.txt", + data: this.stringToBytes(previewText), + mime: "text/plain" + }, + { + name: "settings.xml", + data: this.stringToBytes(buildSettingsXml()), + mime: "application/xml" + } + ]; + for (const bin of ctx.bins) { + const ext = bin.name.split(".").pop()?.toLowerCase() ?? "png"; + const ct = ext === "png" ? "image/png" : ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "gif" ? "image/gif" : "image/bmp"; + entries.push({ name: `BinData/${bin.name}`, data: bin.data, mime: ct }); + } + return succeed(await this.zip(entries)); + } catch (e) { + return fail(`HWPX \uC778\uCF54\uB529 \uC624\uB958: ${e?.message ?? String(e)}`); + } + } +}; +var VERSION_XML = ``; +var CONTAINER_XML = ``; +var CONTAINER_RDF = ``; +function buildContentHpf(ctx, meta) { + const title = esc(meta?.title ?? ""); + const creator = esc(meta?.author ?? "text"); + const subject = esc(meta?.subject ?? "text"); + const desc = esc(meta?.desc ?? "text"); + const keyword = esc(meta?.keywords ?? "text"); + const created = meta?.created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z"); + const modified = meta?.modified ?? created; + let items = ``; + for (const bin of ctx.bins) { + const ext = bin.name.split(".").pop()?.toLowerCase() ?? "png"; + const ct = ext === "png" ? "image/png" : ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "gif" ? "image/gif" : "image/bmp"; + items += ``; + } + return `${title}ko${creator}${subject}${desc}${created}${modified}${keyword}0${items}`; +} +function buildSettingsXml() { + return `falsefalse4000100100`; +} +function buildNumberingsXml() { + return ``; +} +function buildBulletsXml() { + return ``; +} +function buildHeaderXml(dims, meta, ctx) { + const fontFacesXml = ctx.fontBank.toXml(); + let charPrXml = ""; + for (const cp of ctx.charPrs) { + const bold = cp.bold ? "" : ""; + const italic = cp.italic ? "" : ""; + const hid = cp.hangulId; + const lid = cp.latinId; + const shadeColor = cp.bg ? cp.bg.startsWith("#") ? cp.bg : `#${cp.bg}` : "none"; + charPrXml += `` + bold + italic + ``; + } + let paraPrXml = ""; + for (const pp of ctx.paraPrs) { + paraPrXml += ``; + } + const borderFillXml = ctx.borderFillBank.toXml(); + const stylesXml2 = `` + ctx.hwpxStyles.map( + (s) => `` + ).join("") + ``; + return `` + fontFacesXml + borderFillXml + `${charPrXml}` + buildNumberingsXml() + buildBulletsXml() + `${paraPrXml}` + stylesXml2 + ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; +} +function buildHeaderFooterRunXml(sheet, dims, ctx) { + const headers = sheet.headers || {}; + const footers = sheet.footers || {}; + const hasAny = Object.keys(headers).length> 0 || Object.keys(footers).length> 0; + if (!hasAny) return ""; + const availW = ctx.availableWidth; + const mtHwp = Metric.ptToHwp(dims.mt); + const mbHwp = Metric.ptToHwp(dims.mb); + const headerZoneH = dims.headerPt ? Math.max(100, mtHwp - Metric.ptToHwp(dims.headerPt)) : 3600; + const footerZoneH = dims.footerPt ? Math.max(100, mbHwp - Metric.ptToHwp(dims.footerPt)) : 3600; + let inner = ""; + const hideFirst = !!(headers.first || footers.first); + inner += ``; + for (const [type, paras] of Object.entries(headers)) { + const applyPageType = type === "even" ? "EVEN" : type === "default" || type === "first" ? "BOTH" : "ODD"; + const savedId = ctx.nextElementId; + ctx.nextElementId = 0; + const parasXml = paras.map((p) => encodeParaPositioned(p, ctx, 0, "", availW).xml).join(""); + ctx.nextElementId = savedId; + inner += `` + parasXml + ``; + } + for (const [type, paras] of Object.entries(footers)) { + const applyPageType = type === "even" ? "EVEN" : type === "default" || type === "first" ? "BOTH" : "ODD"; + const savedId = ctx.nextElementId; + ctx.nextElementId = 0; + const parasXml = paras.map((p) => encodeParaPositioned(p, ctx, 0, "", availW).xml).join(""); + ctx.nextElementId = savedId; + inner += `` + parasXml + ``; + } + return `${inner}`; +} +function buildSectionXml(sheet, dims, ctx) { + const secPrXml = buildSecPrXml(dims); + const kids = sheet?.kids ?? []; + const hfRunXml = sheet ? buildHeaderFooterRunXml(sheet, dims, ctx) : ""; + const availWidth = Math.max( + 1e3, + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr) + ); + ctx.availableWidth = availWidth; + let contentXml = ""; + let vertPos = 0; + for (let i = 0; i < kids.length; i++) { + const kid = kids[i]; + const isFirst = i === 0; + const curSecPr = isFirst ? secPrXml : ""; + const curHfRun = isFirst ? hfRunXml : ""; + if (kid.tag === "para") { + const { xml, nextVertPos } = encodeParaPositioned( + kid, + ctx, + vertPos, + curSecPr, + availWidth, + curHfRun + ); + contentXml += xml; + vertPos = nextVertPos; + } else if (kid.tag === "grid") { + const { xml, nextVertPos } = encodeGridPositioned( + kid, + ctx, + vertPos, + curSecPr, + curHfRun + ); + contentXml += xml; + vertPos = nextVertPos; + } + } + if (kids.length === 0) { + const fs = 1e3; + const vs = 1600; + const { xml: linesegXml } = buildLinesegarray(" ", 0, fs, vs / (fs / 100), availWidth); + contentXml = `` + secPrXml + hfRunXml + `` + linesegXml + ``; + } + return `${contentXml}`; +} +function buildSecPrXml(dims) { + const wHwp = Metric.ptToHwp(dims.wPt); + const hHwp = Metric.ptToHwp(dims.hPt); + const ml = Metric.ptToHwp(dims.ml); + const mr = Metric.ptToHwp(dims.mr); + const mt = Metric.ptToHwp(dims.mt); + const mb = Metric.ptToHwp(dims.mb); + const headerZone = dims.headerPt ? Math.max(0, mt - Metric.ptToHwp(dims.headerPt)) : 0; + const footerZone = dims.footerPt ? Math.max(0, mb - Metric.ptToHwp(dims.footerPt)) : 0; + const pageBorderFill = ``; + return `` + pageBorderFill + ``; +} +function buildLinesegarray(text, vertPosStart, fontSize, lineSpacingPct, horzSize) { + const vertsizeLine = Math.round(fontSize * lineSpacingPct / 100); + const spacing = vertsizeLine - fontSize; + const baseline = Math.round(fontSize * 0.83); + const isKorean = /[\uAC00-\uD7A3\u3131-\u318E]/.test(text); + const charW = isKorean ? fontSize : Math.round(fontSize * 0.47); + const charsPerLine = Math.max(1, Math.floor(horzSize / charW)); + const lineCount = text.length === 0 ? 1 : Math.ceil(text.length / charsPerLine); + const linesegParts = []; + for (let i = 0; i < lineCount; i++) { + const flags = i === 0 ? LINESEG_FLAGS_FIRST : LINESEG_FLAGS_OTHER; + linesegParts.push( + `` + ); + } + return { + xml: `${linesegParts.join("")}`, + totalHeight: lineCount * vertsizeLine + }; +} +function extractParaText(para) { + let text = ""; + const walk = (kids) => { + for (const k of kids) { + if (k.tag === "span") { + for (const c of k.kids) if (c.tag === "txt") text += c.content; + } else if (k.tag === "link") { + walk(k.kids); + } + } + }; + walk(para.kids); + return text; +} +function fontSizeForPara(para, ctx) { + for (const kid of para.kids) { + if (kid.tag === "span") { + const id = ctx.charPrMap.get(charPrKey(kid.props)); + if (id !== void 0 && ctx.charPrs[id]) return ctx.charPrs[id].height; + } + } + return 1e3; +} +function encodeParaPositioned(para, ctx, vertPos, secPr = "", availWidth, hfRun = "") { + const gridKid = para.kids.find((k) => k.tag === "grid"); + if (gridKid) { + return encodeTablePara(para, gridKid, ctx, vertPos, secPr, hfRun); + } + const paraPrId = ctx.paraPrMap.get(paraPrKey(para.props)) ?? 0; + const styleIDRef = para.props.styleId ? ctx.styleIdToHwpxId.get(para.props.styleId) ?? 0 : 0; + const fontSize = fontSizeForPara(para, ctx); + const paraPr = ctx.paraPrs[paraPrId]; + const lineSpacing = paraPr?.lineSpacing ?? 160; + const spacing = Math.max(0, Math.round(fontSize * (lineSpacing / 100 - 1))); + let vertSize = fontSize + spacing; + const horzSize = availWidth ?? ctx.availableWidth; + const isCourierFont = (kids) => kids.some( + (k) => k.tag === "span" && k.props.font?.toLowerCase().includes("courier") || k.tag === "link" && isCourierFont(k.kids) + ); + const isCode = availWidth === void 0 && (para.props.styleId?.toLowerCase().includes("code") || isCourierFont(para.kids)); + if (isCode) + return encodeCodeBlockPositioned( + para, + ctx, + vertPos, + secPr, + fontSize, + spacing, + vertSize + ); + let runsXml = encodeParaKids(para.kids, ctx); + if (!runsXml) runsXml = ``; + const paraText = extractParaText(para); + const { xml: linesegXml, totalHeight } = buildLinesegarray( + paraText, + vertPos, + fontSize, + lineSpacing, + horzSize + ); + const hasPageBreak = para.kids.some( + (k) => k.tag === "span" && k.kids.some((c) => c.tag === "pb") + ); + const xml = `` + secPr + hfRun + runsXml + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function encodeTablePara(para, grid, ctx, vertPos, secPr, hfRun) { + const paraPrId = ctx.paraPrMap.get(paraPrKey(para.props)) ?? 0; + const { xml: gridXml, height: tblHeight } = buildGridXml(grid, ctx); + const fontSize = 1e3; + const totalHeight = Math.max(1600, tblHeight); + const baseline = 850; + const spacing = Math.max(0, totalHeight - fontSize); + const linesegXml = ``; + const xml = `` + secPr + gridXml + hfRun + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function encodeCodeBlockPositioned(para, ctx, vertPos, secPr, fontSize, spacing, vertSize) { + const codeBfId = ctx.borderFillBank.addUniform( + { kind: "solid", pt: 0.5, color: "aaaaaa" }, + "f4f4f4" + ); + const cellW = ctx.availableWidth; + const innerW = Math.max(cellW - 510, 100); + const subListId = ctx.nextElementId++; + const { xml: innerXml } = encodeParaPositioned(para, ctx, 0, "", innerW); + const paraText = extractParaText(para); + const { xml: linesegXml, totalHeight } = buildLinesegarray( + paraText, + vertPos, + fontSize, + 160, + // 코드 블록 기본 줄간격 160% + ctx.availableWidth + ); + const xml = `` + secPr + `` + innerXml + `` + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function encodeParaKids(kids, ctx) { + let xml = ""; + let currentRunCharPrId = null; + let currentRunContent = ""; + const flushRun = () => { + if (currentRunCharPrId !== null) { + const content = currentRunContent || ``; + xml += `${content}`; + } + currentRunCharPrId = null; + currentRunContent = ""; + }; + for (const kid of kids) { + if (kid.tag === "span") { + const span = kid; + const charPrId = ctx.charPrMap.get(charPrKey(span.props)) ?? 0; + if (currentRunCharPrId !== null && currentRunCharPrId !== charPrId) { + flushRun(); + } + currentRunCharPrId = charPrId; + currentRunContent += encodeRunInner(span); + } else if (kid.tag === "link") { + const link = kid; + let charPrId = 0; + if (link.kids.length> 0 && link.kids[0].tag === "span") { + charPrId = ctx.charPrMap.get(charPrKey(link.kids[0].props)) ?? 0; + } + if (currentRunCharPrId !== null && currentRunCharPrId !== charPrId) { + flushRun(); + } + currentRunCharPrId = charPrId; + currentRunContent += encodeLinkInner(link, ctx); + } else if (kid.tag === "img") { + flushRun(); + xml += encodeImgWrapped(kid, ctx); + } + } + flushRun(); + return xml; +} +function encodeRunInner(span) { + let xml = ""; + for (const kid of span.kids) { + if (kid.tag === "txt") { + const content = esc(kid.content); + if (content) xml += `${content}`; + } else if (kid.tag === "br") { + xml += ` +`; + } else if (kid.tag === "pagenum") { + const fmt = kid.format === "roman" ? "ROMAN_LOWER" : kid.format === "romanCaps" ? "ROMAN_UPPER" : "DIGIT"; + xml += ``; + } + } + return xml; +} +function encodeLinkInner(link, ctx) { + const fieldId = 6e8 + ctx.nextElementId++ % 1e8; + const instanceId = 21e8 + ctx.nextElementId++ % 1e8; + const url = link.href; + let xml = `0${esc(url.replace(/:/g, "\\:"))};1;5;-1;${esc(url)}HWPHYPERLINK_TYPE_URLHWPHYPERLINK_TARGET_HYPERLINKHWPHYPERLINK_JUMP_DONTCARE`; + for (const kid of link.kids) { + if (kid.tag === "span") { + xml += encodeRunInner(kid); + } + } + xml += ``; + return xml; +} +var WRAP_MAP = { + inline: "TOP_AND_BOTTOM", + square: "SQUARE", + tight: "BOTH_SIDES", + through: "BOTH_SIDES", + none: "FRONT_TEXT", + behind: "BEHIND_TEXT", + front: "FRONT_TEXT" +}; +var FLOW_MAP = { + inline: "BOTH_SIDES", + square: "LARGEST_ONLY", + tight: "BOTH_SIDES", + through: "BOTH_SIDES", + none: "BOTH_SIDES", + behind: "BOTH_SIDES", + front: "BOTH_SIDES" +}; +function encodeImage(img, ctx) { + if (!img.b64) { + return `${esc(img.alt || "[\uAC1C\uCCB4]")}`; + } + const binId = ctx.imgMap.get(img); + if (!binId) return ""; + const pixelDims = readPixelDims(img.b64, img.mime); + let wHwp, hHwp; + if (pixelDims && pixelDims.w> 0 && pixelDims.h> 0) { + wHwp = Metric.ptToHwp(pixelDims.w * 72 / 96); + hHwp = Metric.ptToHwp(pixelDims.h * 72 / 96); + } else { + wHwp = Metric.ptToHwp(img.w); + hHwp = Metric.ptToHwp(img.h); + } + if (wHwp> ctx.availableWidth) { + hHwp = Math.round(hHwp * ctx.availableWidth / wHwp); + wHwp = ctx.availableWidth; + } + const rotationCenterX = Math.round(wHwp / 2); + const rotationCenterY = Math.round(hHwp / 2); + const layout = img.layout; + const isInline = !layout || layout.wrap === "inline"; + const textWrap = layout ? WRAP_MAP[layout.wrap] ?? "SQUARE" : "SQUARE"; + const textFlow = layout ? FLOW_MAP[layout.wrap] ?? "BOTH_SIDES" : "BOTH_SIDES"; + const zOrder = ctx.nextZOrder++; + return ``; +} +function encodeImgWrapped(img, ctx) { + const content = encodeImage(img, ctx); + if (!img.b64) { + return `${content}`; + } + return `${content}`; +} +function encodeGridPositioned(grid, ctx, vertPos, secPr = "", hfRun = "") { + const { xml: gridXml, height: tblHeight } = buildGridXml(grid, ctx); + const totalHeight = Math.max(1600, tblHeight); + const fontSize = 1e3; + const baseline = Math.round(fontSize * 0.83); + const spacing = Math.max(0, totalHeight - fontSize); + const linesegXml = ``; + const xml = `` + secPr + hfRun + gridXml + linesegXml + ``; + return { xml, nextVertPos: vertPos + totalHeight }; +} +function buildGridXml(grid, ctx) { + const rowCount = grid.kids.length; + const tableMap = Array.from({ length: rowCount }, () => []); + for (let ri = 0; ri < rowCount; ri++) { + let ci = 0; + for (const cell of grid.kids[ri].kids) { + while (tableMap[ri][ci]) ci++; + tableMap[ri][ci] = { type: "real", cell }; + for (let rr = 0; rr < cell.rs; rr++) { + const tri = ri + rr; + if (tri>= rowCount) break; + for (let cc = 0; cc < cell.cs; cc++) { + if (rr === 0 && cc === 0) continue; + tableMap[tri][ci + cc] = { type: "absorbed" }; + } + } + ci += cell.cs; + } + } + let colCount = 0; + for (let ri = 0; ri < rowCount; ri++) + colCount = Math.max(colCount, tableMap[ri].length); + if (colCount === 0) colCount = 1; + const totalW = ctx.availableWidth; + const colWidths = []; + if (grid.props.colWidths && grid.props.colWidths.length === colCount) { + for (const wPt of grid.props.colWidths) { + colWidths.push(Metric.ptToHwp(wPt)); + } + } else { + const defW = Math.round(totalW / colCount); + for (let c = 0; c < colCount; c++) colWidths.push(defW); + } + const rawTotal = colWidths.reduce((s, w) => s + w, 0); + if (rawTotal> totalW && rawTotal> 0) { + const scale = totalW / rawTotal; + for (let i = 0; i < colWidths.length; i++) { + colWidths[i] = Math.max(100, Math.round(colWidths[i] * scale)); + } + } + const actualTotal = colWidths.reduce((s, w) => s + w, 0); + const rowHeights = []; + for (let ri = 0; ri < rowCount; ri++) { + if (grid.kids[ri].heightPt != null && grid.kids[ri].heightPt> 0) { + rowHeights.push(Metric.ptToHwp(grid.kids[ri].heightPt)); + } else { + let maxH = 0; + for (let ci = 0; ci < colCount; ci++) { + const entry = tableMap[ri][ci]; + if (entry?.type === "real") { + const h = estimateCellHeight(entry.cell, ctx); + if (h> maxH) maxH = h; + } + } + rowHeights.push(maxH || Math.round(1e3 * 1.6)); + } + } + const totalH = rowHeights.reduce((s, h) => s + h, 0); + const defStroke = grid.props.defaultStroke ?? DEFAULT_STROKE; + const tblBfId = ctx.borderFillBank.addUniform(defStroke); + let rowsXml = ""; + for (let ri = 0; ri < rowCount; ri++) { + let cellsXml = ""; + for (let ci = 0; ci < colCount; ci++) { + const entry = tableMap[ri][ci]; + if (!entry || entry.type === "absorbed") continue; + const cell = entry.cell; + const cp = cell.props; + const cellBfId = ctx.borderFillBank.addFromCellProps(cp, defStroke); + let cellW = 0; + for (let sc = ci; sc < ci + cell.cs && sc < colWidths.length; sc++) + cellW += colWidths[sc]; + if (!cellW) cellW = Math.round(totalW / colCount) * cell.cs; + const subListId = ctx.nextElementId++; + const padL = cp.padL !== void 0 ? Metric.ptToHwp(cp.padL) : 141; + const padR = cp.padR !== void 0 ? Metric.ptToHwp(cp.padR) : 141; + const padT = cp.padT !== void 0 ? Metric.ptToHwp(cp.padT) : 141; + const padB = cp.padB !== void 0 ? Metric.ptToHwp(cp.padB) : 141; + const innerW = Math.max(cellW - padL - padR, 100); + let parasXml = ""; + if (cell.kids.length> 0) { + for (const kid of cell.kids) { + if (kid.tag === "grid") { + const { xml: tblXml } = buildGridXml(kid, ctx); + const pid = ctx.nextElementId++; + const rid = ctx.nextElementId++; + parasXml += `${tblXml}`; + } else { + parasXml += encodeParaPositioned(kid, ctx, 0, "", innerW).xml; + } + } + } else { + parasXml = ``; + } + const vAlign = cp.va === "mid" ? "CENTER" : cp.va === "bot" ? "BOTTOM" : "TOP"; + cellsXml += `` + parasXml + ``; + } + rowsXml += `${cellsXml}`; + } + const alignMap = { + left: "LEFT", + right: "RIGHT", + center: "CENTER", + justify: "JUSTIFY" + }; + const horzAlign = alignMap[grid.props.align ?? "left"] ?? "LEFT"; + const headerRow = grid.props.headerRow ? ' repeatHeader="1"' : ""; + const xml = `` + rowsXml + ``; + return { xml, height: totalH }; +} +function estimateCellHeight(cell, ctx) { + const topPad = 141; + const botPad = 141; + let h = 0; + for (const kid of cell.kids) { + if (kid.tag === "grid") { + h += 1600; + continue; + } + const para = kid; + const fs = fontSizeForPara(para, ctx); + const ppId = ctx.paraPrMap.get(paraPrKey(para.props)); + const pp = ppId !== void 0 ? ctx.paraPrs[ppId] : null; + const ls = pp?.lineSpacing ?? 160; + const before = pp?.prevHwp ?? 0; + const after = pp?.nextHwp ?? 0; + h += Math.round(fs * ls / 100) + before + after; + } + if (!h) h = Math.round(1e3 * 1.6); + return h + topPad + botPad; +} +function extractPreviewText(sheet) { + if (!sheet) return ""; + const lines = []; + for (const kid of sheet.kids) { + if (kid.tag === "para") { + const text = kid.kids.flatMap( + (k) => k.tag === "span" ? k.kids.flatMap((c) => c.tag === "txt" ? [c.content] : []) : [] + ).join(""); + if (text) lines.push(text); + } else if (kid.tag === "grid") { + for (const row of kid.kids) { + const cells = row.kids.map( + (cell) => cell.kids.flatMap( + (p) => p.tag === "para" ? p.kids.flatMap( + (k) => k.tag === "span" ? k.kids.flatMap((c) => c.tag === "txt" ? [c.content] : []) : [] + ) : [] + ).join("") + ); + lines.push(cells.join(" ")); + } + } + } + return lines.join("\r\n"); +} +function esc(s) { + if (!s) return ""; + s = s.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + s = s.replace(/湰灧/g, "").replace(/\uFEFF/g, ""); + s = s.replace( + /[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/gu, + "" + ); + return TextKit.escapeXml(s); +} +registry.registerEncoder(new HwpxEncoder()); + +// src/encoders/docx/DocxEncoder.ts +var DocxEncoder = class extends BaseEncoder { + getFormat() { + return "docx"; + } + async encode(doc) { + try { + const sheets = doc.kids.length> 0 ? doc.kids : []; + const firstSheet = sheets[0]; + const dims = normalizeDims(firstSheet?.dims ?? A4); + const allKids = sheets.flatMap((s) => s?.kids ?? []); + const images = []; + const ctx = { + images, + nextId: 10, + nextImgNum: 1, + warns: [], + imgMap: /* @__PURE__ */ new WeakMap() + }; + collectImages(allKids, ctx); + let headerParas = firstSheet?.headers?.default; + let footerParas = firstSheet?.footers?.default; + const hasHeader = headerParas && headerParas.length> 0; + const hasFooter = footerParas && footerParas.length> 0; + if (hasHeader) collectImagesFromParas(headerParas, ctx); + if (hasFooter) collectImagesFromParas(footerParas, ctx); + const headerRId = hasHeader ? `rId${ctx.nextId++}` : ""; + const footerRId = hasFooter ? `rId${ctx.nextId++}` : ""; + const numInfo = collectNumbering(allKids); + const kids = allKids; + const entries = [ + { + name: "[Content_Types].xml", + data: this.stringToBytes(contentTypes(images, hasHeader, hasFooter)) + }, + { name: "_rels/.rels", data: this.stringToBytes(pkgRels()) }, + { + name: "word/document.xml", + data: this.stringToBytes( + documentXml(kids, dims, ctx, headerRId, footerRId) + ) + }, + { name: "word/styles.xml", data: this.stringToBytes(stylesXml()) }, + { name: "word/settings.xml", data: this.stringToBytes(settingsXml()) }, + { + name: "word/_rels/document.xml.rels", + data: this.stringToBytes( + docRels(images, headerRId, footerRId, numInfo.hasLists) + ) + }, + { name: "docProps/app.xml", data: this.stringToBytes(appXml()) }, + { + name: "docProps/core.xml", + data: this.stringToBytes(coreXml(doc.meta)) + } + ]; + if (numInfo.hasLists) { + entries.push({ + name: "word/numbering.xml", + data: this.stringToBytes(numberingXml(numInfo)) + }); + } + if (hasHeader) { + entries.push({ + name: "word/header1.xml", + data: this.stringToBytes(headerFooterXml("hdr", headerParas, ctx)) + }); + } + if (hasFooter) { + entries.push({ + name: "word/footer1.xml", + data: this.stringToBytes(headerFooterXml("ftr", footerParas, ctx)) + }); + } + for (const img of images) { + entries.push({ name: `word/media/${img.name}`, data: img.data }); + } + return succeed(await this.zip(entries)); + } catch (e) { + return fail(`DOCX encode error: ${e?.message ?? String(e)}`); + } + } +}; +function mimeToExt2(mime) { + if (mime.includes("jpeg")) return "jpeg"; + if (mime.includes("gif")) return "gif"; + if (mime.includes("bmp")) return "bmp"; + return "png"; +} +function collectImages(kids, ctx) { + for (const kid of kids) { + if (kid.tag === "para") collectImagesFromPara(kid, ctx); + else if (kid.tag === "grid") { + for (const row of kid.kids) + for (const cell of row.kids) + for (const p of cell.kids) + if (p.tag === "para") collectImagesFromPara(p, ctx); + else collectImages([p], ctx); + } + } +} +function collectImagesFromParas(paras, ctx) { + for (const p of paras) collectImagesFromPara(p, ctx); +} +function collectImagesFromPara(para, ctx) { + for (const kid of para.kids) { + if (kid.tag === "img") registerImage2(kid, ctx); + } +} +function registerImage2(img, ctx) { + if (ctx.imgMap.has(img)) return; + const ext = mimeToExt2(img.mime); + const name = `image${ctx.nextImgNum++}.${ext}`; + const rId = `rId${ctx.nextId++}`; + const data = TextKit.base64Decode(img.b64); + ctx.images.push({ rId, name, data, ext }); + ctx.imgMap.set(img, rId); +} +function collectNumbering(kids) { + let hasBullet = false; + let hasNumbered = false; + for (const kid of kids) { + if (kid.tag === "para") { + if (kid.props.listOrd === true) hasNumbered = true; + else if (kid.props.listOrd === false) hasBullet = true; + } + } + return { hasLists: hasBullet || hasNumbered, hasBullet, hasNumbered }; +} +function contentTypes(images, hasHeader, hasFooter) { + const imgDefaults = /* @__PURE__ */ new Set(); + for (const img of images) imgDefaults.add(img.ext); + let defaults = ` + `; + for (const ext of imgDefaults) { + const ct = ext === "png" ? "image/png" : ext === "jpeg" ? "image/jpeg" : ext === "gif" ? "image/gif" : "image/bmp"; + defaults += ` + `; + } + let overrides = ` + + + + `; + if (hasHeader) + overrides += ` + `; + if (hasFooter) + overrides += ` + `; + return ` + + ${defaults} + ${overrides} +`; +} +function pkgRels() { + return ` + + + + +`; +} +function docRels(images, headerRId, footerRId, hasLists) { + let rels = ` + `; + if (hasLists) { + rels += ` + `; + } + for (const img of images) { + rels += ` + `; + } + if (headerRId) { + rels += ` + `; + } + if (footerRId) { + rels += ` + `; + } + return ` + + ${rels} +`; +} +function appXml() { + return ` + + hwpkit +`; +} +function coreXml(meta) { + const now = (/* @__PURE__ */ new Date()).toISOString(); + return ` + + ${esc2(meta.title ?? "")} + ${esc2(meta.author ?? "")} + ${meta.created ?? now} + ${now} +`; +} +function stylesXml() { + return ` + + + + + + + + + + + + + + + + + + + + +`; +} +function settingsXml() { + return ` + + + + + + + + + + + + + + +`; +} +function numberingXml(info) { + let abstractNums = ""; + let nums = ""; + if (info.hasBullet) { + abstractNums += ``; + for (let lvl = 0; lvl < 9; lvl++) { + const marker = lvl === 0 ? "\u25CF" : lvl === 1 ? "\u25CB" : "\u25A0"; + const indent = (lvl + 1) * 720; + abstractNums += ``; + } + abstractNums += ``; + nums += ``; + } + if (info.hasNumbered) { + abstractNums += ``; + for (let lvl = 0; lvl < 9; lvl++) { + const fmt = lvl % 3 === 0 ? "decimal" : lvl % 3 === 1 ? "lowerLetter" : "lowerRoman"; + const indent = (lvl + 1) * 720; + abstractNums += ``; + } + abstractNums += ``; + nums += ``; + } + return ` + + ${abstractNums} + ${nums} +`; +} +function headerFooterXml(type, paras, ctx) { + const tag = type === "hdr" ? "w:hdr" : "w:ftr"; + const body = paras.map((p) => encodeParaInner(p, ctx)).join("\n"); + return ` +<${tag} xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"> +${body} +`; +} +function documentXml(kids, dims, ctx, headerRId, footerRId) { + const body = kids.map((k) => encodeContent(k, ctx, dims)).join("\n"); + let sectRefs = ""; + if (headerRId) + sectRefs += ` + `; + if (footerRId) + sectRefs += ` + `; + return ` + + +${body} + ${sectRefs} + + + + +`; +} +function encodeContent(node, ctx, dims) { + return node.tag === "grid" ? encodeGrid(node, ctx, dims) : encodeParaInner(node, ctx); +} +function encodeParaInner(para, ctx) { + const align = para.props.align ?? "left"; + const headStyle = para.props.heading ? `` : ""; + let numPr = ""; + if (para.props.listOrd !== void 0) { + const numId = para.props.listOrd ? 2 : 1; + const ilvl = para.props.listLv ?? 0; + numPr = ``; + } + let spacingXml = ""; + const { spaceBefore, spaceAfter, lineHeight, lineHeightFixed } = para.props; + if (spaceBefore !== void 0 || spaceAfter !== void 0 || lineHeight !== void 0 || lineHeightFixed !== void 0) { + const parts = []; + if (spaceBefore !== void 0) + parts.push(`w:before="${Math.max(0, Metric.ptToDxa(spaceBefore))}"`); + if (spaceAfter !== void 0) + parts.push(`w:after="${Math.max(0, Metric.ptToDxa(spaceAfter))}"`); + if (lineHeightFixed !== void 0) { + parts.push( + `w:line="${Math.max(1, Metric.ptToDxa(lineHeightFixed))}" w:lineRule="exact"` + ); + } else if (lineHeight !== void 0) { + parts.push(`w:line="${Math.round(lineHeight * 240)}" w:lineRule="auto"`); + } + spacingXml = ``; + } + let indentXml = ""; + const leftDxa = Math.round(Metric.ptToDxa(para.props.indentPt ?? 0)); + const rightDxa = Math.round(Metric.ptToDxa(para.props.indentRightPt ?? 0)); + const firstPt = para.props.firstLineIndentPt ?? 0; + const indParts = []; + if (leftDxa> 0) indParts.push(`w:left="${leftDxa}"`); + if (rightDxa> 0) indParts.push(`w:right="${rightDxa}"`); + if (firstPt> 0) + indParts.push(`w:firstLine="${Math.round(Metric.ptToDxa(firstPt))}"`); + if (firstPt < 0) + indParts.push(`w:hanging="${Math.round(Metric.ptToDxa(-firstPt))}"`); + if (indParts.length> 0) indentXml = ``; + const runs = para.kids.map((k) => { + if (k.tag === "span") return encodeRun(k, ctx); + if (k.tag === "img") return encodeImage2(k, ctx); + return ""; + }).join(""); + return ` + ${headStyle}${numPr}${spacingXml}${indentXml} + ${runs} + `; +} +function encodeRun(span, _ctx) { + const p = span.props; + const rPr = []; + if (p.b) rPr.push(""); + if (p.i) rPr.push(""); + if (p.u) rPr.push(''); + if (p.s) rPr.push(""); + if (p.sup) rPr.push(''); + if (p.sub) rPr.push(''); + if (p.pt) + rPr.push( + `` + ); + if (p.color) rPr.push(``); + if (p.font) + rPr.push( + `` + ); + if (p.bg) rPr.push(``); + const parts = []; + for (const kid of span.kids) { + if (kid.tag === "txt") { + const content = kid.content.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + if (content) { + parts.push( + `${rPr.join("")}${esc2(content)}` + ); + } + } else if (kid.tag === "pagenum") { + parts.push( + `${rPr.join("")}${rPr.join("")} PAGE ${rPr.join("")}${rPr.join("")}1${rPr.join("")}` + ); + } else if (kid.tag === "br") { + parts.push(``); + } else if (kid.tag === "pb") { + parts.push(``); + } + } + return parts.join(""); +} +function encodeImage2(img, ctx) { + const rId = ctx.imgMap.get(img); + if (!rId) return ""; + const cx = Metric.ptToEmu(img.w> 0 ? img.w : 72); + const cy = Metric.ptToEmu(img.h> 0 ? img.h : 72); + const alt = esc2(img.alt ?? ""); + const docPrId = ctx.nextId++; + const graphic = ``; + const layout = img.layout; + const isInline = !layout || layout.wrap === "inline"; + const forceAnchor = layout?.wrap === "topAndBottom" || layout?.wrap === "square" || layout?.wrap === "tight" || layout?.wrap === "behind" || layout?.wrap === "front"; + if (isInline && !forceAnchor) { + return `${graphic}`; + } + return `${encodeAnchor(img, cx, cy, alt, docPrId, graphic, layout)}`; +} +function encodeAnchor(_img, cx, cy, alt, docPrId, graphic, layout) { + const distT = Metric.ptToEmu(layout.distT ?? 0); + const distB = Metric.ptToEmu(layout.distB ?? 0); + const distL = Metric.ptToEmu(layout.distL ?? 9144); + const distR = Metric.ptToEmu(layout.distR ?? 9144); + const behindDoc = layout.behindDoc || layout.wrap === "behind" ? "1" : "0"; + const relH = layout.zOrder ?? 251658240; + const horzRelFrom = HORZ_RELTO_DOCX[layout.horzRelTo ?? "column"] ?? "column"; + let posH; + if (layout.xPt != null) { + posH = `${Metric.ptToEmu(layout.xPt)}`; + } else { + const ha = HORZ_ALIGN_DOCX[layout.horzAlign ?? "left"] ?? "left"; + posH = `${ha}`; + } + const vertRelFrom = VERT_RELTO_DOCX[layout.vertRelTo ?? "para"] ?? "paragraph"; + let posV; + if (layout.yPt != null) { + posV = `${Metric.ptToEmu(layout.yPt)}`; + } else { + const va = VERT_ALIGN_DOCX[layout.vertAlign ?? "top"] ?? "top"; + posV = `${va}`; + } + const wrapXml = WRAP_DOCX[layout.wrap] ?? ''; + return `${posH}${posV}${wrapXml}${graphic}`; +} +var HORZ_RELTO_DOCX = { + margin: "margin", + column: "column", + page: "page", + para: "paragraph" +}; +var VERT_RELTO_DOCX = { + margin: "margin", + line: "line", + page: "page", + para: "paragraph" +}; +var HORZ_ALIGN_DOCX = { + left: "left", + center: "center", + right: "right" +}; +var VERT_ALIGN_DOCX = { + top: "top", + center: "center", + bottom: "bottom" +}; +var WRAP_DOCX = { + square: '', + tight: '', + through: '', + // ECMA-376 §20.4.2.15: wrapTopAndBottom — 텍스트가 이미지 위아래로만 흐름 + topAndBottom: "", + none: "", + behind: "", + front: "" +}; +function encodeGrid(grid, ctx, dims = A4) { + const gp = grid.props; + const look = gp.look; + const firstRow = look?.firstRow ? "1" : "0"; + const lastRow = look?.lastRow ? "1" : "0"; + const firstCol = look?.firstCol ? "1" : "0"; + const lastCol = look?.lastCol ? "1" : "0"; + const noHBand = look?.bandedRows ? "0" : "1"; + const noVBand = look?.bandedCols ? "0" : "1"; + const d = dims ?? A4; + const availDxa = Metric.ptToDxa(d.wPt - d.ml - d.mr); + const tableMap = Array.from( + { length: grid.kids.length }, + () => [] + ); + for (let ri = 0; ri < grid.kids.length; ri++) { + let c = 0; + for (const cell of grid.kids[ri].kids) { + while (tableMap[ri][c]) c++; + tableMap[ri][c] = { type: "real", cell, width: cell.cs }; + for (let rr = 0; rr < cell.rs; rr++) { + const targetRi = ri + rr; + if (targetRi>= grid.kids.length) break; + if (!tableMap[targetRi]) tableMap[targetRi] = []; + for (let cc = 0; cc < cell.cs; cc++) { + if (rr === 0 && cc === 0) continue; + if (rr> 0 && cc === 0) { + tableMap[targetRi][c + cc] = { type: "continue", width: cell.cs }; + } else { + tableMap[targetRi][c + cc] = { type: "absorbed" }; + } + } + } + c += cell.cs; + } + } + let colCount = 0; + for (let ri = 0; ri < grid.kids.length; ri++) { + colCount = Math.max(colCount, tableMap[ri].length); + } + if (colCount === 0) colCount = 1; + for (let ri = 0; ri < grid.kids.length; ri++) { + for (let c = 0; c < colCount; c++) { + if (!tableMap[ri][c]) tableMap[ri][c] = { type: "void" }; + } + } + const defaultColDxa = Math.round(availDxa / colCount); + let colWidthsDxa = []; + if (grid.props.colWidths && grid.props.colWidths.length> 0) { + const srcPt = [...grid.props.colWidths]; + while (srcPt.length < colCount) srcPt.push(0); + srcPt.length = colCount; + const knownTotalPt = srcPt.filter((w) => w> 0).reduce((s, w) => s + w, 0); + const zeroCount = srcPt.filter((w) => w <= 0).length; + const availPt = Metric.dxaToPt(availDxa); + const remainingPt = Math.max(0, availPt - knownTotalPt); + const zeroFillPt = zeroCount> 0 ? remainingPt / zeroCount : 0; + for (let i = 0; i < srcPt.length; i++) { + if (srcPt[i] <= 0) { + srcPt[i] = zeroFillPt> 0 ? zeroFillPt : availPt / colCount; + } + } + colWidthsDxa = srcPt.map((w) => Math.round(Metric.ptToDxa(w))); + const computedTotalDxa = colWidthsDxa.reduce((s, w) => s + w, 0); + if (computedTotalDxa> availDxa) { + const scale = availDxa / computedTotalDxa; + colWidthsDxa = colWidthsDxa.map((w) => Math.round(w * scale)); + } + } else { + for (let c = 0; c < colCount; c++) colWidthsDxa.push(defaultColDxa); + } + const totalDxa = colWidthsDxa.reduce((s, w) => s + w, 0); + const gridCols = colWidthsDxa.map((w) => ``).join(""); + const rows = tableMap.map((rowMap, ri) => { + const cellXmls = []; + for (let c = 0; c < colCount; c++) { + const mapEntry = rowMap[c]; + if (mapEntry.type === "absorbed") continue; + const isContinue = mapEntry.type === "continue"; + const isReal = mapEntry.type === "real"; + const isVoid = mapEntry.type === "void"; + if (isContinue || isReal || isVoid) { + let cw = 0; + const cellWidth = mapEntry.width || 1; + const safeColWidths = colWidthsDxa.length>= colCount ? colWidthsDxa : [ + ...colWidthsDxa, + ...Array(colCount - colWidthsDxa.length).fill(defaultColDxa) + ]; + for (let sc = c; sc < c + cellWidth && sc < safeColWidths.length; sc++) { + cw += safeColWidths[sc]; + } + if (cw <= 0) cw = defaultColDxa * cellWidth; + const tcPrParts = []; + tcPrParts.push(``); + if (cellWidth> 1) { + tcPrParts.push(``); + } + if (isContinue) { + tcPrParts.push(``); + } + let cellContent = ""; + if (isReal) { + const cell = mapEntry.cell; + const cp = cell.props; + if (cell.rs> 1) tcPrParts.push(``); + const borders = encodeCellBorders(cp); + if (borders) tcPrParts.push(borders); + if (cp.bg) + tcPrParts.push( + `` + ); + if (cp.va) { + const vaMap = { + top: "top", + mid: "center", + bot: "bottom" + }; + tcPrParts.push(``); + } + const cPadT = cp.padT != null ? Math.round(Metric.ptToDxa(cp.padT)) : null; + const cPadB = cp.padB != null ? Math.round(Metric.ptToDxa(cp.padB)) : null; + const cPadL = cp.padL != null ? Math.round(Metric.ptToDxa(cp.padL)) : null; + const cPadR = cp.padR != null ? Math.round(Metric.ptToDxa(cp.padR)) : null; + if (cPadT != null || cPadB != null || cPadL != null || cPadR != null) { + const t = cPadT ?? 28; + const b = cPadB ?? 28; + const l = cPadL ?? 72; + const r = cPadR ?? 72; + tcPrParts.push( + `` + ); + } + const parts = []; + for (const kid of cell.kids) { + if (kid.tag === "grid") { + parts.push(encodeGrid(kid, ctx)); + } else if (kid.tag === "para") { + parts.push(encodeParaInner(kid, ctx)); + } + } + const lastKid = cell.kids[cell.kids.length - 1]; + if (cell.kids.length === 0 || lastKid?.tag === "grid") { + parts.push(''); + } + cellContent = parts.join(""); + } else { + cellContent = ``; + } + const tcPr = `${tcPrParts.join("")}`; + cellXmls.push(` ${tcPr}${cellContent}`); + } + } + const trPrParts = []; + if (ri === 0 && (gp.headerRow || look?.firstRow)) { + trPrParts.push(""); + } + const originalRow = grid.kids[ri]; + if (originalRow?.heightPt != null && originalRow.heightPt> 0) { + const hDxa = Math.round(Metric.ptToDxa(originalRow.heightPt)); + trPrParts.push(``); + } + const trPr = trPrParts.length> 0 ? `${trPrParts.join("")}` : ""; + return ` ${trPr} +${cellXmls.join("\n")} + `; + }).join("\n"); + let tblBorders = ""; + const strokeKindMap = { + solid: "single", + dash: "dash", + dot: "dot", + double: "double", + none: "none", + dotDash: "dotDash", + dotDotDash: "dotDotDash", + triple: "triple", + thinThickSmallGap: "thinThickSmallGap", + thickThinSmallGap: "thickThinSmallGap", + thinThickThinSmallGap: "thinThickThinSmallGap" + }; + if (gp.defaultStroke) { + const s = gp.defaultStroke; + const val = strokeKindMap[s.kind] ?? "single"; + if (val === "none" || s.pt <= 0) { + tblBorders = ''; + } else { + const sz = Math.max(2, Math.round(s.pt * 8)); + const clr = s.color ? s.color.replace("#", "") : "auto"; + const bdr = `w:val="${val}" w:sz="${sz}" w:space="0" w:color="${clr}"`; + tblBorders = ``; + } + } + const tblAlignMap = { + left: "start", + center: "center", + right: "end", + justify: "start" + }; + const tblJc = gp.align ? `` : ""; + return ` + ${tblBorders}${tblJc} + ${gridCols} +${rows} + `; +} +function encodeCellBorders(cp) { + if (!cp.top && !cp.bot && !cp.left && !cp.right) return ""; + const strokeKindMap = { + solid: "single", + dash: "dash", + dot: "dot", + double: "double", + none: "none", + dotDash: "dotDash", + dotDotDash: "dotDotDash", + triple: "triple" + }; + const encode = (s, tag) => { + if (!s || !tag) return ""; + const val = strokeKindMap[s.kind] ?? "single"; + if (val === "none" || s.pt <= 0) { + return ``; + } + const sz = Math.max(2, Math.round(s.pt * 8)); + const clr = s.color ? s.color.replace("#", "") : "auto"; + return ``; + }; + return `${encode(cp.top, "top")}${encode(cp.bot, "bottom")}${encode(cp.left, "left")}${encode(cp.right, "right")}`; +} +function esc2(s) { + if (!s) return ""; + s = s.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + s = s.replace(/湰灧/g, ""); + s = s.replace(/\uFEFF/g, ""); + s = s.replace(/[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD]/g, ""); + return TextKit.escapeXml(s); +} +registry.registerEncoder(new DocxEncoder()); + +// src/encoders/md/MdEncoder.ts +var MdEncoder = class extends BaseEncoder { + getFormat() { + return "md"; + } + async encode(doc, options) { + const includeImages = options?.includeImages !== false; + try { + const warns = []; + const parts = []; + for (const sheet of doc.kids) { + if (sheet.headers && sheet.headers.default && sheet.headers.default.length> 0) warns.push("[SHIELD] MD: \uBA38\uB9AC\uAE00(header) \uD45C\uD604 \uBD88\uAC00 \u2014 \uC190\uC2E4\uB428"); + if (sheet.footers && sheet.footers.default && sheet.footers.default.length> 0) warns.push("[SHIELD] MD: \uBC14\uB2E5\uAE00(footer) \uD45C\uD604 \uBD88\uAC00 \u2014 \uC190\uC2E4\uB428"); + for (const kid of sheet.kids) parts.push(encodeContent2(kid, warns, includeImages)); + } + return succeed(this.stringToBytes(parts.join("\n\n")), warns); + } catch (e) { + return fail(`MD encode error: ${e?.message ?? String(e)}`); + } + } +}; +function encodeContent2(node, warns, includeImages) { + return node.tag === "grid" ? encodeGrid2(node, warns, includeImages) : encodePara(node, warns, includeImages); +} +function encodePara(para, warns, includeImages) { + const text = para.kids.map((k) => { + if (k.tag === "span") return encodeSpan(k, warns); + if (k.tag === "img") return encodeImage3(k, includeImages); + return ""; + }).join(""); + if (para.props.heading) return `${"#".repeat(para.props.heading)} ${text}`; + if (para.props.listOrd !== void 0) { + const indent = " ".repeat(para.props.listLv ?? 0); + return `${indent}${para.props.listOrd ? "1." : "-"} ${text}`; + } + if (para.props.align && para.props.align !== "left" && para.props.align !== "justify") { + return `
            ${text}
            `; + } + return text; +} +function encodeSpan(span, warns) { + let hasPageNum = false; + const textParts = []; + for (const kid of span.kids) { + if (kid.tag === "txt") textParts.push(kid.content); + else if (kid.tag === "pagenum") { + hasPageNum = true; + warns.push("[SHIELD] MD: \uD398\uC774\uC9C0 \uBC88\uD638 \uD45C\uD604 \uBD88\uAC00 \u2014 \uC190\uC2E4\uB428"); + } + } + let r = textParts.join(""); + if (hasPageNum && r === "") r = "[\uD398\uC774\uC9C0 \uBC88\uD638]"; + const cssStyles = []; + if (span.props.font) cssStyles.push(`font-family: ${span.props.font}`); + if (span.props.pt) cssStyles.push(`font-size: ${span.props.pt}pt`); + if (span.props.color) cssStyles.push(`color: #${span.props.color}`); + if (span.props.bg) cssStyles.push(`background-color: #${span.props.bg}`); + const hasHtmlStyle = cssStyles.length> 0; + if (hasHtmlStyle) { + if (span.props.b) cssStyles.push("font-weight: bold"); + if (span.props.i) cssStyles.push("font-style: italic"); + if (span.props.s) cssStyles.push("text-decoration: line-through"); + if (span.props.u) { + const existing = cssStyles.find((s) => s.startsWith("text-decoration:")); + if (existing) { + const idx = cssStyles.indexOf(existing); + cssStyles[idx] = existing.replace("line-through", "underline line-through"); + if (!existing.includes("line-through")) cssStyles[idx] = existing + " underline"; + } else { + cssStyles.push("text-decoration: underline"); + } + } + const styleAttr = cssStyles.join("; "); + if (span.props.sup) return `${r}`; + if (span.props.sub) return `${r}`; + return `${r}`; + } + if (span.props.b && span.props.i) r = `***${r}***`; + else if (span.props.b) r = `**${r}**`; + else if (span.props.i) r = `*${r}*`; + if (span.props.s) r = `~~${r}~~`; + if (span.props.u) r = `${r}`; + if (span.props.sup) r = `${r}`; + if (span.props.sub) r = `${r}`; + return r; +} +function encodeImage3(img, includeImages) { + if (!includeImages) { + return `![${img.alt ?? ""}]`; + } + return `![${img.alt ?? ""}](data:${img.mime};base64,${img.b64})`; +} +function strokeToCss(s) { + if (!s || s.kind === "none" || s.pt <= 0) return void 0; + const kindMap = { solid: "solid", dash: "dashed", dot: "dotted", double: "double", none: "none" }; + const style = kindMap[s.kind] ?? "solid"; + const px = Math.max(1, Math.round(s.pt * 96 / 72)); + const color = s.color.startsWith("#") ? s.color : `#${s.color}`; + return `${px}px ${style} ${color}`; +} +function encodeGrid2(grid, warns, includeImages) { + if (grid.kids.length === 0) return ""; + const rowCount = grid.kids.length; + const occupancy = Array.from({ length: rowCount }, () => /* @__PURE__ */ new Set()); + let colCount = 0; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let ci = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(ci)) ci++; + if (cell.rs> 1) { + for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) { + for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c); + } + } + ci += cell.cs; + } + while (occupancy[ri].has(ci)) ci++; + if (ci> colCount) colCount = ci; + } + let rows = ""; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let cells = ""; + let colIdx = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(colIdx)) colIdx++; + const cs = cell.cs> 1 ? ` colspan="${cell.cs}"` : ""; + const rs = cell.rs> 1 ? ` rowspan="${cell.rs}"` : ""; + const styles = ["padding:4px 6px", "vertical-align:top"]; + const top = strokeToCss(cell.props.top); + const bot = strokeToCss(cell.props.bot); + const left = strokeToCss(cell.props.left); + const right = strokeToCss(cell.props.right); + if (top) styles.push(`border-top:${top}`); + if (bot) styles.push(`border-bottom:${bot}`); + if (left) styles.push(`border-left:${left}`); + if (right) styles.push(`border-right:${right}`); + if (cell.props.bg) styles.push(`background-color:#${cell.props.bg}`); + if (cell.props.va === "mid") styles[1] = "vertical-align:middle"; + else if (cell.props.va === "bot") styles[1] = "vertical-align:bottom"; + const tag = grid.props.headerRow && ri === 0 || cell.props.isHeader ? "th" : "td"; + const content = cell.kids.map((p) => p.tag === "para" ? encodePara(p, warns, includeImages) : encodeGrid2(p, warns, includeImages)).join("\n"); + cells += `<${tag}${cs}${rs} ;")}">${content}`; + colIdx += cell.cs; + } + rows += `
            ${cells}
            +`; + } + return ` + +${rows} + +`; +} +registry.registerEncoder(new MdEncoder()); + +// src/encoders/html/HtmlEncoder.ts +var HtmlEncoder = class extends BaseEncoder { + getFormat() { + return "html"; + } + async encode(doc) { + try { + const warns = []; + const bodyParts = []; + for (const sheet of doc.kids) { + if (sheet.headers?.default && sheet.headers.default.length> 0) { + const hText = sheet.headers.default.map((p) => encodePara2(p, warns)).join(""); + bodyParts.push(`
            ${hText}
            `); + } + for (const kid of sheet.kids) { + bodyParts.push(encodeContent3(kid, warns)); + } + if (sheet.footers?.default && sheet.footers.default.length> 0) { + const fText = sheet.footers.default.map((p) => encodePara2(p, warns)).join(""); + bodyParts.push(`
            ${fText}
            `); + } + } + const title = this.escapeXml(doc.meta?.title ?? ""); + const html = ` + + + + +${title} + + + +
            +${bodyParts.join("\n")} +
            + +`; + return succeed(this.stringToBytes(html), warns); + } catch (e) { + return fail(`HTML encode error: ${e?.message ?? String(e)}`); + } + } +}; +var BASE_CSS = ` +body { margin: 0; padding: 0; background: #f0f0f0; } +.hwp-doc { max-width: 800px; margin: 0 auto; background: #fff; padding: 40px 60px; box-shadow: 0 0 8px rgba(0,0,0,0.15); } +.hwp-header, .hwp-footer { color: #666; font-size: 0.9em; border-bottom: 1px solid #ddd; margin-bottom: 8px; padding-bottom: 4px; } +.hwp-footer { border-top: 1px solid #ddd; border-bottom: none; margin-top: 8px; padding-top: 4px; } +p { margin: 0; padding: 0; line-height: 1; } +table { border-collapse: collapse; width: 100%; margin: 8px 0; } +td, th { border: 1px solid #ccc; padding: 4px 8px; vertical-align: top; } +img { max-width: 100%; height: auto; } +`.trim(); +function encodeContent3(node, warns) { + return node.tag === "grid" ? encodeGrid3(node, warns) : encodePara2(node, warns); +} +function encodePara2(para, warns) { + const kids = para.kids.map((k) => { + if (k.tag === "span") return encodeSpan2(k, warns); + if (k.tag === "img") return encodeImage4(k); + if (k.tag === "link") { + const link = k; + const inner = link.kids.map((s) => encodeSpan2(s, warns)).join(""); + return `${inner}`; + } + return ""; + }).join(""); + if (para.props.heading) { + const tag = `h${para.props.heading}`; + return `<${tag}>${kids} +`; + } + if (para.props.listOrd !== void 0) { + const indent = (para.props.listLv ?? 0) * 20; + const style = indent> 0 ? ` style="margin-left:${indent}px"` : ""; + const marker = para.props.listOrd ? `1. ` : `\u2022 `; + return `${marker}${kids}

            +`; + } + const align = para.props.align; + const styleAttrs = []; + if (align && align !== "left") styleAttrs.push(`text-align:${align}`); + if (para.props.indentPt) styleAttrs.push(`margin-left:${para.props.indentPt.toFixed(1)}pt`); + if (para.props.spaceBefore) styleAttrs.push(`margin-top:${para.props.spaceBefore.toFixed(1)}pt`); + if (para.props.spaceAfter) styleAttrs.push(`margin-bottom:${para.props.spaceAfter.toFixed(1)}pt`); + if (para.props.lineHeight) styleAttrs.push(`line-height:${para.props.lineHeight}`); + const styleAttr = styleAttrs.length> 0 ? ` style="${styleAttrs.join(";")}"` : ""; + return `${kids || " "}

            +`; +} +function encodeSpan2(span, warns) { + const parts = []; + let hasPageNum = false; + for (const kid of span.kids) { + if (kid.tag === "txt") { + const content = kid.content.replace(/__EXT_\d+(?:_W\d+_H\d+)?__/g, ""); + if (content) parts.push(TextKit.escapeXml(content)); + } else if (kid.tag === "br") { + parts.push("
            "); + } else if (kid.tag === "pb") { + parts.push(''); + } else if (kid.tag === "pagenum") { + hasPageNum = true; + warns.push("[SHIELD] HTML: \uD398\uC774\uC9C0 \uBC88\uD638 \u2014 \uC815\uC801 \uAC12\uC73C\uB85C \uB300\uCCB4\uB428"); + parts.push('[\uD398\uC774\uC9C0]'); + } + } + let text = parts.join(""); + if (hasPageNum && text.trim() === '[\uD398\uC774\uC9C0]') { + } + const p = span.props; + const css = []; + if (p.font) css.push(`font-family:${TextKit.escapeXml(p.font)}`); + if (p.pt) css.push(`font-size:${p.pt}pt`); + if (p.color) css.push(`color:#${p.color}`); + if (p.bg) css.push(`background-color:#${p.bg}`); + if (p.b) css.push("font-weight:bold"); + if (p.i) css.push("font-style:italic"); + const decorations = []; + if (p.u) decorations.push("underline"); + if (p.s) decorations.push("line-through"); + if (decorations.length> 0) css.push(`text-decoration:${decorations.join(" ")}`); + if (p.sup) return `${text}
            `; + if (p.sub) return `${text}`; + if (css.length> 0) return `${text}`; + return text; +} +function encodeImage4(img) { + const wStyle = img.w ? ` width="${Math.round(img.w / 72 * 96)}px"` : ""; + const hStyle = img.h ? ` height="${Math.round(img.h / 72 * 96)}px"` : ""; + const alt = TextKit.escapeXml(img.alt ?? ""); + return `${alt}`; +} +function encodeGrid3(grid, warns) { + if (grid.kids.length === 0) return ""; + const rowCount = grid.kids.length; + const occupancy = Array.from({ length: rowCount }, () => /* @__PURE__ */ new Set()); + let colCount = 0; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let ci = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(ci)) ci++; + if (cell.rs> 1) { + for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) { + for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c); + } + } + ci += cell.cs; + } + while (occupancy[ri].has(ci)) ci++; + if (ci> colCount) colCount = ci; + } + let rows = ""; + for (let ri = 0; ri < rowCount; ri++) { + const row = grid.kids[ri]; + let cells = ""; + let ci = 0; + for (const cell of row.kids) { + while (occupancy[ri].has(ci)) ci++; + const isHeader = cell.props.isHeader || grid.props.headerRow && ri === 0; + const tag = isHeader ? "th" : "td"; + const cs = cell.cs> 1 ? ` colspan="${cell.cs}"` : ""; + const rs = cell.rs> 1 ? ` rowspan="${cell.rs}"` : ""; + const styleAttrs = []; + if (cell.props.bg) styleAttrs.push(`background-color:#${cell.props.bg}`); + const va = cell.props.va; + if (va === "mid") styleAttrs.push("vertical-align:middle"); + else if (va === "bot") styleAttrs.push("vertical-align:bottom"); + const styleAttr = styleAttrs.length> 0 ? ` style="${styleAttrs.join(";")}"` : ""; + const content = cell.kids.map((p) => p.tag === "para" ? encodePara2(p, warns) : encodeGrid3(p, warns)).join(""); + cells += `<${tag}${cs}${rs}${styleattr}>${content}`; + ci += cell.cs; + } + rows += `
            ${cells}
            +`; + } + return ` + +${rows} + +`; +} +registry.registerEncoder(new HtmlEncoder()); + +// src/encoders/hwp/HwpEncoder.ts +import pako3 from "pako"; +var T = 16; +var TAG_DOCUMENT_PROPERTIES = T + 0; +var TAG_ID_MAPPINGS = T + 1; +var TAG_BIN_DATA = T + 2; +var TAG_FACE_NAME2 = T + 3; +var TAG_BORDER_FILL2 = T + 4; +var TAG_CHAR_SHAPE2 = T + 5; +var TAG_PARA_SHAPE2 = T + 9; +var TAG_STYLE = T + 10; +var TAG_PARA_HEADER2 = T + 50; +var TAG_PARA_TEXT2 = T + 51; +var TAG_PARA_CHAR_SHAPE2 = T + 52; +var TAG_PARA_LINE_SEG = T + 53; +var TAG_CTRL_HEADER2 = T + 55; +var TAG_LIST_HEADER2 = T + 56; +var TAG_PAGE_DEF2 = T + 57; +var TAG_FOOTNOTE_SHAPE = T + 58; +var TAG_TABLE = T + 61; +var TAG_SHAPE_COMPONENT_PICTURE = T + 69; +var CTRL_TABLE2 = 1952607264; +var CTRL_SECD = 1936024420; +var CTRL_PIC = 611346787; +var CTRL_FIELD_BEGIN = 1684825637; +var CTRL_FIELD_END = 1684825692; +var BORDER_W_PT2 = [ + 0.28, + 0.34, + 0.43, + 0.57, + 0.71, + 0.85, + 1.13, + 1.42, + 1.7, + 1.98, + 2.84, + 4.25, + 5.67, + 8.5, + 11.34, + 14.17 +]; +var BORDER_KIND_IDX = { + solid: 0, + dot: 1, + dash: 2, + double: 7, + triple: 8, + none: 0 +}; +var ALIGN_CODE = { + justify: 0, + left: 1, + right: 2, + center: 3, + distribute: 4 +}; +var BufWriter = class { + constructor() { + this.chunks = []; + this._sz = 0; + } + get size() { + return this._sz; + } + u8(v) { + this.chunks.push(new Uint8Array([v & 255])); + this._sz++; + return this; + } + u16(v) { + this.chunks.push(new Uint8Array([v & 255, v>> 8 & 255])); + this._sz += 2; + return this; + } + u32(v) { + const b = new Uint8Array(4); + b[0] = v & 255; + b[1] = v>>> 8 & 255; + b[2] = v>>> 16 & 255; + b[3] = v>>> 24 & 255; + this.chunks.push(b); + this._sz += 4; + return this; + } + i32(v) { + return this.u32(v < 0 ? v + 4294967296 : v); + } + i16(v) { + return this.u16(v < 0 ? v + 65536 : v); + } + bytes(d) { + this.chunks.push(d); + this._sz += d.length; + return this; + } + zeros(n) { + this.chunks.push(new Uint8Array(n)); + this._sz += n; + return this; + } + utf16(s) { + for (let i = 0; i < s.length; i++) this.u16(s.charCodeAt(i)); + return this; + } + colorRef(hex) { + const h = (hex || "000000").replace("#", "").padStart(6, "0"); + return this.u8(parseInt(h.slice(0, 2), 16)).u8(parseInt(h.slice(2, 4), 16)).u8(parseInt(h.slice(4, 6), 16)).u8(0); + } + build() { + const out = new Uint8Array(this._sz); + let off = 0; + for (const c of this.chunks) { + out.set(c, off); + off += c.length; + } + return out; + } +}; +function mkRec(tag, level, data) { + const sz = data.length; + const enc = Math.min(sz, 4095); + const hdr = enc << 20 | (level & 1023) << 10 | tag & 1023; + const w = new BufWriter().u32(hdr); + if (enc>= 4095) w.u32(sz); + w.bytes(data); + return w.build(); +} +function readPixelDims2(data, mime) { + try { + const view = new DataView(data.buffer, data.byteOffset, data.byteLength); + if (mime.includes("png")) { + if (data.length>= 24 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) { + return { w: view.getUint32(16), h: view.getUint32(20) }; + } + } else if (mime.includes("jpeg") || mime.includes("jpg")) { + let off = 2; + while (off < data.length - 4) { + const marker = view.getUint16(off); + off += 2; + if (marker === 65472 || marker === 65474) { + return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) }; + } + if ((marker & 65280) !== 65280) break; + off += view.getUint16(off); + } + } + } catch { + } + return null; +} +var LANG_GROUPS2 = [ + "HANGUL", + "LATIN", + "HANJA", + "JAPANESE", + "OTHER", + "SYMBOL", + "USER" +]; +function isKoreanFont(face) { + return /[\uAC00-\uD7A3\u3131-\u318E]/.test(face) || ["\uB9D1\uC740", "\uB098\uB214", "\uAD74\uB9BC", "\uB3CB\uC6C0", "\uBC14\uD0D5", "\uD568\uCD08\uB86C", "\uD55C\uCEF4", "HY"].some( + (k) => face.includes(k) + ); +} +var HwpStyleBank = class { + // id=0 → 모두 0 + constructor() { + this.DEF_STROKE = { kind: "solid", pt: 0.5, color: "000000" }; + // 언어별 독립 폰트 목록 (ANYTOHWP langFontFaces) + this.langFonts = new Map( + LANG_GROUPS2.map((g) => [g, []]) + ); + this.langFontIdx = new Map( + LANG_GROUPS2.map((g) => [g, /* @__PURE__ */ new Map()]) + ); + // charShape, parShape, borderFill 레지스트리 + this.csProps = [{}]; + this.csIdx = /* @__PURE__ */ new Map([[csKey({}), 0]]); + this.psProps = [{}]; + this.psIdx = /* @__PURE__ */ new Map([[psKey({}), 0]]); + this.bfData = []; + this.bfIdx = /* @__PURE__ */ new Map(); + // charShape마다 언어별 fontId를 기록 + this.csFontIds = [[0, 0, 0, 0, 0, 0, 0]]; + for (const g of LANG_GROUPS2) this._registerLangFont(g, "\uD568\uCD08\uB86C\uBC14\uD0D5"); + this.addBorderFill(this.DEF_STROKE); + } + _registerLangFont(lang, face) { + const idx = this.langFontIdx.get(lang); + if (idx.has(face)) return idx.get(face); + const id = this.langFonts.get(lang).length; + this.langFonts.get(lang).push(face); + idx.set(face, id); + return id; + } + /** 폰트 이름 → 언어별 7개 ID 반환 (ANYTOHWP 방식) */ + registerFontForLangs(rawFace) { + const face = safeFontToKr(rawFace) || "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const isKor = isKoreanFont(face); + const hangulFace = isKor ? face : "\uD568\uCD08\uB86C\uBC14\uD0D5"; + const latinFace = isKor ? "\uD568\uCD08\uB86C\uBC14\uD0D5" : face; + const ids = []; + for (const lang of LANG_GROUPS2) { + const f = lang === "LATIN" ? latinFace : hangulFace; + ids.push(this._registerLangFont(lang, f)); + } + return ids; + } + /** 언어별 폰트 목록 반환 */ + getFontsForLang(lang) { + return [...this.langFonts.get(lang) ?? []]; + } + /** 폰트 수 반환 (mkIdMappings용) */ + getFontCount(lang) { + return this.langFonts.get(lang)?.length ?? 0; + } + addCharShape(p) { + const k = csKey(p); + if (this.csIdx.has(k)) return this.csIdx.get(k); + const id = this.csProps.length; + const fIds = p.font ? this.registerFontForLangs(p.font) : [0, 0, 0, 0, 0, 0, 0]; + this.csProps.push(p); + this.csFontIds.push(fIds); + this.csIdx.set(k, id); + return id; + } + addParaShape(p) { + const k = psKey(p); + if (this.psIdx.has(k)) return this.psIdx.get(k); + const id = this.psProps.length; + this.psProps.push(p); + this.psIdx.set(k, id); + return id; + } + addBorderFill(s, bg) { + const k = bfKey(s, bg); + if (this.bfIdx.has(k)) return this.bfIdx.get(k); + const id = this.bfData.length + 1; + this.bfData.push({ uniform: true, s, bg }); + this.bfIdx.set(k, id); + return id; + } + addBorderFillPerSide(l, r, t, b, bg) { + const k = bfPerSideKey(l, r, t, b, bg); + if (this.bfIdx.has(k)) return this.bfIdx.get(k); + const id = this.bfData.length + 1; + this.bfData.push({ uniform: false, l, r, t, b, bg }); + this.bfIdx.set(k, id); + return id; + } +}; +function csKey(p) { + return [ + p.font ?? "", + p.pt ?? 10, + p.b ? 1 : 0, + p.i ? 1 : 0, + p.u ? 1 : 0, + p.s ? 1 : 0, + p.sup ? 1 : 0, + p.sub ? 1 : 0, + p.color ?? "000000" + ].join("|"); +} +function psKey(p) { + return [ + p.align ?? "left", + p.indentPt ?? 0, + p.firstLineIndentPt ?? 0, + p.spaceBefore ?? 0, + p.spaceAfter ?? 0, + p.lineHeight ?? 1 + ].join("|"); +} +function bfKey(s, bg) { + return `${s.kind}|${s.pt}|${s.color}|${bg ?? ""}`; +} +function bfPerSideKey(l, r, t, b, bg) { + return `${bfKey(l)}/${bfKey(r)}/${bfKey(t)}/${bfKey(b)}/${bg ?? ""}`; +} +function collectNode(node, bank) { + if (node.tag === "para") { + bank.addParaShape(node.props); + for (const kid of node.kids) { + if (kid.tag === "span") bank.addCharShape(kid.props); + } + } else if (node.tag === "grid") { + if (node.props.defaultStroke) bank.addBorderFill(node.props.defaultStroke); + for (const row of node.kids) { + for (const cell of row.kids) { + const defStroke = node.props.defaultStroke ?? bank.DEF_STROKE; + const cp = cell.props; + if (cp.top || cp.bot || cp.left || cp.right) { + bank.addBorderFillPerSide( + cp.left ?? defStroke, + cp.right ?? defStroke, + cp.top ?? defStroke, + cp.bot ?? defStroke, + cp.bg + ); + } else { + bank.addBorderFill(defStroke, cp.bg); + } + for (const para of cell.kids) collectNode(para, bank); + } + } + } +} +function mkDocumentProperties() { + return new BufWriter().u16(1).u16(1).u16(1).u16(1).u16(1).u16(1).u16(1).u32(0).u32(0).u32(0).build(); +} +function mkIdMappings(bank, nBinData = 0) { + const w = new BufWriter(); + w.u32(nBinData); + for (const lang of LANG_GROUPS2) w.u32(bank.getFontCount(lang)); + w.u32(bank.bfData.length); + w.u32(bank.csProps.length); + w.u32(0); + w.u32(0); + w.u32(0); + w.u32(bank.psProps.length); + w.u32(1); + w.u32(0); + w.u32(0); + w.u32(0); + return w.build(); +} +function mkStyle(name, engName, paraPrId, charPrId) { + return new BufWriter().u16(name.length).utf16(name).u16(engName.length).utf16(engName).u16(paraPrId).u16(charPrId).u16(0).u16(1042).u16(0).build(); +} +function mkFaceName(name) { + return new BufWriter().u8(0).u16(name.length).utf16(name).u8(0).u16(0).zeros(10).u16(0).build(); +} +function borderWidthIdx(pt) { + let best = 0; + for (let i = 0; i < BORDER_W_PT2.length; i++) { + if (Math.abs(BORDER_W_PT2[i] - pt) < Math.abs(BORDER_W_PT2[best] - pt)) + best = i; + } + return best; +} +function mkBorderFill(s, bg) { + const w = new BufWriter(); + const t = BORDER_KIND_IDX[s.kind] ?? 0; + const wi = borderWidthIdx(s.pt); + const col = s.color || "000000"; + w.u16(0); + for (let i = 0; i < 4; i++) w.u8(t); + for (let i = 0; i < 4; i++) w.u8(wi); + for (let i = 0; i < 4; i++) w.colorRef(col); + w.u8(0).u8(0).colorRef("000000"); + if (bg) { + w.u32(1).colorRef(bg).colorRef("FFFFFF").u32(0); + } else { + w.u32(0); + } + return w.build(); +} +function mkBorderFillPerSide(l, r, t, b, bg) { + const w = new BufWriter(); + w.u16(0); + w.u8(BORDER_KIND_IDX[l.kind] ?? 0).u8(BORDER_KIND_IDX[r.kind] ?? 0).u8(BORDER_KIND_IDX[t.kind] ?? 0).u8(BORDER_KIND_IDX[b.kind] ?? 0); + w.u8(borderWidthIdx(l.pt)).u8(borderWidthIdx(r.pt)).u8(borderWidthIdx(t.pt)).u8(borderWidthIdx(b.pt)); + w.colorRef(l.color || "000000").colorRef(r.color || "000000").colorRef(t.color || "000000").colorRef(b.color || "000000"); + w.u8(0).u8(0).colorRef("000000"); + if (bg) { + w.u32(1).colorRef(bg).colorRef("FFFFFF").u32(0); + } else { + w.u32(0); + } + return w.build(); +} +function mkCharShape(fontIds, p) { + const height = Math.round((p.pt ?? 10) * 100); + let attr = 0; + if (p.i) attr |= 1 << 0; + if (p.b) attr |= 1 << 1; + if (p.u) attr |= 1 << 2; + if (p.s) attr |= 1 << 18; + if (p.sup) attr |= 1 << 16; + if (p.sub) attr |= 2 << 16; + const w = new BufWriter(); + for (const id of fontIds) w.u16(id); + for (let i = 0; i < 7; i++) w.u8(100); + for (let i = 0; i < 7; i++) w.u8(0); + for (let i = 0; i < 7; i++) w.u8(100); + for (let i = 0; i < 7; i++) w.u8(0); + w.i32(height).u32(attr).u8(0).u8(0); + w.colorRef(p.color ?? "000000"); + w.colorRef("000000"); + w.colorRef(p.bg ?? "FFFFFF"); + w.colorRef("000000"); + w.u16(0); + w.colorRef("000000"); + return w.build(); +} +function mkParaShape(p) { + const alignVal = ALIGN_CODE[p.align ?? "left"] ?? 1; + const attr1 = (alignVal & 7) << 2; + const lineSpacePct = p.lineHeight ? Math.round(p.lineHeight * 100) : 160; + return new BufWriter().u32(attr1).i32(Metric.ptToHwp(p.indentPt ?? 0)).i32(Metric.ptToHwp(p.indentRightPt ?? 0)).i32(Metric.ptToHwp(p.firstLineIndentPt ?? 0)).i32(Metric.ptToHwp(p.spaceBefore ?? 0)).i32(Metric.ptToHwp(p.spaceAfter ?? 0)).i32(lineSpacePct).u16(0).u16(0).u16(0).i16(0).i16(0).i16(0).i16(0).u32(0).u32(4).u32(lineSpacePct).build(); +} +function mkBinData(id, ext) { + return new BufWriter().u16(2).u16(id).u16(ext.length).utf16(ext).build(); +} +function buildDocInfoStream(bank, images = []) { + const chunks = []; + chunks.push(mkRec(TAG_DOCUMENT_PROPERTIES, 0, mkDocumentProperties())); + chunks.push(mkRec(TAG_ID_MAPPINGS, 1, mkIdMappings(bank, images.length))); + for (const img of images) { + chunks.push(mkRec(TAG_BIN_DATA, 1, mkBinData(img.id, img.ext))); + } + for (const lang of LANG_GROUPS2) { + for (const face of bank.getFontsForLang(lang)) { + chunks.push(mkRec(TAG_FACE_NAME2, 1, mkFaceName(face))); + } + } + for (const entry of bank.bfData) { + chunks.push( + mkRec( + TAG_BORDER_FILL2, + 1, + entry.uniform ? mkBorderFill(entry.s, entry.bg) : mkBorderFillPerSide(entry.l, entry.r, entry.t, entry.b, entry.bg) + ) + ); + } + for (let i = 0; i < bank.csProps.length; i++) { + chunks.push( + mkRec(TAG_CHAR_SHAPE2, 1, mkCharShape(bank.csFontIds[i], bank.csProps[i])) + ); + } + for (const p of bank.psProps) { + chunks.push(mkRec(TAG_PARA_SHAPE2, 1, mkParaShape(p))); + } + chunks.push(mkRec(TAG_STYLE, 1, mkStyle("\uBC14\uD0D5\uAE00", "Normal", 0, 0))); + return concatU8(chunks); +} +function mkPageDef(dims) { + return new BufWriter().u32(Metric.ptToHwp(dims.wPt)).u32(Metric.ptToHwp(dims.hPt)).u32(Metric.ptToHwp(dims.ml)).u32(Metric.ptToHwp(dims.mr)).u32(Metric.ptToHwp(dims.mt)).u32(Metric.ptToHwp(dims.mb)).zeros(12).u32(dims.orient === "landscape" ? 1 : 0).build(); +} +function mkParaHeader(nchars, ctrlMask, psId, csCount, lineAlignCount = 0, instanceId = 0) { + return new BufWriter().u32(nchars).u32(ctrlMask).u16(psId).u8(0).u8(0).u16(csCount).u16(0).u16(lineAlignCount).u32(instanceId).u16(0).build(); +} +function mkParaText(text) { + const w = new BufWriter(); + for (let i = 0; i < text.length; i++) { + const c = text.charCodeAt(i); + w.u16(c); + } + w.u16(13); + return w.build(); +} +function mkParaCharShape(pairs) { + const w = new BufWriter(); + for (const [pos, id] of pairs) w.u32(pos).u32(id); + return w.build(); +} +function calcLineHeight(type, value, textHeight) { + switch (type) { + case 0: + return Math.floor(textHeight * value / 100); + case 1: + return value; + case 2: + return Math.max(textHeight, value); + case 3: + return textHeight + value; + case 4: + return Math.floor(textHeight * value); + default: + return Math.floor(textHeight * value / 100); + } +} +function mkLineSeg(textStartPos, vertPos, vertSize, textHeight, baseline, spacing, horzPos, horzSize, flags) { + return new BufWriter().u32(textStartPos).i32(vertPos).i32(vertSize).i32(textHeight).i32(baseline).i32(spacing).i32(horzPos).i32(horzSize).u32(flags).build(); +} +function buildDefaultLineSeg(availWidthHwp, fontHwp, nchars, paraProps, vertPos = 0) { + const ratio = paraProps?.lineHeight ? Math.round(paraProps.lineHeight * 100) : 160; + const vertSize = calcLineHeight(0, ratio, fontHwp); + const baseline = Math.round(fontHwp * 0.85); + const spacing = vertSize - fontHwp; + const flags = 3; + return mkLineSeg( + 0, + vertPos, + vertSize, + fontHwp, + baseline, + spacing, + 0, + availWidthHwp, + flags + ); +} +function mkSecdParaText() { + const lo = CTRL_SECD & 65535; + const hi = CTRL_SECD>>> 16 & 65535; + return new BufWriter().u16(2).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(2).u16(13).build(); +} +function mkTableParaText() { + const lo = CTRL_TABLE2 & 65535; + const hi = CTRL_TABLE2>>> 16 & 65535; + return new BufWriter().u16(11).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(11).u16(13).build(); +} +function mkPicParaText() { + const lo = CTRL_PIC & 65535; + const hi = CTRL_PIC>>> 16 & 65535; + return new BufWriter().u16(11).u16(lo).u16(hi).u16(0).u16(0).u16(0).u16(0).u16(11).u16(13).build(); +} +function mkShapeComponentPicture(binDataId, wHwp, hHwp) { + const w = new BufWriter(); + w.u32(CTRL_PIC).zeros(15); + w.u32(0).u32(0).u32(wHwp).u32(hHwp); + w.u32(0).u32(0).u32(wHwp).u32(hHwp); + w.zeros(36); + w.u16(binDataId).u8(0).u8(0).u8(0).zeros(5); + return w.build(); +} +function mkObjectCtrl(ctrlId, wHwp, hHwp, instanceId, layout) { + let attr = 136978960; + if (layout?.wrap === "inline") attr |= 1 << 3; + return new BufWriter().u32(ctrlId).u32(attr).i32(layout?.yPt ? Metric.ptToHwp(layout.yPt) : 0).i32(layout?.xPt ? Metric.ptToHwp(layout.xPt) : 0).u32(wHwp).u32(hHwp).i32(layout?.zOrder ?? 0).u16(layout?.distL ? Metric.ptToHwp(layout.distL) : 0).u16(layout?.distR ? Metric.ptToHwp(layout.distR) : 0).u16(layout?.distT ? Metric.ptToHwp(layout.distT) : 0).u16(layout?.distB ? Metric.ptToHwp(layout.distB) : 0).u32(instanceId).i32(0).u16(0).build(); +} +function mkFieldBeginCtrl(instanceId) { + return new BufWriter().u32(CTRL_FIELD_BEGIN).u32(2).zeros(28).u32(instanceId).zeros(6).build(); +} +function mkFieldEndCtrl(beginId) { + return new BufWriter().u32(CTRL_FIELD_END).u32(0).zeros(28).u32(beginId).zeros(6).build(); +} +function encodePicPara(imgNode, binDataId, bank, lv, idGen, availWidthHwp) { + const rawData = TextKit.base64Decode(imgNode.b64); + const pixDims = readPixelDims2(rawData, imgNode.mime); + let wHwp, hHwp; + if (pixDims && pixDims.w> 0 && pixDims.h> 0) { + wHwp = Metric.ptToHwp(pixDims.w * 72 / 96); + hHwp = Metric.ptToHwp(pixDims.h * 72 / 96); + } else { + wHwp = Metric.ptToHwp(imgNode.w); + hHwp = Metric.ptToHwp(imgNode.h); + } + if (wHwp> availWidthHwp) { + hHwp = Math.round(hHwp * availWidthHwp / wHwp); + wHwp = availWidthHwp; + } + const CTRL_MASK = 1 << 11; + const instanceId = idGen(); + const psId = bank.addParaShape({}); + return [ + mkRec( + TAG_PARA_HEADER2, + lv, + mkParaHeader(9, CTRL_MASK, psId, 1, 1, instanceId) + ), + mkRec(TAG_PARA_TEXT2, lv + 1, mkPicParaText()), + mkRec(TAG_PARA_CHAR_SHAPE2, lv + 1, mkParaCharShape([[0, 0]])), + mkRec( + TAG_PARA_LINE_SEG, + lv + 1, + buildDefaultLineSeg(availWidthHwp, hHwp, 9) + ), + mkRec( + TAG_CTRL_HEADER2, + lv + 1, + mkObjectCtrl(CTRL_PIC, wHwp, hHwp, idGen(), imgNode.layout) + ), + mkRec( + TAG_SHAPE_COMPONENT_PICTURE, + lv + 2, + mkShapeComponentPicture(binDataId, wHwp, hHwp) + ) + ]; +} +function encodePara3(para, bank, lv, instanceId, availWidthHwp, mask = 0, vertPos = 0) { + let text = ""; + const csPairs = []; + let pos = 0; + let fontHwp = 1e3; + const ctrlRecords = []; + for (const kid of para.kids) { + if (kid.tag === "span" && kid.props.pt && kid.props.pt> 0) { + fontHwp = Metric.ptToHwp(kid.props.pt); + break; + } + } + let localIdCounter = 1e4; + const localIdGen = () => localIdCounter++; + function processKids(kids) { + for (const kid of kids) { + if (kid.tag === "span") { + const span = kid; + const csId = bank.addCharShape(span.props); + if (!csPairs.length || csPairs[csPairs.length - 1][1] !== csId) { + csPairs.push([pos, csId]); + } + for (const t of span.kids) { + if (t.tag === "txt") { + text += t.content; + pos += t.content.length; + } + } + } else if (kid.tag === "link") { + const link = kid; + mask |= 1 << 11; + const fieldBeginId = localIdGen(); + text += String.fromCharCode(3); + pos += 1; + ctrlRecords.push( + mkRec(TAG_CTRL_HEADER2, lv + 1, mkFieldBeginCtrl(fieldBeginId)) + ); + processKids(link.kids); + text += String.fromCharCode(4); + pos += 1; + ctrlRecords.push( + mkRec(TAG_CTRL_HEADER2, lv + 1, mkFieldEndCtrl(fieldBeginId)) + ); + } + } + } + processKids(para.kids); + if (!csPairs.length) csPairs.push([0, 0]); + const psId = bank.addParaShape(para.props); + const nchars = text.length + 1; + return [ + mkRec( + TAG_PARA_HEADER2, + lv, + mkParaHeader(nchars, mask, psId, csPairs.length, 1, instanceId) + ), + mkRec(TAG_PARA_TEXT2, lv + 1, mkParaText(text)), + mkRec(TAG_PARA_CHAR_SHAPE2, lv + 1, mkParaCharShape(csPairs)), + mkRec( + TAG_PARA_LINE_SEG, + lv + 1, + buildDefaultLineSeg(availWidthHwp, fontHwp, nchars, para.props, vertPos) + ), + ...ctrlRecords + ]; +} +function mkTableCtrl(wHwp, hHwp, instanceId, align = "left") { + const alignFlags = { left: 0, center: 1, right: 2, justify: 3 }[align] ?? 0; + return new BufWriter().u32(CTRL_TABLE2).u32(136978961).i32(0).i32(0).u32(wHwp).u32(hHwp).i32(7).u16(140).u16(140).u16(140).u16(140).u32(instanceId).i32(alignFlags).u16(0).build(); +} +function mkTableRecord(rowCnt, colCnt, rowHwp, bfId) { + const w = new BufWriter(); + w.u32(67108870).u16(rowCnt).u16(colCnt).u16(0); + w.u16(510).u16(510).u16(141).u16(141); + for (const h of rowHwp) w.u16(Math.max(1, h & 65535)); + w.u16(bfId).u16(0); + return w.build(); +} +function mkCellListHeader(paraCount, row, col, rs, cs, wHwp, hHwp, bfId, padL = 141, padR = 141, padT = 141, padB = 141) { + return new BufWriter().u16(paraCount).u32(0).u16(0).u16(col).u16(row).u16(rs).u16(cs).u32(wHwp).u32(hHwp).u16(padL).u16(padR).u16(padT).u16(padB).u16(bfId).zeros(13).build(); +} +var DEFAULT_ROW_HEIGHT_PT = 14; +function encodeGrid4(grid, bank, lv, idGen, availWidthHwp) { + const records = []; + const rowCnt = grid.kids.length; + const colCnt = Math.max(1, grid.kids[0]?.kids.length ?? 1); + const cwPt = grid.props.colWidths ?? []; + const totalPt = cwPt.reduce((s, w) => s + w, 0) || 453; + const defColPt = totalPt / colCnt; + const defStroke = grid.props.defaultStroke ?? bank.DEF_STROKE; + const defBfId = bank.addBorderFill(defStroke); + const rowHwp = grid.kids.map( + (row) => row.heightPt != null && row.heightPt> 0 ? Metric.ptToHwp(row.heightPt) : Metric.ptToHwp(DEFAULT_ROW_HEIGHT_PT) + ); + const tblWPt = cwPt.length> 0 ? cwPt.reduce((s, w) => s + w, 0) : totalPt; + const tblHPt = grid.kids.reduce( + (s, row) => s + (row.heightPt != null && row.heightPt> 0 ? row.heightPt : DEFAULT_ROW_HEIGHT_PT), + 0 + ); + const tblInstanceId = idGen(); + const tblAlign = grid.props.align ?? "left"; + records.push( + mkRec( + TAG_CTRL_HEADER2, + lv, + mkTableCtrl( + Metric.ptToHwp(tblWPt), + Metric.ptToHwp(tblHPt), + tblInstanceId, + tblAlign + ) + ) + ); + records.push( + mkRec(TAG_TABLE, lv + 1, mkTableRecord(rowCnt, colCnt, rowHwp, defBfId)) + ); + for (let r = 0; r < grid.kids.length; r++) { + for (let c = 0; c < grid.kids[r].kids.length; c++) { + const cell = grid.kids[r].kids[c]; + const wHwp = Metric.ptToHwp(cwPt[c] ?? defColPt); + const hHwp = rowHwp[r]; + const cp = cell.props; + const hasPerSide = cp.top || cp.bot || cp.left || cp.right; + const bfId = hasPerSide ? bank.addBorderFillPerSide( + cp.left ?? defStroke, + cp.right ?? defStroke, + cp.top ?? defStroke, + cp.bot ?? defStroke, + cp.bg + ) : bank.addBorderFill(defStroke, cp.bg); + const paras = cell.kids.length> 0 ? cell.kids : [{ tag: "para", props: {}, kids: [] }]; + const padL = cp.padL !== void 0 ? Metric.ptToHwp(cp.padL) : 510; + const padR = cp.padR !== void 0 ? Metric.ptToHwp(cp.padR) : 510; + const padT = cp.padT !== void 0 ? Metric.ptToHwp(cp.padT) : 141; + const padB = cp.padB !== void 0 ? Metric.ptToHwp(cp.padB) : 141; + records.push( + mkRec( + TAG_LIST_HEADER2, + lv + 1, + mkCellListHeader( + paras.length, + r, + c, + cell.rs, + cell.cs, + wHwp, + hHwp, + bfId, + padL, + padR, + padT, + padB + ) + ) + ); + const cellWidthHwp = Metric.ptToHwp(cwPt[c] ?? defColPt); + for (const para of paras) { + records.push( + ...encodePara3(para, bank, lv + 2, idGen(), cellWidthHwp) + ); + } + } + } + return records; +} +function mkSectionCtrl() { + return new BufWriter().u32(CTRL_SECD).u32(0).u32(1134).u16(16384).u16(31).zeros(31).build(); +} +function buildSectionParagraph(dims, instanceId) { + const SECD_CTRL_MASK = 1 << 2; + const nchars = 9; + const availWidthHwp = Math.max( + 1e3, + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr) + ); + return [ + mkRec( + TAG_PARA_HEADER2, + 0, + mkParaHeader(nchars, SECD_CTRL_MASK, 0, 1, 1, instanceId) + ), + mkRec(TAG_PARA_TEXT2, 1, mkSecdParaText()), + mkRec(TAG_PARA_CHAR_SHAPE2, 1, mkParaCharShape([[0, 0]])), + mkRec( + TAG_PARA_LINE_SEG, + 1, + buildDefaultLineSeg(availWidthHwp, 1e3, nchars) + ), + mkRec(TAG_CTRL_HEADER2, 1, mkSectionCtrl()), + mkRec(TAG_PAGE_DEF2, 2, mkPageDef(dims)), + mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)), + mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)) + ]; +} +function flatImgNodes(kids) { + const result = []; + for (const kid of kids) { + if (kid.tag === "img") result.push(kid); + else if (kid.tag === "link" && Array.isArray(kid.kids)) + result.push(...flatImgNodes(kid.kids)); + } + return result; +} +function b64Matches(binImg, b64) { + const a = TextKit.base64Encode(binImg.data).replace(/\s/g, ""); + const b = b64.replace(/\s/g, ""); + return a === b; +} +function buildBodyTextStream(doc, bank, images) { + const chunks = []; + const dims = doc.kids[0]?.dims ?? A4; + let instanceIdCounter = 1; + const idGen = () => instanceIdCounter++; + const availWidthHwp = Math.max( + 1e3, + Metric.ptToHwp(dims.wPt) - Metric.ptToHwp(dims.ml) - Metric.ptToHwp(dims.mr) + ); + for (const r of buildSectionParagraph(dims, idGen())) chunks.push(r); + const TABLE_CTRL_MASK = 1 << 11; + let vertPos = 0; + for (const sheet of doc.kids) { + for (const node of sheet.kids) { + if (node.tag === "para") { + const para = node; + const hasPageBreak = para.kids.some( + (k) => k.tag === "span" && k.kids.some((c) => c.tag === "pb") + ); + let paraMask = hasPageBreak ? 1 << 2 : 0; + const hasCourier = (kids) => kids.some( + (k) => k.tag === "span" && k.props.font?.toLowerCase().includes("courier") || k.tag === "link" && hasCourier(k.kids) + ); + const isCode = para.props.styleId?.toLowerCase().includes("code") || hasCourier(para.kids); + if (isCode) { + const gridNode = { + tag: "grid", + props: { + colWidths: [Metric.hwpToPt(availWidthHwp)], + defaultStroke: { kind: "solid", pt: 0.5, color: "aaaaaa" } + }, + kids: [ + { + tag: "row", + kids: [ + { + tag: "cell", + rs: 1, + cs: 1, + props: { bg: "f4f4f4" }, + kids: [para] + } + ] + } + ] + }; + chunks.push( + mkRec( + TAG_PARA_HEADER2, + 0, + mkParaHeader(9, TABLE_CTRL_MASK | paraMask, 0, 1, 1, idGen()) + ) + ); + chunks.push(mkRec(TAG_PARA_TEXT2, 1, mkTableParaText())); + chunks.push(mkRec(TAG_PARA_CHAR_SHAPE2, 1, mkParaCharShape([[0, 0]]))); + chunks.push( + mkRec( + TAG_PARA_LINE_SEG, + 1, + buildDefaultLineSeg(availWidthHwp, 1e3, 9, void 0, vertPos) + ) + ); + vertPos += Metric.ptToHwp(20); + for (const r of encodeGrid4(gridNode, bank, 1, idGen, availWidthHwp)) + chunks.push(r); + continue; + } + const imgNodes = flatImgNodes(para.kids); + if (imgNodes.length> 0) { + for (const img of imgNodes) { + const binImg = images.find((b) => b64Matches(b, img.b64)); + if (binImg) { + for (const r of encodePicPara( + img, + binImg.id, + bank, + 0, + idGen, + availWidthHwp + )) { + chunks.push(r); + } + vertPos += Metric.ptToHwp(img.h ?? 100); + } + } + const textKids = para.kids.filter( + (k) => k.tag !== "img" && k.tag !== "link" + ); + if (textKids.length> 0) { + const textPara = { + tag: "para", + props: para.props, + kids: textKids + }; + for (const r of encodePara3( + textPara, + bank, + 0, + idGen(), + availWidthHwp, + paraMask, + vertPos + )) { + if (r[0] === (TAG_PARA_HEADER2 & 255)) { + } + chunks.push(r); + } + const fontHwp_img = textKids.find( + (k) => k.tag === "span" && k.props?.pt + )?.props.pt ? Metric.ptToHwp( + textKids.find( + (k) => k.tag === "span" && k.props?.pt + ).props.pt + ) : 1e3; + const lineSpacePct_img = Math.round((para.props.lineHeight ?? 1.6) * 100); + vertPos += Math.round(fontHwp_img * lineSpacePct_img / 100); + } + } else { + for (const r of encodePara3( + para, + bank, + 0, + idGen(), + availWidthHwp, + paraMask, + vertPos + )) + chunks.push(r); + const fontHwp_para = para.kids.find( + (k) => k.tag === "span" && k.props?.pt + )?.props.pt ? Metric.ptToHwp( + para.kids.find( + (k) => k.tag === "span" && k.props?.pt + ).props.pt + ) : 1e3; + const lineSpacePct_para = para.props.lineHeight ? Math.round(para.props.lineHeight * 100) : 160; + vertPos += Math.round(fontHwp_para * lineSpacePct_para / 100); + } + } else if (node.tag === "grid") { + chunks.push( + mkRec( + TAG_PARA_HEADER2, + 0, + mkParaHeader(9, TABLE_CTRL_MASK, 0, 1, 1, idGen()) + ) + ); + chunks.push(mkRec(TAG_PARA_TEXT2, 1, mkTableParaText())); + chunks.push(mkRec(TAG_PARA_CHAR_SHAPE2, 1, mkParaCharShape([[0, 0]]))); + chunks.push( + mkRec( + TAG_PARA_LINE_SEG, + 1, + buildDefaultLineSeg(availWidthHwp, 1e3, 9, void 0, vertPos) + ) + ); + vertPos += Metric.ptToHwp(20); + for (const r of encodeGrid4( + node, + bank, + 1, + idGen, + availWidthHwp + )) + chunks.push(r); + } + } + } + return concatU8(chunks); +} +function buildHwpFileHeader() { + const SIZE = 256; + const buf = new Uint8Array(SIZE); + const dv = new DataView(buf.buffer); + const sig = "HWP Document File"; + for (let i = 0; i < sig.length; i++) { + buf[i] = sig.charCodeAt(i); + } + dv.setUint32(32, 83886848, true); + dv.setUint32(36, 1, true); + if (buf.length !== SIZE) { + throw new Error(`FileHeader \uD06C\uAE30 \uC624\uB958: ${buf.length} (\uAE30\uB300: ${SIZE})`); + } + if (new TextDecoder().decode(buf.subarray(0, sig.length)) !== sig) { + throw new Error("FileHeader \uC2DC\uADF8\uB2C8\uCC98 \uC624\uB958"); + } + if (dv.getUint32(32, true) !== 83886848) { + throw new Error("FileHeader \uBC84\uC804 \uC624\uB958"); + } + return buf; +} +function buildHwpOle2(fileHeaderData, docInfoData, section0Data, binImages = []) { + const SS = 512; + const ENDOFCHAIN = 4294967294; + const FREESECT = 4294967295; + const FATSECT = 4294967293; + if (fileHeaderData.length < 256) { + throw new Error( + `FileHeader \uD06C\uAE30 \uBD80\uC871: ${fileHeaderData.length} (\uCD5C\uC18C 256)` + ); + } + function padSector(d) { + const n = Math.ceil(Math.max(d.length, 1) / SS) * SS; + if (d.length === n) return d; + const out2 = new Uint8Array(n); + out2.set(d); + return out2; + } + const fhPad = padSector(fileHeaderData); + const diPad = padSector(docInfoData); + const s0Pad = padSector(section0Data); + const imgPads = binImages.map((img) => padSector(img.data)); + const fhN = fhPad.length / SS; + const diN = diPad.length / SS; + const s0N = s0Pad.length / SS; + const imgNs = imgPads.map((p) => p.length / SS); + const totalImgN = imgNs.reduce((s, n) => s + n, 0); + const numDirEntries = 5 + (binImages.length> 0 ? 1 + binImages.length : 0); + const dirN = Math.max(2, Math.ceil(numDirEntries / 4)); + let fatN = 1; + for (let iter = 0; iter < 10; iter++) { + const total = fatN + dirN + fhN + diN + s0N + totalImgN; + const needed = Math.ceil(total / 128); + if (needed <= fatN) break; + fatN = needed; + } + const dir1Sec = fatN; + const fhSec = dir1Sec + dirN; + const diSec = fhSec + fhN; + const s0Sec = diSec + diN; + const imgSecs = []; + let curSec = s0Sec + s0N; + for (const n of imgNs) { + imgSecs.push(curSec); + curSec += n; + } + const totalSec = curSec; + const fatBuf = new Uint8Array(fatN * SS).fill(255); + const setFat = (i, v) => { + fatBuf[i * 4] = v & 255; + fatBuf[i * 4 + 1] = v>>> 8 & 255; + fatBuf[i * 4 + 2] = v>>> 16 & 255; + fatBuf[i * 4 + 3] = v>>> 24 & 255; + }; + for (let i = 0; i < fatN; i++) setFat(i, FATSECT); + for (let i = 0; i < dirN; i++) + setFat(dir1Sec + i, i + 1 < dirN ? dir1Sec + i + 1 : ENDOFCHAIN); + for (let i = 0; i < fhN; i++) + setFat(fhSec + i, i + 1 < fhN ? fhSec + i + 1 : ENDOFCHAIN); + for (let i = 0; i < diN; i++) + setFat(diSec + i, i + 1 < diN ? diSec + i + 1 : ENDOFCHAIN); + for (let i = 0; i < s0N; i++) + setFat(s0Sec + i, i + 1 < s0N ? s0Sec + i + 1 : ENDOFCHAIN); + for (let ii = 0; ii < imgNs.length; ii++) { + const start = imgSecs[ii]; + const n = imgNs[ii]; + for (let i = 0; i < n; i++) + setFat(start + i, i + 1 < n ? start + i + 1 : ENDOFCHAIN); + } + const dirBuf = new Uint8Array(dirN * SS); + const dv = new DataView(dirBuf.buffer); + function writeDirEntry(idx, name, type, left, right, child, startSec, size) { + const base = idx * 128; + const nl = name.length; + for (let i = 0; i < nl; i++) + dv.setUint16(base + i * 2, name.charCodeAt(i), true); + dv.setUint16(base + 64, (nl + 1) * 2, true); + dirBuf[base + 66] = type; + dirBuf[base + 67] = 1; + dv.setInt32(base + 68, left, true); + dv.setInt32(base + 72, right, true); + dv.setInt32(base + 76, child, true); + dv.setUint32(base + 116, startSec>>> 0, true); + dv.setUint32(base + 120, size>>> 0, true); + } + for (let i = 0; i < dirN * 4; i++) { + const base = i * 128; + dv.setInt32(base + 68, -1, true); + dv.setInt32(base + 72, -1, true); + dv.setInt32(base + 76, -1, true); + } + if (binImages.length> 0) { + writeDirEntry(0, "Root Entry", 5, -1, -1, 1, ENDOFCHAIN, 0); + writeDirEntry(1, "FileHeader", 2, -1, 2, -1, fhSec, fileHeaderData.length); + writeDirEntry(2, "DocInfo", 2, -1, 3, -1, diSec, docInfoData.length); + writeDirEntry(3, "BodyText", 1, -1, 5, 4, ENDOFCHAIN, 0); + writeDirEntry(4, "Section0", 2, -1, -1, -1, s0Sec, section0Data.length); + writeDirEntry(5, "BinData", 1, -1, -1, 6, ENDOFCHAIN, 0); + for (let ii = 0; ii < binImages.length; ii++) { + const img = binImages[ii]; + const streamName = `BIN${String(img.id).padStart(4, "0")}.${img.ext}`; + const sibling = ii + 1 < binImages.length ? 7 + ii : -1; + writeDirEntry( + 6 + ii, + streamName, + 2, + -1, + sibling, + -1, + imgSecs[ii], + img.data.length + ); + } + } else { + writeDirEntry(0, "Root Entry", 5, -1, -1, 1, ENDOFCHAIN, 0); + writeDirEntry(1, "FileHeader", 2, -1, 2, -1, fhSec, fileHeaderData.length); + writeDirEntry(2, "DocInfo", 2, -1, 3, -1, diSec, docInfoData.length); + writeDirEntry(3, "BodyText", 1, -1, -1, 4, ENDOFCHAIN, 0); + writeDirEntry(4, "Section0", 2, -1, -1, -1, s0Sec, section0Data.length); + } + const HWP_CLSID = [ + 32, + 233, + 227, + 192, + 70, + 53, + 207, + 17, + 141, + 129, + 0, + 170, + 0, + 56, + 155, + 113 + ]; + for (let i = 0; i < 16; i++) dirBuf[80 + i] = HWP_CLSID[i]; + const hdr = new Uint8Array(SS); + const hdv = new DataView(hdr.buffer); + const MAGIC = [208, 207, 17, 224, 161, 177, 26, 225]; + MAGIC.forEach((b, i) => { + hdr[i] = b; + }); + hdv.setUint16(24, 62, true); + hdv.setUint16(26, 3, true); + hdv.setUint16(28, 254, true); + hdv.setUint16(30, 9, true); + hdv.setUint16(32, 6, true); + hdv.setUint32(40, fatN, true); + hdv.setUint32(44, dir1Sec, true); + hdv.setUint32(48, 0, true); + hdv.setUint32(52, 4096, true); + hdv.setUint32(56, ENDOFCHAIN, true); + hdv.setUint32(60, 0, true); + hdv.setUint32(64, ENDOFCHAIN, true); + hdv.setUint32(68, 0, true); + hdv.setUint32(72, 0, true); + for (let i = 0; i < 109; i++) { + hdv.setUint32(76 + i * 4, i < fatN ? i : FREESECT, true); + } + const out = new Uint8Array(SS + totalSec * SS); + out.set(hdr, 0); + for (let i = 0; i < fatN; i++) + out.set(fatBuf.subarray(i * SS, (i + 1) * SS), SS + i * SS); + for (let i = 0; i < dirN; i++) + out.set(dirBuf.subarray(i * SS, (i + 1) * SS), SS + (dir1Sec + i) * SS); + out.set(fhPad, SS + fhSec * SS); + out.set(diPad, SS + diSec * SS); + out.set(s0Pad, SS + s0Sec * SS); + for (let ii = 0; ii < imgPads.length; ii++) + out.set(imgPads[ii], SS + imgSecs[ii] * SS); + return out; +} +function concatU8(arrays) { + const total = arrays.reduce((s, a) => s + a.length, 0); + const out = new Uint8Array(total); + let off = 0; + for (const a of arrays) { + out.set(a, off); + off += a.length; + } + return out; +} +function validateOle2Magic(hwp) { + const OLE_MAGIC = [208, 207, 17, 224, 161, 177, 26, 225]; + return OLE_MAGIC.every((b, i) => hwp[i] === b); +} +var HwpEncoder = class extends BaseEncoder { + getFormat() { + return "hwp"; + } + getAliases() { + return ["application/vnd.hancom.hwp"]; + } + async encode(doc) { + try { + let registerImg2 = function(img) { + const key = img.b64.substring(0, 50); + if (seenB64.has(key)) return; + seenB64.add(key); + const raw = TextKit.base64Decode(img.b64); + const ext = img.mime === "image/png" ? "png" : img.mime === "image/gif" ? "gif" : img.mime === "image/bmp" ? "bmp" : "jpg"; + images.push({ id: binIdCounter++, ext, data: new Uint8Array(raw) }); + }, collectImages3 = function(node) { + if (node.tag === "para") { + for (const img of flatImgNodes(node.kids)) registerImg2(img); + } else if (node.tag === "grid") { + for (const row of node.kids) + for (const cell of row.kids) + for (const para of cell.kids) collectImages3(para); + } + }; + var registerImg = registerImg2, collectImages2 = collectImages3; + const bank = new HwpStyleBank(); + for (const sheet of doc.kids) { + for (const node of sheet.kids) collectNode(node, bank); + } + const images = []; + const seenB64 = /* @__PURE__ */ new Set(); + let binIdCounter = 1; + for (const sheet of doc.kids) { + for (const node of sheet.kids) collectImages3(node); + } + const docInfoRaw = buildDocInfoStream(bank, images); + const bodyRaw = buildBodyTextStream(doc, bank, images); + const docInfoCmp = pako3.deflateRaw(docInfoRaw); + const bodyCmp = pako3.deflateRaw(bodyRaw); + const fileHdr = buildHwpFileHeader(); + if (fileHdr.length !== 256) { + return fail( + `HwpEncoder: FileHeader \uD06C\uAE30 \uC624\uB958 - ${fileHdr.length} bytes (\uAE30\uB300: 256 bytes)` + ); + } + const hwp = buildHwpOle2(fileHdr, docInfoCmp, bodyCmp, images); + if (!validateOle2Magic(hwp)) { + return fail("HwpEncoder: OLE2 \uB9E4\uC9C1 \uBC14\uC774\uD2B8 \uC624\uB958"); + } + if (hwp.length < 512) { + return fail( + `HwpEncoder: HWP \uD30C\uC77C \uD06C\uAE30 \uBD80\uC871 - ${hwp.length} bytes (\uCD5C\uC18C 512 bytes)` + ); + } + return succeed(hwp); + } catch (e) { + return fail(`HwpEncoder: ${e instanceof Error ? e.message : String(e)}`); + } + } +}; +registry.registerEncoder(new HwpEncoder()); + +// src/pipeline/Pipeline.ts +var Pipeline = class _Pipeline { + constructor(raw, srcFmt) { + this.raw = raw; + this.srcFmt = srcFmt; + } + /** 파일을 열고 포맷을 자동 감지하거나 명시 */ + static open(input, fmt) { + if (typeof input === "string") { + return new _Pipeline(new TextEncoder().encode(input), fmt ?? "md"); + } + return new _Pipeline(input, fmt ?? detectFormat(input)); + } + /** File/Blob 비동기 입력 */ + static async openAsync(input, fmt) { + if (input instanceof Uint8Array || typeof input === "string") { + return _Pipeline.open(input, fmt); + } + const buf = await input.arrayBuffer(); + const data = new Uint8Array(buf); + const detectedFmt = fmt ?? (input instanceof File ? getExt(input.name) : void 0) ?? detectFormat(data); + return new _Pipeline(data, detectedFmt); + } + /** 목표 포맷으로 변환 */ + async to(targetFmt, options) { + const decoder = registry.getDecoder(this.srcFmt); + const encoder = registry.getEncoder(targetFmt); + if (!decoder) return fail(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC785\uB825 \uD3EC\uB9F7: ${this.srcFmt}`); + if (!encoder) return fail(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uCD9C\uB825 \uD3EC\uB9F7: ${targetFmt}`); + const docResult = await decoder.decode(this.raw); + if (!docResult.ok) return docResult; + const encResult = await encoder.encode(docResult.data, options); + if (!encResult.ok) return { ...encResult, warns: [...docResult.warns, ...encResult.warns] }; + return { ...encResult, warns: [...docResult.warns, ...encResult.warns] }; + } + /** DocRoot만 추출 (인코딩 없이) */ + async inspect() { + const decoder = registry.getDecoder(this.srcFmt); + if (!decoder) return fail(`\uB514\uCF54\uB354 \uC5C6\uC74C: ${this.srcFmt}`); + return decoder.decode(this.raw); + } +}; +function detectFormat(data) { + if (data[0] === 208 && data[1] === 207 && data[2] === 17 && data[3] === 224) return "hwp"; + if (data[0] === 80 && data[1] === 75) { + const str = new TextDecoder("utf-8", { fatal: false }).decode(data.slice(0, 4096)); + if (str.includes("wordprocessingml")) return "docx"; + if (str.includes("ha-xml")) return "hwpx"; + if (str.includes("hwpml/")) return "hwpx"; + if (str.includes("word/")) return "docx"; + return "hwpx"; + } + return "md"; +} +function getExt(name) { + const parts = name.split("."); + return parts.length> 1 ? parts[parts.length - 1].toLowerCase() : void 0; +} + +// src/walk/TreeWalker.ts +function walkNode(node, cb, parent = null, depth = 0) { + const result = cb(node, parent, depth); + if (result === "stop") return false; + if ("kids" in node && Array.isArray(node.kids)) { + for (const kid of node.kids) { + if (!walkNode(kid, cb, node, depth + 1)) return false; + } + } + return true; +} +var TreeWalker = class { + walk(root, cb) { + walkNode(root, cb); + } + findAll(root, predicate) { + const results = []; + walkNode(root, (n) => { + if (predicate(n)) results.push(n); + }); + return results; + } + extractText(root) { + const parts = []; + walkNode(root, (n) => { + if (n.tag === "txt") parts.push(n.content); + if (n.tag === "br") parts.push("\n"); + if (n.tag === "pb") parts.push("\n\n"); + }); + return parts.join(""); + } +}; + +// src/walk/tree-ops.ts +function countNodes(root) { + const counts = {}; + walkNode(root, (n) => { + counts[n.tag] = (counts[n.tag] ?? 0) + 1; + }); + return counts; +} +function validateRoot(root) { + const errors = []; + if (root.tag !== "root") errors.push('Root node must have tag "root"'); + if (!Array.isArray(root.kids)) errors.push("Root.kids must be an array"); + if (root.kids.length === 0) errors.push("Document has no sheets"); + walkNode(root, (n) => { + if (n.tag === "cell" && n.kids.length === 0) { + errors.push("CellNode must have at least one ParaNode child"); + } + if (n.tag === "grid" && n.kids.length === 0) { + errors.push("GridNode must have at least one RowNode"); + } + }); + return errors; +} +export { + A4, + A4_LANDSCAPE, + ArchiveKit, + BinaryKit, + DEFAULT_STROKE, + Metric, + Pipeline, + ShieldedParser, + TextKit, + TreeWalker, + XmlKit, + buildBr, + buildCell, + buildGrid, + buildImg, + buildPageNum, + buildPara, + buildPb, + buildRoot, + buildRow, + buildSheet, + buildSpan, + countNodes, + fail, + normalizeDims, + registry, + safeAlign, + safeFont, + safeFontToKr, + safeHex, + safeStrokeDocx, + safeStrokeHwpx, + succeed, + validateRoot, + walkNode +}; +//# sourceMappingURL=index.mjs.map \ No newline at end of file diff --git a/hwpkit-extension/index.mjs.map b/hwpkit-extension/index.mjs.map new file mode 100644 index 000000000..813610d0d --- /dev/null +++ b/hwpkit-extension/index.mjs.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/contract/result.ts","../src/pipeline/registry.ts","../src/model/doc-props.ts","../src/model/builders.ts","../src/safety/ShieldedParser.ts","../src/safety/StyleBridge.ts","../src/toolkit/ArchiveKit.ts","../src/toolkit/XmlKit.ts","../src/toolkit/TextKit.ts","../src/core/BaseDecoder.ts","../src/encoders/hwpx/constants.ts","../src/decoders/hwpx/HwpxDecoder.ts","../src/toolkit/BinaryKit.ts","../src/decoders/hwp/HwpScanner.ts","../src/decoders/docx/DocxDecoder.ts","../src/decoders/md/MdDecoder.ts","../src/decoders/html/HtmlDecoder.ts","../src/core/BaseEncoder.ts","../src/encoders/hwpx/HwpxEncoder.ts","../src/encoders/docx/DocxEncoder.ts","../src/encoders/md/MdEncoder.ts","../src/encoders/html/HtmlEncoder.ts","../src/encoders/hwp/HwpEncoder.ts","../src/pipeline/Pipeline.ts","../src/walk/TreeWalker.ts","../src/walk/tree-ops.ts"],"sourcesContent":["export type Outcome = Ok | Fail;\n\nexport interface Ok {\n ok: true;\n data: T;\n warns: string[];\n}\n\nexport interface Fail {\n ok: false;\n error: string;\n warns: string[];\n}\n\nexport function succeed(data: T, warns: string[] = []): Ok {\n return { ok: true, data, warns };\n}\n\nexport function fail(error: string, warns: string[] = []): Fail {\n return { ok: false, error, warns };\n}\n","import type { Decoder } from '../contract/decoder';\nimport type { Encoder } from '../contract/encoder';\n\nclass FormatRegistry {\n private decoders = new Map();\n private encoders = new Map();\n\n registerDecoder(d: Decoder): void {\n this.decoders.set(d.format, d);\n if (d.aliases) {\n for (const alias of d.aliases) this.decoders.set(alias, d);\n }\n }\n\n registerEncoder(e: Encoder): void {\n this.encoders.set(e.format, e);\n if (e.aliases) {\n for (const alias of e.aliases) this.encoders.set(alias, e);\n }\n }\n\n getDecoder(fmt: string): Decoder | undefined { return this.decoders.get(fmt); }\n getEncoder(fmt: string): Encoder | undefined { return this.encoders.get(fmt); }\n\n supportedInputs(): string[] { return [...this.decoders.keys()]; }\n supportedOutputs(): string[] { return [...this.encoders.keys()]; }\n}\n\nexport const registry = new FormatRegistry();\n","export type Align = 'left' | 'center' | 'right' | 'justify';\n\n// ─── 이미지 배치 ────────────────────────────────────────────\nexport type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front' | 'topAndBottom';\nexport type ImgHorzAlign = 'left' | 'center' | 'right';\nexport type ImgVertAlign = 'top' | 'center' | 'bottom';\nexport type ImgHorzRelTo = 'margin' | 'column' | 'page' | 'para';\nexport type ImgVertRelTo = 'margin' | 'line' | 'page' | 'para';\n\nexport interface ImgLayout {\n wrap: ImgWrap;\n horzAlign?: ImgHorzAlign; // 정렬 기준 (xPt 없을 때)\n vertAlign?: ImgVertAlign; // 정렬 기준 (yPt 없을 때)\n horzRelTo?: ImgHorzRelTo; // 가로 기준점\n vertRelTo?: ImgVertRelTo; // 세로 기준점\n xPt?: number; // 명시적 가로 오프셋 (pt)\n yPt?: number; // 명시적 세로 오프셋 (pt)\n distT?: number; // 텍스트와의 거리 top (pt)\n distB?: number;\n distL?: number;\n distR?: number;\n behindDoc?: boolean; // 텍스트 뒤에 배치\n zOrder?: number;\n}\nexport type VAlign = 'top' | 'mid' | 'bot';\nexport type Heading = 1 | 2 | 3 | 4 | 5 | 6;\nexport type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none' | 'dashDot' | 'dashDotDot' | 'wave';\n\nexport interface TextProps {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n sup?: boolean;\n sub?: boolean;\n font?: string;\n pt?: number;\n color?: string;\n bg?: string;\n}\n\nexport interface ParaProps {\n align?: Align;\n heading?: Heading;\n styleId?: string; // DOCX pStyle styleId (e.g. \"Heading1\", \"TOC1\")\n indentPt?: number; // 문단 왼쪽 전체 들여쓰기 (pt) — OWPML hc:left\n indentRightPt?: number; // 문단 오른쪽 전체 들여쓰기 (pt) — OWPML hc:right\n firstLineIndentPt?: number; // 첫 줄 들여쓰기 (pt, 음수=내어쓰기) — OWPML hc:indent\n leftMargin?: number; // 문단 왼쪽 여백 (HWP leftMargin, pt)\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number; // 줄 간격 배율 (예: 1.5 = 150%)\n lineHeightFixed?: number; // 고정 줄 높이 (pt) — OWPML lineSpacing type=\"FIXED\"\n listLv?: number;\n listOrd?: boolean;\n listMark?: string;\n}\n\nexport interface Stroke {\n kind: StrokeKind;\n pt: number;\n color: string;\n}\n\nexport interface CellProps {\n top?: Stroke;\n bot?: Stroke;\n left?: Stroke;\n right?: Stroke;\n bg?: string;\n padPt?: number; // 모든 방향 균일 패딩 (하위 호환)\n padT?: number; // 상단 패딩 (pt)\n padB?: number; // 하단 패딩\n padL?: number; // 좌측 패딩\n padR?: number; // 우측 패딩\n align?: Align;\n va?: VAlign;\n isHeader?: boolean;\n}\n\nexport interface TableLook {\n firstRow?: boolean;\n lastRow?: boolean;\n firstCol?: boolean;\n lastCol?: boolean;\n bandedRows?: boolean;\n bandedCols?: boolean;\n}\n\nexport interface GridProps {\n widthPct?: number;\n colWidths?: number[]; // column widths in points\n defaultStroke?: Stroke;\n look?: TableLook;\n headerRow?: boolean;\n align?: Align; // 표 정렬: 'left' | 'center' | 'right' | 'justify'\n}\n\nexport interface PageDims {\n wPt: number;\n hPt: number;\n mt: number;\n mb: number;\n ml: number;\n mr: number;\n orient?: 'portrait' | 'landscape';\n headerPt?: number; // distance from paper top to header top (DOCX w:header)\n footerPt?: number; // distance from paper bottom to footer bottom (DOCX w:footer)\n}\n\nexport interface DocMeta {\n title?: string;\n author?: string;\n subject?: string;\n desc?: string;\n keywords?: string;\n created?: string;\n modified?: string;\n zoom?: number;\n viewMode?: string;\n}\n\nexport const A4: PageDims = {\n wPt: 595.28, hPt: 841.89,\n mt: 56.69, mb: 56.69, ml: 70.87, mr: 70.87,\n orient: 'portrait',\n};\n\nexport const A4_LANDSCAPE: PageDims = {\n wPt: 841.89, hPt: 595.28,\n mt: 56.69, mb: 56.69, ml: 70.87, mr: 70.87,\n orient: 'landscape',\n};\n\n/**\n * orient === 'landscape'일 때 wPt < hPt이면 swap,\n * orient === 'portrait'일 때 wPt> hPt이면 swap하여\n * 방향과 치수가 항상 일치하도록 정규화합니다.\n */\n\nexport function normalizeDims(dims: PageDims): PageDims {\n const orient = dims.orient ?? 'portrait';\n if (orient === 'landscape' && dims.wPt < dims.hPt) {\n return { ...dims, wPt: dims.hPt, hPt: dims.wPt };\n }\n if (orient === 'portrait' && dims.wPt> dims.hPt) {\n return { ...dims, wPt: dims.hPt, hPt: dims.wPt };\n }\n return dims;\n}\n\nexport const DEFAULT_STROKE: Stroke = { kind: 'solid', pt: 0.5, color: '000000' };\n","import type {\n DocRoot, SheetNode, ParaNode, SpanNode, ImgNode,\n GridNode, RowNode, CellNode, ContentNode, TxtNode, PageNumNode, BrNode, PbNode,\n} from './doc-tree';\nimport type { TextProps, ParaProps, CellProps, GridProps, DocMeta, PageDims, ImgLayout } from './doc-props';\nimport { A4 } from './doc-props';\n\nexport function buildRoot(meta: DocMeta = {}, kids: SheetNode[] = []): DocRoot {\n return { tag: 'root', meta, kids };\n}\n\nexport function buildSheet(\n kids: ContentNode[] = [],\n dims: PageDims = A4,\n opts?: { headers?: SheetNode[\"headers\"]; footers?: SheetNode[\"footers\"] },\n): SheetNode {\n const node: SheetNode = { tag: 'sheet', dims, kids };\n if (opts?.headers) node.headers = opts.headers;\n if (opts?.footers) node.footers = opts.footers;\n return node;\n}\n\nexport function buildPageNum(format?: PageNumNode['format']): PageNumNode {\n return { tag: 'pagenum', format };\n}\n\nexport function buildBr(): BrNode { return { tag: 'br' }; }\nexport function buildPb(): PbNode { return { tag: 'pb' }; }\n\nexport function buildPara(kids: ParaNode['kids'] = [], props: ParaProps = {}): ParaNode {\n return { tag: 'para', props, kids };\n}\n\nexport function buildSpan(content: string, props: TextProps = {}): SpanNode {\n const txt: TxtNode = { tag: 'txt', content };\n return { tag: 'span', props, kids: [txt] };\n}\n\nexport function buildImg(\n b64: string,\n mime: ImgNode['mime'],\n w: number,\n h: number,\n alt?: string,\n layout?: ImgLayout,\n): ImgNode {\n const node: ImgNode = { tag: 'img', b64, mime, w, h };\n if (alt) node.alt = alt;\n if (layout) node.layout = layout;\n return node;\n}\n\nexport function buildGrid(kids: RowNode[], props: GridProps = {}): GridNode {\n return { tag: 'grid', props, kids };\n}\n\nexport function buildRow(kids: CellNode[], heightPt?: number): RowNode {\n const node: RowNode = { tag: 'row', kids };\n if (heightPt != null) node.heightPt = heightPt;\n return node;\n}\n\nexport function buildCell(\n kids: (ParaNode | GridNode)[],\n opts: { cs?: number; rs?: number; props?: CellProps } = {},\n): CellNode {\n return { tag: 'cell', cs: opts.cs ?? 1, rs: opts.rs ?? 1, props: opts.props ?? {}, kids };\n}\n","export class ShieldedParser {\n private log: string[] = [];\n\n /** 단일 요소 안전 파싱 */\n guard(fn: () => T, fallback: T, label: string): T {\n try {\n const v = fn();\n if (v == null) {\n this.warn(label, 'returned null/undefined');\n return fallback;\n }\n return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n return fallback;\n }\n }\n\n /** 배열 각 요소 독립 파싱 (하나 실패해도 나머지 계속) */\n guardAll(\n items: I[],\n fn: (x: I, i: number) => O,\n fb: (x: I, i: number) => O,\n label: string,\n ): O[] {\n return items.map((x, i) =>\n this.guard(() => fn(x, i), fb(x, i), `${label}[${i}]`),\n );\n }\n\n /**\n * 표 전용 4단계 폴백\n * Lv1: Full → Lv2: Grid → Lv3: Flat → Lv4: Text\n */\n guardGrid(\n node: unknown,\n lv1Full: (n: unknown) => T,\n lv2Grid: (n: unknown) => T,\n lv3Flat: (n: unknown) => T,\n lv4Text: (n: unknown) => T,\n label: string,\n ): { value: T; level: 1 | 2 | 3 | 4 } {\n const levels: [(n: unknown) => T, 1 | 2 | 3 | 4][] = [\n [lv1Full, 1], [lv2Grid, 2], [lv3Flat, 3], [lv4Text, 4],\n ];\n\n for (const [fn, lv] of levels) {\n try {\n const v = fn(node);\n if (v != null) {\n if (lv> 1) this.warn(label, `degraded to level ${lv}`);\n return { value: v, level: lv };\n }\n } catch (e: any) {\n this.warn(label, `Lv${lv} failed: ${e?.message ?? String(e)}`);\n }\n }\n\n this.warn(label, 'ALL LEVELS FAILED — returning lv4Text forced');\n return { value: lv4Text(null), level: 4 };\n }\n\n /** 이미지 안전 파싱 */\n guardImg(\n node: unknown,\n fn: (n: unknown) => T,\n placeholder: (alt: string) => T,\n label: string,\n ): T {\n try {\n const v = fn(node);\n if (v != null) return v;\n } catch (e: any) {\n this.warn(label, e?.message ?? String(e));\n }\n this.warn(label, 'using placeholder image');\n return placeholder(`[이미지 로드 실패: ${label}]`);\n }\n\n private warn(label: string, msg: string): void {\n const w = `[SHIELD] ${label}: ${msg}`;\n console.warn(w);\n this.log.push(w);\n }\n\n flush(): string[] {\n const r = [...this.log];\n this.log = [];\n return r;\n }\n}\n","import type { Align, StrokeKind, Stroke } from '../model/doc-props';\n\n// ─── 단위 변환 ─────────────────────────────────────────────\nexport const Metric = {\n // HWP 세계 (1 inch = 7200 HWPUNIT)\n hwpToPt: (v: number) => v / 100,\n ptToHwp: (v: number) => Math.round(v * 100),\n hwpToDxa: (v: number) => Math.round(v / 5),\n dxaToHwp: (v: number) => Math.round(v * 5),\n hwpToEmu: (v: number) => Math.round(v * 127),\n emuToHwp: (v: number) => Math.round(v / 127),\n\n // DOCX 세계 (1 inch = 1440 dxa, 1 pt = 20 dxa)\n dxaToPt: (v: number) => v / 20,\n ptToDxa: (v: number) => Math.round(v * 20),\n dxaToEmu: (v: number) => Math.round(v * 635),\n emuToDxa: (v: number) => Math.round(v / 635),\n emuToPt: (v: number) => v / 12700,\n ptToEmu: (v: number) => Math.round(v * 12700),\n\n // HWPX charPr height: 1000 = 10pt\n hHeightToPt: (v: number) => v / 100,\n ptToHHeight: (v: number) => Math.round(v * 100),\n\n // DOCX half-point: 24 = 12pt\n halfPtToPt: (v: number) => v / 2,\n ptToHalfPt: (v: number) => Math.round(v * 2),\n} as const;\n\n// ─── 색상 정규화 ───────────────────────────────────────────\nexport function safeHex(raw: string | number | null | undefined): string | undefined {\n if (raw == null) return undefined;\n if (typeof raw === 'number') {\n if (raw <= 0) return '000000';\n if (raw>= 0xFFFFFF) return undefined;\n return raw.toString(16).padStart(6, '0').toUpperCase();\n }\n let s = String(raw).replace(/^#/, '').toUpperCase();\n if (/^[0-9A-F]{3}$/.test(s)) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2];\n if (/^[0-9A-F]{6}$/.test(s)) return s;\n if (s === 'AUTO' || s === 'NONE' || s === 'TRANSPARENT') return undefined;\n return undefined;\n}\n\n// ─── 정렬 정규화 ───────────────────────────────────────────\nconst ALIGN_MAP: Record = {\n LEFT: 'left', CENTER: 'center', RIGHT: 'right', JUSTIFY: 'justify',\n BOTH: 'justify', DISTRIBUTE: 'justify',\n left: 'left', center: 'center', right: 'right', both: 'justify',\n start: 'left', end: 'right',\n};\nexport function safeAlign(raw?: string): Align {\n return ALIGN_MAP[raw ?? ''] ?? 'left';\n}\n\n// ─── 테두리 정규화 ─────────────────────────────────────────\nconst HWPX_STROKE: Record = {\n SOLID: \"solid\",\n NONE: \"none\",\n DASH: \"dash\",\n DOT: \"dot\",\n DOUBLE: \"double\",\n LONG_DASH: \"dash\",\n DASH_DOT: \"dashDot\",\n DASH_DOT_DOT: \"dashDotDot\",\n THICK_THIN: \"double\",\n THIN_THICK: \"double\",\n TRIPLE: \"double\",\n};\nconst DOCX_STROKE: Record = {\n single: \"solid\",\n none: \"none\",\n nil: \"none\",\n dashed: \"dash\",\n dotted: \"dot\",\n double: \"double\",\n dotDash: \"dashDot\",\n dotDotDash: \"dashDotDot\",\n thickThin: \"double\",\n thinThick: \"double\",\n triple: \"double\",\n wave: \"wave\",\n dashDotStroked: \"dashDot\",\n threeDEmboss: \"solid\",\n threeDEngrave: \"solid\",\n};\n\nexport function safeStrokeHwpx(type?: string, w?: number, c?: string): Stroke {\n return {\n kind: HWPX_STROKE[type ?? ''] ?? 'solid',\n pt: w != null ? Metric.hwpToPt(w) : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\nexport function safeStrokeDocx(val?: string, sz?: number, c?: string): Stroke {\n return {\n kind: DOCX_STROKE[val ?? ''] ?? 'solid',\n pt: sz != null ? sz / 8 : 0.5,\n color: safeHex(c) ?? '000000',\n };\n}\n\n// ─── 폰트 정규화 ───────────────────────────────────────────\nconst FONT_MAP: Record = {\n // 맑은 고딕 계열\n '맑은 고딕': 'Malgun Gothic',\n '맑은고딕': 'Malgun Gothic',\n // 바탕 계열 (serif)\n '바탕': 'Batang',\n '바탕체': 'BatangChe',\n '한컴바탕': 'Batang',\n '함초롬바탕': 'Batang',\n 'HY신명조': 'Batang',\n 'HY견명조': 'Batang',\n 'HY그래픽': 'Batang',\n '궁서': 'Gungsuh',\n '궁서체': 'GungsuhChe',\n // 고딕 계열 (sans-serif)\n '돋움': 'Dotum',\n '돋움체': 'DotumChe',\n '굴림': 'Gulim',\n '굴림체': 'GulimChe',\n '한컴돋움': 'Malgun Gothic',\n '함초롬돋움': 'Malgun Gothic',\n 'HY견고딕': 'Malgun Gothic',\n 'HY중고딕': 'Malgun Gothic',\n 'HY헤드라인M': 'Malgun Gothic',\n 'HY강B': 'Malgun Gothic',\n 'HY나무M': 'Malgun Gothic',\n 'HY목각파임B': 'Malgun Gothic',\n 'HY엽서M': 'Malgun Gothic',\n 'HY엽서L': 'Malgun Gothic',\n // 나눔 계열\n '나눔고딕': 'Malgun Gothic',\n '나눔명조': 'Batang',\n};\nexport function safeFont(raw?: string): string {\n return FONT_MAP[raw ?? ''] ?? raw ?? 'Malgun Gothic';\n}\n\n// Reverse mapping: English → Korean (for HWPX encoding)\nconst FONT_MAP_KR: Record = {\n 'Malgun Gothic': '맑은 고딕',\n 'Batang': '바탕',\n 'Dotum': '돋움',\n 'Gulim': '굴림',\n};\nexport function safeFontToKr(raw?: string): string {\n return FONT_MAP_KR[raw ?? ''] ?? raw ?? '맑은 고딕';\n}\n","import pako from 'pako';\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nexport const ArchiveKit = {\n async inflate(compressed: Uint8Array): Promise {\n return pako.inflate(compressed);\n },\n\n async deflate(data: Uint8Array): Promise {\n return pako.deflate(data, { level: 6 });\n },\n\n async unzip(zipData: Uint8Array): Promise
              > {\n const files = new Map();\n const view = new DataView(zipData.buffer, zipData.byteOffset, zipData.byteLength);\n\n // Find EOCD by scanning backward from end (supports ZIP comment up to 64KB)\n let eocdOffset = -1;\n const searchStart = Math.max(0, zipData.length - 65558);\n for (let i = zipData.length - 22; i>= searchStart; i--) {\n if (view.getUint32(i, true) === 0x06054b50) {\n eocdOffset = i;\n break;\n }\n }\n\n if (eocdOffset !== -1) {\n // Parse central directory — always has correct sizes even with data descriptors\n const entryCount = view.getUint16(eocdOffset + 10, true);\n const centralDirOffset = view.getUint32(eocdOffset + 16, true);\n\n let cdOffset = centralDirOffset;\n for (let i = 0; i < entryCount; i++) {\n if (cdOffset + 46> zipData.length) break;\n if (view.getUint32(cdOffset, true) !== 0x02014b50) break;\n\n const compressionMethod = view.getUint16(cdOffset + 10, true);\n const compressedSize = view.getUint32(cdOffset + 20, true);\n const uncompressedSize = view.getUint32(cdOffset + 24, true);\n const fileNameLength = view.getUint16(cdOffset + 28, true);\n const extraLength = view.getUint16(cdOffset + 30, true);\n const commentLength = view.getUint16(cdOffset + 32, true);\n const localHeaderOffset = view.getUint32(cdOffset + 42, true);\n\n const nameBytes = zipData.subarray(cdOffset + 46, cdOffset + 46 + fileNameLength);\n const name = new TextDecoder('utf-8').decode(nameBytes);\n cdOffset += 46 + fileNameLength + extraLength + commentLength;\n\n if (name.endsWith('/')) continue; // directory entry\n\n // Read actual data using the local header offset from central directory\n const localFnLen = view.getUint16(localHeaderOffset + 26, true);\n const localExtraLen = view.getUint16(localHeaderOffset + 28, true);\n const dataOffset = localHeaderOffset + 30 + localFnLen + localExtraLen;\n\n let fileData: Uint8Array;\n if (compressionMethod === 0) {\n fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize);\n } else if (compressionMethod === 8) {\n const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize);\n fileData = pako.inflateRaw(compressed);\n } else {\n throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`);\n }\n\n files.set(name, new Uint8Array(fileData));\n }\n\n return files;\n }\n\n // Fallback: scan local headers sequentially (no EOCD found — truncated ZIP)\n let offset = 0;\n while (offset < zipData.length - 4) {\n const sig = view.getUint32(offset, true);\n\n if (sig === 0x04034b50) {\n const compressionMethod = view.getUint16(offset + 8, true);\n const compressedSize = view.getUint32(offset + 18, true);\n const uncompressedSize = view.getUint32(offset + 22, true);\n const fileNameLength = view.getUint16(offset + 26, true);\n const extraLength = view.getUint16(offset + 28, true);\n\n const nameBytes = zipData.subarray(offset + 30, offset + 30 + fileNameLength);\n const name = new TextDecoder('utf-8').decode(nameBytes);\n\n const dataOffset = offset + 30 + fileNameLength + extraLength;\n let fileData: Uint8Array;\n\n if (compressionMethod === 0) {\n fileData = zipData.subarray(dataOffset, dataOffset + uncompressedSize);\n } else if (compressionMethod === 8) {\n const compressed = zipData.subarray(dataOffset, dataOffset + compressedSize);\n fileData = pako.inflateRaw(compressed);\n } else {\n throw new Error(`Unsupported ZIP compression method: ${compressionMethod}`);\n }\n\n files.set(name, new Uint8Array(fileData));\n offset = dataOffset + compressedSize;\n } else if (sig === 0x02014b50 || sig === 0x06054b50) {\n break;\n } else {\n offset++;\n }\n }\n\n return files;\n },\n\n async zip(entries: ZipEntry[]): Promise {\n const localHeaders: Uint8Array[] = [];\n const centralHeaders: Uint8Array[] = [];\n let localOffset = 0;\n\n for (const entry of entries) {\n const nameBytes = new TextEncoder().encode(entry.name);\n const crc = crc32(entry.data);\n\n // 'mimetype' and 'version.xml' must be stored uncompressed per HWPX spec\n const store = entry.name === 'mimetype' || entry.name === 'version.xml';\n const method = store ? 0 : 8;\n const payload = store ? entry.data : pako.deflateRaw(entry.data, { level: 6 });\n\n // Local file header (30 bytes + name + data)\n const local = new Uint8Array(30 + nameBytes.length + payload.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0, true);\n lv.setUint16(8, method, true);\n lv.setUint16(10, 0, true);\n lv.setUint16(12, 0x0021, true); // date (1980年01月01日)\n lv.setUint32(14, crc, true);\n lv.setUint32(18, payload.length, true);\n lv.setUint32(22, entry.data.length, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n local.set(payload, 30 + nameBytes.length);\n\n // Central directory header (46 bytes + name)\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0, true);\n cv.setUint16(10, method, true);\n cv.setUint16(12, 0, true); // mod time\n cv.setUint16(14, 0x0021, true); // mod date (1980年01月01日)\n cv.setUint32(16, crc, true);\n cv.setUint32(20, payload.length, true);\n cv.setUint32(24, entry.data.length, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, localOffset, true);\n central.set(nameBytes, 46);\n\n localHeaders.push(local);\n centralHeaders.push(central);\n localOffset += local.length;\n }\n\n const centralDir = concat(centralHeaders);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDir.length, true);\n ev.setUint32(16, localOffset, true);\n ev.setUint16(20, 0, true);\n\n return concat([...localHeaders, centralDir, eocd]);\n },\n};\n\nfunction concat(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const a of arrays) { out.set(a, offset); offset += a.length; }\n return out;\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xFFFFFFFF;\n for (const byte of data) {\n crc ^= byte;\n for (let i = 0; i < 8; i++) {\n crc = (crc & 1) ? (crc>>> 1) ^ 0xEDB88320 : crc>>> 1;\n }\n }\n return (crc ^ 0xFFFFFFFF)>>> 0;\n}\n","import { SaxesParser } from 'saxes';\n\n// Parses XML into an xml2js-compatible object structure:\n// { tagName: [{ _attr: { k: v }, _text: '...', childTag: [...] }] }\nfunction parseXmlStrict(xml: string): Promise {\n return new Promise((resolve, reject) => {\n const parser = new SaxesParser({ xmlns: false });\n\n interface Frame { tag: string; obj: Record }\n const stack: Frame[] = [];\n let result: unknown = null;\n\n parser.on('error', (err: Error) => reject(err));\n\n parser.on('opentag', (node: any) => {\n const obj: Record = {};\n const attrs = node.attributes as Record;\n if (attrs && Object.keys(attrs).length> 0) {\n obj['_attr'] = { ...attrs };\n }\n stack.push({ tag: node.name as string, obj });\n });\n\n const appendText = (text: string) => {\n if (stack.length> 0 && text) {\n const frame = stack[stack.length - 1];\n const cur = frame.obj['_text'];\n frame.obj['_text'] = typeof cur === 'string' ? cur + text : text;\n }\n };\n\n parser.on('text', (text: string) => appendText(text));\n parser.on('cdata', (cdata: string) => appendText(cdata));\n\n parser.on('closetag', () => {\n const frame = stack.pop();\n if (!frame) return;\n const { tag, obj } = frame;\n\n if (stack.length === 0) {\n result = { [tag]: [obj] };\n } else {\n const parent = stack[stack.length - 1].obj;\n const existing = parent[tag];\n if (Array.isArray(existing)) {\n (existing as unknown[]).push(obj);\n } else {\n parent[tag] = [obj];\n }\n // Track child order for document-order iteration\n if (!parent['_childOrder']) parent['_childOrder'] = [];\n (parent['_childOrder'] as string[]).push(tag);\n }\n });\n\n try {\n parser.write(xml).close();\n resolve(result);\n } catch (e) {\n reject(e);\n }\n });\n}\n\nexport const XmlKit = {\n /** @deprecated Use parseStrict instead */\n async parse(xml: string): Promise {\n return parseXmlStrict(xml);\n },\n\n async parseStrict(xml: string): Promise {\n return parseXmlStrict(xml);\n },\n\n attr(node: Record, key: string): string | undefined {\n const a = node['_attr'] as Record | undefined;\n return a?.[key];\n },\n\n text(node: Record | string | undefined): string {\n if (node == null) return '';\n if (typeof node === 'string') return node;\n const t = node['_text'];\n return typeof t === 'string' ? t : '';\n },\n};\n","export const TextKit = {\n decode(data: Uint8Array, encoding = 'utf-8'): string {\n try {\n return new TextDecoder(encoding, { fatal: true }).decode(data);\n } catch {\n return new TextDecoder('utf-8', { fatal: false }).decode(data);\n }\n },\n\n encode(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n },\n\n escapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n },\n\n unescapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\");\n },\n\n normalizeWhitespace(s: string): string {\n return s.replace(/\\s+/g, ' ').trim();\n },\n\n stripControl(s: string): string {\n // eslint-disable-next-line no-control-regex\n return s.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n },\n\n base64Encode(data: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < data.length; i++) {\n binary += String.fromCharCode(data[i]);\n }\n return btoa(binary);\n },\n\n base64Decode(b64: string): Uint8Array {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n },\n};\n","/**\n * BaseDecoder - 모든 디코더의 기본 클래스\n *\n * 공통 로직을 제공하여 각 포맷별 디코더가 포맷 특유의 로직만 구현하도록 합니다.\n */\n\nimport type { Decoder } from '../contract/decoder';\nimport type { Outcome } from '../contract/result';\nimport type { DocRoot } from '../model/doc-tree';\nimport { TextKit } from '../toolkit/TextKit';\nimport { ArchiveKit } from '../toolkit/ArchiveKit';\n\n// ─── BaseDecoder ───────────────────────────────────\n\nexport abstract class BaseDecoder implements Decoder {\n readonly format: string = this.getFormat();\n readonly aliases: string[] = this.getAliases();\n\n /** 포맷 이름 반환 (하위 클래스에서 오버라이드) */\n protected abstract getFormat(): string;\n\n /** 별칭 목록 반환 (하위 클래스에서 필요 시 오버라이드) */\n protected getAliases(): string[] { return []; }\n\n /** 데이터 디코딩 (하위 클래스에서 오버라이드) */\n abstract decode(data: Uint8Array): Promise>;\n\n // ─── 공통 유틸리티 메서드 ──────────────────────────\n\n /** 바이트를 UTF-8 문자열로 변환 */\n protected bytesToString(data: Uint8Array): string {\n return TextKit.decode(data);\n }\n\n /** 문자열을 UTF-8 바이트로 변환 */\n protected stringToBytes(s: string): Uint8Array {\n return TextKit.encode(s);\n }\n\n /** XML 이스케이프 */\n protected escapeXml(s: string): string {\n return TextKit.escapeXml(s);\n }\n\n /** XML 언이스케이프 */\n protected unescapeXml(s: string): string {\n return TextKit.unescapeXml(s);\n }\n\n /** base64 문자열을 Uint8Array 로 변환 */\n protected base64ToBytes(b64: string): Uint8Array {\n return TextKit.base64Decode(b64);\n }\n\n /** Uint8Array 를 base64 문자열로 변환 */\n protected bytesToBase64(data: Uint8Array): string {\n return TextKit.base64Encode(data);\n }\n\n /** ZIP 해제 */\n protected async unzip(data: Uint8Array): Promise
                > {\n return ArchiveKit.unzip(data);\n }\n\n /** ZIP 압축 */\n protected async zip(entries: { name: string; data: Uint8Array }[]): Promise {\n return ArchiveKit.zip(entries);\n }\n\n /** inflate 해제 */\n protected async inflate(data: Uint8Array): Promise {\n return ArchiveKit.inflate(data);\n }\n\n /** deflate 압축 */\n protected async deflate(data: Uint8Array): Promise {\n return ArchiveKit.deflate(data);\n }\n\n /** 제어 문자 제거 */\n protected stripControl(s: string): string {\n return TextKit.stripControl(s);\n }\n\n /** 공백 정규화 */\n protected normalizeWhitespace(s: string): string {\n return TextKit.normalizeWhitespace(s);\n }\n\n /** XML 파싱 (DOMParser 사용) */\n protected parseXml(xmlString: string): Document {\n const parser = new DOMParser();\n return parser.parseFromString(xmlString, 'text/xml');\n }\n\n /** XML 요소에서 텍스트 내용 추출 */\n protected getTextContent(element: Element | null | undefined): string {\n if (!element) return '';\n return element.textContent ?? '';\n }\n\n /** XML 요소의 속성 값 추출 */\n protected getAttr(element: Element | null | undefined, name: string): string | null {\n return element?.getAttribute(name) ?? null;\n }\n\n /** XML 요소의 자식 요소 찾기 */\n protected getChild(element: Element | null | undefined, tagName: string): Element | null {\n if (!element) return null;\n return element.querySelector(`>${tagName}`) ?? null;\n }\n\n /** XML 요소의 모든 자식 요소 찾기 */\n protected getChildren(element: Element | null | undefined, tagName: string): Element[] {\n if (!element) return [];\n return Array.from(element.querySelectorAll(`>${tagName}`));\n }\n}\n","/**\n * HWPX 인코더 관련 상수\n *\n * HWPX 파일 생성에 필요한 모든 설정값을 한곳에 모아 관리합니다.\n * 초중급 개발자도 쉽게 수정할 수 있도록 명확한 주석을 포함했습니다.\n */\n\n// ==================== 파일 형식 관련 ====================\n\n/** HWPX 파일의 MIME 타입 (ZIP 파일 내 mimetype 파일에 저장됨) */\nexport const HWPX_MIME_TYPE = \"application/hwp+zip\";\n\n/** HWPX 파일의 버전 */\nexport const HWPX_VERSION = \"1.2\";\n\n// ==================== XML 네임스페이스 ====================\n\n/** HWPX XML 문서에서 사용되는 네임스페이스 */\nexport const NAMESPACES = {\n /** Hancom 문서 네임스페이스 */\n HANCOM: \"http://www.hancom.co.kr/hwp/xml\",\n /** Hancom 공통 네임스페이스 */\n HANCOM_COMMON: \"http://www.hancom.co.kr/hwp/xml/common\",\n /** Hancom 버전 네임스페이스 */\n HANCOM_VERSION: \"http://www.hancom.co.kr/hwp/xml/version\",\n /** Hancom 속성 네임스페이스 */\n HANCOM_PROP: \"http://www.hancom.co.kr/hwp/xml/property\",\n} as const;\n\n/** XML 헤더에 포함될 네임스페이스 선언 문자열 */\nexport const NAMESPACE_DECLARATIONS = {\n HEAD: `xmlns:hh=\"${NAMESPACES.HANCOM}\" xmlns:hc=\"${NAMESPACES.HANCOM_COMMON}\" xmlns:hv=\"${NAMESPACES.HANCOM_VERSION}\" xmlns:hp=\"${NAMESPACES.HANCOM_PROP}\"`,\n SECTION: `xmlns:hs=\"${NAMESPACES.HANCOM}\" xmlns:hp=\"${NAMESPACES.HANCOM_PROP}\"`,\n} as const;\n\n// ==================== 단위 변환 ====================\n\n/** 1 포인트 (pt) 를 HWPUNIT 으로 변환한 값 (HWPX 내부 단위) */\nexport const HWPUNIT_PER_PT = 1000;\n\n/** 1 인치 (inch) 를 포인트 (pt) 로 변환한 값 */\nexport const PT_PER_INCH = 72;\n\n/** 1 인치 (inch) 를 픽셀로 변환한 값 (표준 96 DPI 기준) */\nexport const PIXELS_PER_INCH = 96;\n\n/** 픽셀을 포인트로 변환하는 계수 */\nexport const PT_PER_PIXEL = PT_PER_INCH / PIXELS_PER_INCH; // 0.75\n\n// ==================== 페이지 크기 (A4 기준) ====================\n\n/** A4 용지 너비 (포인트) */\nexport const A4_WIDTH_PT = 794;\n\n/** A4 용지 높이 (포인트) */\nexport const A4_HEIGHT_PT = 1123;\n\n/** A4 용지 상단 여백 (포인트) */\nexport const A4_TOP_MARGIN_PT = 72;\n\n/** A4 용지 하단 여백 (포인트) */\nexport const A4_BOTTOM_MARGIN_PT = 72;\n\n/** A4 용지 왼쪽 여백 (포인트) */\nexport const A4_LEFT_MARGIN_PT = 83;\n\n/** A4 용지 오른쪽 여백 (포인트) */\nexport const A4_RIGHT_MARGIN_PT = 83;\n\n/** A4 용지 상단 머리글 영역 (포인트) */\nexport const A4_HEADER_MARGIN_PT = 40;\n\n/** A4 용지 하단 바닥글 영역 (포인트) */\nexport const A4_FOOTER_MARGIN_PT = 40;\n\n// ==================== 폰트 관련 ====================\n\n/** 기본 한글 폰트 */\nexport const DEFAULT_KOREAN_FONT = \"Batang\";\n\n/** 기본 영문 폰트 */\nexport const DEFAULT_LATIN_FONT = \"Arial\";\n\n/** 기본 폰트 크기 (포인트) */\nexport const DEFAULT_FONT_SIZE_PT = 10;\n\n// ==================== 줄 간격 ====================\n\n/** 기본 줄 간격 (폰트 크기의 %) */\nexport const DEFAULT_LINE_SPACING_PERCENT = 160;\n\n/** 최소 줄 간격 (HWPUNIT) */\nexport const MIN_LINE_SPACING_HWPUNIT = 1000;\n\n// ==================== 스타일 ID ====================\n\n/** 바탕글 스타일 ID */\nexport const STYLE_ID_BATANGGUL = \"0\";\n\n/** 개요 1 스타일 ID */\nexport const STYLE_ID_GYEYOE1 = \"1\";\n\n/** 개요 2 스타일 ID */\nexport const STYLE_ID_GYEYOE2 = \"2\";\n\n// ==================== 이미지 관련 ====================\n\n/** 이미지 파일이 저장될 디렉토리 경로 (ZIP 내) */\nexport const IMAGE_DIR_PATH = \"image/\";\n\n/** 이미지 파일명 접미사 */\nexport const IMAGE_FILE_EXTENSION = \".png\";\n\n// ==================== 테이블 관련 ====================\n\n/** 테이블 테두리 기본 두께 (HWPUNIT) */\nexport const TABLE_BORDER_WIDTH_HWPUNIT = 500; // 0.5pt\n\n/** 테이블 셀 기본 패딩 (HWPUNIT) */\nexport const TABLE_CELL_PADDING_HWPUNIT = 200; // 0.2pt\n\n// ==================== 색상 코드 ====================\n\n/** 검정색 (hex) */\nexport const COLOR_BLACK = \"#000000\";\n\n/** 흰색 (hex) */\nexport const COLOR_WHITE = \"#FFFFFF\";\n\n/** 회색 (워터마크용) */\nexport const COLOR_GRAY = \"#CCCCCC\";\n\n/** 코드 블록 배경색 */\nexport const COLOR_CODE_BLOCK_BG = \"#f4f4f4\";\n\n// ==================== ZIP 파일 구조 ====================\n\n/** HWPX 파일 내 파일 목록 */\nexport const HWPX_FILE_STRUCTURE = [\n { name: \"mimetype\", mimeType: \"\" },\n { name: \".hwpversions/version.xml\", mimeType: \"application/xml\" },\n { name: \"header.xml\", mimeType: \"application/xml\" },\n { name: \"section0.xml\", mimeType: \"application/xml\" },\n { name: \"content.hpf\", mimeType: \"application/octet-stream\" },\n] as const;\n\n/** ZIP 파일 생성 시 사용할 압축 레벨 (0=압축안함, 9=최대압축) */\nexport const ZIP_COMPRESSION_LEVEL = 9;\n","import type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n PageNumNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n DocMeta,\n PageDims,\n TextProps,\n ParaProps,\n CellProps,\n GridProps,\n Stroke,\n ImgLayout,\n ImgWrap,\n ImgHorzAlign,\n ImgVertAlign,\n ImgHorzRelTo,\n ImgVertRelTo,\n} from \"../../model/doc-props\";\nimport { A4 } from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport {\n buildRoot,\n buildSheet,\n buildPara,\n buildSpan,\n buildImg,\n buildGrid,\n buildRow,\n buildCell,\n buildPb,\n} from \"../../model/builders\";\nimport { ShieldedParser } from \"../../safety/ShieldedParser\";\nimport {\n Metric,\n safeAlign,\n safeFont,\n safeHex,\n safeStrokeHwpx,\n} from \"../../safety/StyleBridge\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { XmlKit } from \"../../toolkit/XmlKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\nimport { BaseDecoder } from \"../../core/BaseDecoder\";\nimport { HWPX_MIME_TYPE } from \"../../encoders/hwpx/constants\";\n\ninterface BorderFillInfo {\n stroke?: Stroke; // uniform fallback (used when all sides are the same)\n top?: Stroke;\n right?: Stroke;\n bottom?: Stroke;\n left?: Stroke;\n bgColor?: string;\n}\n\ninterface CharPrInfo {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n pt?: number;\n color?: string;\n font?: string;\n bg?: string;\n}\n\ninterface ParaPrInfo {\n align?: string;\n indentPt?: number; // hc:left → 문단 전체 왼쪽 여백\n indentRightPt?: number; // hc:right → 문단 전체 오른쪽 여백\n firstLineIndentPt?: number; // hc:indent → 첫 줄 들여쓰기 (양수=들여쓰기, 음수=내어쓰기)\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n lineHeightFixed?: number; // FIXED 행 높이 (pt)\n}\n\ninterface DecCtx {\n files: Map;\n shield: ShieldedParser;\n borderFills: Map;\n charPrs: Map;\n paraPrs: Map;\n warns: string[];\n}\n\nexport class HwpxDecoder extends BaseDecoder {\n protected getFormat(): string {\n return \"hwpx\";\n }\n protected getAliases(): string[] {\n return [HWPX_MIME_TYPE, \"application/hwp+zip\"];\n }\n\n async decode(data: Uint8Array): Promise> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const sectionFiles: Uint8Array[] = [];\n for (let i = 0; ; i++) {\n const sec =\n files.get(`Contents/section${i}.xml`) ?? files.get(`section${i}.xml`);\n if (!sec) break;\n sectionFiles.push(sec);\n }\n if (sectionFiles.length === 0) {\n const fallback = findSectionFile(files);\n if (fallback) sectionFiles.push(fallback);\n }\n\n if (sectionFiles.length === 0)\n return fail(\"HWPX: No section files found\");\n\n const headXml =\n files.get(\"Contents/header.xml\") ?? files.get(\"header.xml\");\n\n let meta: DocMeta = {};\n let dims: PageDims = { ...A4 };\n let borderFills = new Map();\n let charPrs = new Map();\n let paraPrs = new Map();\n\n if (headXml) {\n try {\n const headStr = TextKit.decode(headXml);\n const headObj: any = await XmlKit.parseStrict(headStr);\n if (headObj) {\n meta = extractMeta(headObj);\n dims = extractDims(headObj) ?? dims;\n borderFills = extractBorderFills(headObj);\n charPrs = extractCharPrs(headObj);\n paraPrs = extractParaPrs(headObj);\n }\n } catch {\n // header parse failure is non-fatal\n }\n }\n\n const ctx: DecCtx = {\n files,\n shield,\n borderFills,\n charPrs,\n paraPrs,\n warns,\n };\n\n const allSections: any[] = [];\n for (const secFile of sectionFiles) {\n const bodyStr = TextKit.decode(secFile);\n const bodyObj: any = await XmlKit.parseStrict(bodyStr);\n allSections.push(...normalizeSections(bodyObj));\n }\n\n const kids = shield.guardAll(\n allSections,\n (sec: any) => decodeSection(sec, dims, ctx),\n () => buildSheet([buildPara([buildSpan(\"[섹션 파싱 실패]\")])], dims),\n \"hwpx:section\",\n );\n\n warns.push(...shield.flush());\n return succeed(buildRoot(meta, kids), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWPX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction findSectionFile(\n files: Map,\n): Uint8Array | undefined {\n for (const [key, val] of files) {\n if (key.toLowerCase().includes(\"section\") && key.endsWith(\".xml\"))\n return val;\n }\n return undefined;\n}\n\nfunction normalizeSections(bodyObj: any): any[] {\n // (real HWPX), (legacy)\n if (bodyObj?.[\"hs:sec\"]) return toArr(bodyObj[\"hs:sec\"]);\n if (bodyObj?.[\"hp:SEC\"]) return toArr(bodyObj[\"hp:SEC\"]);\n\n const root = bodyObj?.[\"hp:HWPML\"] ?? bodyObj?.HWPML ?? bodyObj;\n const body =\n root?.[\"hp:BODY\"]?.[0] ??\n root?.BODY?.[0] ??\n root?.[\"hp:BODY\"] ??\n root?.BODY;\n if (!body) return [bodyObj];\n const sections = body?.[\"hp:SECTION\"] ?? body?.SECTION ?? [];\n return Array.isArray(sections) ? sections : [sections];\n}\n\n// Get a tag regardless of namespace/case variations\nfunction getTag(obj: any, ...names: string[]): any[] {\n for (const n of names) {\n const v = obj?.[n];\n if (v != null) return toArr(v);\n }\n return [];\n}\n\nfunction extractMeta(headObj: any): DocMeta {\n try {\n // Support both and \n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const info = root?.[\"hh:DOCSUMMARY\"]?.[0] ?? root?.DOCSUMMARY?.[0];\n if (!info) return {};\n const a = (k: string) =>\n info?.[`hh:${k}`]?.[0]?._text ?? info?.[k]?.[0]?._text ?? \"\";\n return {\n title: a(\"TITLE\") || undefined,\n author: a(\"AUTHOR\") || undefined,\n subject: a(\"SUBJECT\") || undefined,\n };\n } catch {\n return {};\n }\n}\n\nfunction extractDims(headObj: any): PageDims | null {\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return null;\n\n const secPrList =\n refList?.[\"hh:SECPRLST\"]?.[0]?.[\"hh:SECPR\"] ??\n refList?.SECPRLST?.[0]?.SECPR;\n const sec = Array.isArray(secPrList) ? secPrList[0] : secPrList;\n if (!sec) return null;\n\n const pa =\n sec?.[\"hh:PAGEPROPERTY\"]?.[0]?._attr ?? sec?.PAGEPROPERTY?.[0]?._attr;\n if (!pa) return null;\n\n const ew = Number(pa.Width ?? 59528);\n const eh = Number(pa.Height ?? 84188);\n return {\n wPt: Metric.hwpToPt(ew),\n hPt: Metric.hwpToPt(eh),\n mt: Metric.hwpToPt(Number(pa.TopMargin ?? 5670)),\n mb: Metric.hwpToPt(Number(pa.BottomMargin ?? 4252)),\n ml: Metric.hwpToPt(Number(pa.LeftMargin ?? 8504)),\n mr: Metric.hwpToPt(Number(pa.RightMargin ?? 8504)),\n orient: ew> eh ? \"landscape\" : \"portrait\",\n };\n } catch {\n return null;\n }\n}\n\nfunction extractBorderFills(headObj: any): Map {\n const map = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n const bfList =\n refList?.[\"hh:borderFills\"]?.[0] ??\n refList?.[\"hh:BORDERFILLLIST\"]?.[0] ??\n refList?.BORDERFILLLIST?.[0];\n if (!bfList) return map;\n\n const bfs = getTag(bfList, \"hh:borderFill\", \"hh:BORDERFILL\");\n for (const bf of bfs) {\n const attr = bf?._attr ?? {};\n const id = Number(attr.id ?? 0);\n if (id === 0) continue;\n\n const info: BorderFillInfo = {};\n\n // Helper: parse a border element into a Stroke\n const parseBorderEl = (el: any): Stroke | undefined => {\n if (!el) return undefined;\n const a = el?._attr ?? {};\n const mmVal = parseFloat(a.width) || undefined;\n const hwpVal = mmVal != null ? mmVal * 2.835 * 100 : undefined;\n return safeStrokeHwpx(a.type, hwpVal, a.color);\n };\n\n // Parse all four sides\n const topEl =\n bf?.[\"hh:topBorder\"]?.[0] ?? bf?.[\"hh:top\"]?.[0] ?? bf?.top?.[0];\n const rightEl =\n bf?.[\"hh:rightBorder\"]?.[0] ?? bf?.[\"hh:right\"]?.[0] ?? bf?.right?.[0];\n const bottomEl =\n bf?.[\"hh:bottomBorder\"]?.[0] ??\n bf?.[\"hh:bottom\"]?.[0] ??\n bf?.bottom?.[0];\n const leftEl =\n bf?.[\"hh:leftBorder\"]?.[0] ?? bf?.[\"hh:left\"]?.[0] ?? bf?.left?.[0];\n\n info.top = parseBorderEl(topEl);\n info.right = parseBorderEl(rightEl);\n info.bottom = parseBorderEl(bottomEl);\n info.left = parseBorderEl(leftEl);\n\n // Set uniform stroke fallback = top border (for defaultStroke etc.)\n info.stroke = info.top ?? info.left ?? info.right ?? info.bottom;\n\n // Parse fill (real HWPX uses hc:fillBrush, not hh:fillBrush)\n const fillBrush =\n bf?.[\"hc:fillBrush\"]?.[0] ??\n bf?.[\"hh:fillBrush\"]?.[0] ??\n bf?.[\"hh:fill\"]?.[0] ??\n bf?.fill?.[0] ??\n bf?.fillBrush?.[0];\n if (fillBrush) {\n const winBrush =\n fillBrush?.[\"hc:winBrush\"]?.[0]?._attr ??\n fillBrush?.[\"hh:winBrush\"]?.[0]?._attr ??\n fillBrush?.winBrush?.[0]?._attr;\n if (winBrush?.faceColor && winBrush.faceColor !== \"none\") {\n info.bgColor = safeHex(winBrush.faceColor);\n }\n }\n\n map.set(id, info);\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction buildFontIdMap(headObj: any): Map {\n const fontMap = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return fontMap;\n\n const fontfaces =\n refList?.[\"hh:fontfaces\"]?.[0] ?? refList?.[\"hh:FONTFACES\"]?.[0];\n if (!fontfaces) return fontMap;\n\n // Try each fontface group (HANGUL, LATIN, etc.) — use the first group that has entries\n const ffGroups = getTag(fontfaces, \"hh:fontface\", \"hh:FONTFACE\");\n for (const ff of ffGroups) {\n const fonts = getTag(ff, \"hh:font\", \"hh:FONT\");\n for (const font of fonts) {\n const fa = font?._attr ?? {};\n const fid = Number(fa.id ?? -1);\n const name = fa.face ?? fa.name ?? fa.Face ?? \"\";\n if (fid>= 0 && name && !fontMap.has(fid)) fontMap.set(fid, name);\n }\n if (fontMap.size> 0) break; // use first group (usually HANGUL)\n }\n } catch {\n /* non-fatal */\n }\n return fontMap;\n}\n\nfunction extractCharPrs(headObj: any): Map {\n const map = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n // Build font id → name map from fontfaces\n const fontIdMap = buildFontIdMap(headObj);\n\n const cpList =\n refList?.[\"hh:charProperties\"]?.[0] ??\n refList?.[\"hh:CHARPROPERTIES\"]?.[0];\n if (!cpList) return map;\n\n const cps = getTag(cpList, \"hh:charPr\", \"hh:CHARPR\");\n for (const cp of cps) {\n const attr = cp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const info: CharPrInfo = {};\n\n // height → pt\n if (attr.height) info.pt = Metric.hHeightToPt(Number(attr.height));\n\n // textColor\n if (attr.textColor) info.color = safeHex(attr.textColor);\n\n // bold\n if (cp?.[\"hh:bold\"]?.[0] != null) info.b = true;\n\n // italic\n if (cp?.[\"hh:italic\"]?.[0] != null) info.i = true;\n\n // underline\n const ulAttr = cp?.[\"hh:underline\"]?.[0]?._attr;\n if (ulAttr?.type && ulAttr.type !== \"NONE\") info.u = true;\n\n // strikeout — shape=\"3D\" is default \"no strikeout\" in real HWPX; only SOLID/etc means active\n const stAttr = cp?.[\"hh:strikeout\"]?.[0]?._attr;\n if (stAttr?.shape && stAttr.shape !== \"NONE\" && stAttr.shape !== \"3D\")\n info.s = true;\n\n // font name — resolve from fontRef.hangul → fontfaces\n const fontRefAttr =\n cp?.[\"hh:fontRef\"]?.[0]?._attr ?? cp?.[\"hh:FONTREF\"]?.[0]?._attr;\n if (fontRefAttr) {\n const fid = Number(\n fontRefAttr.hangul ?? fontRefAttr.latin ?? fontRefAttr.Hangul ?? 0,\n );\n const name = fontIdMap.get(fid);\n if (name) info.font = safeFont(name);\n }\n\n map.set(id, info);\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction extractParaPrs(headObj: any): Map {\n const map = new Map();\n try {\n const root =\n headObj?.[\"hh:head\"]?.[0] ??\n headObj?.[\"hh:HEAD\"]?.[0] ??\n headObj?.HEAD?.[0] ??\n headObj;\n const refList =\n root?.[\"hh:refList\"]?.[0] ??\n root?.[\"hh:REFLIST\"]?.[0] ??\n root?.REFLIST?.[0];\n if (!refList) return map;\n\n const ppList =\n refList?.[\"hh:paraProperties\"]?.[0] ??\n refList?.[\"hh:PARAPROPERTIES\"]?.[0];\n if (!ppList) return map;\n\n const pps = getTag(ppList, \"hh:paraPr\", \"hh:PARAPR\");\n for (const pp of pps) {\n const attr = pp?._attr ?? {};\n const id = Number(attr.id ?? -1);\n if (id < 0) continue;\n\n const alignNode =\n pp?.[\"hh:align\"]?.[0]?._attr ?? pp?.[\"hh:ALIGN\"]?.[0]?._attr;\n const align = alignNode?.horizontal ?? alignNode?.Horizontal;\n\n // Read margin and lineSpacing from direct child OR hp:switch> hp:default/hp:case\n let marginEl = pp?.[\"hh:margin\"]?.[0] ?? null;\n let lineSpEl = pp?.[\"hh:lineSpacing\"]?.[0] ?? null;\n if (!marginEl) {\n const sw = pp?.[\"hp:switch\"]?.[0];\n const container = sw?.[\"hp:default\"]?.[0] ?? sw?.[\"hp:case\"]?.[0];\n marginEl = container?.[\"hh:margin\"]?.[0] ?? null;\n lineSpEl = lineSpEl ?? container?.[\"hh:lineSpacing\"]?.[0] ?? null;\n }\n\n let indentPt: number | undefined;\n let indentRightPt: number | undefined;\n let firstLineIndentPt: number | undefined;\n let spaceBefore: number | undefined;\n let spaceAfter: number | undefined;\n let lineHeight: number | undefined;\n let lineHeightFixed: number | undefined;\n\n if (marginEl) {\n // OWPML §7.5.4.4: hc:left=전체왼쪽여백, hc:right=전체오른쪽여백,\n // hc:indent=첫줄들여쓰기(양수)/내어쓰기(음수)\n // hc:intent는 자사 인코더가 생성하는 오기 표기로, hc:indent와 동일하게 처리\n const leftEl = marginEl?.[\"hc:left\"]?.[0];\n const rightEl = marginEl?.[\"hc:right\"]?.[0];\n const indentEl =\n marginEl?.[\"hc:intent\"]?.[0] ?? marginEl?.[\"hc:indent\"]?.[0];\n const prevEl = marginEl?.[\"hc:prev\"]?.[0];\n const nextEl = marginEl?.[\"hc:next\"]?.[0];\n\n const leftVal = Number(leftEl?._attr?.value ?? 0);\n const rightVal = Number(rightEl?._attr?.value ?? 0);\n const indentVal = Number(indentEl?._attr?.value ?? 0);\n const prevVal = Number(prevEl?._attr?.value ?? 0);\n const nextVal = Number(nextEl?._attr?.value ?? 0);\n\n if (leftVal !== 0) indentPt = Metric.hwpToPt(leftVal);\n if (rightVal !== 0) indentRightPt = Metric.hwpToPt(rightVal);\n if (indentVal !== 0) firstLineIndentPt = Metric.hwpToPt(indentVal);\n if (prevVal> 0) spaceBefore = Metric.hwpToPt(prevVal);\n if (nextVal> 0) spaceAfter = Metric.hwpToPt(nextVal);\n }\n\n if (lineSpEl) {\n const lsAttr = lineSpEl._attr ?? {};\n const lsType = lsAttr.type ?? \"PERCENT\";\n const lsVal = Number(lsAttr.value ?? 160);\n // OWPML §7.5.4.6: PERCENT(비율), FIXED(고정), BETWEEN_LINE(줄간격), AT_LEAST(최소)\n if (lsType === \"PERCENT\" && lsVal> 0 && lsVal !== 160) {\n lineHeight = lsVal / 100;\n } else if (lsType === \"FIXED\" && lsVal> 0) {\n // FIXED: 값이 HWPUNIT 단위의 고정 줄 높이\n lineHeightFixed = Metric.hwpToPt(lsVal);\n }\n }\n\n map.set(id, {\n align,\n indentPt,\n indentRightPt,\n firstLineIndentPt,\n spaceBefore,\n spaceAfter,\n lineHeight,\n lineHeightFixed,\n });\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\n// ─── Section decoding ──────────────────────────────────────\n\nfunction addParaItems(p: any, items: { type: string; node: any }[]): void {\n // Check if this paragraph contains a table in its runs\n const runs = getTag(p, \"hp:run\", \"hp:RUN\");\n let hasTable = false;\n for (const run of runs) {\n const tbls = getTag(run, \"hp:tbl\", \"hp:TABLE\");\n if (tbls.length> 0) {\n for (const tbl of tbls) {\n items.push({ type: \"table\", node: tbl });\n }\n hasTable = true;\n }\n }\n // 테이블을 포함한 단락은 일반 단락으로 다시 추가하지 않음 (중복 방지)\n if (!hasTable) {\n items.push({ type: \"para\", node: p });\n }\n}\n\nfunction decodeSection(sec: any, dims: PageDims, ctx: DecCtx) {\n // Try to extract dims from first paragraph's secPr\n const firstParas = getTag(sec, \"hp:p\", \"hp:P\");\n const pageDims = extractSecPrDims(firstParas[0]) ?? dims;\n\n // Build items list preserving document order via _childOrder\n const items: { type: string; node: any }[] = [];\n const paras = getTag(sec, \"hp:p\", \"hp:P\");\n const tbls = getTag(sec, \"hp:tbl\", \"hp:TABLE\");\n\n const childOrder = sec?.[\"_childOrder\"] as string[] | undefined;\n\n if (Array.isArray(childOrder)) {\n let pi = 0;\n let ti = 0;\n for (const tag of childOrder) {\n if ((tag === \"hp:p\" || tag === \"hp:P\") && pi < paras.length) {\n addParaItems(paras[pi++], items);\n } else if ((tag === \"hp:tbl\" || tag === \"hp:TABLE\") && ti < tbls.length) {\n items.push({ type: \"table\", node: tbls[ti++] });\n }\n }\n // Append any remaining (fallback)\n while (pi < paras.length) addParaItems(paras[pi++], items);\n while (ti < tbls.length) items.push({ type: \"table\", node: tbls[ti++] });\n } else {\n // No order info — process paragraphs sequentially (fallback to previous logic)\n for (const p of paras) addParaItems(p, items);\n // Note: direct tables are appended after paras in this fallback\n for (const t of tbls) items.push({ type: \"table\", node: t });\n }\n\n const kids: ContentNode[] = ctx.shield.guardAll(\n items,\n (item: any) => {\n if (item.type === \"table\") {\n try {\n const { value } = ctx.shield.guardGrid(\n item.node,\n (n) => decodeGrid(n, ctx),\n (n) => decodeGridSimple(n, ctx),\n (n) => decodeGridFlat(n),\n (n) => decodeGridText(n) as unknown as GridNode,\n \"hwpx:table\",\n );\n return value;\n } catch {\n return buildPara([buildSpan(\"[표 파싱 실패]\")]);\n }\n }\n return decodePara(item.node, ctx);\n },\n () => buildPara([buildSpan(\"[파싱 실패]\")]),\n \"hwpx:content\",\n );\n\n // Decode header/footer\n const headerParas = decodeHeaderFooter(sec, \"header\", ctx);\n const footerParas = decodeHeaderFooter(sec, \"footer\", ctx);\n\n return buildSheet(kids.filter(Boolean) as ContentNode[], pageDims, {\n headers: { default: headerParas },\n footers: { default: footerParas },\n });\n}\n\nfunction parseSecPrDims(secPr: any): PageDims | null {\n const pagePr =\n secPr?.[\"hp:pagePr\"]?.[0]?._attr ?? secPr?.[\"hp:PAGEPR\"]?.[0]?._attr;\n if (!pagePr) return null;\n const margin =\n secPr?.[\"hp:pagePr\"]?.[0]?.[\"hp:margin\"]?.[0]?._attr ??\n secPr?.[\"hp:PAGEPR\"]?.[0]?.[\"hp:MARGIN\"]?.[0]?._attr ??\n {};\n const pw = Number(pagePr.width ?? 59528);\n const ph = Number(pagePr.height ?? 84188);\n return {\n wPt: Metric.hwpToPt(pw),\n hPt: Metric.hwpToPt(ph),\n mt: Metric.hwpToPt(Number(margin.top ?? 5670)),\n mb: Metric.hwpToPt(Number(margin.bottom ?? 4252)),\n ml: Metric.hwpToPt(Number(margin.left ?? 8504)),\n mr: Metric.hwpToPt(Number(margin.right ?? 8504)),\n orient: pw> ph ? \"landscape\" : \"portrait\",\n };\n}\n\nfunction extractSecPrDims(p: any): PageDims | null {\n if (!p) return null;\n try {\n // Primary: hp:secPr is a DIRECT child of hp:p (as generated by HwpxEncoder)\n const secPrDirect = p?.[\"hp:secPr\"]?.[0] ?? p?.[\"hp:SECPR\"]?.[0];\n if (secPrDirect) {\n const dims = parseSecPrDims(secPrDirect);\n if (dims) return dims;\n }\n // Fallback: legacy format may nest hp:secPr inside hp:run\n const runs = getTag(p, \"hp:run\", \"hp:RUN\");\n for (const run of runs) {\n const secPr = run?.[\"hp:secPr\"]?.[0] ?? run?.[\"hp:SECPR\"]?.[0];\n if (!secPr) continue;\n const dims = parseSecPrDims(secPr);\n if (dims) return dims;\n }\n } catch {\n /* ignore */\n }\n return null;\n}\n\nfunction decodeHeaderFooter(\n sec: any,\n kind: \"header\" | \"footer\",\n ctx: DecCtx,\n): ParaNode[] | undefined {\n try {\n const hf =\n sec?.[\"hp:headerFooter\"]?.[0] ??\n sec?.[\"hp:HEADERFOOTER\"]?.[0] ??\n sec?.headerFooter?.[0] ??\n sec?.HEADERFOOTER?.[0];\n if (!hf) return undefined;\n\n const part =\n hf?.[\"hp:\" + kind]?.[0] ??\n hf?.[\"hp:\" + kind.toUpperCase()]?.[0] ??\n hf?.[kind]?.[0] ??\n hf?.[kind.toUpperCase()]?.[0];\n if (!part) return undefined;\n\n const paras = getTag(part, \"hp:p\", \"hp:P\");\n if (paras.length === 0) return undefined;\n\n return paras.map((p: any) => decodePara(p, ctx));\n } catch {\n return undefined;\n }\n}\n\n// ─── Paragraph & run decoding ──────────────────────────────\n\nfunction decodePara(p: any, ctx: DecCtx): ParaNode {\n const pAttr = p?._attr ?? {};\n const paraPrIdRef = Number(pAttr.paraPrIDRef ?? -1);\n\n // Resolve paraPr from IDRef or inline\n let align: string | undefined;\n const paraPrDef = ctx.paraPrs.get(paraPrIdRef);\n if (paraPrDef?.align) align = paraPrDef.align;\n\n // Check inline PARAPR too\n const inlineParaPr =\n p?.[\"hp:PARAPR\"]?.[0] ?? p?.[\"hp:paraPr\"]?.[0] ?? p?.PARAPR?.[0];\n if (inlineParaPr) {\n const alignNode =\n inlineParaPr?.[\"hp:ALIGN\"]?.[0]?._attr ??\n inlineParaPr?.[\"hp:align\"]?.[0]?._attr ??\n inlineParaPr?.ALIGN?.[0]?._attr;\n if (alignNode?.Type) align = alignNode.Type;\n if (alignNode?.horizontal) align = alignNode.horizontal;\n }\n\n const inlineAttr = inlineParaPr?._attr ?? {};\n const props: ParaProps = { align: safeAlign(align) };\n\n // Apply spacing/indent/lineHeight from paraPr definition\n if (paraPrDef) {\n if (paraPrDef.indentPt !== undefined) props.indentPt = paraPrDef.indentPt;\n if (paraPrDef.indentRightPt !== undefined)\n props.indentRightPt = paraPrDef.indentRightPt;\n if (paraPrDef.firstLineIndentPt !== undefined)\n props.firstLineIndentPt = paraPrDef.firstLineIndentPt;\n if (paraPrDef.spaceBefore !== undefined)\n props.spaceBefore = paraPrDef.spaceBefore;\n if (paraPrDef.spaceAfter !== undefined)\n props.spaceAfter = paraPrDef.spaceAfter;\n if (paraPrDef.lineHeight !== undefined)\n props.lineHeight = paraPrDef.lineHeight;\n if (paraPrDef.lineHeightFixed !== undefined)\n props.lineHeightFixed = paraPrDef.lineHeightFixed;\n }\n\n // List support (from inline attr)\n if (inlineAttr.listType) {\n props.listOrd =\n inlineAttr.listType === \"DIGIT\" || inlineAttr.listType === \"DECIMAL\";\n props.listLv = Number(inlineAttr.listLevel ?? 0);\n }\n\n const runs = getTag(p, \"hp:run\", \"hp:RUN\");\n const kids: (SpanNode | ImgNode)[] = [];\n\n // Helper: collect hp:pic elements from a container (direct child OR inside hp:ctrl)\n const collectPics = (container: any): any[] => {\n const direct = getTag(container, \"hp:pic\", \"hp:PIC\");\n const ctrls = getTag(container, \"hp:ctrl\", \"hp:CTRL\");\n const nested = ctrls.flatMap((c: any) => getTag(c, \"hp:pic\", \"hp:PIC\"));\n return [...direct, ...nested];\n };\n\n // Images that are direct children of (common in table cells and floats)\n for (const pic of collectPics(p)) {\n const img = decodePic(pic, ctx);\n if (img) kids.push(img);\n }\n\n for (const run of runs) {\n // Images: directly in run OR in run→ctrl (both patterns appear in practice)\n for (const pic of collectPics(run)) {\n const img = decodePic(pic, ctx);\n if (img) kids.push(img);\n }\n\n // Page number\n const pageNums = getTag(run, \"hp:pageNum\", \"hp:PAGENUM\");\n if (pageNums.length> 0) {\n const pn = pageNums[0]?._attr ?? {};\n const fmt =\n pn.formatType === \"ROMAN_LOWER\"\n ? (\"roman\" as const)\n : pn.formatType === \"ROMAN_UPPER\"\n ? (\"romanCaps\" as const)\n : (\"decimal\" as const);\n const pageNumNode: PageNumNode = { tag: \"pagenum\", format: fmt };\n const spanProps = resolveCharPr(run, ctx);\n kids.push({ tag: \"span\", props: spanProps, kids: [pageNumNode] });\n continue;\n }\n\n // Text\n const runPics = collectPics(run);\n const textNodes = getTag(run, \"hp:t\", \"hp:T\", \"hp:CHAR\");\n const content = textNodes\n .map((t: any) => {\n const val =\n typeof t === \"string\" ? t : (t?._text ?? t?._ ?? t?.[\"#text\"] ?? \"\");\n return val.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n })\n .join(\"\");\n\n // Skip empty secPr-only runs that produced no images\n if (\n content === \"\" &&\n (run?.[\"hp:secPr\"]?.[0] || run?.[\"hp:SECPR\"]?.[0]) &&\n runPics.length === 0 &&\n pageNums.length === 0\n )\n continue;\n\n // Only push text span when there's actual content and no image already pushed for this run\n if (content !== \"\" || (runPics.length === 0 && pageNums.length === 0)) {\n const spanProps = resolveCharPr(run, ctx);\n kids.push(buildSpan(content, spanProps));\n }\n }\n\n // pageBreak=\"1\" → prepend a pb node in its own span\n if (pAttr.pageBreak === \"1\") {\n kids.unshift({ tag: \"span\", props: {}, kids: [buildPb()] });\n }\n\n return buildPara(kids.filter(Boolean) as ParaNode[\"kids\"], props);\n}\n\nfunction resolveCharPr(run: any, ctx: DecCtx): TextProps {\n const runAttr = run?._attr ?? {};\n const charPrIdRef = Number(runAttr.charPrIDRef ?? runAttr.CharPrIDRef ?? -1);\n\n // IDRef로 먼저 조회\n const def = ctx.charPrs.get(charPrIdRef);\n if (def) {\n return {\n b: def.b,\n i: def.i,\n u: def.u,\n s: def.s,\n pt: def.pt,\n color: def.color,\n font: def.font,\n bg: def.bg,\n };\n }\n\n // 인라인 CHARPR fallback — 대소문자 모두 시도\n const inlinePr =\n run?.[\"hp:CHARPR\"]?.[0] ??\n run?.[\"hp:charPr\"]?.[0] ??\n run?.CHARPR?.[0] ??\n run?.charPr?.[0];\n const ca = inlinePr?._attr ?? {};\n\n const bVal = ca.Bold ?? ca.bold ?? ca.B ?? \"\";\n const iVal = ca.Italic ?? ca.italic ?? ca.I ?? \"\";\n const uVal = ca.Underline ?? ca.underline ?? \"\";\n const sVal = ca.Strikeout ?? ca.strikeout ?? \"\";\n const fontName =\n ca.FontName ?? ca.fontName ?? ca.FaceNameHangul ?? ca.faceNameHangul ?? \"\";\n const heightVal = ca.Height ?? ca.height ?? \"\";\n\n return {\n b: bVal === \"1\" || bVal === \"true\" || bVal === \"True\" || undefined,\n i: iVal === \"1\" || iVal === \"true\" || iVal === \"True\" || undefined,\n u: uVal && uVal !== \"NONE\" ? true : undefined,\n s: sVal && sVal !== \"NONE\" && sVal !== \"3D\" ? true : undefined,\n font: fontName ? safeFont(fontName) : undefined,\n pt: heightVal ? Metric.hHeightToPt(Number(heightVal)) : undefined,\n color: safeHex(ca.TextColor ?? ca.textColor),\n bg: safeHex(ca.BgColor ?? ca.bgColor),\n };\n}\n\n// ─── Image decoding ────────────────────────────────────────\n\nfunction decodePic(pic: any, ctx: DecCtx): ImgNode | null {\n try {\n const szAttr = pic?.[\"hp:sz\"]?.[0]?._attr ?? pic?.sz?.[0]?._attr ?? {};\n const w = Metric.hwpToPt(Number(szAttr.width ?? 0));\n const h = Metric.hwpToPt(Number(szAttr.height ?? 0));\n\n // Try multiple tag patterns for image reference\n const imgNode =\n pic?.[\"hp:img\"]?.[0]?._attr ??\n pic?.[\"hc:img\"]?.[0]?._attr ??\n pic?.img?.[0]?._attr ??\n {};\n const binRef = imgNode.binaryItemIDRef ?? imgNode.BinaryItemIDRef;\n if (!binRef) return null;\n\n // Find binary data\n let imgData: Uint8Array | undefined;\n for (const [key, val] of ctx.files) {\n if (\n key.includes(binRef) ||\n key.toLowerCase().includes(binRef.toLowerCase())\n ) {\n imgData = val;\n break;\n }\n }\n if (!imgData) return null;\n\n const ext = binRef.split(\".\").pop()?.toLowerCase() ?? \"png\";\n const mimeMap: Record = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n\n // ── hp:pos에서 layout 추출 ───────────────────────────────\n const posAttr = pic?.[\"hp:pos\"]?.[0]?._attr ?? pic?.pos?.[0]?._attr ?? {};\n const layout = extractHwpxLayout(posAttr, pic);\n\n return buildImg(\n TextKit.base64Encode(imgData),\n mimeMap[ext] ?? \"image/png\",\n w,\n h,\n undefined,\n layout,\n );\n } catch {\n return null;\n }\n}\n\nfunction extractHwpxLayout(posAttr: any, pic: any): ImgLayout {\n const treatAsChar =\n posAttr.treatAsChar === \"1\" || posAttr.treatAsChar === \"true\";\n if (treatAsChar) return { wrap: \"inline\" };\n\n // textWrap → wrap (direct attribute of hp:pic element)\n const textWrap: string =\n pic?._attr?.textWrap ?? pic?.pic?.[0]?._attr?.textWrap ?? \"TOP_AND_BOTTOM\";\n // OWPML §7.5.8.1 textWrap → ImgWrap 매핑\n // TOP_AND_BOTTOM: 텍스트가 이미지 위아래로만 흐름 → DOCX wrapTopAndBottom (float anchor)\n const wrapMap: Record = {\n TOP_AND_BOTTOM: \"topAndBottom\", // float, 위아래 텍스트 흐름\n SQUARE: \"square\",\n BOTH_SIDES: \"tight\",\n LEFT: \"tight\",\n RIGHT: \"tight\",\n LARGER_ONLY: \"tight\",\n SMALLER_ONLY: \"tight\",\n LARGEST_ONLY: \"tight\",\n BEHIND_TEXT: \"behind\",\n FRONT_TEXT: \"front\",\n };\n const wrap: ImgWrap = wrapMap[textWrap] ?? \"square\";\n\n // 기준점\n const horzRelToMap: Record = {\n PARA: \"para\",\n MARGIN: \"margin\",\n PAGE: \"page\",\n COLUMN: \"column\",\n };\n const vertRelToMap: Record = {\n PARA: \"para\",\n MARGIN: \"margin\",\n PAGE: \"page\",\n PAPER: \"page\",\n LINE: \"line\",\n };\n const horzRelTo = horzRelToMap[posAttr.horzRelTo ?? \"\"] ?? \"para\";\n const vertRelTo = vertRelToMap[posAttr.vertRelTo ?? \"\"] ?? \"para\";\n\n // 정렬\n const horzAlignMap: Record = {\n LEFT: \"left\",\n CENTER: \"center\",\n RIGHT: \"right\",\n };\n const vertAlignMap: Record = {\n TOP: \"top\",\n CENTER: \"center\",\n BOTTOM: \"bottom\",\n };\n const horzAlign = horzAlignMap[posAttr.horzAlign ?? \"\"];\n const vertAlign = vertAlignMap[posAttr.vertAlign ?? \"\"];\n\n // 오프셋\n const horzOffset = Number(posAttr.horzOffset ?? 0);\n const vertOffset = Number(posAttr.vertOffset ?? 0);\n const xPt = horzOffset !== 0 ? Metric.hwpToPt(horzOffset) : undefined;\n const yPt = vertOffset !== 0 ? Metric.hwpToPt(vertOffset) : undefined;\n\n return { wrap, horzAlign, vertAlign, horzRelTo, vertRelTo, xPt, yPt };\n}\n\n// ─── Table decoding ────────────────────────────────────────\n\nfunction decodeGrid(tbl: any, ctx: DecCtx): GridNode {\n const tblAttr = tbl?._attr ?? {};\n const borderFillId = Number(tblAttr.borderFillIDRef ?? 0);\n const borderFill = ctx.borderFills.get(borderFillId);\n const headerRow = tblAttr.repeatHeader === \"1\";\n\n const gridProps: GridProps = { headerRow: headerRow || undefined };\n if (borderFill?.stroke) gridProps.defaultStroke = borderFill.stroke;\n\n const rowArr = getTag(tbl, \"hp:tr\", \"hp:ROW\");\n\n // Read column widths: first try a row where ALL cells have cs=1\n for (const row of rowArr) {\n const cells = getTag(row, \"hp:tc\", \"hp:CELL\");\n const rowWidths: number[] = [];\n let allSingle = true;\n for (const cell of cells) {\n const cellSpanAttr = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cs = Number(cellSpanAttr.colSpan ?? cell?._attr?.ColSpan ?? 1);\n if (cs> 1) {\n allSingle = false;\n break;\n }\n const szAttr = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const w = Number(szAttr.width ?? 0);\n rowWidths.push(Metric.hwpToPt(w));\n }\n if (allSingle && rowWidths.length> 0 && rowWidths.some((w) => w> 0)) {\n gridProps.colWidths = rowWidths;\n break;\n }\n }\n\n // Fallback: proportional distribution when no all-single row exists\n if (!gridProps.colWidths) {\n // Determine colCount first: max column index reached across all rows\n let detectedCols = 0;\n for (const row of rowArr) {\n let ci = 0;\n for (const cell of getTag(row, \"hp:tc\", \"hp:CELL\")) {\n const csEl = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n ci += Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1);\n }\n if (ci> detectedCols) detectedCols = ci;\n }\n if (detectedCols> 0) {\n const sums = new Float64Array(detectedCols);\n const counts = new Int32Array(detectedCols);\n for (const row of rowArr) {\n let ci = 0;\n for (const cell of getTag(row, \"hp:tc\", \"hp:CELL\")) {\n const csEl = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cs = Number(csEl.colSpan ?? cell?._attr?.ColSpan ?? 1);\n const szAttr = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const w = Number(szAttr.width ?? 0);\n if (w> 0 && cs> 0) {\n const perCol = w / cs;\n for (let k = 0; k < cs && ci + k < detectedCols; k++) {\n sums[ci + k] += perCol;\n counts[ci + k]++;\n }\n }\n ci += cs;\n }\n }\n const estimated = Array.from(sums).map((s, i) =>\n counts[i]> 0 ? Metric.hwpToPt(s / counts[i]) : 0,\n );\n if (estimated.some((w) => w> 0)) gridProps.colWidths = estimated;\n }\n }\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, \"hp:tc\", \"hp:CELL\");\n const cellNodes = cellArr.map((cell: any) => {\n const ca = cell?._attr ?? {};\n\n // Cell borderFill\n const cellBfId = Number(ca.borderFillIDRef ?? 0);\n const cellBf = ctx.borderFills.get(cellBfId);\n\n const cellProps: CellProps = {\n bg: cellBf?.bgColor ?? safeHex(ca.BgColor),\n };\n\n if (cellBf) {\n // Preserve explicit NONE so it overrides table-level defaultStroke in DOCX tcBorders.\n // Only skip when the side is truly undefined (not specified in borderFill).\n cellProps.top = cellBf.top ?? cellBf.stroke;\n cellProps.bot = cellBf.bottom ?? cellBf.stroke;\n cellProps.left = cellBf.left ?? cellBf.stroke;\n cellProps.right = cellBf.right ?? cellBf.stroke;\n }\n\n // Vertical alignment and cell padding from subList\n const subList = cell?.[\"hp:subList\"]?.[0] ?? cell?.subList?.[0];\n const subAttr = subList?._attr ?? {};\n if (subAttr.vertAlign) {\n const vaMap: Record = {\n TOP: \"top\",\n CENTER: \"mid\",\n BOTTOM: \"bot\",\n };\n cellProps.va = vaMap[subAttr.vertAlign];\n }\n // Cell margins (stored in HWPUNIT on subList attributes)\n const HWPX_DEFAULT_MARGIN_LR = 360; // typical default: 3.6pt\n const HWPX_DEFAULT_MARGIN_TB = 141; // typical default: ~1.4pt\n const mL = Number(subAttr.marginLeft ?? HWPX_DEFAULT_MARGIN_LR);\n const mR = Number(subAttr.marginRight ?? HWPX_DEFAULT_MARGIN_LR);\n const mT = Number(subAttr.marginTop ?? HWPX_DEFAULT_MARGIN_TB);\n const mB = Number(subAttr.marginBottom ?? HWPX_DEFAULT_MARGIN_TB);\n if (mL !== HWPX_DEFAULT_MARGIN_LR) cellProps.padL = Metric.hwpToPt(mL);\n if (mR !== HWPX_DEFAULT_MARGIN_LR) cellProps.padR = Metric.hwpToPt(mR);\n if (mT !== HWPX_DEFAULT_MARGIN_TB) cellProps.padT = Metric.hwpToPt(mT);\n if (mB !== HWPX_DEFAULT_MARGIN_TB) cellProps.padB = Metric.hwpToPt(mB);\n\n // Colspan/rowspan from cellSpan element or attributes\n const cellSpan = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cs = Number(cellSpan.colSpan ?? ca.ColSpan ?? 1);\n const rs = Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1);\n\n // Parse cell content — paragraphs and nested tables (중첩 표)\n const cellKids: (ParaNode | GridNode)[] = [];\n const source = subList ?? cell;\n const sourcePSource = getTag(source, \"hp:p\", \"hp:P\");\n for (const sp of sourcePSource) {\n try {\n // Check if this paragraph contains a nested table in its runs\n const runs = getTag(sp, \"hp:run\", \"hp:RUN\");\n let hasNestedTable = false;\n for (const run of runs) {\n const nestedTbls = getTag(run, \"hp:tbl\", \"hp:TABLE\");\n for (const nestedTbl of nestedTbls) {\n try {\n cellKids.push(decodeGrid(nestedTbl, ctx));\n } catch {\n /* skip malformed nested table */\n }\n hasNestedTable = true;\n }\n }\n if (!hasNestedTable) {\n cellKids.push(decodePara(sp, ctx));\n }\n } catch {\n /* skip corrupted para in cell */\n }\n }\n\n return buildCell(\n cellKids.length> 0 ? cellKids : [buildPara([buildSpan(\"\")])],\n { cs, rs, props: cellProps },\n );\n });\n // Row height: prefer a non-merged cell (rs=1) for accuracy.\n // For merged cells, divide total height by rowSpan to get per-row height.\n let rowHeightPt: number | undefined;\n for (const cell of cellArr) {\n const ca = cell?._attr ?? {};\n const cellSpan = cell?.[\"hp:cellSpan\"]?.[0]?._attr ?? {};\n const cellRs = Math.max(1, Number(cellSpan.rowSpan ?? ca.RowSpan ?? 1));\n const hSz = cell?.[\"hp:cellSz\"]?.[0]?._attr ?? {};\n const hVal = Number(hSz.height ?? 0);\n if (hVal> 0) {\n rowHeightPt = Metric.hwpToPt(hVal) / cellRs;\n if (cellRs === 1) break; // exact match — stop searching\n }\n }\n return buildRow(cellNodes, rowHeightPt);\n });\n return buildGrid(rowNodes, gridProps);\n}\n\nfunction decodeGridSimple(tbl: any, ctx: DecCtx): GridNode {\n const rowArr = getTag(tbl, \"hp:tr\", \"hp:ROW\");\n const rowNodes = rowArr.map((row: any) => {\n const cellArr = getTag(row, \"hp:tc\", \"hp:CELL\");\n return buildRow(\n cellArr.map((cell: any) =>\n buildCell([buildPara([buildSpan(cellText(cell))])]),\n ),\n );\n });\n return buildGrid(rowNodes);\n}\n\nfunction decodeGridFlat(tbl: any): GridNode {\n return buildGrid([\n buildRow([buildCell([buildPara([buildSpan(tableText(tbl))])])]),\n ]);\n}\n\nfunction decodeGridText(tbl: any): ParaNode {\n return buildPara([buildSpan(tableText(tbl))]);\n}\n\nfunction cellText(cell: any): string {\n const subList = cell?.[\"hp:subList\"]?.[0] ?? cell?.subList?.[0];\n const source = subList ?? cell;\n return getTag(source, \"hp:p\", \"hp:P\")\n .map((p: any) =>\n getTag(p, \"hp:run\", \"hp:RUN\")\n .map((r: any) =>\n getTag(r, \"hp:t\", \"hp:T\")\n .map((t: any) => {\n const val =\n typeof t === \"string\"\n ? t\n : (t?._text ?? t?._ ?? t?.[\"#text\"] ?? \"\");\n return val.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, \"\");\n })\n .join(\"\"),\n )\n .join(\"\"),\n )\n .join(\" \");\n}\n\nfunction tableText(tbl: any): string {\n return getTag(tbl, \"hp:tr\", \"hp:ROW\")\n .map((row: any) =>\n getTag(row, \"hp:tc\", \"hp:CELL\")\n .map((c: any) => cellText(c))\n .join(\"\\t\"),\n )\n .join(\"\\n\");\n}\n\nfunction toArr(v: any): any[] {\n return v == null ? [] : Array.isArray(v) ? v : [v];\n}\n\n// Auto-register\nregistry.registerDecoder(new HwpxDecoder());\n","/**\n * OLE2 Compound File Binary Format (CFB) parser.\n * Used for legacy HWP 5.0 files.\n */\n\nexport const BinaryKit = {\n readU16LE(buf: Uint8Array, offset: number): number {\n return buf[offset] | (buf[offset + 1] << 8);\n },\n\n readU32LE(buf: Uint8Array, offset: number): number {\n return (\n (buf[offset] | (buf[offset + 1] << 8) | (buf[offset + 2] << 16))>>> 0\n ) + buf[offset + 3] * 0x1000000;\n },\n\n isOle2(data: Uint8Array): boolean {\n return (\n data.length>= 8 &&\n data[0] === 0xD0 && data[1] === 0xCF &&\n data[2] === 0x11 && data[3] === 0xE0 &&\n data[4] === 0xA1 && data[5] === 0xB1 &&\n data[6] === 0x1A && data[7] === 0xE1\n );\n },\n\n parseCfb(data: Uint8Array): Map {\n const streams = new Map();\n\n if (!this.isOle2(data)) {\n throw new Error('Not a valid OLE2 file');\n }\n\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const sectorSize = 1 << view.getUint16(30, true);\n const miniSectorSz = 1 << view.getUint16(32, true);\n const dirFirstSec = view.getUint32(48, true);\n const miniStreamCutoff = view.getUint32(56, true);\n const miniFatFirst = view.getUint32(60, true);\n const miniFatCnt = view.getUint32(64, true);\n const difatFirst = view.getUint32(68, true);\n\n const ENDOFCHAIN = 0xFFFFFFFE;\n const FREESECT = 0xFFFFFFFF;\n\n const sectorAt = (sec: number): Uint8Array =>\n data.subarray(512 + sec * sectorSize, 512 + (sec + 1) * sectorSize);\n\n // Build FAT from DIFAT\n const fatSecNums: number[] = [];\n for (let i = 0; i < 109; i++) {\n const s = view.getUint32(76 + i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n if (difatFirst !== ENDOFCHAIN && difatFirst !== FREESECT) {\n let difSec = difatFirst;\n while (difSec !== ENDOFCHAIN && difSec !== FREESECT) {\n const sec = sectorAt(difSec);\n const sv = new DataView(sec.buffer, sec.byteOffset, sec.byteLength);\n for (let i = 0; i < (sectorSize / 4) - 1; i++) {\n const s = sv.getUint32(i * 4, true);\n if (s === FREESECT || s === ENDOFCHAIN) break;\n fatSecNums.push(s);\n }\n difSec = sv.getUint32(sectorSize - 4, true);\n }\n }\n\n const fat: number[] = [];\n for (const sec of fatSecNums) {\n const s = sectorAt(sec);\n const sv = new DataView(s.buffer, s.byteOffset, s.byteLength);\n for (let i = 0; i < sectorSize / 4; i++) {\n fat.push(sv.getUint32(i * 4, true));\n }\n }\n\n const readChain = (startSec: number): Uint8Array => {\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < fat.length) {\n chunks.push(sectorAt(sec));\n sec = fat[sec];\n }\n return concatUint8(chunks);\n };\n\n // Directory entries\n const dirData = readChain(dirFirstSec);\n const dirView = new DataView(dirData.buffer, dirData.byteOffset, dirData.byteLength);\n const dirCount = dirData.length / 128;\n\n interface DirEntry {\n name: string;\n type: number;\n startSec: number;\n size: number;\n childId: number;\n siblingLeftId: number;\n siblingRightId: number;\n }\n\n const dirEntries: DirEntry[] = [];\n for (let i = 0; i < dirCount; i++) {\n const base = i * 128;\n const nameLen = dirView.getUint16(base + 64, true);\n const nameBytes = dirData.subarray(base, base + Math.max(0, nameLen - 2));\n const name = new TextDecoder('utf-16le').decode(nameBytes);\n const type = dirData[base + 66];\n const childId = dirView.getInt32(base + 76, true);\n const sibLeft = dirView.getInt32(base + 68, true);\n const sibRight = dirView.getInt32(base + 72, true);\n const startSec = dirView.getUint32(base + 116, true);\n const size = dirView.getUint32(base + 120, true);\n dirEntries.push({ name, type, startSec, size, childId, siblingLeftId: sibLeft, siblingRightId: sibRight });\n }\n\n // Mini stream\n const rootEntry = dirEntries[0];\n let miniStreamData: Uint8Array | null = null;\n let miniFat: number[] = [];\n\n if (rootEntry && rootEntry.startSec !== ENDOFCHAIN && rootEntry.startSec !== FREESECT) {\n miniStreamData = readChain(rootEntry.startSec);\n }\n\n if (miniFatCnt> 0 && miniFatFirst !== ENDOFCHAIN && miniFatFirst !== FREESECT) {\n const mfData = readChain(miniFatFirst);\n const mfv = new DataView(mfData.buffer, mfData.byteOffset, mfData.byteLength);\n for (let i = 0; i < mfData.length / 4; i++) {\n miniFat.push(mfv.getUint32(i * 4, true));\n }\n }\n\n const readMiniChain = (startSec: number, size: number): Uint8Array => {\n if (!miniStreamData) return new Uint8Array(0);\n const chunks: Uint8Array[] = [];\n let sec = startSec;\n let remaining = size;\n while (sec !== ENDOFCHAIN && sec !== FREESECT && sec < miniFat.length && remaining> 0) {\n const off = sec * miniSectorSz;\n const chunk = miniStreamData.subarray(off, off + Math.min(miniSectorSz, remaining));\n chunks.push(chunk);\n remaining -= chunk.length;\n sec = miniFat[sec];\n }\n return concatUint8(chunks).subarray(0, size);\n };\n\n // DFS traversal\n const visit = (id: number, path: string): void => {\n if (id < 0 || id>= dirEntries.length) return;\n const entry = dirEntries[id];\n const fullPath = path ? `${path}/${entry.name}` : entry.name;\n\n if (entry.type === 2) {\n let streamData: Uint8Array;\n if (entry.size < miniStreamCutoff && miniStreamData) {\n streamData = readMiniChain(entry.startSec, entry.size);\n } else {\n streamData = readChain(entry.startSec).subarray(0, entry.size);\n }\n streams.set(fullPath, streamData);\n streams.set(entry.name, streamData);\n }\n\n if (entry.childId>= 0) visit(entry.childId, fullPath);\n if (entry.siblingLeftId>= 0) visit(entry.siblingLeftId, path);\n if (entry.siblingRightId>= 0) visit(entry.siblingRightId, path);\n };\n\n if (dirEntries.length> 0 && dirEntries[0].childId>= 0) {\n visit(dirEntries[0].childId, '');\n }\n\n return streams;\n },\n};\n\nfunction concatUint8(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const a of arrays) { out.set(a, off); off += a.length; }\n return out;\n}\n","import type { Decoder } from '../../contract/decoder';\nimport type { DocRoot, ContentNode, ParaNode, SpanNode, ImgNode, GridNode } from '../../model/doc-tree';\nimport type { Outcome } from '../../contract/result';\nimport type { Align, Stroke, StrokeKind, PageDims, TextProps, ParaProps, CellProps, GridProps } from '../../model/doc-props';\nimport { succeed, fail } from '../../contract/result';\nimport { buildRoot, buildSheet, buildPara, buildSpan, buildGrid, buildRow, buildCell, buildImg } from '../../model/builders';\nimport { ShieldedParser } from '../../safety/ShieldedParser';\nimport { BinaryKit } from '../../toolkit/BinaryKit';\nimport { TextKit } from '../../toolkit/TextKit';\nimport { Metric, safeHex, safeFont } from '../../safety/StyleBridge';\nimport { registry } from '../../pipeline/registry';\nimport { A4 } from '../../model/doc-props';\nimport pako from 'pako';\n\n/* ═══════════════════════════════════════════════════════════════\n HWP 5.0 Tag Constants\n ═══════════════════════════════════════════════════════════════ */\n\nconst HWPTAG_BEGIN = 16;\n\nconst TAG_FACE_NAME = HWPTAG_BEGIN + 3; // 19\nconst TAG_BORDER_FILL = HWPTAG_BEGIN + 4; // 20\nconst TAG_CHAR_SHAPE = HWPTAG_BEGIN + 5; // 21\nconst TAG_PARA_SHAPE = HWPTAG_BEGIN + 9; // 25\nconst TAG_PARA_HEADER = HWPTAG_BEGIN + 50; // 66\nconst TAG_PARA_TEXT = HWPTAG_BEGIN + 51; // 67\nconst TAG_PARA_CHAR_SHAPE = HWPTAG_BEGIN + 52; // 68\nconst TAG_CTRL_HEADER = HWPTAG_BEGIN + 55; // 71\nconst TAG_PAGE_DEF = HWPTAG_BEGIN + 57; // 73\n\n// TABLE / CELL tags vary by HWP version\nconst TAG_LIST_HEADER = HWPTAG_BEGIN + 56; // 72\nconst TAG_TABLE_A = HWPTAG_BEGIN + 61; // 77\nconst TAG_CELL_A = HWPTAG_BEGIN + 62; // 78\nconst TAG_TABLE_B = HWPTAG_BEGIN + 64; // 80\nconst TAG_CELL_B = HWPTAG_BEGIN + 65; // 81\n\nfunction isTableTag(t: number) { return t === TAG_TABLE_A || t === TAG_TABLE_B; }\nfunction isCellTag(t: number) { return t === TAG_CELL_A || t === TAG_CELL_B || t === TAG_LIST_HEADER; }\n\n// CTRL_HEADER ctrlId values (UINT32-LE as ASCII)\nconst CTRL_TABLE = 0x74626C20; // ' lbt' = 표(table)\nconst CTRL_IMAGE = 0x696D6720; // 'img '\nconst CTRL_OBJ = 0x6F626A20; // 'obj '\nconst CTRL_FIG = 0x66696720; // 'fig '\nconst CTRL_GSO = 0x67736F20; // 'gso ' = 그리기 객체 (drawing object, contains embedded images)\n\n/* ═══════════════════════════════════════════════════════════════\n Types\n ═══════════════════════════════════════════════════════════════ */\n\ninterface HwpRecord {\n tag: number;\n level: number;\n data: Uint8Array;\n}\n\ninterface HwpCharShape {\n faceIds: number[];\n height: number;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikeout: boolean;\n superscript: boolean;\n subscript: boolean;\n textColor: string;\n}\n\ninterface HwpParaShape {\n align: Align;\n spaceBefore: number;\n spaceAfter: number;\n lineSpacing: number;\n leftMargin: number;\n indent: number;\n}\n\ninterface HwpBorderFill {\n borders: { type: number; widthPt: number; color: string }[];\n bgColor?: string;\n}\n\ninterface DocInfo {\n faceNames: string[];\n charShapes: HwpCharShape[];\n paraShapes: HwpParaShape[];\n borderFills: HwpBorderFill[];\n}\n\ninterface ParsedChar { pos: number; ch: string }\ninterface ParsedCtrl { pos: number; ctrlId: number; objId: number; matched: boolean }\ninterface ParaTextResult { chars: ParsedChar[]; controls: ParsedCtrl[] }\n\ninterface OleObject {\n id: number;\n data: Uint8Array;\n mimeType: string;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Low-level record parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseRecords(data: Uint8Array): HwpRecord[] {\n const out: HwpRecord[] = [];\n let off = 0;\n while (off + 4 <= data.length) {\n const hdr = BinaryKit.readU32LE(data, off);\n const tag = hdr & 0x3FF;\n const level = (hdr>> 10) & 0x3FF;\n let size = (hdr>> 20) & 0xFFF;\n off += 4;\n if (size === 0xFFF) {\n if (off + 4> data.length) break;\n size = BinaryKit.readU32LE(data, off);\n off += 4;\n }\n if (off + size> data.length) break;\n out.push({ tag, level, data: data.subarray(off, off + size) });\n off += size;\n }\n return out;\n}\n\nfunction tryInflate(data: Uint8Array): Uint8Array {\n try { return pako.inflate(data); } catch {\n try { return pako.inflateRaw(data); } catch { return data; }\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n FileHeader\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseFileHeader(buf: Uint8Array) {\n if (buf.length < 40) return { compressed: true, encrypted: false };\n const props = BinaryKit.readU32LE(buf, 36);\n return { compressed: (props & 1) !== 0, encrypted: (props & 2) !== 0 };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n DocInfo parsing\n ═══════════════════════════════════════════════════════════════ */\n\nfunction parseDocInfo(data: Uint8Array, compressed: boolean): DocInfo {\n const raw = compressed ? tryInflate(data) : data;\n const recs = parseRecords(raw);\n const info: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n\n for (const r of recs) {\n try {\n if (r.tag === TAG_FACE_NAME) info.faceNames.push(parseFaceName(r.data));\n if (r.tag === TAG_CHAR_SHAPE) info.charShapes.push(parseCharShape(r.data));\n if (r.tag === TAG_PARA_SHAPE) info.paraShapes.push(parseParaShape(r.data));\n if (r.tag === TAG_BORDER_FILL) info.borderFills.push(parseBorderFill(r.data));\n } catch { /* skip malformed record */ }\n }\n return info;\n}\n\n/* ── FACE_NAME ──────────────────────────────────────────────── */\n\nfunction parseFaceName(d: Uint8Array): string {\n if (d.length < 3) return '';\n const len = BinaryKit.readU16LE(d, 1); // UTF-16 char count\n if (d.length < 3 + len * 2) return '';\n return new TextDecoder('utf-16le').decode(d.subarray(3, 3 + len * 2));\n}\n\n/* ── CHAR_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 14 faceId[7] (UINT16 ×ばつ 7)\n 14 7 ratio[7]\n 21 7 spacing[7]\n 28 7 relSize[7]\n 35 7 offset[7]\n 42 4 height (UINT32, HWP-units 100 = 1pt)\n 46 4 attr (UINT32, bit flags)\n 50 1 shadowX\n 51 1 shadowY\n 52 4 textColor (COLORREF R,G,B,0) */\n\nfunction parseCharShape(d: Uint8Array): HwpCharShape {\n const faceIds: number[] = [];\n for (let i = 0; i < 7; i++) faceIds.push(d.length>= (i + 1) * 2 ? BinaryKit.readU16LE(d, i * 2) : 0);\n\n const height = d.length>= 46 ? BinaryKit.readU32LE(d, 42) : 1000;\n const attr = d.length>= 50 ? BinaryKit.readU32LE(d, 46) : 0;\n\n // attr bit layout (HWP 5.0 spec Table 35):\n // 0: italic, 1: bold, 2-4: underline type(3), 5-8: underline shape(4),\n // 9-11: outline(3), 12-13: shadow(2), 14: emboss, 15: engrave,\n // 16-17: super/sub(2, 0=none,1=super,2=sub), 18-20: strikeout type(3),\n // 21-24: strikeout shape(4), 25: annotLine, 26-28: annotLine type,\n // 29: useFontSpace, 30: kerning\n const ulType = (attr>> 2) & 0x7; // 3 bits at 2-4\n const skType = (attr>> 18) & 0x7; // 3 bits at 18-20\n const suType = (attr>> 16) & 0x3; // 2 bits at 16-17 (0=none,1=super,2=sub)\n\n return {\n faceIds,\n height: (height> 0 && height < 100000) ? height : 1000,\n italic: (attr & 1) !== 0,\n bold: ((attr>> 1) & 1) !== 0,\n underline: ulType !== 0,\n strikeout: skType !== 0,\n superscript: suType === 1,\n subscript: suType === 2,\n textColor: d.length>= 56 ? colorRef(d, 52) : '000000',\n };\n}\n\n/* ── PARA_SHAPE ─────────────────────────────────────────────── */\n/* offset size field\n 0 4 attr1 (bits 0-1 = alignment: 0=justify,1=left,2=right,3=center)\n 4 4 leftMargin (HWPUNIT)\n 8 4 rightMargin\n 12 4 indent\n 16 4 spaceBefore\n 20 4 spaceAfter\n 24 4 lineSpacing */\n\nconst ALIGN_TBL: Record = { 0: 'justify', 1: 'left', 2: 'right', 3: 'center', 4: 'justify' };\n\nfunction parseParaShape(d: Uint8Array): HwpParaShape {\n if (d.length < 4) return { align: 'left', spaceBefore: 0, spaceAfter: 0, lineSpacing: 160, leftMargin: 0, indent: 0 };\n const attr = BinaryKit.readU32LE(d, 0);\n return {\n align: ALIGN_TBL[(attr>> 2) & 0x7] ?? 'left',\n leftMargin: d.length>= 8 ? i32(d, 4) : 0, // offset 4: leftMargin (들여쓰기)\n indent: d.length>= 16 ? i32(d, 12) : 0, // offset 12: first-line indent\n spaceBefore: d.length>= 20 ? i32(d, 16) : 0,\n spaceAfter: d.length>= 24 ? i32(d, 20) : 0,\n lineSpacing: d.length>= 28 ? i32(d, 24) : 160,\n };\n}\n\n/* ── BORDER_FILL ────────────────────────────────────────────── */\n/* [0:2] attr\n For each of 5 borders (left,right,top,bottom,diagonal): 6 bytes\n +0 type(BYTE) +1 widthIdx(BYTE) +2 color(COLORREF)\n [32:4] fillType\n [36:4] faceColor (bgColor for solid fill) */\n\nconst BORDER_W_PT = [0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.70, 1.98, 2.84, 4.25, 5.67, 8.50, 11.34, 14.17];\nconst BORDER_KIND: Record = { 0:'solid',1:'dash',2:'dash',3:'dot',4:'dash',5:'dash',6:'dash',7:'double',8:'double',9:'double',10:'none' };\n\nfunction parseBorderFill(d: Uint8Array): HwpBorderFill {\n // Spec grouped format (표 23):\n // [0:2] attr\n // [2:4] 4 border types (left, right, top, bottom) — 1 byte each\n // [6:4] 4 border widths (left, right, top, bottom) — 1 byte each (index into BORDER_W_PT)\n // [10:16] 4 border colors (left, right, top, bottom) — 4 bytes each (COLORREF)\n // [26:3] diagonal: type(1) + width(1) + color(4) = 6 bytes actually [26:6]\n // [32:4] fillType\n // [36:4] faceColor (bgColor for solid fill)\n const borders: HwpBorderFill['borders'] = [];\n const BASE_TYPE = 2; // 4 type bytes\n const BASE_WIDTH = 6; // 4 width bytes\n const BASE_COLOR = 10; // 4 ×ばつ 4-byte colors\n for (let i = 0; i < 4; i++) {\n const type = BASE_TYPE + i < d.length ? d[BASE_TYPE + i] : 0;\n const widthPt = BASE_WIDTH + i < d.length ? (BORDER_W_PT[d[BASE_WIDTH + i]] ?? 0.5) : 0.5;\n const color = BASE_COLOR + i * 4 + 4 <= d.length ? colorRef(d, BASE_COLOR + i * 4) : '000000';\n borders.push({ type, widthPt, color });\n }\n let bgColor: string | undefined;\n // after attr(2) + 4 types(4) + 4 widths(4) + 4 colors(16) + diagonal(6) = offset 32\n const fOff = 32;\n if (d.length>= fOff + 8) {\n const ft = BinaryKit.readU32LE(d, fOff);\n if (ft & 1) bgColor = colorRef(d, fOff + 4);\n }\n return { borders, bgColor };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Body section parsing\n ═══════════════════════════════════════════════════════════════ */\n\n// gsoCtx: shared mutable counter for 'gso ' drawing objects.\n// Each 'gso ' CTRL_HEADER encountered increments this counter.\n// objectMap is keyed by 0-based gso order = sequential BinData insertion order.\ninterface GsoCtx { count: number }\n\nfunction parseBody(\n raw: Uint8Array, compressed: boolean, di: DocInfo, shield: ShieldedParser, gsoCtx: GsoCtx,\n): { content: ContentNode[]; pageDims?: PageDims } {\n const recs = parseRecords(compressed ? tryInflate(raw) : raw);\n const content: ContentNode[] = [];\n let pageDims: PageDims | undefined;\n\n // Pre-scan for PAGE_DEF at any nesting level (real HWP stores it at level 2 inside section ctrl)\n for (const r of recs) {\n if (r.tag === TAG_PAGE_DEF) {\n pageDims = shield.guard(() => parsePageDef(r.data), A4, 'hwp:pageDef');\n break;\n }\n }\n\n let i = 0;\n while (i < recs.length) {\n if (recs[i].tag === TAG_PAGE_DEF) {\n i++; // already handled above; skip at top level\n } else if (recs[i].tag === TAG_PARA_HEADER) {\n const r = shield.guard(\n () => parseParagraphGroup(recs, i, di, shield, gsoCtx),\n { nodes: [] as ContentNode[], next: i + 1 },\n `hwp:para@${i}`,\n );\n content.push(...r.nodes);\n i = r.next;\n } else {\n i++;\n }\n }\n return { content, pageDims };\n}\n\n/* ── Paragraph group ────────────────────────────────────────── */\n\nfunction parseParagraphGroup(\n recs: HwpRecord[], start: number, di: DocInfo, shield: ShieldedParser, gsoCtx: GsoCtx,\n): { nodes: ContentNode[]; next: number } {\n const hdr = recs[start];\n const lv = hdr.level;\n\n // paraShapeId at offset 8 (UINT16)\n const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n\n let text: ParaTextResult | null = null;\n let csPairs: [number, number][] = [];\n const grids: ContentNode[] = [];\n // imgId: for 'gso' uses sequential gsoCtx.count; for others uses flags-based objId\n const ctrlHeaders: { ctrlId: number; imgId: number; wPt: number; hPt: number }[] = [];\n let i = start + 1;\n\n while (i < recs.length && recs[i].level> lv) {\n const r = recs[i];\n\n if (r.tag === TAG_PARA_TEXT && r.level === lv + 1) {\n text = decodeParaText(r.data);\n i++;\n } else if (r.tag === TAG_PARA_CHAR_SHAPE && r.level === lv + 1) {\n csPairs = parseCharShapePairs(r.data);\n i++;\n } else if (r.tag === TAG_CTRL_HEADER && r.level === lv + 1) {\n if (r.data.length>= 4) {\n const ctrlId = BinaryKit.readU32LE(r.data, 0);\n\n // HWP 5.0 general-object layout:\n // [0:4] ctrlId [4:4] flags [8:4] xOff [12:4] yOff\n // [16:4] width(HWPUNIT) [20:4] height(HWPUNIT)\n const MAX_HWP = 1_000_000;\n const rawW = r.data.length>= 24 ? BinaryKit.readU32LE(r.data, 16) : 0;\n const rawH = r.data.length>= 28 ? BinaryKit.readU32LE(r.data, 20) : 0;\n const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n\n // 'gso ' (그리기 객체) uses sequential counter; others use flags-based id\n const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : (r.data.length>= 6 ? BinaryKit.readU16LE(r.data, 4) : 0);\n ctrlHeaders.push({ ctrlId, imgId, wPt, hPt });\n\n if (ctrlId === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, i, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, i) },\n `hwp:tbl@${i}`,\n );\n if (tr.grid) grids.push(tr.grid);\n i = tr.next;\n } else {\n i = skipKids(recs, i);\n }\n } else {\n i = skipKids(recs, i);\n }\n } else {\n i++;\n }\n }\n\n const nodes: ContentNode[] = [];\n\n // Build paragraph from text and inline controls (images)\n if (text && (text.chars.length> 0 || text.controls.length> 0)) {\n const paraContent: (SpanNode | ContentNode)[] = [];\n\n if (text.chars.length> 0) {\n const spans = resolveCharShapes(text.chars, csPairs, di);\n paraContent.push(...spans);\n }\n\n // Image placeholder spans: only for actual image controls.\n // Non-image controls (footnotes, TOC entries, etc.) are silently skipped.\n if (text.controls.length> 0) {\n for (let ci = 0; ci < text.controls.length; ci++) {\n const ch = ctrlHeaders[ci];\n if (!ch) continue; // anchor-only ctrl (gso is sibling, not inline)\n const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO;\n if (!isImg) continue; // skip footnotes, TOC, page num, etc.\n const dimStr = (ch.wPt> 0 && ch.hPt> 0)\n ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}`\n : '';\n paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`));\n }\n }\n\n if (paraContent.length> 0) {\n nodes.push(buildPara(paraContent as any, buildParaProps(ps)));\n }\n }\n\n nodes.push(...grids);\n return { nodes, next: i };\n}\n\nfunction skipKids(recs: HwpRecord[], idx: number): number {\n const lv = recs[idx].level;\n let i = idx + 1;\n while (i < recs.length && recs[i].level> lv) i++;\n return i;\n}\n\n/* ── PARA_TEXT ───────────────────────────────────────────────── */\n\n// Extended controls: 8 WORDs, associated CTRL_HEADER\nconst EXT_CTRL = new Set([2, 3, 11, 12, 14, 15]);\n// Inline controls: 8 WORDs, no CTRL_HEADER\nconst INL_CTRL = new Set([4, 5, 6, 7, 8]);\n\nfunction decodeParaText(d: Uint8Array): ParaTextResult {\n const chars: ParsedChar[] = [];\n const controls: ParsedCtrl[] = [];\n let i = 0, pos = 0;\n\n while (i + 1 < d.length) {\n const c = d[i] | (d[i + 1] << 8);\n if (c === 0) { i += 2; pos++; continue; }\n if (c === 13) { break; } // paragraph end\n if (c === 10) { chars.push({ pos, ch: '\\n' }); i += 2; pos++; continue; }\n\n if (EXT_CTRL.has(c)) {\n // Extended control: 8 WORDs (16 bytes)\n // WORD 4 contains objId (for images, charts, etc.)\n let objId = 0;\n if (i + 16 <= d.length) {\n objId = BinaryKit.readU16LE(d, i + 8); // 4th WORD (offset 8) contains objId\n }\n controls.push({ pos, ctrlId: 0, objId, matched: false });\n i += 16; pos += 8; continue;\n }\n if (INL_CTRL.has(c)) {\n i += 16; pos += 8; continue;\n }\n if (c === 9) { // tab (inline 8 WORDs)\n chars.push({ pos, ch: '\\t' });\n i += 16; pos += 8; continue;\n }\n if (c>= 1 && c <= 31) { i += 2; pos++; continue; } // other control\n\n chars.push({ pos, ch: String.fromCharCode(c) });\n i += 2; pos++;\n }\n return { chars, controls };\n}\n\n/* ── PARA_CHAR_SHAPE ────────────────────────────────────────── */\n\nfunction parseCharShapePairs(d: Uint8Array): [number, number][] {\n const out: [number, number][] = [];\n for (let i = 0; i + 7 < d.length; i += 8)\n out.push([BinaryKit.readU32LE(d, i), BinaryKit.readU32LE(d, i + 4)]);\n return out;\n}\n\n/* ── Char-shape → SpanNode resolution ───────────────────────── */\n\nfunction resolveCharShapes(chars: ParsedChar[], pairs: [number, number][], di: DocInfo): SpanNode[] {\n if (chars.length === 0) return [buildSpan('')];\n\n const defaultId = pairs.length> 0 ? pairs[0][1] : 0;\n\n function idFor(pos: number): number {\n let id = defaultId;\n for (const [p, sid] of pairs) { if (p <= pos) id = sid; else break; }\n return id;\n }\n\n const spans: SpanNode[] = [];\n let curId = idFor(chars[0].pos);\n let buf = chars[0].ch;\n\n for (let k = 1; k < chars.length; k++) {\n const sid = idFor(chars[k].pos);\n if (sid !== curId) { spans.push(styledSpan(buf, curId, di)); buf = ''; curId = sid; }\n buf += chars[k].ch;\n }\n if (buf) spans.push(styledSpan(buf, curId, di));\n return spans;\n}\n\nfunction styledSpan(text: string, shapeId: number, di: DocInfo): SpanNode {\n const cs = di.charShapes[shapeId];\n if (!cs) return buildSpan(text);\n\n const props: TextProps = {};\n const fid = cs.faceIds[0] ?? 0;\n if (fid < di.faceNames.length && di.faceNames[fid]) props.font = safeFont(di.faceNames[fid]);\n if (cs.height> 0) props.pt = Metric.hwpToPt(cs.height);\n if (cs.bold) props.b = true;\n if (cs.italic) props.i = true;\n if (cs.underline) props.u = true;\n if (cs.strikeout) props.s = true;\n if (cs.superscript) props.sup = true;\n if (cs.subscript) props.sub = true;\n\n const hex = safeHex(cs.textColor);\n if (hex && hex !== '000000') props.color = hex;\n\n return buildSpan(text, props);\n}\n\n/* ── Table control parsing ──────────────────────────────────── */\n\nfunction parseTableCtrl(\n recs: HwpRecord[], ctrlIdx: number, di: DocInfo, shield: ShieldedParser, gsoCtx: GsoCtx,\n): { grid: ContentNode | null; next: number } {\n const ctrlLv = recs[ctrlIdx].level;\n let i = ctrlIdx + 1;\n\n let tblData: Uint8Array | null = null;\n const cells: { data: Uint8Array; tag: number; cStart: number; cEnd: number }[] = [];\n\n // Collect TABLE and cell records within this control's scope\n const tblLevel = ctrlLv + 1;\n\n while (i < recs.length && recs[i].level> ctrlLv) {\n const r = recs[i];\n\n if (isTableTag(r.tag) && r.level === tblLevel) {\n tblData = r.data;\n i++;\n } else if (r.tag === TAG_LIST_HEADER && r.level === tblLevel) {\n // LIST_HEADER as cell: paraCount tells how many paragraphs follow\n const cellData = r.data;\n const paraCount = cellData.length>= 2 ? BinaryKit.readU16LE(cellData, 0) : 0;\n i++;\n const cStart = i;\n // Consume exactly paraCount paragraphs (each with its child records)\n let consumed = 0;\n while (i < recs.length && consumed < paraCount) {\n if (recs[i].tag === TAG_PARA_HEADER && recs[i].level === tblLevel) {\n consumed++;\n i++;\n // Skip child records of this paragraph\n while (i < recs.length && recs[i].level> tblLevel) i++;\n } else if (recs[i].level> tblLevel) {\n i++;\n } else {\n break; // hit next sibling at same level\n }\n }\n cells.push({ data: cellData, tag: TAG_LIST_HEADER, cStart, cEnd: i });\n } else if (isCellTag(r.tag) && r.level === tblLevel) {\n // Full CELL record (with cell-specific fields)\n const cellData = r.data;\n const cellTag = r.tag;\n i++;\n const cStart = i;\n while (i < recs.length && recs[i].level> tblLevel) i++;\n cells.push({ data: cellData, tag: cellTag, cStart, cEnd: i });\n } else {\n i++;\n }\n }\n\n if (!tblData || cells.length === 0) return { grid: null, next: i };\n\n const rowCnt = tblData.length>= 6 ? BinaryKit.readU16LE(tblData, 4) : 1;\n const colCnt = tblData.length>= 8 ? BinaryKit.readU16LE(tblData, 6) : 1;\n\n interface PC { row: number; col: number; cs: number; rs: number; widthHwp: number; heightHwp?: number; props: CellProps; cellChildren: (ParaNode | GridNode)[] }\n const parsed: PC[] = [];\n\n for (let ci = 0; ci < cells.length; ci++) {\n const c = cells[ci];\n const seqIdx = ci;\n const pc = shield.guard(\n () => parseCellRec(c.data, c.tag, recs, c.cStart, c.cEnd, di, shield, seqIdx, colCnt, gsoCtx),\n { row: Math.floor(ci / (colCnt || 1)), col: ci % (colCnt || 1), cs: 1, rs: 1, widthHwp: 0, heightHwp: undefined, props: {}, cellChildren: [buildPara([buildSpan('')])] },\n `hwp:cell@${c.cStart}`,\n );\n parsed.push(pc);\n }\n\n // Determine actual row count from cell data (may exceed rowCnt for merged cells)\n const maxRow = parsed.reduce((m, c) => Math.max(m, c.row + c.rs), 0);\n const actualRowCnt = Math.max(rowCnt, maxRow);\n\n // Validate cell positions; fallback to sequential layout if invalid\n const posValid = parsed.every(c => c.row>= 0 && c.col>= 0 && c.col < colCnt);\n if (!posValid) {\n let idx = 0;\n for (const c of parsed) { c.row = Math.floor(idx / colCnt); c.col = idx % colCnt; idx++; }\n }\n\n // Compute column widths in points from cell widths\n const colWidthsPt: number[] = new Array(colCnt).fill(0);\n // Pass 1: use cells with cs=1 for exact column widths\n for (const c of parsed) {\n if (c.cs === 1 && c.widthHwp> 0) {\n const wPt = Metric.hwpToPt(c.widthHwp);\n if (wPt> colWidthsPt[c.col]) colWidthsPt[c.col] = wPt;\n }\n }\n // Pass 2: for columns still 0, try to derive from multi-span cells\n // Sort by span size ascending so smaller, more precise spans fill widths before larger spans\n const zeroColumns = colWidthsPt.filter(w => w === 0).length;\n if (zeroColumns> 0) {\n const spanCells = parsed.filter(c => c.cs> 1 && c.widthHwp> 0).sort((a, b) => a.cs - b.cs);\n for (const c of spanCells) {\n if (c.cs> 1 && c.widthHwp> 0) {\n // Subtract known column widths from the span\n let known = 0;\n let unknownCols = 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci]> 0) known += colWidthsPt[ci];\n else unknownCols++;\n }\n if (unknownCols> 0) {\n const remaining = Metric.hwpToPt(c.widthHwp) - known;\n const each = remaining> 0 ? remaining / unknownCols : 0;\n for (let ci = c.col; ci < c.col + c.cs && ci < colCnt; ci++) {\n if (colWidthsPt[ci] === 0 && each> 0) colWidthsPt[ci] = each;\n }\n }\n }\n }\n }\n\n // Post-process: clamp near-zero column widths (< 1pt = floating-point artifact) to minimum 1pt\n for (let i = 0; i < colWidthsPt.length; i++) {\n if (colWidthsPt[i]> 0 && colWidthsPt[i] < 1) colWidthsPt[i] = 1;\n }\n\n const rows = [];\n for (let r = 0; r < actualRowCnt; r++) {\n const rc = parsed.filter(c => c.row === r).sort((a, b) => a.col - b.col);\n if (rc.length === 0) continue;\n\n // Calculate row height — prefer rs=1 cells (exact per-row height)\n let rowHeightPt: number | undefined = undefined;\n for (const c of rc) {\n if (c.heightHwp && c.heightHwp> 0 && c.rs === 1) {\n const hPt = Metric.hwpToPt(c.heightHwp);\n if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt;\n }\n }\n // Fallback: all cells span multiple rows → approximate height per row\n if (rowHeightPt == null) {\n for (const c of rc) {\n if (c.heightHwp && c.heightHwp> 0) {\n const hPt = Metric.hwpToPt(c.heightHwp) / c.rs;\n if (rowHeightPt == null || hPt> rowHeightPt) rowHeightPt = hPt;\n }\n }\n }\n\n rows.push(buildRow(rc.map(c => {\n return buildCell(c.cellChildren, { cs: c.cs, rs: c.rs, props: c.props });\n }), rowHeightPt));\n }\n if (rows.length === 0) return { grid: null, next: i };\n\n // Table-level default stroke\n let defStroke: Stroke | undefined;\n const bfOff = 18 + rowCnt * 2;\n if (tblData.length>= bfOff + 2) {\n const bfId = BinaryKit.readU16LE(tblData, bfOff);\n defStroke = strokeFromBF(bfId, di);\n }\n\n const gp: GridProps = {};\n if (defStroke) gp.defaultStroke = defStroke;\n const hasWidths = colWidthsPt.some(w => w> 0);\n if (hasWidths) gp.colWidths = colWidthsPt;\n return { grid: buildGrid(rows, gp), next: i };\n}\n\n/* ── Cell record ────────────────────────────────────────────── */\n/* LIST_HEADER for cells (HWP 5.0/5.1):\n [0:2] paraCount [2:4] attr (bits 6-7 = vertAlign)\n [6:2] unknown [8:2] rowAddr [10:2] colAddr\n [12:2] rowSpan [14:2] colSpan\n [16:4] width(HWPUNIT) [20:4] height(HWPUNIT)\n [24:8] padding[4] [32:2] borderFillId */\n\nfunction parseCellRec(\n d: Uint8Array, tag: number, recs: HwpRecord[], cStart: number, cEnd: number,\n di: DocInfo, shield: ShieldedParser, seqIdx: number, colCnt: number, gsoCtx: GsoCtx,\n) {\n let col: number, row: number, cs = 1, rs = 1;\n let widthHwp = 0;\n let heightHwp = 0;\n const props: CellProps = {};\n\n const attr = d.length>= 6 ? BinaryKit.readU32LE(d, 2) : 0;\n const va = (attr>> 6) & 0x3;\n if (va === 1) props.va = 'mid';\n else if (va === 2) props.va = 'bot';\n\n const HWP_PAD_LR_DEFAULT = 360;\n const HWP_PAD_TB_DEFAULT = 141;\n\n if (tag === TAG_LIST_HEADER && d.length>= 22) {\n col = BinaryKit.readU16LE(d, 8);\n row = BinaryKit.readU16LE(d, 10);\n cs = Math.max(1, BinaryKit.readU16LE(d, 12));\n rs = Math.max(1, BinaryKit.readU16LE(d, 14));\n widthHwp = BinaryKit.readU32LE(d, 16);\n heightHwp = d.length>= 24 ? BinaryKit.readU32LE(d, 20) : 0;\n if (d.length>= 32) {\n const pL = BinaryKit.readU16LE(d, 24); const pR = BinaryKit.readU16LE(d, 26);\n const pT = BinaryKit.readU16LE(d, 28); const pB = BinaryKit.readU16LE(d, 30);\n if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL);\n if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR);\n if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT);\n if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB);\n }\n const bfId = d.length>= 34 ? BinaryKit.readU16LE(d, 32) : 0;\n if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props);\n } else if (tag !== TAG_LIST_HEADER) {\n col = d.length>= 8 ? BinaryKit.readU16LE(d, 6) : seqIdx % (colCnt || 1);\n row = d.length>= 10 ? BinaryKit.readU16LE(d, 8) : Math.floor(seqIdx / (colCnt || 1));\n cs = d.length>= 12 ? Math.max(1, BinaryKit.readU16LE(d, 10)) : 1;\n rs = d.length>= 14 ? Math.max(1, BinaryKit.readU16LE(d, 12)) : 1;\n widthHwp = d.length>= 18 ? BinaryKit.readU32LE(d, 14) : 0;\n heightHwp = d.length>= 22 ? BinaryKit.readU32LE(d, 18) : 0;\n if (d.length>= 30) {\n const pL = BinaryKit.readU16LE(d, 22); const pR = BinaryKit.readU16LE(d, 24);\n const pT = BinaryKit.readU16LE(d, 26); const pB = BinaryKit.readU16LE(d, 28);\n if (pL !== HWP_PAD_LR_DEFAULT) props.padL = Metric.hwpToPt(pL);\n if (pR !== HWP_PAD_LR_DEFAULT) props.padR = Metric.hwpToPt(pR);\n if (pT !== HWP_PAD_TB_DEFAULT) props.padT = Metric.hwpToPt(pT);\n if (pB !== HWP_PAD_TB_DEFAULT) props.padB = Metric.hwpToPt(pB);\n }\n const bfId = d.length>= 32 ? BinaryKit.readU16LE(d, 30) : 0;\n if (bfId> 0 && bfId <= di.borderFills.length) applyCellBorderFill(di.borderFills[bfId - 1], props);\n } else {\n row = Math.floor(seqIdx / (colCnt || 1));\n col = seqIdx % (colCnt || 1);\n }\n\n const cellChildren: (ParaNode | GridNode)[] = [];\n const MAX_HWP = 1_000_000;\n let k = cStart;\n\n while (k < cEnd) {\n if (recs[k].tag === TAG_PARA_HEADER) {\n // Parse paragraph inside cell — also extracts nested tables within the paragraph\n const r = shield.guard(\n () => {\n const hdr = recs[k];\n const lv = hdr.level;\n const psId = hdr.data.length>= 10 ? BinaryKit.readU16LE(hdr.data, 8) : 0;\n const ps = di.paraShapes[psId];\n let txt: ParaTextResult | null = null;\n let csp: [number, number][] = [];\n const ctrlHdrs: { ctrlId: number; imgId: number; wPt: number; hPt: number }[] = [];\n const innerGrids: GridNode[] = [];\n let j = k + 1;\n while (j < cEnd && recs[j].level> lv) {\n if (recs[j].tag === TAG_PARA_TEXT) { txt = decodeParaText(recs[j].data); j++; }\n else if (recs[j].tag === TAG_PARA_CHAR_SHAPE) { csp = parseCharShapePairs(recs[j].data); j++; }\n else if (recs[j].tag === TAG_CTRL_HEADER && recs[j].level === lv + 1) {\n if (recs[j].data.length>= 4) {\n const ctrlId = BinaryKit.readU32LE(recs[j].data, 0);\n if (ctrlId === CTRL_TABLE) {\n // Nested table inside a cell paragraph — recurse into parseTableCtrl\n const nestedTr = shield.guard(\n () => parseTableCtrl(recs, j, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, j) },\n `hwp:innerNestedTbl@${j}`,\n );\n if (nestedTr.grid) innerGrids.push(nestedTr.grid as GridNode);\n j = nestedTr.next;\n } else {\n const rawW = recs[j].data.length>= 24 ? BinaryKit.readU32LE(recs[j].data, 16) : 0;\n const rawH = recs[j].data.length>= 28 ? BinaryKit.readU32LE(recs[j].data, 20) : 0;\n const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n const imgId = ctrlId === CTRL_GSO ? gsoCtx.count++ : (recs[j].data.length>= 6 ? BinaryKit.readU16LE(recs[j].data, 4) : 0);\n ctrlHdrs.push({ ctrlId, imgId, wPt, hPt });\n j = skipKids(recs, j);\n }\n } else {\n j = skipKids(recs, j);\n }\n }\n else j++;\n }\n const paraContent: (SpanNode | ContentNode)[] = [];\n if (txt && txt.chars.length> 0) paraContent.push(...resolveCharShapes(txt.chars, csp, di));\n if (txt && txt.controls.length> 0) {\n for (let ci = 0; ci < txt.controls.length; ci++) {\n const ch = ctrlHdrs[ci];\n if (!ch) continue;\n const isImg = ch.ctrlId === CTRL_IMAGE || ch.ctrlId === CTRL_FIG || ch.ctrlId === CTRL_OBJ || ch.ctrlId === CTRL_GSO;\n if (!isImg) continue;\n const dimStr = (ch.wPt> 0 && ch.hPt> 0) ? `_W${Math.round(ch.wPt)}_H${Math.round(ch.hPt)}` : '';\n paraContent.push(buildSpan(`__EXT_${ch.imgId}${dimStr}__`));\n }\n }\n const kids = paraContent.length> 0 ? paraContent as any : [buildSpan('')];\n const items: (ParaNode | GridNode)[] = [buildPara(kids, buildParaProps(ps)), ...innerGrids];\n return { items, next: j };\n },\n { items: [buildPara([buildSpan('')])] as (ParaNode | GridNode)[], next: k + 1 },\n `hwp:cellP@${k}`,\n );\n cellChildren.push(...r.items);\n k = r.next;\n } else if (recs[k].tag === TAG_CTRL_HEADER && recs[k].data.length>= 4) {\n // CTRL_HEADER at cell level (sibling of PARA_HEADER) — anchored 'gso' images and outer-level nested tables\n const cellCtrlId = BinaryKit.readU32LE(recs[k].data, 0);\n if (cellCtrlId === CTRL_GSO) {\n const gsoId = gsoCtx.count++;\n const rawW = recs[k].data.length>= 24 ? BinaryKit.readU32LE(recs[k].data, 16) : 0;\n const rawH = recs[k].data.length>= 28 ? BinaryKit.readU32LE(recs[k].data, 20) : 0;\n const wPt = rawW> 0 && rawW < MAX_HWP ? Metric.hwpToPt(rawW) : 0;\n const hPt = rawH> 0 && rawH < MAX_HWP ? Metric.hwpToPt(rawH) : 0;\n const dimStr = (wPt> 0 && hPt> 0) ? `_W${Math.round(wPt)}_H${Math.round(hPt)}` : '';\n cellChildren.push(buildPara([buildSpan(`__EXT_${gsoId}${dimStr}__`)]));\n k = skipKids(recs, k);\n } else if (cellCtrlId === CTRL_TABLE) {\n const tr = shield.guard(\n () => parseTableCtrl(recs, k, di, shield, gsoCtx),\n { grid: null, next: skipKids(recs, k) },\n `hwp:nestedTbl@${k}`,\n );\n if (tr.grid) cellChildren.push(tr.grid as GridNode);\n k = tr.next;\n } else {\n k = skipKids(recs, k);\n }\n } else { k++; }\n }\n\n return {\n row, col, cs, rs, props, widthHwp,\n heightHwp: heightHwp || undefined,\n cellChildren: cellChildren.length ? cellChildren : [buildPara([buildSpan('')])],\n };\n}\n\n/* ── PAGE_DEF ───────────────────────────────────────────────── */\n/* [0:4] width [4:4] height [8:4] ml [12:4] mr\n [16:4] mt [20:4] mb [36:4] attr (bit0=landscape) */\n\nfunction parsePageDef(d: Uint8Array): PageDims {\n if (d.length < 24) return A4;\n const w = BinaryKit.readU32LE(d, 0);\n const h = BinaryKit.readU32LE(d, 4);\n const ml = BinaryKit.readU32LE(d, 8);\n const mr = BinaryKit.readU32LE(d, 12);\n const mt = BinaryKit.readU32LE(d, 16);\n const mb = BinaryKit.readU32LE(d, 20);\n const at = d.length>= 40 ? BinaryKit.readU32LE(d, 36) : 0;\n return {\n wPt: Metric.hwpToPt(w), hPt: Metric.hwpToPt(h),\n ml: Metric.hwpToPt(ml), mr: Metric.hwpToPt(mr),\n mt: Metric.hwpToPt(mt), mb: Metric.hwpToPt(mb),\n orient: (at & 1) ? 'landscape' : 'portrait',\n };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Helpers\n ═══════════════════════════════════════════════════════════════ */\n\nfunction i32(d: Uint8Array, o: number): number {\n const u = BinaryKit.readU32LE(d, o);\n return u> 0x7FFFFFFF ? u - 0x100000000 : u;\n}\n\nfunction colorRef(d: Uint8Array, o: number): string {\n if (o + 3> d.length) return '000000';\n return ((d[o] << 16) | (d[o + 1] << 8) | d[o + 2]).toString(16).padStart(6, '0').toUpperCase();\n}\n\nfunction toStroke(b: { type: number; widthPt: number; color: string }): Stroke {\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\n// Apply borderFill to CellProps. Preserve explicit NONE so DOCX tcBorders can\n// override the table-level tblBorders. Filtering NONE would let tblBorders bleed through.\nfunction applyCellBorderFill(bf: HwpBorderFill, props: CellProps): void {\n if (bf.borders.length>= 4) {\n props.left = toStroke(bf.borders[0]);\n props.right = toStroke(bf.borders[1]);\n props.top = toStroke(bf.borders[2]);\n props.bot = toStroke(bf.borders[3]);\n }\n if (bf.bgColor && bf.bgColor !== 'FFFFFF') props.bg = bf.bgColor;\n}\n\nfunction strokeFromBF(bfId: number, di: DocInfo): Stroke | undefined {\n if (bfId <= 0 || bfId> di.borderFills.length) return undefined;\n const bf = di.borderFills[bfId - 1];\n if (!bf.borders.length) return undefined;\n const b = bf.borders[0];\n return { kind: BORDER_KIND[b.type] ?? 'solid', pt: b.widthPt, color: b.color };\n}\n\nfunction buildParaProps(ps?: HwpParaShape): ParaProps {\n if (!ps) return {};\n const p: ParaProps = {};\n if (ps.align && ps.align !== 'left') p.align = ps.align;\n if (ps.spaceBefore> 0) p.spaceBefore = Metric.hwpToPt(ps.spaceBefore);\n if (ps.spaceAfter> 0) p.spaceAfter = Metric.hwpToPt(ps.spaceAfter);\n if (ps.lineSpacing> 0 && ps.lineSpacing !== 160) p.lineHeight = ps.lineSpacing / 100;\n // leftMargin (offset 4) = 문단 몸체 왼쪽 여백 → leftMargin (pt), ensure non-negative\n const leftMarginPt = Math.max(0, Metric.hwpToPt(ps.leftMargin));\n if (leftMarginPt> 0) p.leftMargin = leftMarginPt;\n // indent (offset 12) = 첫 줄 들여쓰기(양수) / 내어쓰기(음수) → firstLineIndentPt\n if (ps.indent !== 0) p.firstLineIndentPt = Metric.hwpToPt(ps.indent);\n return p;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Decoder class\n ═══════════════════════════════════════════════════════════════ */\n\nexport class HwpScanner implements Decoder {\n readonly format = 'hwp';\n readonly aliases = ['application/vnd.hancom.hwp'];\n\n async decode(data: Uint8Array): Promise> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n if (!BinaryKit.isOle2(data)) return fail('HWP: Invalid OLE2 signature');\n const streams = BinaryKit.parseCfb(data);\n\n // FileHeader\n const fh = streams.get('FileHeader');\n const { compressed, encrypted } = fh ? parseFileHeader(fh) : { compressed: true, encrypted: false };\n if (encrypted) return fail('HWP: 암호화된 파일은 지원하지 않습니다');\n\n // DocInfo\n const diRaw = streams.get('DocInfo');\n let di: DocInfo = { faceNames: [], charShapes: [], paraShapes: [], borderFills: [] };\n if (diRaw) {\n di = shield.guard(() => parseDocInfo(diRaw, compressed), di, 'hwp:docInfo');\n }\n\n // Extract images from BinData streams.\n // HWP duplicates each BinData entry: once as \"BinData/BIN0001.jpg\" and once as \"BIN0001.jpg\".\n // We keep only the \"BinData/\" prefixed versions, sort by BIN number, then assign 0-based keys\n // matching the order 'gso' CTRL_HEADER records are encountered during body parsing.\n const binEntries: { binNum: number; data: Uint8Array }[] = [];\n for (const [path, streamData] of streams) {\n // Match \"BinData/BIN0001.jpg\" style — the canonical form\n const m = path.match(/^BinData[/\\\\]BIN(\\d+)\\.\\w+$/i);\n if (m) binEntries.push({ binNum: parseInt(m[1], 10), data: streamData });\n }\n // Sort by BIN number (ascending) so BIN0001→idx0, BIN0002→idx1, ...\n binEntries.sort((a, b) => a.binNum - b.binNum);\n\n const objectMap = new Map();\n for (let idx = 0; idx < binEntries.length; idx++) {\n const { data: imgData } = binEntries[idx];\n\n // Determine MIME type from binary signature first, then fall back to extension\n let mimeType: ImgNode['mime'] = 'image/jpeg';\n if (imgData[0] === 0x89 && imgData[1] === 0x50) mimeType = 'image/png';\n else if (imgData[0] === 0x47 && imgData[1] === 0x49) mimeType = 'image/gif';\n else if (imgData[0] === 0x42 && imgData[1] === 0x4D) mimeType = 'image/bmp';\n\n const base64 = TextKit.base64Encode(imgData);\n const { wPt, hPt } = getImageDimsPt(imgData, mimeType);\n objectMap.set(idx, buildImg(base64, mimeType, wPt, hPt));\n }\n\n // gsoCtx tracks sequential 'gso' encounter order — must be shared across all sections\n const gsoCtx: GsoCtx = { count: 0 };\n\n // Body sections\n const allContent: ContentNode[] = [];\n let pageDims: PageDims = A4;\n\n for (let s = 0; s < 100; s++) {\n const sec = streams.get(`BodyText/Section${s}`) ?? streams.get(`Section${s}`);\n if (!sec) {\n if (s === 0) {\n const fb = findBodySection(streams);\n if (fb) {\n const r = parseBody(fb, compressed, di, shield, gsoCtx);\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n }\n break;\n }\n const r = shield.guard(\n () => parseBody(sec, compressed, di, shield, gsoCtx),\n { content: [], pageDims: undefined },\n `hwp:sec${s}`,\n );\n allContent.push(...r.content);\n if (r.pageDims) pageDims = r.pageDims;\n }\n\n if (objectMap.size> 0) {\n injectImagesIntoContent(allContent, objectMap);\n }\n\n warns.push(...shield.flush());\n const content = allContent.length> 0 ? allContent : [buildPara([buildSpan('')])];\n return succeed(buildRoot({}, [buildSheet(content, pageDims)]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`HWP decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\nfunction findBodySection(streams: Map): Uint8Array | undefined {\n for (const [k, v] of streams)\n if (k.includes('Section') && !k.includes('Header') && !k.includes('Info')) return v;\n return undefined;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Image dimension extraction from binary headers\n ════════════════════════════════════════════════════════════ */\n\n// Returns { wPt, hPt } by parsing image headers; falls back to { wPt: 72, hPt: 72 } (1-inch)\nfunction getImageDimsPt(data: Uint8Array, mime: string): { wPt: number; hPt: number } {\n const fallback = { wPt: 72, hPt: 72 };\n try {\n if (mime === 'image/png' && data.length>= 24) {\n // PNG IHDR: sig(8) + length(4) + type(4) + width(4) + height(4) — all big-endian\n const w = (data[16] << 24 | data[17] << 16 | data[18] << 8 | data[19])>>> 0;\n const h = (data[20] << 24 | data[21] << 16 | data[22] << 8 | data[23])>>> 0;\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 }; // 96 DPI → pt\n }\n if (mime === 'image/jpeg') {\n // Scan for SOF markers: FF C0 / C1 / C2 / C3\n let i = 2;\n while (i + 8 < data.length) {\n if (data[i] !== 0xFF) { i++; continue; }\n const marker = data[i + 1];\n if (marker>= 0xC0 && marker <= 0xC3) {\n // SOF: 2-byte marker + 2-byte length + 1-byte precision + 2-byte height + 2-byte width\n const h = (data[i + 5] << 8 | data[i + 6])>>> 0;\n const w = (data[i + 7] << 8 | data[i + 8])>>> 0;\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n const segLen = data[i + 2] << 8 | data[i + 3];\n i += 2 + (segLen> 0 ? segLen : 2);\n }\n }\n if (mime === 'image/bmp' && data.length>= 26) {\n // BMP DIB header: width at 18, height at 22 (signed int32 LE; negative = top-down)\n const w = BinaryKit.readU32LE(data, 18);\n const h = Math.abs(BinaryKit.readU32LE(data, 22) | 0);\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n if (mime === 'image/gif' && data.length>= 10) {\n // GIF: width at 6, height at 8 (uint16 LE)\n const w = data[6] | data[7] << 8;\n const h = data[8] | data[9] << 8;\n if (w> 0 && h> 0) return { wPt: w * 0.75, hPt: h * 0.75 };\n }\n } catch { /* ignore */ }\n return fallback;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n OLE Object extraction (images)\n ════════════════════════════════════════════════════════════ */\n\nfunction extractImagesFromOleObjectLink(data: Uint8Array): OleObject[] {\n const objects: OleObject[] = [];\n let off = 0;\n\n while (off + 8 <= data.length) {\n const objId = BinaryKit.readU32LE(data, off);\n const dataSize = BinaryKit.readU32LE(data, off + 4);\n const reserved = BinaryKit.readU32LE(data, off + 8);\n\n if (objId === 0 || dataSize === 0) break;\n\n const objOff = off + 16;\n if (objOff + dataSize> data.length) break;\n\n const objData = data.subarray(objOff, objOff + dataSize);\n\n // Detect MIME type from signature\n let mimeType = 'application/octet-stream';\n if (objData[0] === 0xFF && objData[1] === 0xD8 && objData[2] === 0xFF) {\n mimeType = 'image/jpeg';\n } else if (objData[0] === 0x89 && objData[1] === 0x50 && objData[2] === 0x4E && objData[3] === 0x47) {\n mimeType = 'image/png';\n } else if (objData[0] === 0x47 && objData[1] === 0x49 && objData[2] === 0x46 && objData[3] === 0x3538) {\n mimeType = 'image/gif';\n } else if (objData[0] === 0x42 && objData[1] === 0x4D) {\n mimeType = 'image/bmp';\n }\n\n objects.push({ id: objId, data: objData, mimeType });\n off = objOff + dataSize;\n }\n\n return objects;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Helper to inject images into paragraph content\n ════════════════════════════════════════════════════════════ */\n\nfunction injectImagesIntoContent(\n content: ContentNode[],\n objectMap: Map\n): void {\n if (objectMap.size === 0) return;\n\n // Helper function to process a list of kids (spans, images, etc.)\n const processKids = (kids: any[]) => {\n for (let i = 0; i < kids.length; i++) {\n const kid = kids[i];\n // Span node structure: { tag: 'span', props, kids: [{ tag: 'txt', content }] }\n if (kid.tag === 'span' && kid.kids && kid.kids[0]?.tag === 'txt') {\n const text = kid.kids[0].content;\n // __EXT_N__ or __EXT_N_W_H__ (with encoded display size)\n // N is the objId that matches the index in objectMap\n const match = text.match?.(/^__(?:IMG|EXT)_(\\d+)(?:_W(\\d+)_H(\\d+))?__$/);\n if (match) {\n const objId = parseInt(match[1], 10);\n const base = objectMap.get(objId);\n if (base) {\n const wPt = match[2] ? parseInt(match[2], 10) : 0;\n const hPt = match[3] ? parseInt(match[3], 10) : 0;\n // Use encoded display size when valid; otherwise keep pixel-based dims\n kids[i] = (wPt> 0 && hPt> 0) ? { ...base, w: wPt, h: hPt } : base;\n }\n }\n }\n }\n };\n\n // Recursively process a grid (table): resolves image placeholders in all cells,\n // including nested grids inside cells.\n const processGridKids = (grid: any) => {\n if (!grid.kids || !Array.isArray(grid.kids)) return;\n\n for (const row of grid.kids) {\n if (!row.kids || !Array.isArray(row.kids)) continue;\n\n for (const cell of row.kids) {\n if (!cell.kids || !Array.isArray(cell.kids)) continue;\n\n for (const cellKid of cell.kids) {\n if (cellKid.tag === 'grid') {\n // Nested table inside cell — recurse\n processGridKids(cellKid);\n } else if (cellKid.tag === 'para' && cellKid.kids) {\n processKids(cellKid.kids);\n }\n }\n }\n }\n };\n\n for (const node of content) {\n if (node.tag === 'para' && node.kids) {\n // Process paragraph kids (spans, images, links, grids)\n processKids(node.kids);\n\n // Also process any nested grids inside the paragraph\n for (const kid of node.kids) {\n if (kid.tag === 'grid') {\n processGridKids(kid);\n }\n }\n } else if (node.tag === 'grid') {\n // Process grid nodes (tables)\n processGridKids(node);\n }\n }\n}\n\nregistry.registerDecoder(new HwpScanner());\n","import type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n LinkNode,\n PageNumNode,\n CellNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n DocMeta,\n PageDims,\n TextProps,\n ParaProps,\n CellProps,\n GridProps,\n TableLook,\n Stroke,\n ImgLayout,\n ImgHorzAlign,\n ImgVertAlign,\n ImgHorzRelTo,\n ImgVertRelTo,\n ImgWrap,\n} from \"../../model/doc-props\";\nimport { A4 } from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport {\n buildRoot,\n buildSheet,\n buildPara,\n buildSpan,\n buildImg,\n buildGrid,\n buildRow,\n buildCell,\n buildPb,\n} from \"../../model/builders\";\nimport { ShieldedParser } from \"../../safety/ShieldedParser\";\nimport {\n Metric,\n safeAlign,\n safeFont,\n safeHex,\n safeStrokeDocx,\n} from \"../../safety/StyleBridge\";\nimport { BaseDecoder } from \"../../core/BaseDecoder\";\nimport { ArchiveKit } from \"../../toolkit/ArchiveKit\";\nimport { XmlKit } from \"../../toolkit/XmlKit\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { registry } from \"../../pipeline/registry\";\n\nexport class DocxDecoder extends BaseDecoder {\n protected getFormat(): string {\n return \"docx\";\n }\n\n async decode(data: Uint8Array): Promise> {\n const shield = new ShieldedParser();\n const warns: string[] = [];\n\n try {\n const files = await ArchiveKit.unzip(data);\n\n const getFile = (path: string) => {\n const lower = path.toLowerCase();\n for (const [name, data] of files.entries()) {\n if (name.toLowerCase() === lower) return data;\n }\n return undefined;\n };\n\n const docXml = getFile(\"word/document.xml\");\n if (!docXml) return fail(\"DOCX: word/document.xml not found\");\n\n const relsXml = getFile(\"word/_rels/document.xml.rels\");\n const relsMap = relsXml\n ? await parseRels(TextKit.decode(relsXml))\n : new Map();\n\n const coreXml = getFile(\"docProps/core.xml\");\n let meta: DocMeta = {};\n if (coreXml) {\n try {\n meta = await parseCoreProps(TextKit.decode(coreXml));\n } catch {\n // ignore — meta is optional\n }\n }\n\n // Parse numbering.xml for list support\n const numXml = getFile(\"word/numbering.xml\");\n let numMap: NumMap = new Map();\n if (numXml) {\n try {\n numMap = await parseNumbering(TextKit.decode(numXml));\n } catch {\n /* non-fatal */\n }\n }\n\n // Parse styles.xml for table and paragraph/character style defaults\n let stylesMap: StylesMap = new Map();\n let paraStyleMap: ParaStyleMap = new Map();\n const stylesXml = getFile(\"word/styles.xml\");\n if (stylesXml) {\n try {\n const stylesStr = TextKit.decode(stylesXml);\n stylesMap = await parseStylesMap(stylesStr);\n paraStyleMap = await parseParaStyleMap(stylesStr);\n } catch {\n /* non-fatal */\n }\n }\n\n let docStr = TextKit.decode(docXml).trim();\n if (!docStr) {\n warns.push(\n \"DOCX: word/document.xml is empty, using fallback empty document\",\n );\n docStr =\n '';\n }\n const docObj: any = await XmlKit.parseStrict(docStr);\n\n const body = getBody(docObj);\n const dims = extractDims(body) ?? { ...A4 };\n const elements = getBodyElements(body);\n console.log(\n `[DocxDecoder] 파싱된 전체 본문 요소 개수: ${elements.length}`,\n );\n\n const decCtx: DecCtx = {\n relsMap,\n files,\n shield,\n numMap,\n warns,\n stylesMap,\n paraStyleMap,\n };\n\n const kids: ContentNode[] = [];\n for (const el of elements) {\n const nodes = shield.guard(\n () => decodeElement(el, decCtx),\n [buildPara([buildSpan(\"[요소 파싱 실패]\")])],\n \"docx:bodyElement\",\n );\n if (Array.isArray(nodes)) {\n kids.push(...nodes);\n } else {\n kids.push(nodes);\n }\n\n // Inline sectPr in pPr = section break → insert page-break paragraph after\n if (el.type === \"para\") {\n const pPr = el.node?.[\"w:pPr\"]?.[0] ?? el.node?.pPr?.[0] ?? {};\n const inlineSectPr = pPr?.[\"w:sectPr\"]?.[0] ?? pPr?.sectPr?.[0];\n if (inlineSectPr) {\n const typeAttr = inlineSectPr?.[\"w:type\"]?.[0]?._attr;\n const sectType = typeAttr?.[\"w:val\"] ?? typeAttr?.val ?? \"nextPage\";\n if (sectType !== \"continuous\") {\n kids.push(\n buildPara([{ tag: \"span\", props: {}, kids: [buildPb()] }]),\n );\n }\n }\n }\n }\n\n // Decode header/footer\n const headersMap = await decodeHeaderFooter(\n \"header\",\n body,\n relsMap,\n files,\n decCtx,\n );\n const footersMap = await decodeHeaderFooter(\n \"footer\",\n body,\n relsMap,\n files,\n decCtx,\n );\n\n warns.push(...shield.flush());\n const sheet = buildSheet(kids.filter(Boolean) as ContentNode[], dims, {\n headers: headersMap,\n footers: footersMap,\n });\n return succeed(buildRoot(meta, [sheet]), warns);\n } catch (e: any) {\n warns.push(...shield.flush());\n return fail(`DOCX decode error: ${e?.message ?? String(e)}`, warns);\n }\n }\n}\n\n// ─── types ─────────────────────────────────────────────────\n\ninterface TblBorderDef {\n top?: Stroke;\n bottom?: Stroke;\n left?: Stroke;\n right?: Stroke;\n insideH?: Stroke;\n insideV?: Stroke;\n}\n\n/** Parsed tblStyle defaults from styles.xml */\ninterface TblStyleDef {\n tblBorders?: TblBorderDef;\n cellBg?: string; // default cell background\n}\n\n/** Parsed paragraph/character style defaults */\ninterface ParaStyleDef {\n rPr?: {\n b?: boolean;\n i?: boolean;\n u?: boolean;\n s?: boolean;\n pt?: number;\n color?: string;\n font?: string;\n };\n pPr?: {\n align?: string;\n spaceBefore?: number;\n spaceAfter?: number;\n lineHeight?: number;\n indentPt?: number;\n indentRightPt?: number;\n firstLineIndentPt?: number;\n };\n basedOn?: string; // parent style id\n}\n\ntype StylesMap = Map; // styleId → table style defaults\ntype ParaStyleMap = Map; // styleId → para/char style defaults\n\ninterface DecCtx {\n relsMap: Map;\n files: Map;\n shield: ShieldedParser;\n numMap: NumMap;\n warns: string[];\n stylesMap: StylesMap;\n paraStyleMap: ParaStyleMap;\n}\n\n// numId → { abstractNumId, levels: Map }\ntype NumMap = Map<\n number,\n { levels: Map }\n>;\n\n// ─── helpers ────────────────────────────────────────────────\n\nfunction toArr(v: any): any[] {\n return v == null ? [] : Array.isArray(v) ? v : [v];\n}\n\n/** Resolve DOCX relative paths. e.g. (\"word\", \"../media/image1.png\") → \"word/media/image1.png\" */\nfunction resolveDocxPath(baseDir: string, target: string): string {\n if (target.startsWith(\"/\")) return target.slice(1);\n const parts = (baseDir + \"/\" + target).split(\"/\");\n const stack: string[] = [];\n for (const p of parts) {\n if (p === \"..\") {\n stack.pop();\n } else if (p !== \".\") {\n stack.push(p);\n }\n }\n return stack.join(\"/\");\n}\n\nasync function parseRels(xml: string): Promise
                  > {\n const map = new Map();\n const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\n for (const rel of toArr(obj?.Relationships?.[0]?.Relationship)) {\n const a = rel?._attr ?? {};\n if (a.Id && a.Target) map.set(a.Id, a.Target);\n }\n } catch {\n /* ignore */\n }\n return map;\n}\n\nasync function parseCoreProps(xml: string): Promise {\n const trimmed = xml.trim();\n if (!trimmed) return {};\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\n const c = obj?.[\"cp:coreProperties\"]?.[0] ?? obj?.coreProperties?.[0] ?? {};\n return {\n title: c?.[\"dc:title\"]?.[0]?._text ?? undefined,\n author: c?.[\"dc:creator\"]?.[0]?._text ?? undefined,\n subject: c?.[\"dc:subject\"]?.[0]?._text ?? undefined,\n created: c?.[\"dcterms:created\"]?.[0]?._text ?? undefined,\n modified: c?.[\"dcterms:modified\"]?.[0]?._text ?? undefined,\n };\n } catch {\n return {};\n }\n}\n\nasync function parseNumbering(xml: string): Promise {\n const map: NumMap = new Map();\n const trimmed = xml.trim();\n if (!trimmed) return map;\n try {\n const obj: any = await XmlKit.parseStrict(trimmed);\n const root = obj?.[\"w:numbering\"]?.[0] ?? obj?.numbering?.[0] ?? obj;\n\n // Parse abstractNums\n const absMap = new Map<\n number,\n Map\n>();\n for (const abs of toArr(root?.[\"w:abstractNum\"] ?? root?.abstractNum)) {\n const absId = Number(\n abs?._attr?.[\"w:abstractNumId\"] ?? abs?._attr?.abstractNumId ?? 0,\n );\n const levels = new Map();\n for (const lvl of toArr(abs?.[\"w:lvl\"] ?? abs?.lvl)) {\n const ilvl = Number(lvl?._attr?.[\"w:ilvl\"] ?? lvl?._attr?.ilvl ?? 0);\n const fmtNode =\n lvl?.[\"w:numFmt\"]?.[0]?._attr ?? lvl?.numFmt?.[0]?._attr ?? {};\n const fmt = fmtNode?.[\"w:val\"] ?? fmtNode?.val ?? \"decimal\";\n levels.set(ilvl, { fmt, isOrdered: fmt !== \"bullet\" });\n }\n absMap.set(absId, levels);\n }\n\n // Parse nums\n for (const num of toArr(root?.[\"w:num\"] ?? root?.num)) {\n const numId = Number(num?._attr?.[\"w:numId\"] ?? num?._attr?.numId ?? 0);\n const absRef =\n num?.[\"w:abstractNumId\"]?.[0]?._attr ??\n num?.abstractNumId?.[0]?._attr ??\n {};\n const absId = Number(absRef?.[\"w:val\"] ?? absRef?.val ?? 0);\n const levels = absMap.get(absId) ?? new Map();\n map.set(numId, { levels });\n }\n } catch {\n /* non-fatal */\n }\n return map;\n}\n\nfunction getBody(obj: any): any {\n // XML 파서에 따라 w:document 또는 document 형태일 수 있음\n const doc = obj?.[\"w:document\"]?.[0] ?? obj?.document?.[0] ?? obj;\n const body = doc?.[\"w:body\"]?.[0] ?? doc?.body?.[0] ?? doc;\n\n if (!body) {\n console.error(\"[DocxDecoder] 본문(body)을 찾을 수 없습니다.\");\n }\n return body;\n}\n\nfunction extractDims(body: any): PageDims | null {\n try {\n const sp = body?.[\"w:sectPr\"]?.[0] ?? body?.sectPr?.[0];\n if (!sp) return null;\n const sz = sp?.[\"w:pgSz\"]?.[0]?._attr ?? sp?.pgSz?.[0]?._attr;\n const mar = sp?.[\"w:pgMar\"]?.[0]?._attr ?? sp?.pgMar?.[0]?._attr;\n if (!sz) return null;\n const headerDxa = Number(mar?.[\"w:header\"] ?? mar?.header ?? 0);\n const footerDxa = Number(mar?.[\"w:footer\"] ?? mar?.footer ?? 0);\n return {\n wPt: Metric.dxaToPt(Number(sz[\"w:w\"] ?? sz.w ?? 11906)),\n hPt: Metric.dxaToPt(Number(sz[\"w:h\"] ?? sz.h ?? 16838)),\n mt: Metric.dxaToPt(Number(mar?.[\"w:top\"] ?? mar?.top ?? 1440)),\n mb: Metric.dxaToPt(Number(mar?.[\"w:bottom\"] ?? mar?.bottom ?? 1440)),\n ml: Metric.dxaToPt(Number(mar?.[\"w:left\"] ?? mar?.left ?? 1800)),\n mr: Metric.dxaToPt(Number(mar?.[\"w:right\"] ?? mar?.right ?? 1800)),\n orient:\n (sz[\"w:orient\"] ?? sz.orient) === \"landscape\"\n ? \"landscape\"\n : \"portrait\",\n headerPt: headerDxa> 0 ? Metric.dxaToPt(headerDxa) : undefined,\n footerPt: footerDxa> 0 ? Metric.dxaToPt(footerDxa) : undefined,\n };\n } catch {\n return null;\n }\n}\n\nfunction getBodyElements(body: any): { type: string; node: any }[] {\n const paras = toArr(body?.[\"w:p\"] ?? body?.p);\n const tables = toArr(body?.[\"w:tbl\"] ?? body?.tbl);\n const sdts = toArr(body?.[\"w:sdt\"] ?? body?.sdt);\n\n const childOrder = body?.[\"_childOrder\"] as string[] | undefined;\n if (Array.isArray(childOrder)) {\n const items: { type: string; node: any }[] = [];\n let pi = 0,\n ti = 0,\n si = 0;\n for (const tag of childOrder) {\n if ((tag === \"w:p\" || tag === \"p\") && pi < paras.length) {\n items.push({ type: \"para\", node: paras[pi++] });\n } else if ((tag === \"w:tbl\" || tag === \"tbl\") && ti < tables.length) {\n items.push({ type: \"table\", node: tables[ti++] });\n } else if ((tag === \"w:sdt\" || tag === \"sdt\") && si < sdts.length) {\n items.push({ type: \"sdt\", node: sdts[si++] });\n }\n }\n // Append any remainders\n while (pi < paras.length) items.push({ type: \"para\", node: paras[pi++] });\n while (ti < tables.length)\n items.push({ type: \"table\", node: tables[ti++] });\n while (si < sdts.length) items.push({ type: \"sdt\", node: sdts[si++] });\n return items;\n }\n\n // Fallback: paragraphs, then tables, then sdts\n return [\n ...paras.map((n: any) => ({ type: \"para\", node: n })),\n ...tables.map((n: any) => ({ type: \"table\", node: n })),\n ...sdts.map((n: any) => ({ type: \"sdt\", node: n })),\n ];\n}\n\n// ─── Header/Footer decoding ────────────────────────────────\n\nasync function decodeHeaderFooter(\n kind: \"header\" | \"footer\",\n body: any,\n relsMap: Map, // document.xml.rels (기존)\n files: Map,\n ctx: DecCtx,\n): Promise | undefined> {\n try {\n const sp = body?.[\"w:sectPr\"]?.[0] ?? body?.sectPr?.[0];\n if (!sp) return undefined;\n\n const refTag =\n kind === \"header\" ? \"w:headerReference\" : \"w:footerReference\";\n const refs = toArr(sp?.[refTag] ?? sp?.[refTag.replace(\"w:\", \"\")]);\n if (refs.length === 0) return undefined;\n\n const result: Record = {};\n\n for (const ref of refs) {\n const type = ref._attr?.[\"w:type\"] ?? ref._attr?.type ?? \"default\";\n const rId = ref._attr?.[\"r:id\"] ?? ref._attr?.[\"r:Id\"] ?? ref._attr?.id;\n if (!rId) continue;\n\n const target = relsMap.get(rId);\n if (!target) continue;\n\n const filePath = resolveDocxPath(\"word\", target);\n const fileData = files.get(filePath);\n if (!fileData) continue;\n\n // ★ 핵심 수정: 헤더/풋터 전용 rels 파일 로드\n const hfFileName = filePath.split(\"/\").pop() ?? \"\";\n const hfRelsPath = `word/_rels/${hfFileName}.rels`;\n const hfRelsData = files.get(hfRelsPath);\n // 헤더/풋터 rels를 document rels와 병합\n let hfRelsMap = relsMap;\n if (hfRelsData) {\n const hfRelsStr = TextKit.decode(hfRelsData).trim();\n const parsed = hfRelsStr\n ? await parseRels(hfRelsStr)\n : new Map();\n // 병합 (헤더/풋터 rels 우선)\n hfRelsMap = new Map([...relsMap, ...parsed]);\n }\n\n const xmlStr = TextKit.decode(fileData).trim();\n if (!xmlStr) continue;\n\n const watermark = extractWatermark(xmlStr);\n if (watermark) {\n result[type] = [\n buildPara([\n buildSpan(watermark, { pt: 80, color: \"CCCCCC\", b: true }),\n ]),\n ];\n continue;\n }\n\n try {\n const obj: any = await XmlKit.parseStrict(xmlStr);\n const rootTag = kind === \"header\" ? \"w:hdr\" : \"w:ftr\";\n const root =\n obj?.[rootTag]?.[0] ?? obj?.[rootTag.replace(\"w:\", \"\")]?.[0] ?? obj;\n\n // ctx에 hfRelsMap 임시 적용\n const origRelsMap = ctx.relsMap;\n (ctx as any).relsMap = hfRelsMap;\n const paras = toArr(root?.[\"w:p\"] ?? root?.p);\n result[type] = paras.map((p: any) => decodePara(p, ctx));\n (ctx as any).relsMap = origRelsMap;\n } catch (err) {\n console.warn(`[DocxDecoder] ${kind} (${type}) XML 파싱 실패:`, err);\n continue;\n }\n }\n\n return Object.keys(result).length> 0 ? result : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** 워터마크 텍스트 추출 (VML v:textpath 기반) */\nfunction extractWatermark(xml: string): string | null {\n if (!xml.includes(\"v:textpath\")) return null;\n const m = xml.match(/string=\"([^\"]+)\"/);\n return m ? m[1] : null;\n}\n\n// ─── Element decoding ──────────────────────────────────────\n\n//만약에 drawing 태그가 안에 있으면 true 반환\nfunction hasDrawingDeep(node: any): boolean {\n if (!node || typeof node !== \"object\") return false;\n\n if (node[\"w:drawing\"] || node[\"w:pict\"]) return true;\n\n return Object.values(node).some((v) => {\n if (Array.isArray(v)) return v.some(hasDrawingDeep);\n return hasDrawingDeep(v);\n });\n}\n\nfunction decodeElement(\n el: { type: string; node: any },\n ctx: DecCtx,\n): ContentNode | ContentNode[] {\n if (el.type === \"table\") {\n const { value } = ctx.shield.guardGrid(\n el.node,\n (n) => decodeGrid(n as any, ctx),\n (n) => decodeGridSimple(n as any),\n (n) => decodeGridFlat(n as any),\n (n) => decodeGridText(n as any) as unknown as GridNode,\n \"docx:table\",\n );\n return value;\n } else if (el.type === \"sdt\") {\n return decodeSdt(el.node, ctx);\n }\n return decodePara(el.node, ctx);\n}\n\nfunction decodeSdt(sdt: any, ctx: DecCtx): ContentNode[] {\n const content = sdt?.[\"w:sdtContent\"]?.[0] ?? sdt?.sdtContent?.[0];\n if (!content) return [];\n const elements = getBodyElements(content);\n const kids: ContentNode[] = [];\n for (const el of elements) {\n const res = decodeElement(el, ctx);\n if (Array.isArray(res)) kids.push(...res);\n else kids.push(res);\n }\n return kids;\n}\n\nfunction decodePara(p: any, ctx: DecCtx): ParaNode {\n const pPr = p?.[\"w:pPr\"]?.[0] ?? {};\n const alignVal =\n pPr?.[\"w:jc\"]?.[0]?._attr?.[\"w:val\"] ?? pPr?.[\"w:jc\"]?.[0]?._attr?.val;\n const headStyle =\n pPr?.[\"w:pStyle\"]?.[0]?._attr?.[\"w:val\"] ??\n pPr?.[\"w:pStyle\"]?.[0]?._attr?.val ??\n \"\";\n\n // Resolve paragraph style inheritance chain\n const styleInherited = resolveParaStyle(\n headStyle || undefined,\n ctx.paraStyleMap,\n );\n\n const props: ParaProps = {\n align: safeAlign(alignVal),\n heading: parseHeading(headStyle),\n styleId: headStyle || undefined,\n };\n\n // Spacing (before/after/line height) — inline pPr wins over style\n const spacingAttr =\n pPr?.[\"w:spacing\"]?.[0]?._attr ?? pPr?.spacing?.[0]?._attr ?? {};\n const beforeVal = Number(\n spacingAttr?.[\"w:before\"] ?? spacingAttr?.before ?? 0,\n );\n const afterVal = Number(spacingAttr?.[\"w:after\"] ?? spacingAttr?.after ?? 0);\n const lineVal = Number(spacingAttr?.[\"w:line\"] ?? spacingAttr?.line ?? 0);\n const lineRule =\n spacingAttr?.[\"w:lineRule\"] ?? spacingAttr?.lineRule ?? \"auto\";\n if (beforeVal> 0) props.spaceBefore = Metric.dxaToPt(beforeVal);\n else if (styleInherited.pPr?.spaceBefore)\n props.spaceBefore = styleInherited.pPr.spaceBefore;\n if (afterVal> 0) props.spaceAfter = Metric.dxaToPt(afterVal);\n else if (styleInherited.pPr?.spaceAfter)\n props.spaceAfter = styleInherited.pPr.spaceAfter;\n if (lineVal> 0 && lineRule === \"auto\") props.lineHeight = lineVal / 240;\n else if (styleInherited.pPr?.lineHeight)\n props.lineHeight = styleInherited.pPr.lineHeight;\n\n // Indentation\n const indAttr = pPr?.[\"w:ind\"]?.[0]?._attr ?? pPr?.ind?.[0]?._attr ?? {};\n const leftVal = Number(indAttr?.[\"w:left\"] ?? indAttr?.left ?? 0);\n const rightVal = Number(indAttr?.[\"w:right\"] ?? indAttr?.right ?? 0);\n const firstLineVal = Number(\n indAttr?.[\"w:firstLine\"] ?? indAttr?.firstLine ?? 0,\n );\n const hangingVal = Number(indAttr?.[\"w:hanging\"] ?? indAttr?.hanging ?? 0);\n if (leftVal> 0) props.indentPt = Metric.dxaToPt(leftVal);\n else if (styleInherited.pPr?.indentPt)\n props.indentPt = styleInherited.pPr.indentPt;\n if (rightVal> 0) props.indentRightPt = Metric.dxaToPt(rightVal);\n else if (styleInherited.pPr?.indentRightPt)\n props.indentRightPt = styleInherited.pPr.indentRightPt;\n if (firstLineVal> 0) props.firstLineIndentPt = Metric.dxaToPt(firstLineVal);\n else if (hangingVal> 0)\n props.firstLineIndentPt = -Metric.dxaToPt(hangingVal);\n else if (styleInherited.pPr?.firstLineIndentPt)\n props.firstLineIndentPt = styleInherited.pPr.firstLineIndentPt;\n\n // Alignment from style if not set inline\n if (!alignVal && styleInherited.pPr?.align)\n props.align = safeAlign(styleInherited.pPr.align);\n\n // List/numbering\n const numPr = pPr?.[\"w:numPr\"]?.[0] ?? pPr?.numPr?.[0];\n if (numPr) {\n const ilvlNode =\n numPr?.[\"w:ilvl\"]?.[0]?._attr ?? numPr?.ilvl?.[0]?._attr ?? {};\n const numIdNode =\n numPr?.[\"w:numId\"]?.[0]?._attr ?? numPr?.numId?.[0]?._attr ?? {};\n const ilvl = Number(ilvlNode?.[\"w:val\"] ?? ilvlNode?.val ?? 0);\n const numId = Number(numIdNode?.[\"w:val\"] ?? numIdNode?.val ?? 0);\n\n props.listLv = ilvl;\n const numEntry = ctx.numMap.get(numId);\n if (numEntry) {\n const lvlInfo = numEntry.levels.get(ilvl) ?? numEntry.levels.get(0);\n props.listOrd = lvlInfo?.isOrdered ?? false;\n } else {\n // Fallback: numId=1 is typically bullet, numId=2 is numbered\n props.listOrd = numId>= 2;\n }\n }\n\n // pageBreakBefore: paragraph always starts on a new page\n const pbBeforeNode =\n pPr?.[\"w:pageBreakBefore\"]?.[0] ?? pPr?.pageBreakBefore?.[0];\n const hasPageBreakBefore =\n pbBeforeNode != null &&\n (pbBeforeNode?._attr?.[\"w:val\"] ?? pbBeforeNode?._attr?.val ?? \"1\") !== \"0\";\n\n // Resolve all children (runs AND hyperlinks) in document order\n const children = p?.[\"_childOrder\"] as string[] | undefined;\n const kids: (SpanNode | ImgNode | LinkNode)[] = [];\n\n if (Array.isArray(children)) {\n const runsArr = toArr(p?.[\"w:r\"] ?? p?.r);\n const hlArr = toArr(p?.[\"w:hyperlink\"] ?? p?.hyperlink);\n const sdtArr = toArr(p?.[\"w:sdt\"] ?? p?.sdt);\n let ri = 0;\n let hi = 0;\n let si = 0;\n\n for (const tag of children) {\n if (tag === \"w:r\" || tag === \"r\") {\n const run = runsArr[ri++];\n if (run) {\n kids.push(\n ctx.shield.guard(\n () =>\n hasDrawingDeep(run)\n ? decodeRunOrImage(run, ctx)\n : decodeRun(run, ctx, styleInherited.rPr),\n buildSpan(\"\"),\n \"docx:run\",\n ),\n );\n }\n } else if (tag === \"w:hyperlink\" || tag === \"hyperlink\") {\n const hl = hlArr[hi++];\n if (hl) {\n const rId = hl?._attr?.[\"r:id\"] ?? hl?._attr?.id;\n const url = rId ? ctx.relsMap.get(rId) : \"\";\n const hlRuns = toArr(hl?.[\"w:r\"] ?? hl?.r);\n const hlKids = hlRuns.map((r: any) =>\n decodeRun(r, ctx, {\n ...styleInherited.rPr,\n u: true,\n color: \"0000FF\",\n }),\n );\n kids.push({\n tag: \"link\",\n href: url || \"\",\n kids: hlKids,\n });\n }\n } else if (tag === \"w:sdt\" || tag === \"sdt\") {\n const sdt = sdtArr[si++];\n if (sdt) {\n const sdtContent = sdt?.[\"w:sdtContent\"]?.[0] ?? sdt?.sdtContent?.[0];\n if (sdtContent) {\n const innerRuns = toArr(sdtContent?.[\"w:r\"] ?? sdtContent?.r);\n for (const ir of innerRuns) {\n kids.push(\n ctx.shield.guard(\n () =>\n hasDrawingDeep(ir)\n ? decodeRunOrImage(ir, ctx)\n : decodeRun(ir, ctx, styleInherited.rPr),\n buildSpan(\"\"),\n \"docx:run\",\n ),\n );\n }\n }\n }\n }\n }\n } else {\n // Fallback if _childOrder is missing\n const runs = toArr(p?.[\"w:r\"] ?? p?.r);\n const legacyKids: (SpanNode | ImgNode)[] = ctx.shield.guardAll(\n runs,\n (run: any) =>\n hasDrawingDeep(run)\n ? decodeRunOrImage(run, ctx)\n : decodeRun(run, ctx, styleInherited.rPr),\n () => buildSpan(\"\"),\n \"docx:run\",\n );\n kids.push(...legacyKids);\n }\n\n const filteredKids = kids.filter(Boolean) as ParaNode[\"kids\"];\n\n // Prepend pb span when pageBreakBefore is set\n if (hasPageBreakBefore) {\n filteredKids.unshift({ tag: \"span\", props: {}, kids: [buildPb()] });\n }\n\n return buildPara(filteredKids, props);\n}\n\n// 3/28 코드 수정\nfunction decodeRunOrImage(run: any, ctx: DecCtx): SpanNode | ImgNode {\n function findFirstDrawing(node: any): any | null {\n if (!node || typeof node !== \"object\") return null;\n\n if (node[\"w:drawing\"]) return node[\"w:drawing\"][0];\n if (node[\"w:pict\"]) return node[\"w:pict\"][0];\n\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n const found = findFirstDrawing(v);\n if (found) return found;\n }\n } else {\n const found = findFirstDrawing(value);\n if (found) return found;\n }\n }\n\n return null;\n }\n\n const drawing = findFirstDrawing(run);\n\n if (drawing) {\n const img = decodeDrawing(drawing, ctx);\n if (img) return img;\n }\n\n return decodeRun(run, ctx);\n}\n/** Decode image layout from anchor element */\nfunction decodeImageLayout(anchor: any): ImgLayout {\n const wrap = anchor?.[\"wp:wrapTop\"]?.[0] ?? anchor?.wrapTop?.[0];\n const anchorPos =\n anchor?.[\"wp:anchorPos\"]?.[0]?._attr ?? anchor?.anchorPos?.[0]?._attr ?? {};\n\n const layout: ImgLayout = {\n wrap: \"square\",\n horzAlign: \"left\",\n vertAlign: \"top\",\n horzRelTo: \"page\",\n vertRelTo: \"page\",\n xPt: Number(anchorPos?.x ?? 0) / 12700, // emu to pt\n yPt: Number(anchorPos?.y ?? 0) / 12700, // emu to pt\n };\n\n // Parse wrap type\n if (wrap?.[\"wp:none\"]) layout.wrap = \"none\";\n else if (wrap?.[\"wp:square\"]) layout.wrap = \"square\";\n else if (wrap?.[\"wp:tight\"]) layout.wrap = \"tight\";\n else if (wrap?.[\"wp:through\"]) layout.wrap = \"through\";\n else if (wrap?.[\"wp:behind\"]) layout.wrap = \"behind\";\n else if (wrap?.[\"wp:inFront\"]) layout.wrap = \"front\";\n\n return layout;\n}\n\nfunction decodeDrawing(drawing: any, ctx: DecCtx): ImgNode | null {\n try {\n const inline = drawing?.[\"wp:inline\"]?.[0] ?? drawing?.inline?.[0];\n const anchor = drawing?.[\"wp:anchor\"]?.[0] ?? drawing?.anchor?.[0];\n const container = inline ?? anchor;\n if (!container) return null;\n\n // Get dimensions\n const extent =\n container?.[\"wp:extent\"]?.[0]?._attr ??\n container?.extent?.[0]?._attr ??\n {};\n const cx = Number(extent?.cx ?? 0);\n const cy = Number(extent?.cy ?? 0);\n const wPt = Metric.emuToPt(cx);\n const hPt = Metric.emuToPt(cy);\n\n // Get alt text\n const docPr =\n container?.[\"wp:docPr\"]?.[0]?._attr ?? container?.docPr?.[0]?._attr ?? {};\n const alt = docPr?.descr ?? docPr?.name ?? \"\";\n\n // Navigate to blip\n const graphic = container?.[\"a:graphic\"]?.[0] ?? container?.graphic?.[0];\n const graphicData =\n graphic?.[\"a:graphicData\"]?.[0] ?? graphic?.graphicData?.[0];\n\n // 1. 차트 감지\n if (graphicData?.[\"c:chart\"] || graphicData?.chart) {\n return {\n tag: \"img\",\n b64: \"\", // 플레이스홀더\n mime: \"image/png\",\n w: wPt,\n h: hPt,\n alt: `[차트: ${alt || \"차트\"}]`,\n layout: decodeImageLayout(anchor),\n };\n }\n\n const pic = graphicData?.[\"pic:pic\"]?.[0] ?? graphicData?.pic?.[0];\n const blipFill = pic?.[\"pic:blipFill\"]?.[0] ?? pic?.blipFill?.[0];\n const blip =\n blipFill?.[\"a:blip\"]?.[0]?._attr ?? blipFill?.blip?.[0]?._attr ?? {};\n const rId = blip?.[\"r:embed\"] ?? blip?.embed;\n\n if (!rId) return null;\n\n const target = ctx.relsMap.get(rId);\n if (!target) return null;\n\n let filePath = resolveDocxPath(\"word\", target);\n let fileData = ctx.files.get(filePath);\n\n if (!fileData) {\n filePath = resolveDocxPath(\"word/_rels\", target);\n fileData = ctx.files.get(filePath);\n }\n\n if (!fileData) {\n const fileName = target.split(\"/\").pop() ?? \"\";\n for (const [k, v] of ctx.files) {\n if (fileName && (k.endsWith(\"/\" + fileName) || k === fileName)) {\n fileData = v;\n filePath = k;\n break;\n }\n }\n }\n\n if (!fileData) {\n console.warn(`[DocxDecoder] image not found: \"${target}\"`);\n return null;\n }\n\n const ext = target.split(\".\").pop()?.toLowerCase() ?? \"png\";\n const mimeMap: Record = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n const mime = mimeMap[ext] ?? \"image/png\";\n console.log(\n `[DocxDecoder] image loaded: ${filePath} (${mime}, ${fileData.length} bytes)`,\n );\n\n // ── layout 추출 ──────────────────────────────────────────\n const layout: ImgLayout = inline\n ? { wrap: \"inline\" }\n : extractAnchorLayout(anchor);\n\n return buildImg(\n TextKit.base64Encode(fileData),\n mime,\n wPt,\n hPt,\n alt || undefined,\n layout,\n );\n } catch {\n return null;\n }\n}\n\n/** w:highlight val → hex 색상 매핑 (OOXML 명세) */\nconst HIGHLIGHT_COLOR_MAP: Record = {\n yellow: \"FFFF00\",\n green: \"00FF00\",\n cyan: \"00FFFF\",\n magenta: \"FF00FF\",\n blue: \"0000FF\",\n red: \"FF0000\",\n darkBlue: \"00008B\",\n darkCyan: \"008B8B\",\n darkGreen: \"006400\",\n darkMagenta: \"8B008B\",\n darkRed: \"8B0000\",\n darkYellow: \"808000\",\n darkGray: \"A9A9A9\",\n lightGray: \"D3D3D3\",\n black: \"000000\",\n white: \"FFFFFF\",\n};\n\nfunction decodeRun(\n run: any,\n ctx: DecCtx,\n styleRpr?: ParaStyleDef[\"rPr\"],\n): SpanNode {\n const rPr = run?.[\"w:rPr\"]?.[0] ?? run?.rPr?.[0] ?? {};\n\n // w:vanish — 숨긴 텍스트: run 전체 건너뜀 (빈 span 반환)\n const vanishNode = rPr?.[\"w:vanish\"]?.[0] ?? rPr?.vanish?.[0];\n if (vanishNode != null) {\n const vanishVal =\n vanishNode?._attr?.[\"w:val\"] ?? vanishNode?._attr?.val ?? \"1\";\n if (vanishVal !== \"0\") return buildSpan(\"\");\n }\n\n // w:sz → 없으면 w:szCs 로 fallback (한글 글꼴 크기)\n const szAttr = rPr?.[\"w:sz\"]?.[0]?._attr ?? rPr?.sz?.[0]?._attr ?? {};\n const szVal = szAttr?.[\"w:val\"] ?? szAttr?.val;\n const szCsAttr = rPr?.[\"w:szCs\"]?.[0]?._attr ?? rPr?.szCs?.[0]?._attr ?? {};\n const szCsVal = szCsAttr?.[\"w:val\"] ?? szCsAttr?.val;\n const effectiveSzVal = szVal ?? szCsVal;\n\n const colorAttr =\n rPr?.[\"w:color\"]?.[0]?._attr ?? rPr?.color?.[0]?._attr ?? {};\n const colorVal = colorAttr?.[\"w:val\"] ?? colorAttr?.val;\n\n const fontAttr =\n rPr?.[\"w:rFonts\"]?.[0]?._attr ?? rPr?.rFonts?.[0]?._attr ?? {};\n const fontName =\n fontAttr?.[\"w:ascii\"] ??\n fontAttr?.ascii ??\n fontAttr?.[\"w:hAnsi\"] ??\n fontAttr?.hAnsi ??\n fontAttr?.[\"w:eastAsia\"] ??\n fontAttr?.eastAsia;\n\n const underVal =\n rPr?.[\"w:u\"]?.[0]?._attr?.[\"w:val\"] ?? rPr?.[\"w:u\"]?.[0]?._attr?.val;\n\n // w:shd — 배경색 (낮은 우선순위)\n const shdAttr = rPr?.[\"w:shd\"]?.[0]?._attr ?? rPr?.shd?.[0]?._attr ?? {};\n const shdBg = safeHex(shdAttr?.[\"w:fill\"] ?? shdAttr?.fill);\n\n // w:highlight — 형광펜 색상 (w:shd보다 우선)\n const hlAttr =\n rPr?.[\"w:highlight\"]?.[0]?._attr ?? rPr?.highlight?.[0]?._attr ?? {};\n const hlVal = hlAttr?.[\"w:val\"] ?? hlAttr?.val;\n const bgVal = (hlVal ? HIGHLIGHT_COLOR_MAP[hlVal] : undefined) ?? shdBg;\n\n // w:vertAlign — superscript / subscript\n const vertAlignVal =\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.[\"w:val\"] ??\n rPr?.[\"w:vertAlign\"]?.[0]?._attr?.val;\n\n // w:position — 글자 상하 이동 (half-point, 양수=위, 음수=아래)\n // vertAlign이 없을 때 보조 판단: ±4 half-pt(≈2pt) 이상이면 sup/sub\n const posAttr =\n rPr?.[\"w:position\"]?.[0]?._attr ?? rPr?.position?.[0]?._attr ?? {};\n const posVal = Number(posAttr?.[\"w:val\"] ?? posAttr?.val ?? 0);\n let isSup = vertAlignVal === \"superscript\";\n let isSub = vertAlignVal === \"subscript\";\n if (!isSup && !isSub && posVal !== 0) {\n if (posVal>= 4) isSup = true;\n else if (posVal <= -4) isSub = true;\n }\n\n // Check bold/italic/strike — val=\"0\" means explicitly OFF\n const bNode = rPr?.[\"w:b\"]?.[0] ?? rPr?.b?.[0];\n const isBold =\n bNode != null &&\n (bNode?._attr?.[\"w:val\"] ?? bNode?._attr?.val ?? \"1\") !== \"0\";\n const iNode = rPr?.[\"w:i\"]?.[0] ?? rPr?.i?.[0];\n const isItalic =\n iNode != null &&\n (iNode?._attr?.[\"w:val\"] ?? iNode?._attr?.val ?? \"1\") !== \"0\";\n const sNode = rPr?.[\"w:strike\"]?.[0] ?? rPr?.strike?.[0];\n const isStrike =\n sNode != null &&\n (sNode?._attr?.[\"w:val\"] ?? sNode?._attr?.val ?? \"1\") !== \"0\";\n\n // Run-level properties: run wins, then fall back to paragraph style inheritance\n const props: TextProps = {\n b: (bNode != null ? isBold : styleRpr?.b) || undefined,\n i: (iNode != null ? isItalic : styleRpr?.i) || undefined,\n u: (underVal ? underVal !== \"none\" : styleRpr?.u) || undefined,\n s: (sNode != null ? isStrike : styleRpr?.s) || undefined,\n sup: isSup || undefined,\n sub: isSub || undefined,\n pt: effectiveSzVal\n ? Metric.halfPtToPt(Number(effectiveSzVal))\n : styleRpr?.pt,\n color: safeHex(colorVal) ?? styleRpr?.color,\n font: fontName ? safeFont(fontName) : styleRpr?.font,\n bg: bgVal,\n };\n\n // Check for field codes (PAGE number)\n const fldChar = run?.[\"w:fldChar\"]?.[0]?._attr ?? run?.fldChar?.[0]?._attr;\n const instrText = run?.[\"w:instrText\"]?.[0];\n\n // Page break: \n const brNodes = toArr(run?.[\"w:br\"] ?? run?.br ?? []);\n for (const br of brNodes) {\n const brType = br?._attr?.[\"w:type\"] ?? br?._attr?.type;\n if (brType === \"page\") {\n return { tag: \"span\", props, kids: [buildPb()] };\n }\n }\n\n const textNodes = toArr(run?.[\"w:t\"] ?? run?.t);\n const content = textNodes\n .map((t: any) => (typeof t === \"string\" ? t : (t?._ ?? t?._text ?? \"\")))\n .join(\"\");\n\n // Handle page number field in instrText\n if (instrText) {\n const instrStr =\n typeof instrText === \"string\" ? instrText : (instrText?._text ?? \"\");\n if (instrStr.trim().toUpperCase() === \"PAGE\") {\n const pageNum: PageNumNode = { tag: \"pagenum\", format: \"decimal\" };\n return { tag: \"span\", props, kids: [pageNum] };\n }\n }\n\n return buildSpan(content, props);\n}\n\n/** Parse all 6 border sides from a w:tblBorders or w:tcBorders node */\nfunction parseBorderDef(bdrNode: any): TblBorderDef {\n const sides: [string, keyof TblBorderDef][] = [\n [\"top\", \"top\"],\n [\"bottom\", \"bottom\"],\n [\"left\", \"left\"],\n [\"right\", \"right\"],\n [\"insideH\", \"insideH\"],\n [\"insideV\", \"insideV\"],\n ];\n const result: TblBorderDef = {};\n for (const [xml, prop] of sides) {\n const bdr = bdrNode?.[\"w:\" + xml]?.[0]?._attr ?? bdrNode?.[xml]?.[0]?._attr;\n if (!bdr) continue;\n const val = bdr?.[\"w:val\"] ?? bdr?.val;\n if (val === \"none\" || val === \"nil\") continue; // explicit none → skip (no border)\n result[prop] = safeStrokeDocx(\n val,\n Number(bdr?.[\"w:sz\"] ?? bdr?.sz ?? 4),\n bdr?.[\"w:color\"] ?? bdr?.color,\n );\n }\n return result;\n}\n\n/** Parse styles.xml and build a map of tblStyle defaults */\nasync function parseStylesMap(xml: string): Promise\\n\\n\\n
                  \\n${bodyParts.join('\\n')}\\n
                  \\n\\n`;\n\n return succeed(this.stringToBytes(html), warns);\n } catch (e: any) {\n return fail(`HTML encode error: ${e?.message ?? String(e)}`);\n }\n }\n}\n\nconst BASE_CSS = `\nbody { margin: 0; padding: 0; background: #f0f0f0; }\n.hwp-doc { max-width: 800px; margin: 0 auto; background: #fff; padding: 40px 60px; box-shadow: 0 0 8px rgba(0,0,0,0.15); }\n.hwp-header, .hwp-footer { color: #666; font-size: 0.9em; border-bottom: 1px solid #ddd; margin-bottom: 8px; padding-bottom: 4px; }\n.hwp-footer { border-top: 1px solid #ddd; border-bottom: none; margin-top: 8px; padding-top: 4px; }\np { margin: 0; padding: 0; line-height: 1; }\ntable { border-collapse: collapse; width: 100%; margin: 8px 0; }\ntd, th { border: 1px solid #ccc; padding: 4px 8px; vertical-align: top; }\nimg { max-width: 100%; height: auto; }\n`.trim();\n\nfunction encodeContent(node: ContentNode, warns: string[]): string {\n return node.tag === 'grid' ? encodeGrid(node, warns) : encodePara(node, warns);\n}\n\nfunction encodePara(para: ParaNode, warns: string[]): string {\n const kids = para.kids.map((k): string => {\n if (k.tag === 'span') return encodeSpan(k, warns);\n if (k.tag === 'img') return encodeImage(k);\n if (k.tag === 'link') {\n const link = k as LinkNode;\n const inner = link.kids.map(s => encodeSpan(s, warns)).join('');\n return `${inner}`;\n }\n return '';\n }).join('');\n\n // Heading\n if (para.props.heading) {\n const tag = `h${para.props.heading}`;\n return `<${tag}>${kids}\\n`;\n }\n\n // List\n if (para.props.listOrd !== undefined) {\n const indent = (para.props.listLv ?? 0) * 20;\n const style = indent> 0 ? ` style=\"margin-left:${indent}px\"` : '';\n const marker = para.props.listOrd ? `1. ` : ``;\n return `${marker}${kids}

                  \\n`;\n }\n\n // Alignment\n const align = para.props.align;\n const styleAttrs: string[] = [];\n if (align && align !== 'left') styleAttrs.push(`text-align:${align}`);\n if (para.props.indentPt) styleAttrs.push(`margin-left:${para.props.indentPt.toFixed(1)}pt`);\n if (para.props.spaceBefore) styleAttrs.push(`margin-top:${para.props.spaceBefore.toFixed(1)}pt`);\n if (para.props.spaceAfter) styleAttrs.push(`margin-bottom:${para.props.spaceAfter.toFixed(1)}pt`);\n if (para.props.lineHeight) styleAttrs.push(`line-height:${para.props.lineHeight}`);\n\n const styleAttr = styleAttrs.length> 0 ? ` style=\"${styleAttrs.join(';')}\"` : '';\n return `${kids || ' '}

                  \\n`;\n}\n\nfunction encodeSpan(span: SpanNode, warns: string[]): string {\n const parts: string[] = [];\n let hasPageNum = false;\n\n for (const kid of span.kids) {\n if (kid.tag === 'txt') {\n // __EXT_N__ 또는 __EXT_N_W_H__ 자리표시자 제거\n const content = kid.content.replace(/__EXT_\\d+(?:_W\\d+_H\\d+)?__/g, '');\n if (content) parts.push(TextKit.escapeXml(content));\n } else if (kid.tag === 'br') {\n parts.push('
                  ');\n } else if (kid.tag === 'pb') {\n parts.push('');\n } else if (kid.tag === 'pagenum') {\n hasPageNum = true;\n warns.push('[SHIELD] HTML: 페이지 번호 — 정적 값으로 대체됨');\n parts.push('[페이지]');\n }\n }\n\n let text = parts.join('');\n if (hasPageNum && text.trim() === '[페이지]') {\n // keep as-is\n }\n\n const p = span.props;\n const css: string[] = [];\n if (p.font) css.push(`font-family:${TextKit.escapeXml(p.font)}`);\n if (p.pt) css.push(`font-size:${p.pt}pt`);\n if (p.color) css.push(`color:#${p.color}`);\n if (p.bg) css.push(`background-color:#${p.bg}`);\n if (p.b) css.push('font-weight:bold');\n if (p.i) css.push('font-style:italic');\n\n const decorations: string[] = [];\n if (p.u) decorations.push('underline');\n if (p.s) decorations.push('line-through');\n if (decorations.length> 0) css.push(`text-decoration:${decorations.join(' ')}`);\n\n if (p.sup) return `${text}`;\n if (p.sub) return `${text}`;\n if (css.length> 0) return `${text}`;\n return text;\n}\n\nfunction encodeImage(img: ImgNode): string {\n const wStyle = img.w ? ` width=\"${Math.round(img.w / 72 * 96)}px\"` : '';\n const hStyle = img.h ? ` height=\"${Math.round(img.h / 72 * 96)}px\"` : '';\n const alt = TextKit.escapeXml(img.alt ?? '');\n return `\`;\n}\n\nfunction encodeGrid(grid: GridNode, warns: string[]): string {\n if (grid.kids.length === 0) return '';\n\n // Build occupancy map for rowspan\n const rowCount = grid.kids.length;\n const occupancy: Set[] = Array.from({ length: rowCount }, () => new Set());\n let colCount = 0;\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let ci = 0;\n for (const cell of row.kids) {\n while (occupancy[ri].has(ci)) ci++;\n if (cell.rs> 1) {\n for (let r = ri + 1; r < ri + cell.rs && r < rowCount; r++) {\n for (let c = ci; c < ci + cell.cs; c++) occupancy[r].add(c);\n }\n }\n ci += cell.cs;\n }\n while (occupancy[ri].has(ci)) ci++;\n if (ci> colCount) colCount = ci;\n }\n\n let rows = '';\n for (let ri = 0; ri < rowCount; ri++) {\n const row = grid.kids[ri];\n let cells = '';\n let ci = 0;\n for (const cell of row.kids) {\n while (occupancy[ri].has(ci)) ci++;\n\n const isHeader = cell.props.isHeader || (grid.props.headerRow && ri === 0);\n const tag = isHeader ? 'th' : 'td';\n\n const cs = cell.cs> 1 ? ` colspan=\"${cell.cs}\"` : '';\n const rs = cell.rs> 1 ? ` rowspan=\"${cell.rs}\"` : '';\n\n const styleAttrs: string[] = [];\n if (cell.props.bg) styleAttrs.push(`background-color:#${cell.props.bg}`);\n const va = cell.props.va;\n if (va === 'mid') styleAttrs.push('vertical-align:middle');\n else if (va === 'bot') styleAttrs.push('vertical-align:bottom');\n const styleAttr = styleAttrs.length> 0 ? ` style=\"${styleAttrs.join(';')}\"` : '';\n\n const content = cell.kids.map(p => p.tag === 'para' ? encodePara(p, warns) : encodeGrid(p, warns)).join('');\n cells += `<${tag}${cs}${rs}${styleattr}>${content}`;\n ci += cell.cs;\n }\n rows += `
                  ${cells}
                  \\n`;\n }\n\n return `\\n\\n${rows}\\n\\n`;\n}\n\nregistry.registerEncoder(new HtmlEncoder());\n","/**\n * HwpEncoder — DocRoot → HWP 5.0 바이너리 (OLE2/CFB 컨테이너)\n *\n * ANYTOHWP에서 영감받은 개선 사항:\n * 1. HwpStyleBank — 7개 언어 그룹 독립 폰트 레지스트리 (HANGUL/LATIN/HANJA/...)\n * 2. readPixelDims — PNG/JPEG 바이너리 헤더에서 픽셀 치수 추출 → 정확한 HWPUNIT 변환\n * 3. mkIdMappings — 언어별 폰트 카운트를 개별 기록\n * 4. mkCharShape — 언어별 faceId[7] 사용\n *\n * OLE2 레이아웃:\n * FileHeader (stream) — 256-byte HWP 시그니처 + 플래그\n * DocInfo (stream) — zlib 압축된 FACE_NAME / CHAR_SHAPE / PARA_SHAPE 레코드\n * BodyText (storage)\n * Section0 (stream) — zlib 압축된 PAGE_DEF + 문단/표 레코드\n */\n\nimport type {\n DocRoot,\n ContentNode,\n ParaNode,\n SpanNode,\n GridNode,\n ImgNode,\n LinkNode,\n} from \"../../model/doc-tree\";\nimport type { Outcome } from \"../../contract/result\";\nimport type {\n TextProps,\n ParaProps,\n Stroke,\n PageDims,\n Align,\n} from \"../../model/doc-props\";\nimport { succeed, fail } from \"../../contract/result\";\nimport { Metric, safeFontToKr } from \"../../safety/StyleBridge\";\nimport { registry } from \"../../pipeline/registry\";\nimport { A4 } from \"../../model/doc-props\";\nimport pako from \"pako\";\nimport { TextKit } from \"../../toolkit/TextKit\";\nimport { BaseEncoder } from \"../../core/BaseEncoder\";\n\n// ─── HWP 5.0 태그 ID ────────────────────────────────────────\nconst T = 16; // HWPTAG_BEGIN\n\n// DocInfo 태그\nconst TAG_DOCUMENT_PROPERTIES = T + 0; // 16\nconst TAG_ID_MAPPINGS = T + 1; // 17\nconst TAG_BIN_DATA = T + 2; // 18\nconst TAG_FACE_NAME = T + 3; // 19\nconst TAG_BORDER_FILL = T + 4; // 20\nconst TAG_CHAR_SHAPE = T + 5; // 21\nconst TAG_PARA_SHAPE = T + 9; // 25\nconst TAG_STYLE = T + 10; // 26\n\n// BodyText 태그\nconst TAG_PARA_HEADER = T + 50; // 66\nconst TAG_PARA_TEXT = T + 51; // 67\nconst TAG_PARA_CHAR_SHAPE = T + 52; // 68\nconst TAG_PARA_LINE_SEG = T + 53; // 69\nconst TAG_CTRL_HEADER = T + 55; // 71\nconst TAG_LIST_HEADER = T + 56; // 72\nconst TAG_PAGE_DEF = T + 57; // 73\nconst TAG_FOOTNOTE_SHAPE = T + 58; // 74\nconst TAG_TABLE = T + 61; // 77\nconst TAG_SHAPE_COMPONENT_PICTURE = T + 69; // 85\n\n// Control ID (LE UINT32)\nconst CTRL_TABLE = 0x74626c20; // 'tbl '\nconst CTRL_SECD = 0x73656364; // 'secd'\nconst CTRL_PIC = 0x24706963; // '$pic'\nconst CTRL_FIELD_BEGIN = 0x646c6625; // '%fld'\nconst CTRL_FIELD_END = 0x646c665c; // '\\fld'\n\n/** 테두리선 굵기 인덱스 테이블 (pt) */\nconst BORDER_W_PT = [\n 0.28, 0.34, 0.43, 0.57, 0.71, 0.85, 1.13, 1.42, 1.7, 1.98, 2.84, 4.25, 5.67,\n 8.5, 11.34, 14.17,\n];\n\nconst BORDER_KIND_IDX: Record = {\n solid: 0,\n dot: 1,\n dash: 2,\n double: 7,\n triple: 8,\n none: 0,\n};\n\nconst ALIGN_CODE: Record = {\n justify: 0,\n left: 1,\n right: 2,\n center: 3,\n distribute: 4,\n};\n\n// ─── 바이너리 버퍼 라이터 ────────────────────────────────────\n\nclass BufWriter {\n private chunks: Uint8Array[] = [];\n private _sz = 0;\n get size() {\n return this._sz;\n }\n\n u8(v: number): this {\n this.chunks.push(new Uint8Array([v & 0xff]));\n this._sz++;\n return this;\n }\n u16(v: number): this {\n this.chunks.push(new Uint8Array([v & 0xff, (v>> 8) & 0xff]));\n this._sz += 2;\n return this;\n }\n u32(v: number): this {\n const b = new Uint8Array(4);\n b[0] = v & 0xff;\n b[1] = (v>>> 8) & 0xff;\n b[2] = (v>>> 16) & 0xff;\n b[3] = (v>>> 24) & 0xff;\n this.chunks.push(b);\n this._sz += 4;\n return this;\n }\n i32(v: number): this {\n return this.u32(v < 0 ? v + 0x100000000 : v);\n }\n i16(v: number): this {\n return this.u16(v < 0 ? v + 0x10000 : v);\n }\n bytes(d: Uint8Array): this {\n this.chunks.push(d);\n this._sz += d.length;\n return this;\n }\n zeros(n: number): this {\n this.chunks.push(new Uint8Array(n));\n this._sz += n;\n return this;\n }\n utf16(s: string): this {\n for (let i = 0; i < s.length; i++) this.u16(s.charCodeAt(i));\n return this;\n }\n colorRef(hex: string): this {\n const h = (hex || \"000000\").replace(\"#\", \"\").padStart(6, \"0\");\n return this.u8(parseInt(h.slice(0, 2), 16))\n .u8(parseInt(h.slice(2, 4), 16))\n .u8(parseInt(h.slice(4, 6), 16))\n .u8(0);\n }\n build(): Uint8Array {\n const out = new Uint8Array(this._sz);\n let off = 0;\n for (const c of this.chunks) {\n out.set(c, off);\n off += c.length;\n }\n return out;\n }\n}\n\n// ─── HWP 레코드 빌더 ─────────────────────────────────────────\n\nfunction mkRec(tag: number, level: number, data: Uint8Array): Uint8Array {\n const sz = data.length;\n const enc = Math.min(sz, 0xfff);\n const hdr = (enc << 20) | ((level & 0x3ff) << 10) | (tag & 0x3ff);\n const w = new BufWriter().u32(hdr);\n if (enc>= 0xfff) w.u32(sz);\n w.bytes(data);\n return w.build();\n}\n\n// ─── ANYTOHWP 영감: PNG/JPEG 바이너리 헤더에서 픽셀 치수 추출\nfunction readPixelDims(\n data: Uint8Array,\n mime: string,\n): { w: number; h: number } | null {\n try {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n if (mime.includes(\"png\")) {\n if (\n data.length>= 24 &&\n view.getUint32(0) === 0x89504e47 &&\n view.getUint32(4) === 0x0d0a1a0a\n ) {\n return { w: view.getUint32(16), h: view.getUint32(20) };\n }\n } else if (mime.includes(\"jpeg\") || mime.includes(\"jpg\")) {\n let off = 2;\n while (off < data.length - 4) {\n const marker = view.getUint16(off);\n off += 2;\n if (marker === 0xffc0 || marker === 0xffc2) {\n return { w: view.getUint16(off + 5), h: view.getUint16(off + 3) };\n }\n if ((marker & 0xff00) !== 0xff00) break;\n off += view.getUint16(off);\n }\n }\n } catch {\n /* 무시 */\n }\n return null;\n}\n\n// ─── ANYTOHWP 영감: HwpStyleBank — 7개 언어 그룹 독립 폰트 레지스트리\n// StyleCollector를 대체하는 새로운 스타일 수집기\n\nconst LANG_GROUPS = [\n \"HANGUL\",\n \"LATIN\",\n \"HANJA\",\n \"JAPANESE\",\n \"OTHER\",\n \"SYMBOL\",\n \"USER\",\n] as const;\ntype LangGroup = (typeof LANG_GROUPS)[number];\n\n/** 한글 폰트 여부 판별 */\nfunction isKoreanFont(face: string): boolean {\n return (\n /[\\uAC00-\\uD7A3\\u3131-\\u318E]/.test(face) ||\n [\"맑은\", \"나눔\", \"굴림\", \"돋움\", \"바탕\", \"함초롬\", \"한컴\", \"HY\"].some((k) =>\n face.includes(k),\n )\n );\n}\n\nclass HwpStyleBank {\n readonly DEF_STROKE: Stroke = { kind: \"solid\", pt: 0.5, color: \"000000\" };\n\n // 언어별 독립 폰트 목록 (ANYTOHWP langFontFaces)\n private langFonts = new Map(\n LANG_GROUPS.map((g) => [g, []]),\n );\n private langFontIdx = new Map>(\n LANG_GROUPS.map((g) => [g, new Map()]),\n );\n\n // charShape, parShape, borderFill 레지스트리\n readonly csProps: TextProps[] = [{}];\n private csIdx = new Map([[csKey({}), 0]]);\n\n readonly psProps: ParaProps[] = [{}];\n private psIdx = new Map([[psKey({}), 0]]);\n\n readonly bfData: BfEntry[] = [];\n private bfIdx = new Map();\n\n // charShape마다 언어별 fontId를 기록\n readonly csFontIds: number[][] = [[0, 0, 0, 0, 0, 0, 0]]; // id=0 → 모두 0\n\n constructor() {\n // 기본 폰트 등록 (ANYTOHWP: 함초롬바탕)\n for (const g of LANG_GROUPS) this._registerLangFont(g, \"함초롬바탕\");\n this.addBorderFill(this.DEF_STROKE); // bfId=1\n }\n\n private _registerLangFont(lang: LangGroup, face: string): number {\n const idx = this.langFontIdx.get(lang)!;\n if (idx.has(face)) return idx.get(face)!;\n const id = this.langFonts.get(lang)!.length;\n this.langFonts.get(lang)!.push(face);\n idx.set(face, id);\n return id;\n }\n\n /** 폰트 이름 → 언어별 7개 ID 반환 (ANYTOHWP 방식) */\n registerFontForLangs(rawFace: string): number[] {\n const face = safeFontToKr(rawFace) || \"함초롬바탕\";\n const isKor = isKoreanFont(face);\n const hangulFace = isKor ? face : \"함초롬바탕\";\n const latinFace = isKor ? \"함초롬바탕\" : face;\n\n const ids: number[] = [];\n for (const lang of LANG_GROUPS) {\n const f = lang === \"LATIN\" ? latinFace : hangulFace;\n ids.push(this._registerLangFont(lang, f));\n }\n return ids; // [hangulId, latinId, hanjaId, japaneseId, otherId, symbolId, userId]\n }\n\n /** 언어별 폰트 목록 반환 */\n getFontsForLang(lang: LangGroup): string[] {\n return [...(this.langFonts.get(lang) ?? [])];\n }\n\n /** 폰트 수 반환 (mkIdMappings용) */\n getFontCount(lang: LangGroup): number {\n return this.langFonts.get(lang)?.length ?? 0;\n }\n\n addCharShape(p: TextProps): number {\n const k = csKey(p);\n if (this.csIdx.has(k)) return this.csIdx.get(k)!;\n const id = this.csProps.length;\n const fIds = p.font\n ? this.registerFontForLangs(p.font)\n : [0, 0, 0, 0, 0, 0, 0];\n this.csProps.push(p);\n this.csFontIds.push(fIds);\n this.csIdx.set(k, id);\n return id;\n }\n\n addParaShape(p: ParaProps): number {\n const k = psKey(p);\n if (this.psIdx.has(k)) return this.psIdx.get(k)!;\n const id = this.psProps.length;\n this.psProps.push(p);\n this.psIdx.set(k, id);\n return id;\n }\n\n addBorderFill(s: Stroke, bg?: string): number {\n const k = bfKey(s, bg);\n if (this.bfIdx.has(k)) return this.bfIdx.get(k)!;\n const id = this.bfData.length + 1;\n this.bfData.push({ uniform: true, s, bg });\n this.bfIdx.set(k, id);\n return id;\n }\n\n addBorderFillPerSide(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n ): number {\n const k = bfPerSideKey(l, r, t, b, bg);\n if (this.bfIdx.has(k)) return this.bfIdx.get(k)!;\n const id = this.bfData.length + 1;\n this.bfData.push({ uniform: false, l, r, t, b, bg });\n this.bfIdx.set(k, id);\n return id;\n }\n}\n\n// ─── 키 함수 ────────────────────────────────────────────────\n\nfunction csKey(p: TextProps): string {\n return [\n p.font ?? \"\",\n p.pt ?? 10,\n p.b ? 1 : 0,\n p.i ? 1 : 0,\n p.u ? 1 : 0,\n p.s ? 1 : 0,\n p.sup ? 1 : 0,\n p.sub ? 1 : 0,\n p.color ?? \"000000\",\n ].join(\"|\");\n}\n\nfunction psKey(p: ParaProps): string {\n return [\n p.align ?? \"left\",\n p.indentPt ?? 0,\n p.firstLineIndentPt ?? 0,\n p.spaceBefore ?? 0,\n p.spaceAfter ?? 0,\n p.lineHeight ?? 1,\n ].join(\"|\");\n}\n\nfunction bfKey(s: Stroke, bg?: string): string {\n return `${s.kind}|${s.pt}|${s.color}|${bg ?? \"\"}`;\n}\n\nfunction bfPerSideKey(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n): string {\n return `${bfKey(l)}/${bfKey(r)}/${bfKey(t)}/${bfKey(b)}/${bg ?? \"\"}`;\n}\n\ntype BfEntry =\n | { uniform: true; s: Stroke; bg?: string }\n | { uniform: false; l: Stroke; r: Stroke; t: Stroke; b: Stroke; bg?: string };\n\n// ─── Pre-scan: 스타일 수집 ──────────────────────────────────\n\nfunction collectNode(node: ContentNode, bank: HwpStyleBank): void {\n if (node.tag === \"para\") {\n bank.addParaShape(node.props);\n for (const kid of node.kids) {\n if (kid.tag === \"span\") bank.addCharShape((kid as SpanNode).props);\n }\n } else if (node.tag === \"grid\") {\n if (node.props.defaultStroke) bank.addBorderFill(node.props.defaultStroke);\n for (const row of node.kids) {\n for (const cell of row.kids) {\n const defStroke = node.props.defaultStroke ?? bank.DEF_STROKE;\n const cp = cell.props;\n if (cp.top || cp.bot || cp.left || cp.right) {\n bank.addBorderFillPerSide(\n cp.left ?? defStroke,\n cp.right ?? defStroke,\n cp.top ?? defStroke,\n cp.bot ?? defStroke,\n cp.bg,\n );\n } else {\n bank.addBorderFill(defStroke, cp.bg);\n }\n for (const para of cell.kids) collectNode(para, bank);\n }\n }\n }\n}\n\n// ─── DocInfo 레코드 빌더 ─────────────────────────────────────\n\nfunction mkDocumentProperties(): Uint8Array {\n return new BufWriter()\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1)\n .u16(1) // ×ばつ UINT16 카운터\n .u32(0)\n .u32(0)\n .u32(0) // 캐럿 위치\n .build(); // 26 bytes\n}\n\n/**\n * HWPTAG_ID_MAPPINGS (72 bytes = 18 ×ばつ INT32)\n * [0]=binData, [1-7]=7개 언어별 글꼴 수 (ANYTOHWP 방식으로 언어별 독립),\n * [8]=테두리/배경, [9]=글자모양, [10]=탭, [11]=번호, [12]=글머리,\n * [13]=문단모양, [14]=스타일, [15-17]=메모/변경추적\n */\nfunction mkIdMappings(bank: HwpStyleBank, nBinData = 0): Uint8Array {\n const w = new BufWriter();\n w.u32(nBinData);\n // [1-7]: 언어별 폰트 수 (ANYTOHWP: langFontFaces별 크기)\n for (const lang of LANG_GROUPS) w.u32(bank.getFontCount(lang));\n w.u32(bank.bfData.length); // [8]\n w.u32(bank.csProps.length); // [9]\n w.u32(0); // [10] tabDef\n w.u32(0); // [11] numbering\n w.u32(0); // [12] bullet\n w.u32(bank.psProps.length); // [13]\n w.u32(1); // [14] style (바탕글 1개)\n w.u32(0); // [15]\n w.u32(0); // [16]\n w.u32(0); // [17]\n return w.build(); // 18 ×ばつ 4 = 72 bytes\n}\n\nfunction mkStyle(\n name: string,\n engName: string,\n paraPrId: number,\n charPrId: number,\n): Uint8Array {\n return new BufWriter()\n .u16(name.length)\n .utf16(name)\n .u16(engName.length)\n .utf16(engName)\n .u16(paraPrId)\n .u16(charPrId)\n .u16(0)\n .u16(1042)\n .u16(0)\n .build();\n}\n\nfunction mkFaceName(name: string): Uint8Array {\n return new BufWriter()\n .u8(0)\n .u16(name.length)\n .utf16(name)\n .u8(0)\n .u16(0)\n .zeros(10)\n .u16(0)\n .build();\n}\n\nfunction borderWidthIdx(pt: number): number {\n let best = 0;\n for (let i = 0; i < BORDER_W_PT.length; i++) {\n if (Math.abs(BORDER_W_PT[i] - pt) < Math.abs(BORDER_W_PT[best] - pt))\n best = i;\n }\n return best;\n}\n\nfunction mkBorderFill(s: Stroke, bg?: string): Uint8Array {\n const w = new BufWriter();\n const t = BORDER_KIND_IDX[s.kind] ?? 0;\n const wi = borderWidthIdx(s.pt);\n const col = s.color || \"000000\";\n w.u16(0);\n for (let i = 0; i < 4; i++) w.u8(t);\n for (let i = 0; i < 4; i++) w.u8(wi);\n for (let i = 0; i < 4; i++) w.colorRef(col);\n w.u8(0).u8(0).colorRef(\"000000\");\n if (bg) {\n w.u32(1).colorRef(bg).colorRef(\"FFFFFF\").u32(0);\n } else {\n w.u32(0);\n }\n return w.build();\n}\n\nfunction mkBorderFillPerSide(\n l: Stroke,\n r: Stroke,\n t: Stroke,\n b: Stroke,\n bg?: string,\n): Uint8Array {\n const w = new BufWriter();\n w.u16(0);\n w.u8(BORDER_KIND_IDX[l.kind] ?? 0)\n .u8(BORDER_KIND_IDX[r.kind] ?? 0)\n .u8(BORDER_KIND_IDX[t.kind] ?? 0)\n .u8(BORDER_KIND_IDX[b.kind] ?? 0);\n w.u8(borderWidthIdx(l.pt))\n .u8(borderWidthIdx(r.pt))\n .u8(borderWidthIdx(t.pt))\n .u8(borderWidthIdx(b.pt));\n w.colorRef(l.color || \"000000\")\n .colorRef(r.color || \"000000\")\n .colorRef(t.color || \"000000\")\n .colorRef(b.color || \"000000\");\n w.u8(0).u8(0).colorRef(\"000000\");\n if (bg) {\n w.u32(1).colorRef(bg).colorRef(\"FFFFFF\").u32(0);\n } else {\n w.u32(0);\n }\n return w.build();\n}\n\n/**\n * HWPTAG_CHAR_SHAPE (74 bytes)\n * ANYTOHWP 개선: faceId[7]에 언어별 ID를 개별 기록\n */\nfunction mkCharShape(fontIds: number[], p: TextProps): Uint8Array {\n const height = Math.round((p.pt ?? 10) * 100);\n let attr = 0;\n if (p.i) attr |= 1 << 0;\n if (p.b) attr |= 1 << 1;\n if (p.u) attr |= 1 << 2;\n if (p.s) attr |= 1 << 18;\n if (p.sup) attr |= 1 << 16;\n if (p.sub) attr |= 2 << 16;\n\n const w = new BufWriter();\n // faceId[7]: 언어별 독립 ID (ANYTOHWP 핵심 개선)\n for (const id of fontIds) w.u16(id);\n for (let i = 0; i < 7; i++) w.u8(100); // ratio\n for (let i = 0; i < 7; i++) w.u8(0); // spacing\n for (let i = 0; i < 7; i++) w.u8(100); // relSize\n for (let i = 0; i < 7; i++) w.u8(0); // offset\n w.i32(height).u32(attr).u8(0).u8(0);\n w.colorRef(p.color ?? \"000000\");\n w.colorRef(\"000000\"); // underlineColor\n w.colorRef(p.bg ?? \"FFFFFF\"); // shadeColor\n w.colorRef(\"000000\"); // shadowColor\n w.u16(0); // borderFillId\n w.colorRef(\"000000\"); // strikeColor\n return w.build(); // 74 bytes\n}\n\nfunction mkParaShape(p: ParaProps): Uint8Array {\n const alignVal = ALIGN_CODE[p.align ?? \"left\"] ?? 1;\n const attr1 = (alignVal & 0x7) << 2;\n const lineSpacePct = p.lineHeight ? Math.round(p.lineHeight * 100) : 160;\n return new BufWriter()\n .u32(attr1)\n .i32(Metric.ptToHwp(p.indentPt ?? 0))\n .i32(Metric.ptToHwp(p.indentRightPt ?? 0))\n .i32(Metric.ptToHwp(p.firstLineIndentPt ?? 0))\n .i32(Metric.ptToHwp(p.spaceBefore ?? 0))\n .i32(Metric.ptToHwp(p.spaceAfter ?? 0))\n .i32(lineSpacePct)\n .u16(0)\n .u16(0)\n .u16(0)\n .i16(0)\n .i16(0)\n .i16(0)\n .i16(0)\n .u32(0)\n .u32(4)\n .u32(lineSpacePct)\n .build(); // 54 bytes\n}\n\nfunction mkBinData(id: number, ext: string): Uint8Array {\n return new BufWriter().u16(0x0002).u16(id).u16(ext.length).utf16(ext).build();\n}\n\ninterface BinImage {\n id: number;\n ext: string;\n data: Uint8Array;\n}\n\n/**\n * DocInfo 스트림 빌더\n * ANYTOHWP 개선: 언어별 폰트 목록을 순서대로 독립 기록\n */\nfunction buildDocInfoStream(\n bank: HwpStyleBank,\n images: BinImage[] = [],\n): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n chunks.push(mkRec(TAG_DOCUMENT_PROPERTIES, 0, mkDocumentProperties()));\n chunks.push(mkRec(TAG_ID_MAPPINGS, 1, mkIdMappings(bank, images.length)));\n\n for (const img of images) {\n chunks.push(mkRec(TAG_BIN_DATA, 1, mkBinData(img.id, img.ext)));\n }\n\n // ANYTOHWP 방식: 언어 그룹별로 독립된 FACE_NAME 레코드 직렬화\n for (const lang of LANG_GROUPS) {\n for (const face of bank.getFontsForLang(lang)) {\n chunks.push(mkRec(TAG_FACE_NAME, 1, mkFaceName(face)));\n }\n }\n\n for (const entry of bank.bfData) {\n chunks.push(\n mkRec(\n TAG_BORDER_FILL,\n 1,\n entry.uniform\n ? mkBorderFill(entry.s, entry.bg)\n : mkBorderFillPerSide(entry.l, entry.r, entry.t, entry.b, entry.bg),\n ),\n );\n }\n\n // charShape — 언어별 fontId 배열 사용\n for (let i = 0; i < bank.csProps.length; i++) {\n chunks.push(\n mkRec(TAG_CHAR_SHAPE, 1, mkCharShape(bank.csFontIds[i], bank.csProps[i])),\n );\n }\n\n for (const p of bank.psProps) {\n chunks.push(mkRec(TAG_PARA_SHAPE, 1, mkParaShape(p)));\n }\n\n chunks.push(mkRec(TAG_STYLE, 1, mkStyle(\"바탕글\", \"Normal\", 0, 0)));\n\n return concatU8(chunks);\n}\n\n// ─── BodyText 레코드 빌더 ────────────────────────────────────\n\nfunction mkPageDef(dims: PageDims): Uint8Array {\n return new BufWriter()\n .u32(Metric.ptToHwp(dims.wPt))\n .u32(Metric.ptToHwp(dims.hPt))\n .u32(Metric.ptToHwp(dims.ml))\n .u32(Metric.ptToHwp(dims.mr))\n .u32(Metric.ptToHwp(dims.mt))\n .u32(Metric.ptToHwp(dims.mb))\n .zeros(12)\n .u32(dims.orient === \"landscape\" ? 1 : 0)\n .build(); // 40 bytes\n}\n\nfunction mkParaHeader(\n nchars: number,\n ctrlMask: number,\n psId: number,\n csCount: number,\n lineAlignCount = 0,\n instanceId = 0,\n): Uint8Array {\n return new BufWriter()\n .u32(nchars)\n .u32(ctrlMask)\n .u16(psId)\n .u8(0)\n .u8(0)\n .u16(csCount)\n .u16(0)\n .u16(lineAlignCount)\n .u32(instanceId)\n .u16(0)\n .build(); // 24 bytes\n}\n\nfunction mkParaText(text: string): Uint8Array {\n const w = new BufWriter();\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i);\n // 0x09(탭), 0x0A(줄바꿈), 0x03(필드시작), 0x04(필드종료) 등 허용\n w.u16(c);\n }\n w.u16(13); // 문단 종결자\n return w.build();\n}\n\nfunction mkParaCharShape(pairs: [pos: number, id: number][]): Uint8Array {\n const w = new BufWriter();\n for (const [pos, id] of pairs) w.u32(pos).u32(id);\n return w.build();\n}\n\n/**\n * 5가지 LineSpacing(줄 간격) 타입에 따른 height 계산 로직\n */\nfunction calcLineHeight(\n type: number,\n value: number,\n textHeight: number,\n): number {\n switch (type) {\n case 0:\n return Math.floor((textHeight * value) / 100);\n case 1:\n return value;\n case 2:\n return Math.max(textHeight, value);\n case 3:\n return textHeight + value;\n case 4:\n return Math.floor(textHeight * value);\n default:\n return Math.floor((textHeight * value) / 100);\n }\n}\n\n/**\n * LineSeg 36바이트 구조체 (HWP 5.0 공식 규격)\n */\nfunction mkLineSeg(\n textStartPos: number,\n vertPos: number,\n vertSize: number,\n textHeight: number,\n baseline: number,\n spacing: number,\n horzPos: number,\n horzSize: number,\n flags: number,\n): Uint8Array {\n return new BufWriter()\n .u32(textStartPos)\n .i32(vertPos)\n .i32(vertSize)\n .i32(textHeight)\n .i32(baseline)\n .i32(spacing)\n .i32(horzPos)\n .i32(horzSize)\n .u32(flags)\n .build(); // 36 bytes\n}\n\nfunction buildDefaultLineSeg(\n availWidthHwp: number,\n fontHwp: number,\n nchars: number,\n paraProps?: ParaProps,\n vertPos = 0,\n): Uint8Array {\n const ratio = paraProps?.lineHeight\n ? Math.round(paraProps.lineHeight * 100)\n : 160;\n const vertSize = calcLineHeight(0, ratio, fontHwp);\n const baseline = Math.round(fontHwp * 0.85);\n const spacing = vertSize - fontHwp;\n // flags: bit 0 (페이지 첫 줄), bit 1 (컬럼 첫 줄)\n const flags = 3;\n\n return mkLineSeg(\n 0,\n vertPos,\n vertSize,\n fontHwp,\n baseline,\n spacing,\n 0,\n availWidthHwp,\n flags,\n );\n}\n\nfunction mkSecdParaText(): Uint8Array {\n const lo = CTRL_SECD & 0xffff;\n const hi = (CTRL_SECD>>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x0002)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x0002)\n .u16(0x000d)\n .build();\n}\n\nfunction mkTableParaText(): Uint8Array {\n const lo = CTRL_TABLE & 0xffff;\n const hi = (CTRL_TABLE>>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x000b)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x000b)\n .u16(0x000d)\n .build();\n}\n\nfunction mkPicParaText(): Uint8Array {\n const lo = CTRL_PIC & 0xffff;\n const hi = (CTRL_PIC>>> 16) & 0xffff;\n return new BufWriter()\n .u16(0x000b)\n .u16(lo)\n .u16(hi)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0)\n .u16(0x000b)\n .u16(0x000d)\n .build();\n}\n\n// ─── 이미지 관련 레코드 (ANYTOHWP 영감: 픽셀 치수 우선 사용)\n\ninterface ImgLayout {\n wrap?: string;\n xPt?: number;\n yPt?: number;\n zOrder?: number;\n distL?: number;\n distR?: number;\n distT?: number;\n distB?: number;\n}\n\nfunction mkShapeComponentPicture(\n binDataId: number,\n wHwp: number,\n hHwp: number,\n): Uint8Array {\n const w = new BufWriter();\n w.u32(CTRL_PIC).zeros(15);\n w.u32(0).u32(0).u32(wHwp).u32(hHwp);\n w.u32(0).u32(0).u32(wHwp).u32(hHwp);\n w.zeros(36);\n w.u16(binDataId).u8(0).u8(0).u8(0).zeros(5);\n return w.build();\n}\n\nfunction mkObjectCtrl(\n ctrlId: number,\n wHwp: number,\n hHwp: number,\n instanceId: number,\n layout?: ImgLayout,\n): Uint8Array {\n let attr = 0x082a2210;\n if (layout?.wrap === \"inline\") attr |= 1 << 3;\n return new BufWriter()\n .u32(ctrlId)\n .u32(attr)\n .i32(layout?.yPt ? Metric.ptToHwp(layout.yPt) : 0)\n .i32(layout?.xPt ? Metric.ptToHwp(layout.xPt) : 0)\n .u32(wHwp)\n .u32(hHwp)\n .i32(layout?.zOrder ?? 0)\n .u16(layout?.distL ? Metric.ptToHwp(layout.distL) : 0)\n .u16(layout?.distR ? Metric.ptToHwp(layout.distR) : 0)\n .u16(layout?.distT ? Metric.ptToHwp(layout.distT) : 0)\n .u16(layout?.distB ? Metric.ptToHwp(layout.distB) : 0)\n .u32(instanceId)\n .i32(0)\n .u16(0)\n .build(); // 46 bytes\n}\n\nfunction mkFieldBeginCtrl(instanceId: number): Uint8Array {\n // 46-byte Object Control Header for Field\n return new BufWriter()\n .u32(CTRL_FIELD_BEGIN)\n .u32(0x00000002) // 필드 플래그\n .zeros(28) // xy/size 등 불필요 (필드는 비가시)\n .u32(instanceId)\n .zeros(6)\n .build();\n}\n\nfunction mkFieldEndCtrl(beginId: number): Uint8Array {\n return new BufWriter()\n .u32(CTRL_FIELD_END)\n .u32(0)\n .zeros(28)\n .u32(beginId)\n .zeros(6)\n .build();\n}\n\n/**\n * 이미지 단락 인코딩\n * ANYTOHWP 개선: PNG/JPEG 픽셀 치수에서 HWPUNIT 계산\n */\nfunction encodePicPara(\n imgNode: ImgNode,\n binDataId: number,\n bank: HwpStyleBank,\n lv: number,\n idGen: () => number,\n availWidthHwp: number,\n): Uint8Array[] {\n // ANYTOHWP 방식: 픽셀 치수 추출 시도 → 실패 시 pt 기반으로 폴백\n const rawData = TextKit.base64Decode(imgNode.b64);\n const pixDims = readPixelDims(rawData, imgNode.mime);\n\n let wHwp: number, hHwp: number;\n if (pixDims && pixDims.w> 0 && pixDims.h> 0) {\n wHwp = Metric.ptToHwp((pixDims.w * 72) / 96); // px → pt(96dpi) → hwpunit\n hHwp = Metric.ptToHwp((pixDims.h * 72) / 96);\n } else {\n wHwp = Metric.ptToHwp(imgNode.w);\n hHwp = Metric.ptToHwp(imgNode.h);\n }\n\n // 가용 너비 초과 방지\n if (wHwp> availWidthHwp) {\n hHwp = Math.round((hHwp * availWidthHwp) / wHwp);\n wHwp = availWidthHwp;\n }\n\n const CTRL_MASK = 1 << 11;\n const instanceId = idGen();\n const psId = bank.addParaShape({});\n\n return [\n mkRec(\n TAG_PARA_HEADER,\n lv,\n mkParaHeader(9, CTRL_MASK, psId, 1, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, lv + 1, mkPicParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape([[0, 0]])),\n mkRec(\n TAG_PARA_LINE_SEG,\n lv + 1,\n buildDefaultLineSeg(availWidthHwp, hHwp, 9),\n ),\n mkRec(\n TAG_CTRL_HEADER,\n lv + 1,\n mkObjectCtrl(CTRL_PIC, wHwp, hHwp, idGen(), imgNode.layout),\n ),\n mkRec(\n TAG_SHAPE_COMPONENT_PICTURE,\n lv + 2,\n mkShapeComponentPicture(binDataId, wHwp, hHwp),\n ),\n ];\n}\n\n// ─── 문단 인코딩 ─────────────────────────────────────────────\n\nfunction encodePara(\n para: ParaNode,\n bank: HwpStyleBank,\n lv: number,\n instanceId: number,\n availWidthHwp: number,\n mask = 0,\n vertPos = 0,\n): Uint8Array[] {\n let text = \"\";\n const csPairs: [number, number][] = [];\n let pos = 0;\n let fontHwp = 1000;\n const ctrlRecords: Uint8Array[] = [];\n\n for (const kid of para.kids) {\n if (\n kid.tag === \"span\" &&\n (kid as SpanNode).props.pt &&\n ((kid as SpanNode).props.pt as number)> 0\n ) {\n fontHwp = Metric.ptToHwp((kid as SpanNode).props.pt as number);\n break;\n }\n }\n\n // 내부적으로 사용되는 ID 생성기 (단락 내에서 로컬하게 사용)\n let localIdCounter = 10000;\n const localIdGen = () => localIdCounter++;\n\n function processKids(kids: any[]): void {\n for (const kid of kids) {\n if (kid.tag === \"span\") {\n const span = kid as SpanNode;\n const csId = bank.addCharShape(span.props);\n if (!csPairs.length || csPairs[csPairs.length - 1][1] !== csId) {\n csPairs.push([pos, csId]);\n }\n for (const t of span.kids) {\n if (t.tag === \"txt\") {\n text += t.content;\n pos += t.content.length;\n }\n }\n } else if (kid.tag === \"link\") {\n const link = kid as LinkNode;\n mask |= 1 << 11; // 하이퍼링크 마스크\n\n const fieldBeginId = localIdGen();\n // 1. 시작 제어 문자 (0x03)\n text += String.fromCharCode(3);\n pos += 1;\n ctrlRecords.push(\n mkRec(TAG_CTRL_HEADER, lv + 1, mkFieldBeginCtrl(fieldBeginId)),\n );\n\n // 2. 내용 처리\n processKids(link.kids);\n\n // 3. 종료 제어 문자 (0x04)\n text += String.fromCharCode(4);\n pos += 1;\n ctrlRecords.push(\n mkRec(TAG_CTRL_HEADER, lv + 1, mkFieldEndCtrl(fieldBeginId)),\n );\n }\n }\n }\n processKids(para.kids);\n if (!csPairs.length) csPairs.push([0, 0]);\n\n const psId = bank.addParaShape(para.props);\n const nchars = text.length + 1;\n\n return [\n mkRec(\n TAG_PARA_HEADER,\n lv,\n mkParaHeader(nchars, mask, psId, csPairs.length, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, lv + 1, mkParaText(text)),\n mkRec(TAG_PARA_CHAR_SHAPE, lv + 1, mkParaCharShape(csPairs)),\n mkRec(\n TAG_PARA_LINE_SEG,\n lv + 1,\n buildDefaultLineSeg(availWidthHwp, fontHwp, nchars, para.props, vertPos),\n ),\n ...ctrlRecords,\n ];\n}\n\n// ─── 표 인코딩 ───────────────────────────────────────────────\n\nfunction mkTableCtrl(\n wHwp: number,\n hHwp: number,\n instanceId: number,\n align: Align = \"left\",\n): Uint8Array {\n // 표 정렬 속성 플래그 (HWP 표 제어 문자)\n // offset 20-21: 속성 플래그 (align: left=0, center=1, right=2, justify=3)\n const alignFlags = { left: 0, center: 1, right: 2, justify: 3 }[align] ?? 0;\n return new BufWriter()\n .u32(CTRL_TABLE)\n .u32(0x082a2211)\n .i32(0)\n .i32(0)\n .u32(wHwp)\n .u32(hHwp)\n .i32(7)\n .u16(140)\n .u16(140)\n .u16(140)\n .u16(140)\n .u32(instanceId)\n .i32(alignFlags)\n .u16(0)\n .build(); // 46 bytes\n}\n\nfunction mkTableRecord(\n rowCnt: number,\n colCnt: number,\n rowHwp: number[],\n bfId: number,\n): Uint8Array {\n const w = new BufWriter();\n w.u32(0x04000006).u16(rowCnt).u16(colCnt).u16(0);\n w.u16(510).u16(510).u16(141).u16(141);\n for (const h of rowHwp) w.u16(Math.max(1, h & 0xffff));\n w.u16(bfId).u16(0);\n return w.build();\n}\n\nfunction mkCellListHeader(\n paraCount: number,\n row: number,\n col: number,\n rs: number,\n cs: number,\n wHwp: number,\n hHwp: number,\n bfId: number,\n padL = 141,\n padR = 141,\n padT = 141,\n padB = 141,\n): Uint8Array {\n return new BufWriter()\n .u16(paraCount)\n .u32(0)\n .u16(0)\n .u16(col)\n .u16(row)\n .u16(rs)\n .u16(cs)\n .u32(wHwp)\n .u32(hHwp)\n .u16(padL)\n .u16(padR)\n .u16(padT)\n .u16(padB)\n .u16(bfId)\n .zeros(13)\n .build(); // 47 bytes\n}\n\nconst DEFAULT_ROW_HEIGHT_PT = 14;\n\nfunction encodeGrid(\n grid: GridNode,\n bank: HwpStyleBank,\n lv: number,\n idGen: () => number,\n availWidthHwp: number,\n): Uint8Array[] {\n const records: Uint8Array[] = [];\n const rowCnt = grid.kids.length;\n const colCnt = Math.max(1, grid.kids[0]?.kids.length ?? 1);\n\n const cwPt = (grid.props as any).colWidths ?? [];\n const totalPt = cwPt.reduce((s: number, w: number) => s + w, 0) || 453;\n const defColPt = totalPt / colCnt;\n const defStroke = grid.props.defaultStroke ?? bank.DEF_STROKE;\n const defBfId = bank.addBorderFill(defStroke);\n\n const rowHwp = grid.kids.map((row: any) =>\n row.heightPt != null && row.heightPt> 0\n ? Metric.ptToHwp(row.heightPt)\n : Metric.ptToHwp(DEFAULT_ROW_HEIGHT_PT),\n );\n\n const tblWPt =\n cwPt.length> 0 ? cwPt.reduce((s: number, w: number) => s + w, 0) : totalPt;\n const tblHPt = grid.kids.reduce(\n (s: number, row: any) =>\n s +\n (row.heightPt != null && row.heightPt> 0\n ? row.heightPt\n : DEFAULT_ROW_HEIGHT_PT),\n 0,\n );\n const tblInstanceId = idGen();\n const tblAlign = grid.props.align ?? \"left\";\n\n records.push(\n mkRec(\n TAG_CTRL_HEADER,\n lv,\n mkTableCtrl(\n Metric.ptToHwp(tblWPt),\n Metric.ptToHwp(tblHPt),\n tblInstanceId,\n tblAlign,\n ),\n ),\n );\n records.push(\n mkRec(TAG_TABLE, lv + 1, mkTableRecord(rowCnt, colCnt, rowHwp, defBfId)),\n );\n\n for (let r = 0; r < grid.kids.length; r++) {\n for (let c = 0; c < grid.kids[r].kids.length; c++) {\n const cell = grid.kids[r].kids[c];\n const wHwp = Metric.ptToHwp(cwPt[c] ?? defColPt);\n const hHwp = rowHwp[r];\n const cp = cell.props;\n const hasPerSide = cp.top || cp.bot || cp.left || cp.right;\n const bfId = hasPerSide\n ? bank.addBorderFillPerSide(\n cp.left ?? defStroke,\n cp.right ?? defStroke,\n cp.top ?? defStroke,\n cp.bot ?? defStroke,\n cp.bg,\n )\n : bank.addBorderFill(defStroke, cp.bg);\n\n const paras =\n cell.kids.length> 0\n ? cell.kids\n : [{ tag: \"para\" as const, props: {}, kids: [] }];\n\n const padL = cp.padL !== undefined ? Metric.ptToHwp(cp.padL) : 510;\n const padR = cp.padR !== undefined ? Metric.ptToHwp(cp.padR) : 510;\n const padT = cp.padT !== undefined ? Metric.ptToHwp(cp.padT) : 141;\n const padB = cp.padB !== undefined ? Metric.ptToHwp(cp.padB) : 141;\n\n records.push(\n mkRec(\n TAG_LIST_HEADER,\n lv + 1,\n mkCellListHeader(\n paras.length,\n r,\n c,\n cell.rs,\n cell.cs,\n wHwp,\n hHwp,\n bfId,\n padL,\n padR,\n padT,\n padB,\n ),\n ),\n );\n\n const cellWidthHwp = Metric.ptToHwp(cwPt[c] ?? defColPt);\n for (const para of paras) {\n records.push(\n ...encodePara(para as ParaNode, bank, lv + 2, idGen(), cellWidthHwp),\n );\n }\n }\n }\n return records;\n}\n\nfunction mkSectionCtrl(): Uint8Array {\n return new BufWriter()\n .u32(CTRL_SECD)\n .u32(0)\n .u32(1134)\n .u16(0x4000)\n .u16(0x001f)\n .zeros(31)\n .build(); // 47 bytes\n}\n\nfunction buildSectionParagraph(\n dims: PageDims,\n instanceId: number,\n): Uint8Array[] {\n const SECD_CTRL_MASK = 1 << 2;\n const nchars = 9;\n const availWidthHwp = Math.max(\n 1000,\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(dims.ml) -\n Metric.ptToHwp(dims.mr),\n );\n return [\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(nchars, SECD_CTRL_MASK, 0, 1, 1, instanceId),\n ),\n mkRec(TAG_PARA_TEXT, 1, mkSecdParaText()),\n mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])),\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, nchars),\n ),\n mkRec(TAG_CTRL_HEADER, 1, mkSectionCtrl()),\n mkRec(TAG_PAGE_DEF, 2, mkPageDef(dims)),\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)),\n mkRec(TAG_FOOTNOTE_SHAPE, 2, new Uint8Array(28)),\n ];\n}\n\n// ─── BodyText 스트림 빌더 ─────────────────────────────────────\n\nfunction flatImgNodes(kids: any[]): any[] {\n const result: any[] = [];\n for (const kid of kids) {\n if (kid.tag === \"img\") result.push(kid);\n else if (kid.tag === \"link\" && Array.isArray(kid.kids))\n result.push(...flatImgNodes(kid.kids));\n }\n return result;\n}\n\nfunction b64Matches(binImg: BinImage, b64: string): boolean {\n const a = TextKit.base64Encode(binImg.data).replace(/\\s/g, \"\");\n const b = b64.replace(/\\s/g, \"\");\n return a === b;\n}\n\nfunction buildBodyTextStream(\n doc: DocRoot,\n bank: HwpStyleBank,\n images: BinImage[],\n): Uint8Array {\n const chunks: Uint8Array[] = [];\n const dims = doc.kids[0]?.dims ?? A4;\n let instanceIdCounter = 1;\n const idGen = () => instanceIdCounter++;\n const availWidthHwp = Math.max(\n 1000,\n Metric.ptToHwp(dims.wPt) -\n Metric.ptToHwp(dims.ml) -\n Metric.ptToHwp(dims.mr),\n );\n\n for (const r of buildSectionParagraph(dims, idGen())) chunks.push(r);\n\n const TABLE_CTRL_MASK = 1 << 11;\n let vertPos = 0; // 단락 간격 추적\n\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) {\n if (node.tag === \"para\") {\n const para = node as ParaNode;\n\n const hasPageBreak = para.kids.some(\n (k) => k.tag === \"span\" && k.kids.some((c) => c.tag === \"pb\"),\n );\n let paraMask = hasPageBreak ? 1 << 2 : 0;\n\n // 코드 블록 감지 → ×ばつ1 표로 감싸기\n const hasCourier = (kids: any[]): boolean =>\n kids.some(\n (k) =>\n (k.tag === \"span\" &&\n k.props.font?.toLowerCase().includes(\"courier\")) ||\n (k.tag === \"link\" && hasCourier(k.kids)),\n );\n const isCode =\n para.props.styleId?.toLowerCase().includes(\"code\") ||\n hasCourier(para.kids);\n\n if (isCode) {\n const gridNode: GridNode = {\n tag: \"grid\",\n props: {\n colWidths: [Metric.hwpToPt(availWidthHwp)],\n defaultStroke: { kind: \"solid\", pt: 0.5, color: \"aaaaaa\" },\n },\n kids: [\n {\n tag: \"row\",\n kids: [\n {\n tag: \"cell\",\n rs: 1,\n cs: 1,\n props: { bg: \"f4f4f4\" },\n kids: [para],\n },\n ],\n },\n ],\n };\n chunks.push(\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(9, TABLE_CTRL_MASK | paraMask, 0, 1, 1, idGen()),\n ),\n );\n chunks.push(mkRec(TAG_PARA_TEXT, 1, mkTableParaText()));\n chunks.push(mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])));\n chunks.push(\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, 9, undefined, vertPos),\n ),\n );\n vertPos += Metric.ptToHwp(20); // 코드 블록 후 간격\n for (const r of encodeGrid(gridNode, bank, 1, idGen, availWidthHwp))\n chunks.push(r);\n continue;\n }\n\n const imgNodes = flatImgNodes(para.kids);\n if (imgNodes.length> 0) {\n for (const img of imgNodes) {\n const binImg = images.find((b) => b64Matches(b, img.b64));\n if (binImg) {\n for (const r of encodePicPara(\n img,\n binImg.id,\n bank,\n 0,\n idGen,\n availWidthHwp,\n )) {\n // 첫 레코드가 PARA_HEADER인 경우 페이지 브레이크 마스크 적용\n chunks.push(r);\n }\n vertPos += Metric.ptToHwp(img.h ?? 100); // 이미지 높이 추가\n }\n }\n const textKids = para.kids.filter(\n (k: any) => k.tag !== \"img\" && k.tag !== \"link\",\n );\n if (textKids.length> 0) {\n const textPara: ParaNode = {\n tag: \"para\",\n props: para.props,\n kids: textKids as any,\n };\n for (const r of encodePara(\n textPara,\n bank,\n 0,\n idGen(),\n availWidthHwp,\n paraMask,\n vertPos,\n )) {\n // PARA_HEADER 레코드(목록의 첫 번째)에 마스크 적용\n if (r[0] === (TAG_PARA_HEADER & 0xff)) {\n // 레코드 헤더 수정은 복잡하므로 encodePara 내부에서 처리하는 것이 안전하지만\n // 여기서는 간단히 구현하기 위해 encodePara의 인자로 mask를 넘기도록 구조를 변경하는 것이 좋습니다.\n }\n chunks.push(r);\n }\n // 단락 높이 계산 및 vertPos 업데이트 (이미지/텍스트 혼합)\n const fontHwp_img = (\n textKids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n )?.props.pt\n ? Metric.ptToHwp(\n (\n textKids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n ).props.pt as number,\n )\n : 1000;\n const lineSpacePct_img = Math.round((para.props.lineHeight ?? 1.6) * 100);\n vertPos += Math.round((fontHwp_img * lineSpacePct_img) / 100);\n }\n } else {\n for (const r of encodePara(\n para,\n bank,\n 0,\n idGen(),\n availWidthHwp,\n paraMask,\n vertPos,\n ))\n chunks.push(r);\n // 단락 높이 계산 및 vertPos 업데이트 (일반 단락)\n const fontHwp_para = (\n para.kids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n )?.props.pt\n ? Metric.ptToHwp(\n (\n para.kids.find(\n (k: any) => k.tag === \"span\" && k.props?.pt,\n ) as SpanNode\n ).props.pt as number,\n )\n : 1000;\n const lineSpacePct_para = para.props.lineHeight\n ? Math.round(para.props.lineHeight * 100)\n : 160;\n vertPos += Math.round((fontHwp_para * lineSpacePct_para) / 100);\n }\n } else if (node.tag === \"grid\") {\n chunks.push(\n mkRec(\n TAG_PARA_HEADER,\n 0,\n mkParaHeader(9, TABLE_CTRL_MASK, 0, 1, 1, idGen()),\n ),\n );\n chunks.push(mkRec(TAG_PARA_TEXT, 1, mkTableParaText()));\n chunks.push(mkRec(TAG_PARA_CHAR_SHAPE, 1, mkParaCharShape([[0, 0]])));\n chunks.push(\n mkRec(\n TAG_PARA_LINE_SEG,\n 1,\n buildDefaultLineSeg(availWidthHwp, 1000, 9, undefined, vertPos),\n ),\n );\n vertPos += Metric.ptToHwp(20); // 표 후 간격\n for (const r of encodeGrid(\n node as GridNode,\n bank,\n 1,\n idGen,\n availWidthHwp,\n ))\n chunks.push(r);\n }\n }\n }\n\n return concatU8(chunks);\n}\n\n// ─── HWP FileHeader ─────────────────────────────────────────\n/**\n * HWP 5.0 FileHeader 를 생성합니다.\n *\n * 구조:\n * 0-15: 시그니처 \"HWP Document File\" (16 바이트)\n * 16-31: reserved (16 바이트)\n * 32-35: version (4 바이트, Little-Endian) - 0x05000300 = 5.0.3.0\n * 36-39: flags (4 바이트, Little-Endian) - bit 0 = compressed, bit 1 = encrypted\n * 40-255: reserved (216 바이트)\n *\n * 총 256 바이트\n */\nfunction buildHwpFileHeader(): Uint8Array {\n const SIZE = 256;\n const buf = new Uint8Array(SIZE);\n const dv = new DataView(buf.buffer);\n\n // 0-15: 시그니처 \"HWP Document File\" (16 바이트)\n const sig = \"HWP Document File\";\n for (let i = 0; i < sig.length; i++) {\n buf[i] = sig.charCodeAt(i);\n }\n\n // 16-31: reserved (0 으로 초기화됨)\n\n // 32-35: version (4 바이트, Little-Endian) - 0x05000300 = 5.0.3.0\n dv.setUint32(32, 0x05000300, true);\n\n // 36-39: flags (4 바이트, Little-Endian)\n // bit 0 = 1: compressed (압축됨)\n // bit 1 = 0: not encrypted (암호화 안됨)\n dv.setUint32(36, 0x00000001, true);\n\n // 40-255: reserved (0 으로 초기화됨)\n\n // 검증\n if (buf.length !== SIZE) {\n throw new Error(`FileHeader 크기 오류: ${buf.length} (기대: ${SIZE})`);\n }\n if (new TextDecoder().decode(buf.subarray(0, sig.length)) !== sig) {\n throw new Error(\"FileHeader 시그니처 오류\");\n }\n if (dv.getUint32(32, true) !== 0x05000300) {\n throw new Error(\"FileHeader 버전 오류\");\n }\n\n return buf;\n}\n\n// ─── OLE2/CFB 컨테이너 빌더 ─────────────────────────────────\n\nfunction buildHwpOle2(\n fileHeaderData: Uint8Array,\n docInfoData: Uint8Array,\n section0Data: Uint8Array,\n binImages: BinImage[] = [],\n): Uint8Array {\n const SS = 512;\n const ENDOFCHAIN = 0xfffffffe;\n const FREESECT = 0xffffffff;\n const FATSECT = 0xfffffffd;\n\n // FileHeader 크기 검증\n if (fileHeaderData.length < 256) {\n throw new Error(\n `FileHeader 크기 부족: ${fileHeaderData.length} (최소 256)`,\n );\n }\n\n function padSector(d: Uint8Array): Uint8Array {\n const n = Math.ceil(Math.max(d.length, 1) / SS) * SS;\n if (d.length === n) return d;\n const out = new Uint8Array(n);\n out.set(d);\n return out;\n }\n\n const fhPad = padSector(fileHeaderData);\n const diPad = padSector(docInfoData);\n const s0Pad = padSector(section0Data);\n const imgPads = binImages.map((img) => padSector(img.data));\n\n const fhN = fhPad.length / SS;\n const diN = diPad.length / SS;\n const s0N = s0Pad.length / SS;\n const imgNs = imgPads.map((p) => p.length / SS);\n const totalImgN = imgNs.reduce((s, n) => s + n, 0);\n\n const numDirEntries = 5 + (binImages.length> 0 ? 1 + binImages.length : 0);\n const dirN = Math.max(2, Math.ceil(numDirEntries / 4));\n\n let fatN = 1;\n for (let iter = 0; iter < 10; iter++) {\n const total = fatN + dirN + fhN + diN + s0N + totalImgN;\n const needed = Math.ceil(total / 128);\n if (needed <= fatN) break;\n fatN = needed;\n }\n\n const dir1Sec = fatN;\n const fhSec = dir1Sec + dirN;\n const diSec = fhSec + fhN;\n const s0Sec = diSec + diN;\n\n const imgSecs: number[] = [];\n let curSec = s0Sec + s0N;\n for (const n of imgNs) {\n imgSecs.push(curSec);\n curSec += n;\n }\n const totalSec = curSec;\n\n const fatBuf = new Uint8Array(fatN * SS).fill(0xff);\n const setFat = (i: number, v: number) => {\n fatBuf[i * 4] = v & 0xff;\n fatBuf[i * 4 + 1] = (v>>> 8) & 0xff;\n fatBuf[i * 4 + 2] = (v>>> 16) & 0xff;\n fatBuf[i * 4 + 3] = (v>>> 24) & 0xff;\n };\n\n for (let i = 0; i < fatN; i++) setFat(i, FATSECT);\n for (let i = 0; i < dirN; i++)\n setFat(dir1Sec + i, i + 1 < dirN ? dir1Sec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < fhN; i++)\n setFat(fhSec + i, i + 1 < fhN ? fhSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < diN; i++)\n setFat(diSec + i, i + 1 < diN ? diSec + i + 1 : ENDOFCHAIN);\n for (let i = 0; i < s0N; i++)\n setFat(s0Sec + i, i + 1 < s0N ? s0Sec + i + 1 : ENDOFCHAIN);\n for (let ii = 0; ii < imgNs.length; ii++) {\n const start = imgSecs[ii];\n const n = imgNs[ii];\n for (let i = 0; i < n; i++)\n setFat(start + i, i + 1 < n ? start + i + 1 : ENDOFCHAIN);\n }\n\n const dirBuf = new Uint8Array(dirN * SS);\n const dv = new DataView(dirBuf.buffer);\n\n function writeDirEntry(\n idx: number,\n name: string,\n type: number,\n left: number,\n right: number,\n child: number,\n startSec: number,\n size: number,\n ): void {\n const base = idx * 128;\n const nl = name.length;\n // OLE2: 이름은 UTF-16LE, (글자수+1)*2 바이트가 길이 필드에 기록됨\n for (let i = 0; i < nl; i++)\n dv.setUint16(base + i * 2, name.charCodeAt(i), true);\n dv.setUint16(base + 64, (nl + 1) * 2, true);\n dirBuf[base + 66] = type;\n dirBuf[base + 67] = 1; // DE_NODE\n dv.setInt32(base + 68, left, true);\n dv.setInt32(base + 72, right, true);\n dv.setInt32(base + 76, child, true);\n dv.setUint32(base + 116, startSec>>> 0, true);\n dv.setUint32(base + 120, size>>> 0, true);\n }\n\n // 초기값 -1 (NOSTREAM)\n for (let i = 0; i < dirN * 4; i++) {\n const base = i * 128;\n dv.setInt32(base + 68, -1, true);\n dv.setInt32(base + 72, -1, true);\n dv.setInt32(base + 76, -1, true);\n }\n\n /**\n * 트리 구조 설계:\n * 0: Root Entry (child -> 1)\n * 1: FileHeader (left -> -1, right -> 2)\n * 2: DocInfo (left -> -1, right -> 3)\n * 3: BodyText (left -> -1, right -> 5, child -> 4)\n * 4: Section0 (left -> -1, right -> -1)\n * 5: BinData (left -> -1, right -> -1, child -> 6...)\n */\n\n if (binImages.length> 0) {\n writeDirEntry(0, \"Root Entry\", 5, -1, -1, 1, ENDOFCHAIN, 0);\n writeDirEntry(1, \"FileHeader\", 2, -1, 2, -1, fhSec, fileHeaderData.length);\n writeDirEntry(2, \"DocInfo\", 2, -1, 3, -1, diSec, docInfoData.length);\n writeDirEntry(3, \"BodyText\", 1, -1, 5, 4, ENDOFCHAIN, 0);\n writeDirEntry(4, \"Section0\", 2, -1, -1, -1, s0Sec, section0Data.length);\n writeDirEntry(5, \"BinData\", 1, -1, -1, 6, ENDOFCHAIN, 0);\n for (let ii = 0; ii < binImages.length; ii++) {\n const img = binImages[ii];\n const streamName = `BIN${String(img.id).padStart(4, \"0\")}.${img.ext}`;\n const sibling = ii + 1 < binImages.length ? 7 + ii : -1;\n writeDirEntry(\n 6 + ii,\n streamName,\n 2,\n -1,\n sibling,\n -1,\n imgSecs[ii],\n img.data.length,\n );\n }\n } else {\n writeDirEntry(0, \"Root Entry\", 5, -1, -1, 1, ENDOFCHAIN, 0);\n writeDirEntry(1, \"FileHeader\", 2, -1, 2, -1, fhSec, fileHeaderData.length);\n writeDirEntry(2, \"DocInfo\", 2, -1, 3, -1, diSec, docInfoData.length);\n writeDirEntry(3, \"BodyText\", 1, -1, -1, 4, ENDOFCHAIN, 0);\n writeDirEntry(4, \"Section0\", 2, -1, -1, -1, s0Sec, section0Data.length);\n }\n\n // HWP Root Entry CLSID\n const HWP_CLSID = [\n 0x20, 0xe9, 0xe3, 0xc0, 0x46, 0x35, 0xcf, 0x11, 0x8d, 0x81, 0x00, 0xaa,\n 0x00, 0x38, 0x9b, 0x71,\n ];\n for (let i = 0; i < 16; i++) dirBuf[80 + i] = HWP_CLSID[i];\n\n const hdr = new Uint8Array(SS);\n const hdv = new DataView(hdr.buffer);\n\n // OLE2/CFB 헤더 구조:\n // 0-7: Magic number (D0 CF 11 E0 A1 B1 1A E1)\n // 8-23: CLSID (16 bytes)\n // 24-25: Minor version (0x003E = 62)\n // 26-27: Major version (0x0003 = 3)\n // 28-29: Byte order (0x00FE = Little-Endian)\n // 30-31: Sector size exponent (0x0009 = 2^9 = 512)\n // 32-33: Mini sector size exponent (0x0006 = 2^6 = 64)\n // 34-39: Reserved (6 bytes)\n // 40-43: Number of FAT sectors\n // 44-47: Directory start sector location\n // 48-51: Transaction signature number\n // 52-55: Mini stream cutoff size (0x1000 = 4096)\n // 56-59: Mini FAT start sector location\n // 60-63: Number of mini FAT sectors\n // 64-67: FAT start sector location\n // 68-71: Number of backup FAT sectors\n // 72-75: Backup FAT start sector location\n // 76-511: Sector bitmap (109 sectors worth)\n\n // Magic number\n const MAGIC = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];\n MAGIC.forEach((b, i) => {\n hdr[i] = b;\n });\n\n // CLSID is already set in dirBuf[0][80:96] for Root Entry\n\n // Version\n hdv.setUint16(24, 0x003e, true); // Minor version\n hdv.setUint16(26, 0x0003, true); // Major version\n\n // Byte order\n hdv.setUint16(28, 0x00fe, true); // Little-Endian\n\n // Sector size exponent (2^9 = 512)\n hdv.setUint16(30, 0x0009, true);\n\n // Mini sector size exponent (2^6 = 64)\n hdv.setUint16(32, 0x0006, true);\n\n // Reserved (34-39, 6 bytes) - already zero\n\n // Number of FAT sectors\n hdv.setUint32(40, fatN, true);\n\n // Directory start sector location\n hdv.setUint32(44, dir1Sec, true);\n\n // Transaction signature number\n hdv.setUint32(48, 0, true);\n\n // Mini stream cutoff size\n hdv.setUint32(52, 0x1000, true);\n\n // Mini FAT start sector location\n hdv.setUint32(56, ENDOFCHAIN, true);\n\n // Number of mini FAT sectors\n hdv.setUint32(60, 0, true);\n\n // FAT start sector location\n hdv.setUint32(64, ENDOFCHAIN, true);\n\n // Number of backup FAT sectors\n hdv.setUint32(68, 0, true);\n\n // Backup FAT start sector location\n hdv.setUint32(72, 0, true);\n\n // Sector bitmap (76-511)\n for (let i = 0; i < 109; i++) {\n hdv.setUint32(76 + i * 4, i < fatN ? i : FREESECT, true);\n }\n\n const out = new Uint8Array(SS + totalSec * SS);\n out.set(hdr, 0);\n for (let i = 0; i < fatN; i++)\n out.set(fatBuf.subarray(i * SS, (i + 1) * SS), SS + i * SS);\n for (let i = 0; i < dirN; i++)\n out.set(dirBuf.subarray(i * SS, (i + 1) * SS), SS + (dir1Sec + i) * SS);\n out.set(fhPad, SS + fhSec * SS);\n out.set(diPad, SS + diSec * SS);\n out.set(s0Pad, SS + s0Sec * SS);\n for (let ii = 0; ii < imgPads.length; ii++)\n out.set(imgPads[ii], SS + imgSecs[ii] * SS);\n return out;\n}\n\n// ─── 유틸리티 ────────────────────────────────────────────────\n\nfunction concatU8(arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((s, a) => s + a.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const a of arrays) {\n out.set(a, off);\n off += a.length;\n }\n return out;\n}\n\n// ─── OLE2 검증 ──────────────────────────────────────────────\n\nfunction validateOle2Magic(hwp: Uint8Array): boolean {\n const OLE_MAGIC = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];\n return OLE_MAGIC.every((b, i) => hwp[i] === b);\n}\n\n// ─── Encoder 진입점 ──────────────────────────────────────────\n\nexport class HwpEncoder extends BaseEncoder {\n protected getFormat(): string {\n return \"hwp\";\n }\n protected getAliases(): string[] {\n return [\"application/vnd.hancom.hwp\"];\n }\n\n async encode(doc: DocRoot): Promise> {\n try {\n // 패스 1: 스타일 수집 (HwpStyleBank — ANYTOHWP 방식 언어별 폰트)\n const bank = new HwpStyleBank();\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectNode(node, bank);\n }\n\n // 이미지 수집 (ANYTOHWP 개선: 픽셀 치수는 encodePicPara에서 추출)\n const images: BinImage[] = [];\n const seenB64 = new Set();\n let binIdCounter = 1;\n\n function registerImg(img: any): void {\n const key = img.b64.substring(0, 50);\n if (seenB64.has(key)) return;\n seenB64.add(key);\n const raw = TextKit.base64Decode(img.b64);\n const ext =\n img.mime === \"image/png\"\n ? \"png\"\n : img.mime === \"image/gif\"\n ? \"gif\"\n : img.mime === \"image/bmp\"\n ? \"bmp\"\n : \"jpg\";\n images.push({ id: binIdCounter++, ext, data: new Uint8Array(raw) });\n }\n\n function collectImages(node: any): void {\n if (node.tag === \"para\") {\n for (const img of flatImgNodes(node.kids)) registerImg(img);\n } else if (node.tag === \"grid\") {\n for (const row of node.kids)\n for (const cell of row.kids)\n for (const para of cell.kids) collectImages(para);\n }\n }\n for (const sheet of doc.kids) {\n for (const node of sheet.kids) collectImages(node);\n }\n\n // 패스 2: 스트림 빌드\n const docInfoRaw = buildDocInfoStream(bank, images);\n const bodyRaw = buildBodyTextStream(doc, bank, images);\n\n // HWP 5.0: Zlib 헤더 없는 Raw Deflate\n const docInfoCmp = pako.deflateRaw(docInfoRaw);\n const bodyCmp = pako.deflateRaw(bodyRaw);\n\n const fileHdr = buildHwpFileHeader();\n\n // FileHeader 검증\n if (fileHdr.length !== 256) {\n return fail(\n `HwpEncoder: FileHeader 크기 오류 - ${fileHdr.length} bytes (기대: 256 bytes)`,\n );\n }\n\n const hwp = buildHwpOle2(fileHdr, docInfoCmp, bodyCmp, images);\n\n if (!validateOle2Magic(hwp)) {\n return fail(\"HwpEncoder: OLE2 매직 바이트 오류\");\n }\n\n // HWP 파일 크기 검증 (최소 512 바이트 - OLE2 헤더 1 섹터)\n if (hwp.length < 512) {\n return fail(\n `HwpEncoder: HWP 파일 크기 부족 - ${hwp.length} bytes (최소 512 bytes)`,\n );\n }\n\n return succeed(hwp);\n } catch (e: any) {\n return fail(`HwpEncoder: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n}\n\nregistry.registerEncoder(new HwpEncoder());\n","import type { DocRoot } from '../model/doc-tree';\nimport type { Outcome } from '../contract/result';\nimport type { EncoderOptions } from '../contract/encoder';\nimport { succeed, fail } from '../contract/result';\nimport { registry } from './registry';\n\n// Side-effect imports: auto-register all decoders and encoders\nimport '../decoders/hwpx/HwpxDecoder';\nimport '../decoders/hwp/HwpScanner';\nimport '../decoders/docx/DocxDecoder';\nimport '../decoders/md/MdDecoder';\nimport '../decoders/html/HtmlDecoder';\nimport '../encoders/hwpx/HwpxEncoder';\nimport '../encoders/docx/DocxEncoder';\nimport '../encoders/md/MdEncoder';\nimport '../encoders/html/HtmlEncoder';\nimport '../encoders/hwp/HwpEncoder';\n\nexport class Pipeline {\n private constructor(private raw: Uint8Array, private srcFmt: string) {}\n\n /** 파일을 열고 포맷을 자동 감지하거나 명시 */\n static open(input: Uint8Array | string, fmt?: string): Pipeline {\n if (typeof input === 'string') {\n return new Pipeline(new TextEncoder().encode(input), fmt ?? 'md');\n }\n return new Pipeline(input, fmt ?? detectFormat(input));\n }\n\n /** File/Blob 비동기 입력 */\n static async openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise {\n if (input instanceof Uint8Array || typeof input === 'string') {\n return Pipeline.open(input, fmt);\n }\n const buf = await input.arrayBuffer();\n const data = new Uint8Array(buf);\n const detectedFmt = fmt ?? (input instanceof File ? getExt(input.name) : undefined) ?? detectFormat(data);\n return new Pipeline(data, detectedFmt);\n }\n\n /** 목표 포맷으로 변환 */\n async to(targetFmt: string, options?: EncoderOptions): Promise> {\n const decoder = registry.getDecoder(this.srcFmt);\n const encoder = registry.getEncoder(targetFmt);\n\n if (!decoder) return fail(`지원하지 않는 입력 포맷: ${this.srcFmt}`);\n if (!encoder) return fail(`지원하지 않는 출력 포맷: ${targetFmt}`);\n\n const docResult = await decoder.decode(this.raw);\n if (!docResult.ok) return docResult;\n\n const encResult = await encoder.encode(docResult.data, options);\n if (!encResult.ok) return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n\n return { ...encResult, warns: [...docResult.warns, ...encResult.warns] };\n }\n\n /** DocRoot만 추출 (인코딩 없이) */\n async inspect(): Promise> {\n const decoder = registry.getDecoder(this.srcFmt);\n if (!decoder) return fail(`디코더 없음: ${this.srcFmt}`);\n return decoder.decode(this.raw);\n }\n}\n\nfunction detectFormat(data: Uint8Array): string {\n // HWP 파일 (OLE Compound Document)\n if (data[0] === 0xD0 && data[1] === 0xCF && data[2] === 0x11 && data[3] === 0xE0) return 'hwp';\n\n // ZIP 기반 파일 (DOCX, HWPX)\n if (data[0] === 0x50 && data[1] === 0x4B) {\n // DOCX 는 [Content_Types].xml 에 application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml 이 있음\n // HWPX 는 application/ha-xml-core-document\n const str = new TextDecoder('utf-8', { fatal: false }).decode(data.slice(0, 4096));\n if (str.includes('wordprocessingml')) return 'docx';\n if (str.includes('ha-xml')) return 'hwpx';\n if (str.includes('hwpml/')) return 'hwpx';\n if (str.includes('word/')) return 'docx';\n return 'hwpx'; // 기본값\n }\n\n return 'md';\n}\n\nfunction getExt(name: string): string | undefined {\n const parts = name.split('.');\n return parts.length> 1 ? parts[parts.length - 1].toLowerCase() : undefined;\n}\n","import type { AnyNode, DocRoot } from '../model/doc-tree';\n\nexport type WalkCallback = (node: AnyNode, parent: AnyNode | null, depth: number) => void | 'stop';\n\nexport function walkNode(\n node: AnyNode,\n cb: WalkCallback,\n parent: AnyNode | null = null,\n depth = 0,\n): boolean {\n const result = cb(node, parent, depth);\n if (result === 'stop') return false;\n\n if ('kids' in node && Array.isArray((node as any).kids)) {\n for (const kid of (node as any).kids) {\n if (!walkNode(kid as AnyNode, cb, node, depth + 1)) return false;\n }\n }\n return true;\n}\n\nexport class TreeWalker {\n walk(root: DocRoot, cb: WalkCallback): void {\n walkNode(root, cb);\n }\n\n findAll(root: DocRoot, predicate: (n: AnyNode) => n is T): T[] {\n const results: T[] = [];\n walkNode(root, (n) => { if (predicate(n)) results.push(n); });\n return results;\n }\n\n extractText(root: DocRoot): string {\n const parts: string[] = [];\n walkNode(root, (n) => {\n if (n.tag === 'txt') parts.push(n.content);\n if (n.tag === 'br') parts.push('\\n');\n if (n.tag === 'pb') parts.push('\\n\\n');\n });\n return parts.join('');\n }\n}\n","import type { DocRoot, GridNode } from '../model/doc-tree';\nimport { walkNode } from './TreeWalker';\n\nexport function countNodes(root: DocRoot): Record {\n const counts: Record = {};\n walkNode(root, (n) => { counts[n.tag] = (counts[n.tag] ?? 0) + 1; });\n return counts;\n}\n\nexport function validateRoot(root: DocRoot): string[] {\n const errors: string[] = [];\n if (root.tag !== 'root') errors.push('Root node must have tag \"root\"');\n if (!Array.isArray(root.kids)) errors.push('Root.kids must be an array');\n if (root.kids.length === 0) errors.push('Document has no sheets');\n\n walkNode(root, (n) => {\n if (n.tag === 'cell' && n.kids.length === 0) {\n errors.push('CellNode must have at least one ParaNode child');\n }\n if (n.tag === 'grid' && (n as GridNode).kids.length === 0) {\n errors.push('GridNode must have at least one RowNode');\n }\n });\n\n return errors;\n}\n"],"mappings":"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","names":["pako","i","r","data","coreXml","stylesXml","extractDims","decodeHeaderFooter","toArr","decodePara","decodeGrid","decodeGridSimple","decodeGridFlat","decodeGridText","cellText","tableText","end","t","paraKids","stylesXml","mimeToExt","registerImage","esc","encodeImage","encodeContent","encodeGrid","encodeImage","encodePara","encodeContent","encodeGrid","encodeSpan","encodeImage","pako","TAG_FACE_NAME","TAG_BORDER_FILL","TAG_CHAR_SHAPE","TAG_PARA_SHAPE","TAG_PARA_HEADER","TAG_PARA_TEXT","TAG_PARA_CHAR_SHAPE","TAG_CTRL_HEADER","TAG_LIST_HEADER","TAG_PAGE_DEF","CTRL_TABLE","BORDER_W_PT","readPixelDims","LANG_GROUPS","encodePara","encodeGrid","out","registerImg","collectImages","pako"]} \ No newline at end of file diff --git a/hwpkit-extension/package.json b/hwpkit-extension/package.json new file mode 100644 index 000000000..15335182d --- /dev/null +++ b/hwpkit-extension/package.json @@ -0,0 +1,18 @@ +{ + "name": "hwpkit-extension", + "version": "1.0.0", + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "type": "module", + "exports": { + ".": { + "types": { + "import": "./index.d.mts", + "require": "./index.d.ts" + }, + "import": "./index.mjs", + "require": "./index.js" + } + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..c70631c30 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "rhwp-anther-extention", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/rhwp-chrome/package-lock.json b/rhwp-chrome/package-lock.json index d3b70721e..f575177d4 100644 --- a/rhwp-chrome/package-lock.json +++ b/rhwp-chrome/package-lock.json @@ -1,13 +1,17 @@ { "name": "rhwp-chrome", - "version": "0.1.0", + "version": "0.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rhwp-chrome", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", + "dependencies": { + "pako": "^2.1.0", + "saxes": "^6.0.0" + }, "devDependencies": { "typescript": "^5.7.0", "vite": "^6.1.0" @@ -430,9 +434,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", - "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", + "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", "cpu": [ "arm" ], @@ -443,9 +447,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", - "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", + "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", "cpu": [ "arm64" ], @@ -456,9 +460,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", - "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", + "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", "cpu": [ "arm64" ], @@ -469,9 +473,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", - "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", + "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", "cpu": [ "x64" ], @@ -482,9 +486,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", - "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", + "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", "cpu": [ "arm64" ], @@ -495,9 +499,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", - "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", + "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", "cpu": [ "x64" ], @@ -508,9 +512,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", - "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", + "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", "cpu": [ "arm" ], @@ -521,9 +525,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", - "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", + "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", "cpu": [ "arm" ], @@ -534,9 +538,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", - "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", + "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", "cpu": [ "arm64" ], @@ -547,9 +551,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", - "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", "cpu": [ "arm64" ], @@ -560,9 +564,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", - "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", "cpu": [ "loong64" ], @@ -573,9 +577,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", - "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", "cpu": [ "loong64" ], @@ -586,9 +590,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", - "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", "cpu": [ "ppc64" ], @@ -599,9 +603,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", - "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", "cpu": [ "ppc64" ], @@ -612,9 +616,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", - "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", "cpu": [ "riscv64" ], @@ -625,9 +629,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", - "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", "cpu": [ "riscv64" ], @@ -638,9 +642,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", - "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", "cpu": [ "s390x" ], @@ -651,9 +655,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", - "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", "cpu": [ "x64" ], @@ -664,9 +668,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", - "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", "cpu": [ "x64" ], @@ -677,9 +681,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", - "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", "cpu": [ "x64" ], @@ -690,9 +694,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", - "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", "cpu": [ "arm64" ], @@ -703,9 +707,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", - "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", "cpu": [ "arm64" ], @@ -716,9 +720,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", - "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", "cpu": [ "ia32" ], @@ -729,9 +733,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", - "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", "cpu": [ "x64" ], @@ -742,9 +746,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", - "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", "cpu": [ "x64" ], @@ -850,6 +854,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 ||>=15.0.1" } }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -869,9 +879,9 @@ } }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "dev": true, "funding": [ { @@ -897,9 +907,9 @@ } }, "node_modules/rollup": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", - "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", + "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", "dev": true, "dependencies": { "@types/estree": "1.0.8" @@ -912,34 +922,46 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.1", - "@rollup/rollup-android-arm64": "4.60.1", - "@rollup/rollup-darwin-arm64": "4.60.1", - "@rollup/rollup-darwin-x64": "4.60.1", - "@rollup/rollup-freebsd-arm64": "4.60.1", - "@rollup/rollup-freebsd-x64": "4.60.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", - "@rollup/rollup-linux-arm-musleabihf": "4.60.1", - "@rollup/rollup-linux-arm64-gnu": "4.60.1", - "@rollup/rollup-linux-arm64-musl": "4.60.1", - "@rollup/rollup-linux-loong64-gnu": "4.60.1", - "@rollup/rollup-linux-loong64-musl": "4.60.1", - "@rollup/rollup-linux-ppc64-gnu": "4.60.1", - "@rollup/rollup-linux-ppc64-musl": "4.60.1", - "@rollup/rollup-linux-riscv64-gnu": "4.60.1", - "@rollup/rollup-linux-riscv64-musl": "4.60.1", - "@rollup/rollup-linux-s390x-gnu": "4.60.1", - "@rollup/rollup-linux-x64-gnu": "4.60.1", - "@rollup/rollup-linux-x64-musl": "4.60.1", - "@rollup/rollup-openbsd-x64": "4.60.1", - "@rollup/rollup-openharmony-arm64": "4.60.1", - "@rollup/rollup-win32-arm64-msvc": "4.60.1", - "@rollup/rollup-win32-ia32-msvc": "4.60.1", - "@rollup/rollup-win32-x64-gnu": "4.60.1", - "@rollup/rollup-win32-x64-msvc": "4.60.1", + "@rollup/rollup-android-arm-eabi": "4.60.2", + "@rollup/rollup-android-arm64": "4.60.2", + "@rollup/rollup-darwin-arm64": "4.60.2", + "@rollup/rollup-darwin-x64": "4.60.2", + "@rollup/rollup-freebsd-arm64": "4.60.2", + "@rollup/rollup-freebsd-x64": "4.60.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", + "@rollup/rollup-linux-arm-musleabihf": "4.60.2", + "@rollup/rollup-linux-arm64-gnu": "4.60.2", + "@rollup/rollup-linux-arm64-musl": "4.60.2", + "@rollup/rollup-linux-loong64-gnu": "4.60.2", + "@rollup/rollup-linux-loong64-musl": "4.60.2", + "@rollup/rollup-linux-ppc64-gnu": "4.60.2", + "@rollup/rollup-linux-ppc64-musl": "4.60.2", + "@rollup/rollup-linux-riscv64-gnu": "4.60.2", + "@rollup/rollup-linux-riscv64-musl": "4.60.2", + "@rollup/rollup-linux-s390x-gnu": "4.60.2", + "@rollup/rollup-linux-x64-gnu": "4.60.2", + "@rollup/rollup-linux-x64-musl": "4.60.2", + "@rollup/rollup-openbsd-x64": "4.60.2", + "@rollup/rollup-openharmony-arm64": "4.60.2", + "@rollup/rollup-win32-arm64-msvc": "4.60.2", + "@rollup/rollup-win32-ia32-msvc": "4.60.2", + "@rollup/rollup-win32-x64-gnu": "4.60.2", + "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" } }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -950,13 +972,13 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dev": true, "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -1051,6 +1073,12 @@ "optional": true } } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" } } } diff --git a/rhwp-chrome/package.json b/rhwp-chrome/package.json index 521995e44..8ec893ce3 100644 --- a/rhwp-chrome/package.json +++ b/rhwp-chrome/package.json @@ -13,5 +13,9 @@ "devDependencies": { "typescript": "^5.7.0", "vite": "^6.1.0" + }, + "dependencies": { + "pako": "^2.1.0", + "saxes": "^6.0.0" } } diff --git a/rhwp-chrome/vite.config.ts b/rhwp-chrome/vite.config.ts index f9996ba44..31ffec883 100644 --- a/rhwp-chrome/vite.config.ts +++ b/rhwp-chrome/vite.config.ts @@ -21,6 +21,9 @@ export default defineConfig({ alias: { '@': resolve(__dirname, '..', 'rhwp-studio', 'src'), '@wasm': resolve(__dirname, '..', 'pkg'), + 'hwpkit-extension': resolve(__dirname, '..', 'hwpkit-extension'), + 'pako': resolve(__dirname, 'node_modules', 'pako'), + 'saxes': resolve(__dirname, 'node_modules', 'saxes'), }, }, build: { diff --git a/rhwp-studio/index.html b/rhwp-studio/index.html index b84960de2..e0ccc7a7d 100644 --- a/rhwp-studio/index.html +++ b/rhwp-studio/index.html @@ -17,7 +17,9 @@
                  새로 만들기
                  열기
                  -
                  저장Ctrl+S
                  +
                  저장Ctrl+S
                  +
                  다른 이름으로 저장
                  +
                  포맷 변경하여 저장
                  편집 용지F7
                  인쇄Ctrl+P
                  diff --git a/rhwp-studio/package-lock.json b/rhwp-studio/package-lock.json index 8ab76f9af..13ad01c71 100644 --- a/rhwp-studio/package-lock.json +++ b/rhwp-studio/package-lock.json @@ -1,13 +1,18 @@ { "name": "rhwp-studio", - "version": "0.7.2", + "version": "0.7.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rhwp-studio", - "version": "0.7.2", + "version": "0.7.3", "license": "MIT", + "dependencies": { + "hwpkit-extension": "file:../hwpkit-extension", + "pako": "^2.1.0", + "saxes": "^6.0.0" + }, "devDependencies": { "@types/chrome": "^0.1.40", "puppeteer-core": "^24.40.0", @@ -15,10 +20,13 @@ "vite": "^8.0.8" } }, + "../hwpkit-extension": { + "version": "1.0.0" + }, "node_modules/@emnapi/core": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", - "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", "optional": true, @@ -28,9 +36,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", - "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "license": "MIT", "optional": true, @@ -50,9 +58,9 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", - "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "license": "MIT", "optional": true, @@ -69,9 +77,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.124.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz", - "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==", + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz", + "integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==", "dev": true, "license": "MIT", "funding": { @@ -83,6 +91,7 @@ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz", "integrity": "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "debug": "^4.4.3", "extract-zip": "^2.0.1", @@ -100,9 +109,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==", "cpu": [ "arm64" ], @@ -117,9 +126,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==", "cpu": [ "arm64" ], @@ -134,9 +143,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==", "cpu": [ "x64" ], @@ -151,9 +160,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==", "cpu": [ "x64" ], @@ -168,9 +177,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", - "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz", + "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==", "cpu": [ "arm" ], @@ -185,9 +194,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==", "cpu": [ "arm64" ], @@ -202,9 +211,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==", "cpu": [ "arm64" ], @@ -219,9 +228,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==", "cpu": [ "ppc64" ], @@ -236,9 +245,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==", "cpu": [ "s390x" ], @@ -253,9 +262,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==", "cpu": [ "x64" ], @@ -270,9 +279,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==", "cpu": [ "x64" ], @@ -287,9 +296,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==", "cpu": [ "arm64" ], @@ -304,9 +313,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", - "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz", + "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==", "cpu": [ "wasm32" ], @@ -314,18 +323,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "1.9.2", - "@emnapi/runtime": "1.9.2", - "@napi-rs/wasm-runtime": "^1.1.3" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { - "node": ">=14.0.0" + "node": "^20.19.0 ||>=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==", "cpu": [ "arm64" ], @@ -340,9 +349,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==", "cpu": [ "x64" ], @@ -357,9 +366,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", - "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz", + "integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==", "dev": true, "license": "MIT" }, @@ -367,7 +376,8 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", @@ -385,6 +395,7 @@ "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.40.tgz", "integrity": "sha512-UnfyRAe8ORu9HSuTH0EqyOEUin3JrWW9Nl/gDXezNfTUrfIoxw+WRZgKOxGz0t5BnjbfXBnS2eCYfW2PxH1wcA==", "dev": true, + "license": "MIT", "dependencies": { "@types/filesystem": "*", "@types/har-format": "*" @@ -395,6 +406,7 @@ "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.36.tgz", "integrity": "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==", "dev": true, + "license": "MIT", "dependencies": { "@types/filewriter": "*" } @@ -403,22 +415,25 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz", "integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/har-format": { "version": "1.2.16", "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.16.tgz", "integrity": "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.4.0.tgz", - "integrity": "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==", + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "undici-types": "~7.18.0" + "undici-types": "~7.19.0" } }, "node_modules/@types/yauzl": { @@ -426,6 +441,7 @@ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@types/node": "*" @@ -436,6 +452,7 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14" } @@ -445,6 +462,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -454,6 +472,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -469,6 +488,7 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -481,6 +501,7 @@ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", "dev": true, + "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" }, @@ -495,6 +516,7 @@ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "dev": true, + "license": "Apache-2.0", "peerDependencies": { "bare-abort-controller": "*" }, @@ -505,10 +527,11 @@ } }, "node_modules/bare-fs": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.5.tgz", - "integrity": "sha512-XvwYM6VZqKoqDll8BmSww5luA5eflDzY0uEFfBJtFKe4PAAtxBjU3YIxzIBzhyaEQBy1VXEQBto4cpN5RZJw+w==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.1.tgz", + "integrity": "sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", @@ -529,10 +552,11 @@ } }, "node_modules/bare-os": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.7.1.tgz", - "integrity": "sha512-ebvMaS5BgZKmJlvuWh14dg9rbUI84QeV3WlWn6Ph6lFI8jJoh7ADtVTyD2c93euwbe+zgi0DVrl4YmqXeM9aIA==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.0.tgz", + "integrity": "sha512-JTjuZyNIDpw+GytMO4a6TK1VXdVKKJr6DRxEHasyuYyShV2deuiHJK/ahGZlebc+SG0/wJCB9XK8gprBGDFi/Q==", "dev": true, + "license": "Apache-2.0", "engines": { "bare": ">=1.14.0" } @@ -542,24 +566,30 @@ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bare-os": "^3.0.1" } }, "node_modules/bare-stream": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.0.tgz", - "integrity": "sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.0.tgz", + "integrity": "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "streamx": "^2.21.0", + "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { + "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + }, "bare-buffer": { "optional": true }, @@ -569,19 +599,21 @@ } }, "node_modules/bare-url": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", - "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.2.tgz", + "integrity": "sha512-/9a2j4ac6ckpmAHvod/ob7x439OAHst/drc2Clnq+reRYd/ovddwcF4LfoxHyNk5AuGBnPg+HqFjmE/Zpq6v0A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bare-path": "^3.0.0" } }, "node_modules/basic-ftp": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", - "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz", + "integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -591,6 +623,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -600,6 +633,7 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" @@ -613,6 +647,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -627,6 +662,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -638,13 +674,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14" } @@ -654,6 +692,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -671,6 +710,7 @@ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, + "license": "MIT", "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -691,22 +731,25 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1581282", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz", - "integrity": "sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==", - "dev": true + "version": "0.0.1595872", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1595872.tgz", + "integrity": "sha512-kRfgp8vWVjBu/fbYCiVFiOqsCk3CrMKEo3WbgGT2NXK2dG7vawWPBljixajVgGK9II8rDO9G0oD0zLt3I1daRg==", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -716,6 +759,7 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -725,6 +769,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -746,6 +791,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -759,6 +805,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -768,6 +815,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -777,6 +825,7 @@ "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bare-events": "^2.7.0" } @@ -786,6 +835,7 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -805,13 +855,15 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "license": "MIT", "dependencies": { "pend": "~1.2.0" } @@ -821,6 +873,7 @@ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.0.0" }, @@ -853,6 +906,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* ||>= 10.*" } @@ -862,6 +916,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -877,6 +932,7 @@ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", "dev": true, + "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -891,6 +947,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -904,6 +961,7 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "4" @@ -912,11 +970,16 @@ "node": ">= 14" } }, + "node_modules/hwpkit-extension": { + "resolved": "../hwpkit-extension", + "link": true + }, "node_modules/ip-address": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12" } @@ -926,6 +989,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1196,6 +1260,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -1204,13 +1269,15 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.11", @@ -1232,10 +1299,11 @@ } }, "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -1245,6 +1313,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -1254,6 +1323,7 @@ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", @@ -1273,6 +1343,7 @@ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, + "license": "MIT", "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -1281,11 +1352,18 @@ "node": ">= 14" } }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", @@ -1308,9 +1386,9 @@ } }, "node_modules/postcss": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz", - "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "dev": true, "funding": [ { @@ -1341,6 +1419,7 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1350,6 +1429,7 @@ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", @@ -1368,29 +1448,31 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pump": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/puppeteer-core": { - "version": "24.40.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.40.0.tgz", - "integrity": "sha512-MWL3XbUCfVgGR0gRsidzT6oKJT2QydPLhMITU6HoVWiiv4gkb6gJi3pcdAa8q4HwjBTbqISOWVP4aJiiyUJvag==", + "version": "24.42.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.42.0.tgz", + "integrity": "sha512-T4zXokk/izH01fYPhyyev1A4piWiOKrYq7CUFpdoYQxmOnXoV6YjUabmfIjCYkNspSoAXIxRid3Tw+Vg0fthYg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.13.0", "chromium-bidi": "14.0.0", "debug": "^4.4.3", - "devtools-protocol": "0.0.1581282", + "devtools-protocol": "0.0.1595872", "typed-query-selector": "^2.12.1", "webdriver-bidi-protocol": "0.4.1", "ws": "^8.19.0" @@ -1404,19 +1486,20 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/rolldown": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz", - "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==", + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz", + "integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.124.0", - "@rolldown/pluginutils": "1.0.0-rc.15" + "@oxc-project/types": "=0.127.0", + "@rolldown/pluginutils": "1.0.0-rc.17" }, "bin": { "rolldown": "bin/cli.mjs" @@ -1425,21 +1508,33 @@ "node": "^20.19.0 ||>=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-x64": "1.0.0-rc.15", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" + "@rolldown/binding-android-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-x64": "1.0.0-rc.17", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" } }, "node_modules/semver": { @@ -1447,6 +1542,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -1459,6 +1555,7 @@ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -1469,6 +1566,7 @@ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "dev": true, + "license": "MIT", "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" @@ -1483,6 +1581,7 @@ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", @@ -1497,6 +1596,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -1513,10 +1613,11 @@ } }, "node_modules/streamx": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", - "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz", + "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==", "dev": true, + "license": "MIT", "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", @@ -1528,6 +1629,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1542,6 +1644,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1554,6 +1657,7 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", "integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==", "dev": true, + "license": "MIT", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -1568,6 +1672,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==", "dev": true, + "license": "MIT", "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", @@ -1580,6 +1685,7 @@ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "dev": true, + "license": "MIT", "dependencies": { "streamx": "^2.12.5" } @@ -1589,18 +1695,20 @@ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dev": true, + "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -1613,19 +1721,22 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/typed-query-selector": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.1.tgz", - "integrity": "sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==", - "dev": true + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz", + "integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==", + "dev": true, + "license": "MIT" }, "node_modules/typescript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1635,24 +1746,25 @@ } }, "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/vite": { - "version": "8.0.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz", - "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==", + "version": "8.0.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz", + "integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", - "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.15", - "tinyglobby": "^0.2.15" + "postcss": "^8.5.10", + "rolldown": "1.0.0-rc.17", + "tinyglobby": "^0.2.16" }, "bin": { "vite": "bin/vite.js" @@ -1723,13 +1835,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz", "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1746,13 +1860,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -1769,11 +1885,18 @@ } } }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -1783,6 +1906,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -1801,6 +1925,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -1810,6 +1935,7 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -1820,6 +1946,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/rhwp-studio/package.json b/rhwp-studio/package.json index fbb1081a0..f4efe0897 100644 --- a/rhwp-studio/package.json +++ b/rhwp-studio/package.json @@ -9,6 +9,11 @@ "preview": "vite preview", "e2e": "node e2e/text-flow.test.mjs" }, + "dependencies": { + "hwpkit-extension": "file:../hwpkit-extension", + "pako": "^2.1.0", + "saxes": "^6.0.0" + }, "devDependencies": { "@types/chrome": "^0.1.40", "puppeteer-core": "^24.40.0", diff --git a/rhwp-studio/src/command/commands/file.ts b/rhwp-studio/src/command/commands/file.ts index f52d170be..bb86e3da5 100644 --- a/rhwp-studio/src/command/commands/file.ts +++ b/rhwp-studio/src/command/commands/file.ts @@ -3,6 +3,8 @@ import { PageSetupDialog } from '@/ui/page-setup-dialog'; import { AboutDialog } from '@/ui/about-dialog'; import { showConfirm } from '@/ui/confirm-dialog'; import { showSaveAs } from '@/ui/save-as-dialog'; +import { showExport, showExportDialog, type ExportFormat, EXPORT_FORMATS } from '@/ui/export-dialog'; +import { Pipeline } from 'hwpkit-extension'; import { pickOpenFileHandle, readFileFromHandle, @@ -65,10 +67,22 @@ export const fileCommands: CommandDef[] = [ const saveName = services.wasm.fileName; const sourceFormat = services.wasm.getSourceFormat(); const isHwpx = sourceFormat === 'hwpx'; - const bytes = isHwpx ? services.wasm.exportHwpx() : services.wasm.exportHwp(); + + // WASM 에서 원본 바이트 획득 + const rawBytes = isHwpx ? services.wasm.exportHwpx() : services.wasm.exportHwp(); + + // hwpkit-extension Pipeline 을 사용하여 문서 처리 (구조 검증 및 최적화) + const pipeline = await Pipeline.openAsync(rawBytes as Uint8Array); + const processResult = await pipeline.to(isHwpx ? 'hwpx' : 'hwp'); + + if (!processResult.ok) { + throw new Error(`hwpkit-extension 처리 실패: ${processResult.error}`); + } + + const bytes = processResult.data; const mimeType = isHwpx ? 'application/hwp+zip' : 'application/x-hwp'; const blob = new Blob([bytes as unknown as BlobPart], { type: mimeType }); - console.log(`[file:save] format=${sourceFormat}, isHwpx=${isHwpx}, ${bytes.length} bytes`); + console.log(`[file:save] format=${sourceFormat}, isHwpx=${isHwpx}, ${bytes.length} bytes (Pipeline 처리됨)`); // 1) 기존 파일 handle이 있으면 같은 파일에 저장, 없으면 save picker 시도 try { @@ -118,6 +132,173 @@ export const fileCommands: CommandDef[] = [ } }, }, + { + id: 'file:save-as', + label: '다른 이름으로 저장', + canExecute: (ctx) => ctx.hasDocument && ctx.sourceFormat !== 'hwpx', + async execute(services) { + try { + const saveName = services.wasm.fileName; + const sourceFormat = services.wasm.getSourceFormat(); + const isHwpx = sourceFormat === 'hwpx'; + const rawBytes = isHwpx ? services.wasm.exportHwpx() : services.wasm.exportHwp(); + + // hwpkit-extension Pipeline을 사용하여 문서 처리 (우리가 만든 기능 적용) + console.log(`[file:save-as] hwpkit-extension Pipeline 시작...`); + const pipeline = await Pipeline.openAsync(rawBytes as Uint8Array); + const processResult = await pipeline.to(isHwpx ? 'hwpx' : 'hwp'); + + if (!processResult.ok) { + throw new Error(`hwpkit-extension 처리 실패: ${processResult.error}`); + } + + const bytes = processResult.data; + const mimeType = isHwpx ? 'application/hwp+zip' : 'application/x-hwp'; + const blob = new Blob([bytes as unknown as BlobPart], { type: mimeType }); + + // '다른 이름으로 저장'은 항상 새 파일 선택 창(save picker)을 띄운다 (currentHandle: null) + try { + const saveResult = await saveDocumentToFileSystem({ + blob, + suggestedName: saveName, + currentHandle: null, // 무조건 새 위치 선택 + windowLike: window as FileSystemWindowLike, + }); + + if (saveResult.method !== 'fallback') { + services.wasm.currentFileHandle = saveResult.handle; + services.wasm.fileName = saveResult.fileName; + console.log(`[file:save-as] ${saveResult.fileName} (${(bytes.length / 1024).toFixed(1)}KB)`); + return; + } + } catch (e) { + if (e instanceof DOMException && e.name === 'AbortError') return; + console.warn('[file:save-as] File System Access API 실패, 폴백:', e); + } + + // 폴백: 브라우저 다운로드 방식 (파일 이름 입력받음) + const baseName = saveName.replace(/\.hwp$/i, ''); + const result = await showSaveAs(baseName); + if (!result) return; + const downloadName = result; + + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = downloadName; + a.click(); + setTimeout(() => URL.revokeObjectURL(url), 1000); + + console.log(`[file:save-as] ${downloadName} (${(bytes.length / 1024).toFixed(1)}KB)`); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error('[file:save-as] 저장 실패:', msg); + alert(`다른 이름으로 저장에 실패했습니다:\n${msg}`); + } + }, + }, + // ─── 포맷 변경하여 저장 ───────────────────────────── + { + id: 'file:save-as-format', + label: '포맷 변경하여 저장', + canExecute: (ctx) => ctx.hasDocument, + async execute(services) { + try { + const saveName = services.wasm.fileName; + const baseName = saveName.replace(/\.[^.]+$/, ''); + + // 포맷 선택 대화상자 표시 + const result = await showExport(baseName); + if (!result) return; + + const { name: fileName, format } = result; + + // WASM 에서 원본 바이트 획득 + const sourceFormat = services.wasm.getSourceFormat(); + const isHwpx = sourceFormat === 'hwpx'; + const rawBytes = isHwpx ? services.wasm.exportHwpx() : services.wasm.exportHwp(); + + // hwpkit-extension Pipeline 을 사용하여 포맷 변환 + console.log(`[file:save-as-format] hwpkit-extension Pipeline 시작... (→ ${format})`); + const pipeline = await Pipeline.openAsync(rawBytes as Uint8Array); + const processResult = await pipeline.to(format as any); + + if (!processResult.ok) { + throw new Error(`hwpkit-extension 처리 실패: ${processResult.error}`); + } + + const bytes = processResult.data; + const formatOption = EXPORT_FORMATS.find(f => f.format === format); + const mimeType = formatOption?.mimeType ?? 'application/octet-stream'; + const blob = new Blob([bytes as unknown as BlobPart], { type: mimeType }); + + // 새 파일로 저장 + try { + const saveResult = await saveDocumentToFileSystem({ + blob, + suggestedName: fileName, + currentHandle: null, + windowLike: window as FileSystemWindowLike, + }); + + if (saveResult.method !== 'fallback') { + console.log(`[file:save-as-format] ${fileName} (${format}, ${(bytes.length / 1024).toFixed(1)}KB)`); + return; + } + } catch (e) { + if (e instanceof DOMException && e.name === 'AbortError') return; + console.warn('[file:save-as-format] File System Access API 실패, 폴백:', e); + } + + // 폴백: 브라우저 다운로드 + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = fileName; + a.click(); + setTimeout(() => URL.revokeObjectURL(url), 1000); + + console.log(`[file:save-as-format] ${fileName} (${format}, ${(bytes.length / 1024).toFixed(1)}KB)`); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error('[file:save-as-format] 저장 실패:', msg); + alert(`파일 저장에 실패했습니다:\n${msg}`); + } + }, + }, + // ─── 내보내기 (Export) ───────────────────────────────── + { + id: 'file:export', + label: '내보내기', + canExecute: (ctx) => ctx.hasDocument, + async execute(services) { + await showExportMenu(services); + }, + }, + { + id: 'file:export-docx', + label: 'Word 문서 (.docx)', + canExecute: (ctx) => ctx.hasDocument, + async execute(services) { + await exportToFormat(services, 'docx'); + }, + }, + { + id: 'file:export-md', + label: 'Markdown (.md)', + canExecute: (ctx) => ctx.hasDocument, + async execute(services) { + await exportToFormat(services, 'md'); + }, + }, + { + id: 'file:export-html', + label: 'HTML (.html)', + canExecute: (ctx) => ctx.hasDocument, + async execute(services) { + await exportToFormat(services, 'html'); + }, + }, { id: 'file:page-setup', label: '편집 용지', @@ -227,3 +408,94 @@ ${svgPages.map(svg => `
                  ${svg}
                  `).join('\n')} }, }, ]; + +// ─── 내보내기 헬퍼 함수 ────────────────────────────── +/** 내보내기 메뉴 표시 (드롭다운 항목 클릭 시 호출됨) */ +async function showExportMenu(services: Parameters>[0]) { + const saveName = services.wasm.fileName; + const baseName = saveName.replace(/\.[^.]+$/, ''); + + const result = await showExportDialog(baseName); + if (!result) return; + + await exportToFormat(services, result.format, result.name); +} + +/** 지정된 포맷으로 내보내기 */ +async function exportToFormat( + services: Parameters>[0], + format: ExportFormat, + suggestedName?: string, +): Promise { + try { + const wasm = services.wasm; + const sourceFormat = wasm.getSourceFormat(); + const isHwpx = sourceFormat === 'hwpx'; + + // 원본 바이트 획득 + const rawBytes = isHwpx ? wasm.exportHwpx() : wasm.exportHwp(); + + console.log(`[export:${format}] hwpkit-extension Pipeline 시작...`); + + // Pipeline 을 사용하여 포맷 변환 + const pipeline = await Pipeline.openAsync(rawBytes as Uint8Array); + const processResult = await pipeline.to(format); + + if (!processResult.ok) { + throw new Error(`hwpkit-extension 변환 실패: ${processResult.error}`); + } + + const bytes = processResult.data; + + // 포맷별 설정 + const matched = EXPORT_FORMATS.find(f => f.format === format); + if (!matched) { + throw new Error(`지원하지 않는 내보내기 형식입니다: ${format}`); + } + + const formatConfig = { + ext: matched.extension, + mimeType: matched.mimeType, + }; + + // 파일 이름 결정 + let fileName = suggestedName ?? wasm.fileName; + if (!fileName.toLowerCase().endsWith(formatConfig.ext)) { + fileName = fileName.replace(/\.[^.]+$/, '') + formatConfig.ext; + } + + const blob = new Blob([bytes as unknown as BlobPart], { type: formatConfig.mimeType }); + + // File System Access API 로 저장 시도 + try { + const saveResult = await saveDocumentToFileSystem({ + blob, + suggestedName: fileName, + currentHandle: null, // 내보내기는 항상 새 파일 + windowLike: window as FileSystemWindowLike, + }); + + if (saveResult.method !== 'fallback') { + console.log(`[export:${format}] ${saveResult.fileName} (${(bytes.length / 1024).toFixed(1)}KB)`); + return; + } + } catch (e) { + if (e instanceof DOMException && e.name === 'AbortError') return; + console.warn(`[export:${format}] File System Access API 실패, 폴백:`, e); + } + + // 폴백: 브라우저 다운로드 방식 + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = fileName; + a.click(); + setTimeout(() => URL.revokeObjectURL(url), 1000); + + console.log(`[export:${format}] ${fileName} (${(bytes.length / 1024).toFixed(1)}KB)`); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`[export:${format}]`, msg); + alert(`내보내기에 실패했습니다:\n${msg}`); + } +} diff --git a/rhwp-studio/src/ui/export-dialog.ts b/rhwp-studio/src/ui/export-dialog.ts new file mode 100644 index 000000000..44b676e10 --- /dev/null +++ b/rhwp-studio/src/ui/export-dialog.ts @@ -0,0 +1,151 @@ +/** + * 문서 내보내기 대화상자 + * + * HWP/HWPX 를 DOCX, Markdown, HTML 형식으로 내보낼 수 있다. + */ +import { ModalDialog } from './dialog'; + +export type ExportFormat = 'hwp' | 'hwpx' | 'docx' | 'md' | 'html'; + +interface ExportFormatOption { + format: ExportFormat; + label: string; + extension: string; + mimeType: string; +} + +export const EXPORT_FORMATS: ExportFormatOption[] = [ + { format: 'hwp', label: '한글 문서 (.hwp)', extension: '.hwp', mimeType: 'application/x-hwp' }, + { format: 'hwpx', label: '한글 문서 XML (.hwpx)', extension: '.hwpx', mimeType: 'application/hwp+zip' }, + { format: 'docx', label: 'Word 문서 (.docx)', extension: '.docx', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }, + { format: 'md', label: 'Markdown (.md)', extension: '.md', mimeType: 'text/markdown' }, + { format: 'html', label: 'HTML (.html)', extension: '.html', mimeType: 'text/html' }, +]; + +class ExportDialog extends ModalDialog { + private defaultName: string; + private formatOptions: ExportFormatOption[]; + private formatSelect!: HTMLSelectElement; + private input!: HTMLInputElement; + private resolve!: (value: { name: string; format: ExportFormat } | null) => void; + + constructor(defaultName: string, formats?: ExportFormatOption[]) { + super('문서 내보내기', 400); + this.defaultName = defaultName; + this.formatOptions = formats ?? EXPORT_FORMATS; + } + + protected createBody(): HTMLElement { + const body = document.createElement('div'); + body.style.padding = '16px 20px'; + + // 포맷 선택 + const formatLabel = document.createElement('label'); + formatLabel.textContent = '포맷(F):'; + formatLabel.style.display = 'block'; + formatLabel.style.marginBottom = '6px'; + formatLabel.style.fontSize = '13px'; + body.appendChild(formatLabel); + + this.formatSelect = document.createElement('select'); + this.formatSelect.style.width = '100%'; + this.formatSelect.style.boxSizing = 'border-box'; + this.formatSelect.style.height = '26px'; + this.formatSelect.style.padding = '2px 6px'; + this.formatSelect.style.border = '1px solid #b4b4b4'; + this.formatSelect.style.fontSize = '13px'; + + this.formatOptions.forEach((opt, idx) => { + const option = document.createElement('option'); + option.value = opt.format; + option.textContent = opt.label; + this.formatSelect.appendChild(option); + }); + body.appendChild(this.formatSelect); + + // 파일 이름 입력 + const nameLabel = document.createElement('label'); + nameLabel.textContent = '파일 이름(N):'; + nameLabel.style.display = 'block'; + nameLabel.style.marginTop = '12px'; + nameLabel.style.marginBottom = '6px'; + nameLabel.style.fontSize = '13px'; + body.appendChild(nameLabel); + + this.input = document.createElement('input'); + this.input.type = 'text'; + this.input.value = this.defaultName; + this.input.style.width = '100%'; + this.input.style.boxSizing = 'border-box'; + this.input.style.height = '26px'; + this.input.style.padding = '2px 6px'; + this.input.style.border = '1px solid #b4b4b4'; + this.input.style.fontSize = '13px'; + + this.input.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + this.onConfirm(); + this.hide(); + } + }); + + // 포맷 변경 시 파일 이름 확장자 자동 업데이트 + this.formatSelect.addEventListener('change', () => { + const format = this.formatSelect.value as ExportFormat; + const ext = this.formatOptions.find(f => f.format === format)?.extension ?? '.docx'; + const baseName = this.input.value.replace(/\.[^.]+$/, ''); + this.input.value = baseName + ext; + }); + + body.appendChild(this.input); + + return body; + } + + protected onConfirm(): void { + const name = this.input.value.trim(); + const format = this.formatSelect.value as ExportFormat; + + if (!name) return; + + // 파일 이름에 확장자가 없으면 추가 + const ext = this.formatOptions.find(f => f.format === format)?.extension ?? '.docx'; + const fileName = name.toLowerCase().endsWith(ext) ? name : name + ext; + + this.resolve({ name: fileName, format }); + } + + override hide(): void { + this.resolve(null); + super.hide(); + } + + showAsync(): Promise<{ name: string; format: ExportFormat } | null> { + return new Promise((resolve) => { + let resolved = false; + this.resolve = (v: { name: string; format: ExportFormat } | null) => { + if (!resolved) { + resolved = true; + resolve(v); + } + }; + super.show(); + requestAnimationFrame(() => { + this.input.focus(); + this.input.select(); + }); + }); + } +} + +/** 내보내기 대화상자를 표시하고 사용자가 선택한 파일 이름과 포맷을 반환한다. 취소 시 null. */ +export function showExport(defaultName: string, formats?: ExportFormatOption[]): Promise<{ name: string; format: ExportFormat } | null> { + return new ExportDialog(defaultName, formats).showAsync(); +} + +/** 내보내기 대화상자를 표시한다. HWP/HWPX 포맷은 제외되며, DOCX/MD/HTML 만 선택 가능하다. */ +export function showExportDialog(defaultName: string): Promise<{ name: string; format: ExportFormat } | null> { + const exportFormats = EXPORT_FORMATS.filter(f => !['hwp', 'hwpx'].includes(f.format)); + return new ExportDialog(defaultName, exportFormats).showAsync(); +} \ No newline at end of file diff --git a/rhwp-studio/vite.config.ts b/rhwp-studio/vite.config.ts index 2b64352d1..f9dbf16bf 100644 --- a/rhwp-studio/vite.config.ts +++ b/rhwp-studio/vite.config.ts @@ -8,10 +8,16 @@ export default defineConfig({ define: { __APP_VERSION__: JSON.stringify(pkg.version), }, + optimizeDeps: { + include: ['pako', 'saxes'], + }, resolve: { alias: { '@': resolve(__dirname, 'src'), '@wasm': resolve(__dirname, '..', 'pkg'), + 'hwpkit-extension': resolve(__dirname, '..', 'hwpkit-extension'), + 'pako': resolve(__dirname, 'node_modules', 'pako'), + 'saxes': resolve(__dirname, 'node_modules', 'saxes'), }, }, server: {