label-studio-converter 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_jiti@2.4.2_postcss@8.5.6_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","../src/constants.ts","../src/lib/geometry.ts","../src/lib/ppocr-label.ts","../src/lib/schema.ts","../src/lib/sort.ts","../src/commands/toLabelStudio/impl.ts","../src/lib/label-studio.ts","../src/commands/toPPOCR/impl.ts","../src/bin/bash-complete.ts","../src/app.ts","../package.json","../src/commands/toLabelStudio/command.ts","../src/commands/toPPOCR/commands.ts","../src/context.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","export const OUTPUT_BASE_DIR = './output';\n\nexport const DEFAULT_LABEL_NAME = 'Text';\nexport const DEFAULT_LABEL_STUDIO_FULL_JSON = true;\nexport const DEFAULT_CREATE_FILE_PER_IMAGE = false;\nexport const DEFAULT_CREATE_FILE_LIST_FOR_SERVING = true;\nexport const DEFAULT_FILE_LIST_NAME = 'files.txt';\nexport const DEFAULT_BASE_SERVER_URL = 'http://localhost:8081';\n\nexport const DEFAULT_PPOCR_FILE_NAME = 'Label.txt';\n\n// Vertical sorting options\nexport const SORT_VERTICAL_NONE = 'none';\nexport const SORT_VERTICAL_TOP_BOTTOM = 'top-bottom';\nexport const SORT_VERTICAL_BOTTOM_TOP = 'bottom-top';\nexport const DEFAULT_SORT_VERTICAL = SORT_VERTICAL_NONE;\n\n// Horizontal sorting options\nexport const SORT_HORIZONTAL_NONE = 'none';\nexport const SORT_HORIZONTAL_LTR = 'ltr';\nexport const SORT_HORIZONTAL_RTL = 'rtl';\nexport const DEFAULT_SORT_HORIZONTAL = SORT_HORIZONTAL_NONE;\n\nexport type VerticalSortOrder =\n | typeof SORT_VERTICAL_NONE\n | typeof SORT_VERTICAL_TOP_BOTTOM\n | typeof SORT_VERTICAL_BOTTOM_TOP;\n\nexport type HorizontalSortOrder =\n | typeof SORT_HORIZONTAL_NONE\n | typeof SORT_HORIZONTAL_LTR\n | typeof SORT_HORIZONTAL_RTL;\n\n// Shape normalization options\nexport const SHAPE_NORMALIZE_NONE = 'none';\nexport const SHAPE_NORMALIZE_RECTANGLE = 'rectangle';\nexport const DEFAULT_SHAPE_NORMALIZE = SHAPE_NORMALIZE_NONE;\n\nexport type ShapeNormalizeOption =\n | typeof SHAPE_NORMALIZE_NONE\n | typeof SHAPE_NORMALIZE_RECTANGLE;\n\n// Bounding box resize options\nexport const DEFAULT_WIDTH_INCREMENT = 0;\nexport const DEFAULT_HEIGHT_INCREMENT = 0;\n\n// Number precision options\n// For Label Studio: keep full precision (no rounding) by default\nexport const DEFAULT_LABEL_STUDIO_PRECISION = -1; // -1 means no rounding\n// For PPOCR: round to integers\nexport const DEFAULT_PPOCR_PRECISION = 0;\n","/**\n * Geometry utility functions for shape normalization and bounding box operations\n */\n\nimport type { ShapeNormalizeOption } from '@/constants';\n\nexport type Point = [number, number];\n\n/**\n * Round a number to a specified precision\n * @param value - The number to round\n * @param precision - Number of decimal places (-1 means no rounding)\n * @returns Rounded number\n */\nexport function roundToPrecision(value: number, precision: number): number {\n if (precision < 0) {\n return value; // No rounding\n }\n const multiplier = Math.pow(10, precision);\n return Math.round(value * multiplier) / multiplier;\n}\n\n/**\n * Round points array to a specified precision\n * @param points - Array of points to round\n * @param precision - Number of decimal places (-1 means no rounding)\n * @returns Rounded points\n */\nexport function roundPoints(points: Point[], precision: number): Point[] {\n if (precision < 0) {\n return points; // No rounding\n }\n return points.map(\n ([x, y]) =>\n [roundToPrecision(x, precision), roundToPrecision(y, precision)] as Point,\n );\n}\n\n/**\n * Calculate the center point of a polygon\n */\nexport function calculateCenter(points: Point[]): Point {\n const sum = points.reduce((acc, [x, y]) => [acc[0] + x, acc[1] + y], [\n 0, 0,\n ] as Point);\n return [sum[0] / points.length, sum[1] / points.length];\n}\n\n/**\n * Calculate the minimum bounding rectangle of a polygon\n */\nexport function getMinimumBoundingRect(points: Point[]): {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n width: number;\n height: number;\n} {\n const minX = Math.min(...points.map(([x]) => x));\n const maxX = Math.max(...points.map(([x]) => x));\n const minY = Math.min(...points.map(([, y]) => y));\n const maxY = Math.max(...points.map(([, y]) => y));\n\n return {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\n/**\n * Convert diamond-like shapes to axis-aligned rectangles\n * @param points - Array of points representing the shape\n * @returns Normalized rectangle points\n */\nexport function normalizeShape(points: Point[]): Point[] {\n if (points.length < 3) {\n return points;\n }\n\n // Convert to axis-aligned bounding rectangle\n const { minX, minY, maxX, maxY } = getMinimumBoundingRect(points);\n\n return [\n [minX, minY],\n [maxX, minY],\n [maxX, maxY],\n [minX, maxY],\n ];\n}\n\n/**\n * Resize bounding box by a certain amount while keeping it centered\n * @param points - Array of points representing the bounding box\n * @param widthIncrement - Amount to increase width (can be negative to decrease)\n * @param heightIncrement - Amount to increase height (can be negative to decrease)\n * @returns Resized points\n */\nexport function resizeBoundingBox(\n points: Point[],\n widthIncrement: number,\n heightIncrement: number,\n): Point[] {\n if (points.length === 0) {\n return points;\n }\n\n // Calculate center\n const center = calculateCenter(points);\n\n // Calculate current bounding box\n const bbox = getMinimumBoundingRect(points);\n\n // Calculate new dimensions\n const newWidth = Math.max(1, bbox.width + widthIncrement);\n const newHeight = Math.max(1, bbox.height + heightIncrement);\n\n // Calculate scale factors\n const scaleX = newWidth / bbox.width;\n const scaleY = newHeight / bbox.height;\n\n // Transform each point: translate to origin, scale, translate back\n return points.map(([x, y]) => {\n const relX = x - center[0];\n const relY = y - center[1];\n\n return [center[0] + relX * scaleX, center[1] + relY * scaleY] as Point;\n });\n}\n\n/**\n * Apply geometry transformations to points\n * @param points - Original points\n * @param options - Transformation options\n * @returns Transformed points\n */\nexport function transformPoints(\n points: Point[],\n options: {\n normalizeShape?: ShapeNormalizeOption;\n widthIncrement?: number;\n heightIncrement?: number;\n },\n): Point[] {\n let result = points;\n\n // Apply shape normalization first\n if (options.normalizeShape && options.normalizeShape === 'rectangle') {\n result = normalizeShape(result);\n }\n\n // Then apply resizing\n if (\n options.widthIncrement !== undefined ||\n options.heightIncrement !== undefined\n ) {\n result = resizeBoundingBox(\n result,\n options.widthIncrement ?? 0,\n options.heightIncrement ?? 0,\n );\n }\n\n return result;\n}\n","import { randomUUID } from 'node:crypto';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport sizeOf from 'image-size';\nimport {\n DEFAULT_LABEL_NAME,\n DEFAULT_LABEL_STUDIO_PRECISION,\n type ShapeNormalizeOption,\n} from '@/constants';\nimport { type Point, roundToPrecision, transformPoints } from '@/lib/geometry';\nimport {\n type FullOCRLabelStudio,\n type MinOCRLabelStudio,\n type PPOCRLabel,\n} from '@/lib/schema';\n\nexport type ToLabelStudioOptions = {\n imagePath: string;\n baseServerUrl: string;\n inputDir?: string;\n toFullJson?: boolean;\n taskId?: number;\n labelName?: string;\n normalizeShape?: ShapeNormalizeOption;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n};\n\nexport const ppocrToLabelStudio = async (\n data: PPOCRLabel,\n options: ToLabelStudioOptions,\n): Promise<FullOCRLabelStudio | MinOCRLabelStudio> => {\n const {\n imagePath,\n baseServerUrl,\n inputDir,\n toFullJson = true,\n taskId = 1,\n labelName = DEFAULT_LABEL_NAME,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = DEFAULT_LABEL_STUDIO_PRECISION,\n } = options || {};\n\n if (toFullJson) {\n return ppocrToFullLabelStudio(\n data,\n imagePath,\n baseServerUrl,\n inputDir,\n taskId,\n labelName,\n normalizeShape,\n widthIncrement,\n heightIncrement,\n precision,\n );\n } else {\n return ppocrToMinLabelStudio(\n data,\n imagePath,\n baseServerUrl,\n inputDir,\n labelName,\n normalizeShape,\n widthIncrement,\n heightIncrement,\n precision,\n );\n }\n};\n\nexport const ppocrToFullLabelStudio = (\n data: PPOCRLabel,\n imagePath: string,\n baseServerUrl: string,\n inputDir?: string,\n taskId: number = 1,\n labelName: string = DEFAULT_LABEL_NAME,\n normalizeShape?: ShapeNormalizeOption,\n widthIncrement: number = 0,\n heightIncrement: number = 0,\n precision: number = DEFAULT_LABEL_STUDIO_PRECISION,\n): FullOCRLabelStudio => {\n const newBaseServerUrl =\n baseServerUrl.replace(/\\/+$/, '') + (baseServerUrl === '' ? '' : '/');\n\n const now = new Date().toISOString();\n\n // Get actual image dimensions from the image file\n let original_width = 1920;\n let original_height = 1080;\n\n // Resolve absolute path to image file\n const resolvedImagePath = inputDir ? join(inputDir, imagePath) : imagePath;\n\n if (!existsSync(resolvedImagePath)) {\n throw new Error(`Image file not found: ${resolvedImagePath}`);\n }\n\n const buffer = readFileSync(resolvedImagePath);\n const dimensions = sizeOf(buffer);\n if (!dimensions.width || !dimensions.height) {\n throw new Error(\n `Failed to read image dimensions from: ${resolvedImagePath}`,\n );\n }\n original_width = dimensions.width;\n original_height = dimensions.height;\n\n // Extract filename from imagePath for file_upload (just the filename)\n const fileName = imagePath.split('/').pop() || imagePath;\n\n // Group all PPOCRLabel items into a single task with one annotation\n const result: FullOCRLabelStudio = [\n {\n id: taskId,\n annotations: [\n {\n id: taskId,\n completed_by: 1,\n result: data\n .map((item) => {\n let { points } = item;\n\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Generate a single ID for all three related annotations\n const annotationId = randomUUID().slice(0, 10);\n const polygonPoints = points.map(([x, y]) => [\n roundToPrecision(((x ?? 0) / original_width) * 100, precision),\n roundToPrecision(((y ?? 0) / original_height) * 100, precision),\n ]);\n\n // Create result items: polygon, labels, and textarea\n return [\n // 1. Polygon geometry only\n {\n original_width,\n original_height,\n image_rotation: 0,\n value: {\n points: polygonPoints,\n closed: true,\n },\n id: annotationId,\n from_name: 'poly',\n to_name: 'image',\n type: 'polygon',\n origin: 'manual',\n },\n // 2. Labels with polygon geometry\n {\n original_width,\n original_height,\n image_rotation: 0,\n value: {\n points: polygonPoints,\n closed: true,\n labels: [labelName],\n },\n id: annotationId,\n from_name: 'label',\n to_name: 'image',\n type: 'labels',\n origin: 'manual',\n },\n // 3. Textarea with polygon geometry and text\n {\n original_width,\n original_height,\n image_rotation: 0,\n value: {\n points: polygonPoints,\n closed: true,\n text: [item.transcription],\n },\n id: annotationId,\n from_name: 'transcription',\n to_name: 'image',\n type: 'textarea',\n origin: 'manual',\n },\n ];\n })\n .flat(),\n was_cancelled: false,\n ground_truth: false,\n created_at: now,\n updated_at: now,\n draft_created_at: now,\n lead_time: 0,\n prediction: {},\n result_count: data.length * 3,\n unique_id: randomUUID(),\n import_id: null,\n last_action: null,\n bulk_created: false,\n task: taskId,\n project: 1,\n updated_by: 1,\n parent_prediction: null,\n parent_annotation: null,\n last_created_by: null,\n },\n ],\n file_upload: fileName,\n drafts: [],\n predictions: [],\n data: { ocr: `${newBaseServerUrl}${imagePath}` },\n meta: {},\n created_at: now,\n updated_at: now,\n allow_skip: false,\n inner_id: taskId,\n total_annotations: 1,\n cancelled_annotations: 0,\n total_predictions: 0,\n comment_count: 0,\n unresolved_comment_count: 0,\n last_comment_updated_at: null,\n project: 1,\n updated_by: 1,\n comment_authors: [],\n },\n ];\n\n return result;\n};\n\nexport const ppocrToMinLabelStudio = (\n data: PPOCRLabel,\n imagePath: string,\n baseServerUrl: string,\n inputDir?: string,\n labelName: string = 'text',\n normalizeShape?: ShapeNormalizeOption,\n widthIncrement: number = 0,\n heightIncrement: number = 0,\n precision: number = DEFAULT_LABEL_STUDIO_PRECISION,\n): MinOCRLabelStudio => {\n const newBaseServerUrl =\n baseServerUrl.replace(/\\/+$/, '') + (baseServerUrl === '' ? '' : '/');\n\n const now = new Date().toISOString();\n\n // Get actual image dimensions from the image file\n let original_width = 1920;\n let original_height = 1080;\n\n // Resolve absolute path to image file\n const resolvedImagePath = inputDir ? join(inputDir, imagePath) : imagePath;\n\n if (!existsSync(resolvedImagePath)) {\n throw new Error(`Image file not found: ${resolvedImagePath}`);\n }\n\n const buffer = readFileSync(resolvedImagePath);\n const dimensions = sizeOf(buffer);\n if (!dimensions.width || !dimensions.height) {\n throw new Error(\n `Failed to read image dimensions from: ${resolvedImagePath}`,\n );\n }\n original_width = dimensions.width;\n original_height = dimensions.height;\n\n return data.map((item, index) => {\n let { points } = item;\n\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Round coordinates based on precision first\n const roundedPoints = points.map(\n ([x, y]) =>\n [\n roundToPrecision(x ?? 0, precision),\n roundToPrecision(y ?? 0, precision),\n ] as [number, number],\n );\n\n // Calculate bbox from rounded points\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const point of roundedPoints) {\n const [x, y] = point;\n if (x !== undefined && y !== undefined) {\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n return {\n ocr: encodeURI(`${newBaseServerUrl}${imagePath}`),\n id: index + 1,\n bbox: [\n {\n x: minX,\n y: minY,\n width: width,\n height: height,\n rotation: 0,\n original_width,\n original_height,\n },\n ],\n label: [\n {\n points: roundedPoints,\n closed: true,\n labels: [labelName],\n original_width,\n original_height,\n },\n ],\n transcription: [item.transcription],\n poly: [\n {\n points: roundedPoints,\n closed: true,\n original_width,\n original_height,\n },\n ],\n annotator: 1,\n annotation_id: index + 1,\n created_at: now,\n updated_at: now,\n lead_time: 0,\n };\n });\n};\n","import z from 'zod';\n\nexport const FullOCRLabelStudioSchema = z.array(\n z.object({\n id: z.number(),\n annotations: z.array(\n z.object({\n id: z.number(),\n completed_by: z.number(),\n result: z.array(\n z.union([\n // Most specific rectangle variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base rectangle without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Most specific polygon variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base polygon without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n ]),\n ),\n was_cancelled: z.boolean(),\n ground_truth: z.boolean(),\n created_at: z.string(),\n updated_at: z.string(),\n draft_created_at: z.string(),\n lead_time: z.number(),\n prediction: z.object({}),\n result_count: z.number(),\n unique_id: z.string(),\n import_id: z.null(),\n last_action: z.null(),\n bulk_created: z.boolean(),\n task: z.number(),\n project: z.number(),\n updated_by: z.number(),\n parent_prediction: z.null(),\n parent_annotation: z.null(),\n last_created_by: z.null(),\n }),\n ),\n file_upload: z.string(),\n drafts: z.array(\n z.object({\n id: z.number(),\n user: z.string(),\n created_username: z.string(),\n created_ago: z.string(),\n result: z.array(\n z.union([\n // Most specific rectangle variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base rectangle without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Most specific polygon variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base polygon without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n ]),\n ),\n lead_time: z.number(),\n was_postponed: z.boolean(),\n import_id: z.null(),\n created_at: z.string(),\n updated_at: z.string(),\n task: z.number(),\n annotation: z.number(),\n }),\n ),\n predictions: z.array(z.unknown()),\n data: z.object({ ocr: z.string() }),\n meta: z.object({}),\n created_at: z.string(),\n updated_at: z.string(),\n allow_skip: z.boolean(),\n inner_id: z.number(),\n total_annotations: z.number(),\n cancelled_annotations: z.number(),\n total_predictions: z.number(),\n comment_count: z.number(),\n unresolved_comment_count: z.number(),\n last_comment_updated_at: z.null(),\n project: z.number(),\n updated_by: z.number(),\n comment_authors: z.array(z.unknown()),\n }),\n);\n\nexport const MinOCRLabelStudioSchema = z.array(\n z.object({\n ocr: z.string(),\n id: z.number(),\n bbox: z\n .array(\n z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n original_width: z.number(),\n original_height: z.number(),\n }),\n )\n .optional()\n .default([]),\n label: z\n .array(\n z.union([\n z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n labels: z.array(z.string()),\n original_width: z.number(),\n original_height: z.number(),\n }),\n z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n labels: z.array(z.string()),\n original_width: z.number(),\n original_height: z.number(),\n }),\n ]),\n )\n .optional()\n .default([]),\n transcription: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .transform((val) => {\n if (!val) return [];\n return Array.isArray(val) ? val : [val];\n }),\n poly: z\n .array(\n z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n original_width: z.number(),\n original_height: z.number(),\n }),\n )\n .optional()\n .default([]),\n annotator: z.number(),\n annotation_id: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n lead_time: z.number(),\n }),\n);\n\nexport const PPOCRLabelSchema = z.array(\n z.object({\n transcription: z.string(),\n points: z.array(z.array(z.number())),\n dt_score: z.number(),\n }),\n);\n\nexport type FullOCRLabelStudio = z.infer<typeof FullOCRLabelStudioSchema>;\nexport type MinOCRLabelStudio = z.infer<typeof MinOCRLabelStudioSchema>;\nexport type PPOCRLabel = z.infer<typeof PPOCRLabelSchema>;\n","import type { HorizontalSortOrder, VerticalSortOrder } from '@/constants';\nimport {\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\nimport type { PPOCRLabel } from '@/lib/schema';\n\n// Tolerance for grouping bounding boxes into columns/rows\n// Boxes within this pixel distance are considered in the same column/row\nconst GROUPING_TOLERANCE = 50;\n\n/**\n * Calculate the bounding box center point from polygon points\n */\nfunction getBoundingBoxCenter(points: number[][]): {\n x: number;\n y: number;\n width: number;\n height: number;\n} {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const [x, y] of points) {\n if (x !== undefined && y !== undefined) {\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n\n return {\n x: (minX + maxX) / 2,\n y: (minY + maxY) / 2,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\n/**\n * Sort PPOCRLabel array based on bounding box positions\n * Supports both traditional reading order (top-bottom, then left-right)\n * and SinoNom reading order (right-left columns, top-bottom within each column)\n * @param annotations - Array of PPOCR annotations to sort\n * @param verticalSort - Vertical sort order: 'none', 'top-bottom', 'bottom-top'\n * @param horizontalSort - Horizontal sort order: 'none', 'ltr', 'rtl'\n * @returns Sorted array (or original array if both sorts are 'none')\n */\nexport function sortBoundingBoxes(\n annotations: PPOCRLabel,\n verticalSort: VerticalSortOrder,\n horizontalSort: HorizontalSortOrder,\n): PPOCRLabel {\n if (\n verticalSort === SORT_VERTICAL_NONE &&\n horizontalSort === SORT_HORIZONTAL_NONE\n ) {\n return annotations;\n }\n\n // Create a copy to avoid mutating the original array\n const sorted = [...annotations];\n\n // Detect if this is vertical text (SinoNom style) or horizontal text (Arabic/Hebrew style)\n // by checking if most boxes are taller than they are wide\n const isVerticalText =\n sorted.length > 0 &&\n (() => {\n const verticalCount = sorted.filter((ann) => {\n const center = getBoundingBoxCenter(ann.points);\n return center.height > center.width * 1.5; // At least 1.5x taller than wide\n }).length;\n return verticalCount > sorted.length / 2; // More than half are vertical\n })();\n\n // For RTL with vertical sorting and vertical text (SinoNom):\n // Group into columns first, then sort within each column\n if (\n horizontalSort === SORT_HORIZONTAL_RTL &&\n verticalSort !== SORT_VERTICAL_NONE &&\n isVerticalText\n ) {\n // Calculate centers for all annotations\n const annotationsWithCenters = sorted.map((ann) => ({\n annotation: ann,\n center: getBoundingBoxCenter(ann.points),\n }));\n\n // Group annotations into columns based on x-position\n const columns: (typeof annotationsWithCenters)[] = [];\n\n for (const item of annotationsWithCenters) {\n let addedToColumn = false;\n\n for (const column of columns) {\n // Check if this annotation belongs to an existing column\n const avgX =\n column.reduce((sum, c) => sum + c.center.x, 0) / column.length;\n if (Math.abs(item.center.x - avgX) < GROUPING_TOLERANCE) {\n column.push(item);\n addedToColumn = true;\n break;\n }\n }\n\n if (!addedToColumn) {\n columns.push([item]);\n }\n }\n\n // Sort columns right-to-left\n columns.sort((colA, colB) => {\n const avgXA = colA.reduce((sum, c) => sum + c.center.x, 0) / colA.length;\n const avgXB = colB.reduce((sum, c) => sum + c.center.x, 0) / colB.length;\n return avgXB - avgXA; // Right to left\n });\n\n // Sort within each column top-to-bottom or bottom-to-top\n for (const column of columns) {\n column.sort((a, b) => {\n return verticalSort === SORT_VERTICAL_TOP_BOTTOM\n ? a.center.y - b.center.y\n : b.center.y - a.center.y;\n });\n }\n\n // Flatten back to a single array\n return columns.flat().map((item) => item.annotation);\n }\n\n // For all other cases, use simple sort with priority\n sorted.sort((a, b) => {\n const centerA = getBoundingBoxCenter(a.points);\n const centerB = getBoundingBoxCenter(b.points);\n\n // Apply vertical sorting first (if specified)\n if (verticalSort !== SORT_VERTICAL_NONE) {\n const yDiff =\n verticalSort === SORT_VERTICAL_TOP_BOTTOM\n ? centerA.y - centerB.y\n : centerB.y - centerA.y;\n\n // If there's a significant difference in y-position, return that\n if (Math.abs(yDiff) > GROUPING_TOLERANCE) {\n return yDiff;\n }\n }\n\n // Apply horizontal sorting (if specified and y-positions are similar or not sorting vertically)\n if (horizontalSort !== SORT_HORIZONTAL_NONE) {\n return horizontalSort === SORT_HORIZONTAL_LTR\n ? centerA.x - centerB.x\n : centerB.x - centerA.x;\n }\n\n return 0;\n });\n\n return sorted;\n}\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport chalk from 'chalk';\nimport {\n DEFAULT_BASE_SERVER_URL,\n DEFAULT_CREATE_FILE_LIST_FOR_SERVING,\n DEFAULT_CREATE_FILE_PER_IMAGE,\n DEFAULT_FILE_LIST_NAME,\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_LABEL_NAME,\n DEFAULT_LABEL_STUDIO_FULL_JSON,\n DEFAULT_LABEL_STUDIO_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n type HorizontalSortOrder,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n type ShapeNormalizeOption,\n type VerticalSortOrder,\n} from '@/constants';\nimport type { LocalContext } from '@/context';\nimport { ppocrToLabelStudio } from '@/lib/ppocr-label';\nimport { type PPOCRLabel, PPOCRLabelSchema } from '@/lib/schema';\nimport { sortBoundingBoxes } from '@/lib/sort';\n\ninterface CommandFlags {\n outDir?: string;\n defaultLabelName?: string;\n toFullJson?: boolean;\n createFilePerImage?: boolean;\n createFileListForServing?: boolean;\n fileListName?: string;\n baseServerUrl?: string;\n sortVertical?: string;\n sortHorizontal?: string;\n normalizeShape?: string;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nexport async function convertToLabelStudio(\n this: LocalContext,\n flags: CommandFlags,\n ...inputDirs: string[]\n): Promise<void> {\n const {\n outDir = OUTPUT_BASE_DIR,\n defaultLabelName = DEFAULT_LABEL_NAME,\n toFullJson = DEFAULT_LABEL_STUDIO_FULL_JSON,\n createFilePerImage = DEFAULT_CREATE_FILE_PER_IMAGE,\n createFileListForServing = DEFAULT_CREATE_FILE_LIST_FOR_SERVING,\n fileListName = DEFAULT_FILE_LIST_NAME,\n baseServerUrl = DEFAULT_BASE_SERVER_URL,\n sortVertical = DEFAULT_SORT_VERTICAL,\n sortHorizontal = DEFAULT_SORT_HORIZONTAL,\n normalizeShape = DEFAULT_SHAPE_NORMALIZE,\n widthIncrement = DEFAULT_WIDTH_INCREMENT,\n heightIncrement = DEFAULT_HEIGHT_INCREMENT,\n precision = DEFAULT_LABEL_STUDIO_PRECISION,\n } = flags;\n\n // NOTE: Ensure baseServerUrl ends with a single slash, but keeps empty string\n // as is\n const newBaseServerUrl =\n baseServerUrl.replace(/\\/+$/, '') + (baseServerUrl === '' ? '' : '/');\n\n // Create output directory if it doesn't exist\n await mkdir(outDir, { recursive: true });\n\n for (const inputDir of inputDirs) {\n console.log(chalk.blue(`Processing input directory: ${inputDir}`));\n\n const files = await readdir(inputDir);\n\n for (const file of files) {\n if (!file.endsWith('.txt')) {\n continue;\n }\n\n const filePath = join(inputDir, file);\n console.log(chalk.gray(`Processing file: ${file}`));\n\n try {\n const fileData = await readFile(filePath, 'utf-8');\n const lines = fileData.trim().split('\\n');\n\n // Parse PPOCRLabelV2 format: <filename>\\t<json_array_of_annotations>\n // Group by filename since each line represents one image file with its annotations\n const imageDataMap = new Map<string, PPOCRLabel>();\n\n for (const line of lines) {\n const parts = line.split('\\t');\n\n if (parts.length !== 2) {\n throw new Error(`Invalid PPOCRLabelV2 format in line: ${line}`);\n }\n const [imagePath, annotationsStr] = parts;\n const annotations = JSON.parse(annotationsStr!);\n\n // Each annotation already has the structure: {transcription, points, dt_score}\n // Validate each annotation\n PPOCRLabelSchema.parse(annotations);\n\n imageDataMap.set(imagePath!, annotations);\n }\n\n // Convert each image's annotations to Label Studio format\n const allLabelStudioData = [];\n const fileList: string[] = [];\n let taskId = 1;\n\n for (const [imagePath, ppocrData] of imageDataMap.entries()) {\n // Sort annotations if requested\n const sortedPpocrData = sortBoundingBoxes(\n ppocrData,\n sortVertical as VerticalSortOrder,\n sortHorizontal as HorizontalSortOrder,\n );\n\n // Update imagePath to use baseServerUrl if createFileListForServing is enabled\n const finalImagePath = createFileListForServing\n ? encodeURI(`${newBaseServerUrl}${imagePath}`)\n : imagePath;\n\n const labelStudioData = await ppocrToLabelStudio(sortedPpocrData, {\n toFullJson,\n imagePath,\n baseServerUrl: newBaseServerUrl,\n inputDir,\n taskId,\n labelName: defaultLabelName,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n if (toFullJson) {\n allLabelStudioData.push(labelStudioData[0]);\n } else {\n allLabelStudioData.push(...labelStudioData);\n }\n\n // Create individual file per image if requested\n if (createFilePerImage) {\n const imageBaseName = imagePath\n .replace(/\\//g, '_')\n .replace(/\\.[^.]+$/, '');\n const individualOutputPath = join(\n outDir,\n `${imageBaseName}_${toFullJson ? 'full' : 'min'}.json`,\n );\n await writeFile(\n individualOutputPath,\n JSON.stringify(\n toFullJson ? labelStudioData[0] : labelStudioData,\n null,\n 2,\n ),\n 'utf-8',\n );\n console.log(\n chalk.gray(\n ` ✓ Created individual file: ${individualOutputPath}`,\n ),\n );\n }\n\n // Add to file list for serving\n if (createFileListForServing) {\n fileList.push(finalImagePath);\n }\n\n taskId++;\n }\n\n // Write combined output file\n const baseName = file.replace('.txt', '');\n const outputPath = join(\n outDir,\n `${baseName}_${toFullJson ? 'full' : 'min'}.json`,\n );\n await writeFile(\n outputPath,\n JSON.stringify(allLabelStudioData, null, 2),\n 'utf-8',\n );\n\n console.log(chalk.green(`✓ Converted ${file} -> ${outputPath}`));\n\n // Create file list for serving if requested\n if (createFileListForServing && fileList.length > 0) {\n const fileListPath = join(outDir, fileListName);\n await writeFile(fileListPath, fileList.join('\\n'), 'utf-8');\n console.log(\n chalk.green(\n `✓ Created file list: ${fileListPath} (${fileList.length} files)`,\n ),\n );\n }\n } catch (error) {\n console.error(\n chalk.red(`✗ Failed to process ${file}:`),\n error instanceof Error ? error.message : error,\n );\n }\n }\n }\n\n console.log(chalk.green('\\n✓ Conversion completed!'));\n}\n","import * as turf from '@turf/turf';\nimport { type ShapeNormalizeOption } from '@/constants';\nimport { type Point, roundPoints, transformPoints } from '@/lib/geometry';\nimport {\n type FullOCRLabelStudio,\n type MinOCRLabelStudio,\n type PPOCRLabel,\n} from '@/lib/schema';\n\nexport interface ConversionOptions {\n baseImageDir?: string;\n normalizeShape?: ShapeNormalizeOption;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nexport const labelStudioToPPOCR = async (\n data: FullOCRLabelStudio,\n options?: ConversionOptions,\n): Promise<Map<string, PPOCRLabel>> => {\n const {\n baseImageDir,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = 0,\n } = options || {};\n const resultMap = new Map<string, PPOCRLabel>();\n\n for (const task of data) {\n // Extract image path from data.ocr (full path with URL) or file_upload (just filename)\n let imagePath = task.file_upload || '';\n if (task.data.ocr) {\n // Extract path from URL: http://localhost:8081/ch/image.jpg -> ch/image.jpg\n const urlPath = task.data.ocr.replace(/^https?:\\/\\/[^/]+\\//, '');\n imagePath = decodeURIComponent(urlPath);\n }\n\n // Apply baseImageDir if provided\n if (baseImageDir) {\n imagePath = `${baseImageDir}/${task.file_upload || imagePath.split('/').pop() || imagePath}`;\n }\n\n const imageAnnotations: PPOCRLabel = [];\n\n // Process each annotation in the task\n for (const annotation of task.annotations) {\n // Group result items by their ID to avoid duplicates\n // (polygon, labels, and textarea share the same ID)\n const groupedById = new Map<string, typeof annotation.result>();\n\n for (const resultItem of annotation.result) {\n const { id } = resultItem;\n if (!groupedById.has(id)) {\n groupedById.set(id, []);\n }\n groupedById.get(id)!.push(resultItem);\n }\n\n // Process each group of result items (with same ID)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for (const [_, resultItems] of groupedById) {\n let points: number[][] | undefined;\n let transcription = '';\n\n // Process all result items in this group to extract points and transcription\n for (const resultItem of resultItems) {\n // Extract points from different value types\n if ('points' in resultItem.value && resultItem.value.points) {\n // Polygon/polyline with percentage points - convert to absolute\n const { points: valuePoints } = resultItem.value;\n const { original_width, original_height } = resultItem;\n\n // Convert percentage coordinates to absolute pixels\n points = valuePoints.map(([x, y]) => [\n ((x ?? 0) * original_width) / 100,\n ((y ?? 0) * original_height) / 100,\n ]);\n } else if (\n 'x' in resultItem.value &&\n 'y' in resultItem.value &&\n 'width' in resultItem.value &&\n 'height' in resultItem.value\n ) {\n // Rectangle - convert to 4 corner points\n const { x, y, width, height } = resultItem.value;\n const { original_width, original_height } = resultItem;\n\n // Convert normalized values to absolute coordinates\n const absX = (x * original_width) / 100;\n const absY = (y * original_height) / 100;\n const absWidth = (width * original_width) / 100;\n const absHeight = (height * original_height) / 100;\n\n points = [\n [absX, absY],\n [absX + absWidth, absY],\n [absX + absWidth, absY + absHeight],\n [absX, absY + absHeight],\n ];\n }\n\n // Extract transcription from text field\n if (\n 'text' in resultItem.value &&\n Array.isArray(resultItem.value.text)\n ) {\n transcription = resultItem.value.text[0] || '';\n }\n }\n\n // If we have points, create a PPOCRLabel entry\n if (points && points.length > 0) {\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Round points to specified precision\n points = roundPoints(points as Point[], precision);\n\n // Calculate dt_score based on polygon area\n let dt_score = 1.0;\n try {\n const firstPoint = points[0];\n if (firstPoint) {\n const polygon = turf.polygon([points.concat([firstPoint])]);\n const area = turf.area(polygon);\n dt_score = Math.min(1.0, Math.max(0.5, area / 10000));\n }\n } catch {\n dt_score = 0.8;\n }\n\n imageAnnotations.push({\n transcription,\n points,\n dt_score,\n });\n }\n }\n }\n\n if (imageAnnotations.length > 0) {\n resultMap.set(imagePath, imageAnnotations);\n }\n }\n\n return resultMap;\n};\n\nexport const minLabelStudioToPPOCR = async (\n data: MinOCRLabelStudio,\n options?: ConversionOptions,\n): Promise<Map<string, PPOCRLabel>> => {\n const {\n baseImageDir,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = 0,\n } = options || {};\n const resultMap = new Map<string, PPOCRLabel>();\n\n for (const item of data) {\n // Extract image path from ocr URL\n let imagePath = item.ocr || '';\n if (imagePath) {\n // Extract path from URL: http://localhost:8081/ch/image.jpg -> ch/image.jpg\n imagePath = decodeURIComponent(\n imagePath.replace(/^https?:\\/\\/[^/]+\\//, ''),\n );\n }\n\n // Apply baseImageDir if provided\n if (baseImageDir) {\n imagePath = `${baseImageDir}/${imagePath.split('/').pop() || imagePath}`;\n }\n\n // Process each bbox/poly with its corresponding transcription\n const numAnnotations = Math.max(\n item.poly?.length || 0,\n item.bbox?.length || 0,\n item.transcription?.length || 0,\n );\n\n for (let i = 0; i < numAnnotations; i++) {\n let points: number[][] | undefined;\n\n // Use poly if available, otherwise convert from bbox\n if (item.poly && item.poly.length > i && item.poly[i]) {\n const poly = item.poly[i];\n if (poly) {\n const { points: polyPoints } = poly;\n points = polyPoints;\n }\n } else if (item.bbox && item.bbox.length > i && item.bbox[i]) {\n const bbox = item.bbox[i];\n if (bbox) {\n const { x, y, width, height } = bbox;\n\n // Convert bbox to 4 corner points\n points = [\n [x, y],\n [x + width, y],\n [x + width, y + height],\n [x, y + height],\n ];\n }\n }\n\n // Skip if no geometry data for this annotation\n if (!points) {\n continue;\n }\n\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Round points to specified precision\n points = roundPoints(points as Point[], precision);\n\n // Get transcription text for this annotation\n const transcription =\n item.transcription && item.transcription.length > i\n ? item.transcription[i]\n : '';\n\n // Calculate dt_score based on polygon area\n let dt_score = 1.0;\n try {\n const firstPoint = points[0];\n if (firstPoint) {\n const polygon = turf.polygon([points.concat([firstPoint])]);\n const area = turf.area(polygon);\n dt_score = Math.min(1.0, Math.max(0.5, area / 10000));\n }\n } catch {\n dt_score = 0.8;\n }\n\n const annotation = {\n transcription: transcription ?? '',\n points,\n dt_score,\n };\n\n // Group by image path\n if (!resultMap.has(imagePath)) {\n resultMap.set(imagePath, []);\n }\n resultMap.get(imagePath)!.push(annotation);\n }\n }\n\n return resultMap;\n};\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport chalk from 'chalk';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_PPOCR_FILE_NAME,\n DEFAULT_PPOCR_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n type HorizontalSortOrder,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n type ShapeNormalizeOption,\n type VerticalSortOrder,\n} from '@/constants';\nimport type { LocalContext } from '@/context';\nimport { labelStudioToPPOCR, minLabelStudioToPPOCR } from '@/lib/label-studio';\nimport {\n type FullOCRLabelStudio,\n FullOCRLabelStudioSchema,\n type MinOCRLabelStudio,\n MinOCRLabelStudioSchema,\n PPOCRLabelSchema,\n} from '@/lib/schema';\nimport { sortBoundingBoxes } from '@/lib/sort';\n\ninterface CommandFlags {\n outDir?: string;\n fileName?: string;\n baseImageDir?: string;\n sortVertical?: string;\n sortHorizontal?: string;\n normalizeShape?: string;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nconst isLabelStudioFullJSON = (\n data: unknown,\n): {\n isFull: boolean;\n data: FullOCRLabelStudio | MinOCRLabelStudio;\n} => {\n // Try parsing as full format array\n const parsedFull = FullOCRLabelStudioSchema.safeParse(data);\n if (parsedFull.success) {\n return { isFull: true, data: parsedFull.data };\n }\n\n // Try parsing as single full format object (wrap in array)\n if (!Array.isArray(data) && typeof data === 'object' && data !== null) {\n const parsedSingleFull = FullOCRLabelStudioSchema.safeParse([data]);\n if (parsedSingleFull.success) {\n return { isFull: true, data: parsedSingleFull.data };\n }\n }\n\n // Try parsing as min format\n const parsedMin = MinOCRLabelStudioSchema.safeParse(data);\n if (parsedMin.success) {\n return { isFull: false, data: parsedMin.data };\n }\n\n throw new Error('Input data is not valid Label Studio JSON format.');\n};\n\nexport async function convertToPPOCR(\n this: LocalContext,\n flags: CommandFlags,\n ...inputDirs: string[]\n): Promise<void> {\n const {\n outDir = `${OUTPUT_BASE_DIR}`,\n fileName = DEFAULT_PPOCR_FILE_NAME,\n baseImageDir,\n sortVertical = DEFAULT_SORT_VERTICAL,\n sortHorizontal = DEFAULT_SORT_HORIZONTAL,\n normalizeShape = DEFAULT_SHAPE_NORMALIZE,\n widthIncrement = DEFAULT_WIDTH_INCREMENT,\n heightIncrement = DEFAULT_HEIGHT_INCREMENT,\n precision = DEFAULT_PPOCR_PRECISION,\n } = flags;\n\n // Create output directory if it doesn't exist\n await mkdir(outDir, { recursive: true });\n\n for (const inputDir of inputDirs) {\n console.log(chalk.blue(`Processing input directory: ${inputDir}`));\n\n const files = await readdir(inputDir);\n\n for (const file of files) {\n if (!file.endsWith('.json')) {\n continue;\n }\n\n const filePath = join(inputDir, file);\n console.log(chalk.gray(`Processing file: ${file}`));\n\n try {\n const fileData = await readFile(filePath, 'utf-8');\n const labelStudioData = JSON.parse(fileData);\n\n const { data, isFull } = isLabelStudioFullJSON(labelStudioData);\n\n // Convert based on format type\n const ppocrDataMap = isFull\n ? await labelStudioToPPOCR(data as FullOCRLabelStudio, {\n baseImageDir,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n })\n : await minLabelStudioToPPOCR(data as MinOCRLabelStudio, {\n baseImageDir,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n // Format output as PPOCR label format: image_path<tab>[{JSON array}]\n const outputLines: string[] = [];\n for (const [imagePath, annotations] of ppocrDataMap.entries()) {\n // Sort annotations if requested\n const sortedAnnotations = sortBoundingBoxes(\n annotations,\n sortVertical as VerticalSortOrder,\n sortHorizontal as HorizontalSortOrder,\n );\n\n // Validate each annotation group\n PPOCRLabelSchema.parse(sortedAnnotations);\n\n // Format as: image_path<tab>[{annotations}]\n const jsonArray = JSON.stringify(sortedAnnotations);\n outputLines.push(`${imagePath}\\t${jsonArray}`);\n }\n\n // Write to output file\n const baseName = file.replace('.json', '');\n const outputPath = join(outDir, `${baseName}_${fileName}`);\n await writeFile(outputPath, outputLines.join('\\n'), 'utf-8');\n\n console.log(chalk.green(`✓ Converted ${file} -> ${outputPath}`));\n } catch (error) {\n console.error(\n chalk.red(`✗ Failed to process ${file}:`),\n error instanceof Error ? error.message : error,\n );\n }\n }\n }\n\n console.log(chalk.green('\\n✓ Conversion completed!'));\n}\n","#!/usr/bin/env node\nimport { proposeCompletions } from '@stricli/core';\nimport { app } from '@/app';\nimport { buildContext } from '@/context';\n\n(async () => {\n const inputs = process.argv.slice(3);\n if (process.env.COMP_LINE?.endsWith(' ')) {\n inputs.push('');\n }\n await proposeCompletions(app, inputs, buildContext(process));\n try {\n for (const { completion } of await proposeCompletions(\n app,\n inputs,\n buildContext(process),\n )) {\n process.stdout.write(`${completion}\\n`);\n }\n } catch {\n // ignore\n }\n})();\n","import {\n buildInstallCommand,\n buildUninstallCommand,\n} from '@stricli/auto-complete';\nimport { buildApplication, buildRouteMap } from '@stricli/core';\nimport { description, version } from '@/../package.json';\nimport { toLabelStudioCommand } from '@/commands/toLabelStudio/command';\nimport { toPPOCRCommand } from '@/commands/toPPOCR/commands';\n\nconst routes = buildRouteMap({\n routes: {\n toLabelStudio: toLabelStudioCommand,\n toPPOCR: toPPOCRCommand,\n install: buildInstallCommand('label-studio-converter', {\n bash: '__label-studio-converter_bash_complete',\n }),\n uninstall: buildUninstallCommand('label-studio-converter', { bash: true }),\n },\n docs: {\n brief: description,\n hideRoute: {\n install: true,\n uninstall: true,\n },\n },\n});\n\nexport const app = buildApplication(routes, {\n name: 'label-studio-converter',\n versionInfo: {\n currentVersion: version,\n },\n});\n","{\n \"name\": \"label-studio-converter\",\n \"version\": \"1.1.0\",\n \"author\": \"DuckyMomo20012\",\n \"description\": \"Convert between Label Studio OCR format and PPOCRLabelv2 format\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/DuckyMomo20012/label-studio-converter.git\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"liturgical\"\n ],\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"bin\": {\n \"label-studio-converter\": \"./dist/cli.js\",\n \"__label-studio-converter_bash_complete\": \"./dist/bash-complete.js\"\n },\n \"scripts\": {\n \"prepare\": \"husky\",\n \"lint\": \"tsc\",\n \"build\": \"tsc && tsup\",\n \"test\": \"vitest\",\n \"test:ui\": \"vitest --ui\",\n \"test:run\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\",\n \"check-exports\": \"attw --pack . --ignore-rules=cjs-resolves-to-esm\",\n \"prepublish\": \"pnpm run build && pnpm run check-exports && pnpm run lint\",\n \"postinstall\": \"npx @stricli/auto-complete@latest install label-studio-converter --bash __label-studio-converter_bash_complete\"\n },\n \"dependencies\": {\n \"@stricli/auto-complete\": \"1.2.4\",\n \"@stricli/core\": \"1.2.4\",\n \"@turf/turf\": \"7.3.1\",\n \"chalk\": \"5.6.2\",\n \"es-toolkit\": \"1.43.0\",\n \"image-size\": \"2.0.2\",\n \"zod\": \"4.2.1\"\n },\n \"devDependencies\": {\n \"@arethetypeswrong/cli\": \"0.18.2\",\n \"@babel/core\": \"7.28.5\",\n \"@commitlint/cli\": \"20.2.0\",\n \"@commitlint/config-conventional\": \"20.2.0\",\n \"@types/node\": \"24.10.4\",\n \"@typescript-eslint/eslint-plugin\": \"8.51.0\",\n \"@typescript-eslint/parser\": \"8.51.0\",\n \"@vitest/eslint-plugin\": \"1.6.4\",\n \"@vitest/ui\": \"4.0.16\",\n \"eslint\": \"9.39.2\",\n \"eslint-config-prettier\": \"10.1.8\",\n \"eslint-import-resolver-typescript\": \"4.4.4\",\n \"eslint-plugin-import\": \"2.32.0\",\n \"eslint-plugin-prettier\": \"5.5.4\",\n \"globals\": \"16.5.0\",\n \"husky\": \"9.1.7\",\n \"lint-staged\": \"16.2.7\",\n \"prettier\": \"3.7.4\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"5.9.3\",\n \"vitest\": \"4.0.16\"\n }\n}\n","import { buildCommand } from '@stricli/core';\nimport {\n DEFAULT_BASE_SERVER_URL,\n DEFAULT_CREATE_FILE_LIST_FOR_SERVING,\n DEFAULT_CREATE_FILE_PER_IMAGE,\n DEFAULT_FILE_LIST_NAME,\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_LABEL_NAME,\n DEFAULT_LABEL_STUDIO_FULL_JSON,\n DEFAULT_LABEL_STUDIO_PRECISION,\n DEFAULT_WIDTH_INCREMENT,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n SHAPE_NORMALIZE_RECTANGLE,\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_BOTTOM_TOP,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\n\nexport const toLabelStudioCommand = buildCommand({\n loader: async () => {\n const { convertToLabelStudio } = await import('./impl');\n return convertToLabelStudio;\n },\n parameters: {\n positional: {\n kind: 'array',\n parameter: {\n brief: 'Input directories containing PPOCRLabel files',\n parse: String,\n },\n minimum: 1,\n },\n flags: {\n outDir: {\n kind: 'parsed',\n brief: `Output directory. Default to \"${OUTPUT_BASE_DIR}\"`,\n parse: String,\n optional: true,\n },\n defaultLabelName: {\n kind: 'parsed',\n brief: `Default label name for text annotations. Default to \"${DEFAULT_LABEL_NAME}\"`,\n parse: String,\n optional: true,\n },\n toFullJson: {\n kind: 'boolean',\n brief: `Convert to Full OCR Label Studio format. Default to \"${DEFAULT_LABEL_STUDIO_FULL_JSON}\"`,\n optional: true,\n },\n createFilePerImage: {\n kind: 'boolean',\n brief: `Create a separate Label Studio JSON file for each image. Default to \"${DEFAULT_CREATE_FILE_PER_IMAGE}\"`,\n optional: true,\n },\n createFileListForServing: {\n kind: 'boolean',\n brief: `Create a file list for serving in Label Studio. Default to \"${DEFAULT_CREATE_FILE_LIST_FOR_SERVING}\"`,\n optional: true,\n },\n fileListName: {\n kind: 'parsed',\n brief: `Name of the file list for serving. Default to \"${DEFAULT_FILE_LIST_NAME}\"`,\n parse: String,\n optional: true,\n },\n baseServerUrl: {\n kind: 'parsed',\n brief: `Base server URL for constructing image URLs in the file list. Default to \"${DEFAULT_BASE_SERVER_URL}\"`,\n parse: String,\n optional: true,\n },\n sortVertical: {\n kind: 'parsed',\n brief: `Sort bounding boxes vertically. Options: \"${SORT_VERTICAL_NONE}\" (default), \"${SORT_VERTICAL_TOP_BOTTOM}\", \"${SORT_VERTICAL_BOTTOM_TOP}\"`,\n parse: String,\n optional: true,\n },\n sortHorizontal: {\n kind: 'parsed',\n brief: `Sort bounding boxes horizontally. Options: \"${SORT_HORIZONTAL_NONE}\" (default), \"${SORT_HORIZONTAL_LTR}\", \"${SORT_HORIZONTAL_RTL}\"`,\n parse: String,\n optional: true,\n },\n normalizeShape: {\n kind: 'parsed',\n brief: `Normalize diamond-like shapes to axis-aligned rectangles. Options: \"${SHAPE_NORMALIZE_NONE}\" (default), \"${SHAPE_NORMALIZE_RECTANGLE}\"`,\n parse: String,\n optional: true,\n },\n widthIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_WIDTH_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n heightIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_HEIGHT_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n precision: {\n kind: 'parsed',\n brief: `Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: ${DEFAULT_LABEL_STUDIO_PRECISION}`,\n parse: Number,\n optional: true,\n },\n },\n },\n docs: {\n brief: 'Convert PPOCRLabel files to Label Studio format',\n },\n});\n","import { buildCommand } from '@stricli/core';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_PPOCR_FILE_NAME,\n DEFAULT_PPOCR_PRECISION,\n DEFAULT_WIDTH_INCREMENT,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n SHAPE_NORMALIZE_RECTANGLE,\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_BOTTOM_TOP,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\n\nexport const toPPOCRCommand = buildCommand({\n loader: async () => {\n const { convertToPPOCR } = await import('./impl');\n return convertToPPOCR;\n },\n parameters: {\n positional: {\n kind: 'array',\n parameter: {\n brief: 'Input directories containing Label Studio files',\n parse: String,\n },\n minimum: 1,\n },\n flags: {\n outDir: {\n kind: 'parsed',\n brief: `Output directory. Default to \"${OUTPUT_BASE_DIR}\"`,\n parse: String,\n optional: true,\n },\n fileName: {\n kind: 'parsed',\n brief: `Output PPOCR file name. Default to \"${DEFAULT_PPOCR_FILE_NAME}\"`,\n parse: String,\n optional: true,\n },\n baseImageDir: {\n kind: 'parsed',\n brief:\n 'Base directory path to prepend to image filenames in output (e.g., \"ch\" or \"images/ch\")',\n parse: String,\n optional: true,\n },\n sortVertical: {\n kind: 'parsed',\n brief: `Sort bounding boxes vertically. Options: \"${SORT_VERTICAL_NONE}\" (default), \"${SORT_VERTICAL_TOP_BOTTOM}\", \"${SORT_VERTICAL_BOTTOM_TOP}\"`,\n parse: String,\n optional: true,\n },\n sortHorizontal: {\n kind: 'parsed',\n brief: `Sort bounding boxes horizontally. Options: \"${SORT_HORIZONTAL_NONE}\" (default), \"${SORT_HORIZONTAL_LTR}\", \"${SORT_HORIZONTAL_RTL}\"`,\n parse: String,\n optional: true,\n },\n normalizeShape: {\n kind: 'parsed',\n brief: `Normalize diamond-like shapes to axis-aligned rectangles. Options: \"${SHAPE_NORMALIZE_NONE}\" (default), \"${SHAPE_NORMALIZE_RECTANGLE}\"`,\n parse: String,\n optional: true,\n },\n widthIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_WIDTH_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n heightIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_HEIGHT_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n precision: {\n kind: 'parsed',\n brief: `Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: ${DEFAULT_PPOCR_PRECISION} (integers)`,\n parse: Number,\n optional: true,\n },\n },\n },\n docs: {\n brief: 'Convert Label Studio files to PPOCRLabel format',\n },\n});\n","import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { StricliAutoCompleteContext } from '@stricli/auto-complete';\nimport type { CommandContext } from '@stricli/core';\n\nexport interface LocalContext\n extends CommandContext, StricliAutoCompleteContext {\n readonly process: NodeJS.Process;\n // ...\n}\n\nexport function buildContext(process: NodeJS.Process): LocalContext {\n return {\n process,\n os,\n fs,\n path,\n };\n}\n"],"mappings":"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","names":["normalizeShape","sizeOf","z","normalizeShape","chalk","normalizeShape","polygon","area","impl_exports","normalizeShape","chalk","import_promises","import_path","import_chalk","init_impl","import_core","import_core","convertToLabelStudio","import_core","convertToPPOCR","import_node_fs","import_node_path","process","os","fs","path"]}
1
+ {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_jiti@2.4.2_postcss@8.5.6_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","../src/constants.ts","../src/lib/geometry.ts","../src/lib/sort.ts","../src/lib/enhance.ts","../src/lib/label-studio.ts","../src/lib/schema.ts","../src/commands/enhance-labelstudio/impl.ts","../src/commands/enhance-ppocr/impl.ts","../src/lib/ppocr-label.ts","../src/commands/toLabelStudio/impl.ts","../src/commands/toPPOCR/impl.ts","../src/bin/bash-complete.ts","../src/app.ts","../package.json","../src/commands/enhance-labelstudio/command.ts","../src/commands/enhance-ppocr/command.ts","../src/commands/toLabelStudio/command.ts","../src/commands/toPPOCR/commands.ts","../src/context.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","export const OUTPUT_BASE_DIR = './output';\n\nexport const DEFAULT_LABEL_NAME = 'Text';\nexport const DEFAULT_LABEL_STUDIO_FULL_JSON = true;\nexport const DEFAULT_CREATE_FILE_PER_IMAGE = false;\nexport const DEFAULT_CREATE_FILE_LIST_FOR_SERVING = true;\nexport const DEFAULT_FILE_LIST_NAME = 'files.txt';\nexport const DEFAULT_BASE_SERVER_URL = 'http://localhost:8081';\n\nexport const DEFAULT_PPOCR_FILE_NAME = 'Label.txt';\n\n// Vertical sorting options\nexport const SORT_VERTICAL_NONE = 'none';\nexport const SORT_VERTICAL_TOP_BOTTOM = 'top-bottom';\nexport const SORT_VERTICAL_BOTTOM_TOP = 'bottom-top';\nexport const DEFAULT_SORT_VERTICAL = SORT_VERTICAL_NONE;\n\n// Horizontal sorting options\nexport const SORT_HORIZONTAL_NONE = 'none';\nexport const SORT_HORIZONTAL_LTR = 'ltr';\nexport const SORT_HORIZONTAL_RTL = 'rtl';\nexport const DEFAULT_SORT_HORIZONTAL = SORT_HORIZONTAL_NONE;\n\nexport type VerticalSortOrder =\n | typeof SORT_VERTICAL_NONE\n | typeof SORT_VERTICAL_TOP_BOTTOM\n | typeof SORT_VERTICAL_BOTTOM_TOP;\n\nexport type HorizontalSortOrder =\n | typeof SORT_HORIZONTAL_NONE\n | typeof SORT_HORIZONTAL_LTR\n | typeof SORT_HORIZONTAL_RTL;\n\n// Shape normalization options\nexport const SHAPE_NORMALIZE_NONE = 'none';\nexport const SHAPE_NORMALIZE_RECTANGLE = 'rectangle';\nexport const DEFAULT_SHAPE_NORMALIZE = SHAPE_NORMALIZE_NONE;\n\nexport type ShapeNormalizeOption =\n | typeof SHAPE_NORMALIZE_NONE\n | typeof SHAPE_NORMALIZE_RECTANGLE;\n\n// Bounding box resize options\nexport const DEFAULT_WIDTH_INCREMENT = 0;\nexport const DEFAULT_HEIGHT_INCREMENT = 0;\n\n// Number precision options\n// For Label Studio: keep full precision (no rounding) by default\nexport const DEFAULT_LABEL_STUDIO_PRECISION = -1; // -1 means no rounding\n// For PPOCR: round to integers\nexport const DEFAULT_PPOCR_PRECISION = 0;\n","/**\n * Geometry utility functions for shape normalization and bounding box operations\n */\n\nimport type { ShapeNormalizeOption } from '@/constants';\n\nexport type Point = [number, number];\n\n/**\n * Round a number to a specified precision\n * @param value - The number to round\n * @param precision - Number of decimal places (-1 means no rounding)\n * @returns Rounded number\n */\nexport function roundToPrecision(value: number, precision: number): number {\n if (precision < 0) {\n return value; // No rounding\n }\n const multiplier = Math.pow(10, precision);\n return Math.round(value * multiplier) / multiplier;\n}\n\n/**\n * Round points array to a specified precision\n * @param points - Array of points to round\n * @param precision - Number of decimal places (-1 means no rounding)\n * @returns Rounded points\n */\nexport function roundPoints(points: Point[], precision: number): Point[] {\n if (precision < 0) {\n return points; // No rounding\n }\n return points.map(\n ([x, y]) =>\n [roundToPrecision(x, precision), roundToPrecision(y, precision)] as Point,\n );\n}\n\n/**\n * Calculate the center point of a polygon\n */\nexport function calculateCenter(points: Point[]): Point {\n const sum = points.reduce((acc, [x, y]) => [acc[0] + x, acc[1] + y], [\n 0, 0,\n ] as Point);\n return [sum[0] / points.length, sum[1] / points.length];\n}\n\n/**\n * Calculate the minimum bounding rectangle of a polygon\n */\nexport function getMinimumBoundingRect(points: Point[]): {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n width: number;\n height: number;\n} {\n const minX = Math.min(...points.map(([x]) => x));\n const maxX = Math.max(...points.map(([x]) => x));\n const minY = Math.min(...points.map(([, y]) => y));\n const maxY = Math.max(...points.map(([, y]) => y));\n\n return {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\n/**\n * Convert diamond-like shapes to axis-aligned rectangles\n * @param points - Array of points representing the shape\n * @returns Normalized rectangle points\n */\nexport function normalizeShape(points: Point[]): Point[] {\n if (points.length < 3) {\n return points;\n }\n\n // Convert to axis-aligned bounding rectangle\n const { minX, minY, maxX, maxY } = getMinimumBoundingRect(points);\n\n return [\n [minX, minY],\n [maxX, minY],\n [maxX, maxY],\n [minX, maxY],\n ];\n}\n\n/**\n * Resize bounding box by a certain amount while keeping it centered\n * @param points - Array of points representing the bounding box\n * @param widthIncrement - Amount to increase width (can be negative to decrease)\n * @param heightIncrement - Amount to increase height (can be negative to decrease)\n * @returns Resized points\n */\nexport function resizeBoundingBox(\n points: Point[],\n widthIncrement: number,\n heightIncrement: number,\n): Point[] {\n if (points.length === 0) {\n return points;\n }\n\n // Calculate center\n const center = calculateCenter(points);\n\n // Calculate current bounding box\n const bbox = getMinimumBoundingRect(points);\n\n // Calculate new dimensions\n const newWidth = Math.max(1, bbox.width + widthIncrement);\n const newHeight = Math.max(1, bbox.height + heightIncrement);\n\n // Calculate scale factors\n const scaleX = newWidth / bbox.width;\n const scaleY = newHeight / bbox.height;\n\n // Transform each point: translate to origin, scale, translate back\n return points.map(([x, y]) => {\n const relX = x - center[0];\n const relY = y - center[1];\n\n return [center[0] + relX * scaleX, center[1] + relY * scaleY] as Point;\n });\n}\n\n/**\n * Apply geometry transformations to points\n * @param points - Original points\n * @param options - Transformation options\n * @returns Transformed points\n */\nexport function transformPoints(\n points: Point[],\n options: {\n normalizeShape?: ShapeNormalizeOption;\n widthIncrement?: number;\n heightIncrement?: number;\n },\n): Point[] {\n let result = points;\n\n // Apply shape normalization first\n if (options.normalizeShape && options.normalizeShape === 'rectangle') {\n result = normalizeShape(result);\n }\n\n // Then apply resizing\n if (\n options.widthIncrement !== undefined ||\n options.heightIncrement !== undefined\n ) {\n result = resizeBoundingBox(\n result,\n options.widthIncrement ?? 0,\n options.heightIncrement ?? 0,\n );\n }\n\n return result;\n}\n","import type { HorizontalSortOrder, VerticalSortOrder } from '@/constants';\nimport {\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\nimport type { PPOCRLabel } from '@/lib/schema';\n\n// Tolerance for grouping bounding boxes into columns/rows\n// Boxes within this pixel distance are considered in the same column/row\nconst GROUPING_TOLERANCE = 50;\n\n/**\n * Calculate the bounding box center point from polygon points\n */\nfunction getBoundingBoxCenter(points: number[][]): {\n x: number;\n y: number;\n width: number;\n height: number;\n} {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const [x, y] of points) {\n if (x !== undefined && y !== undefined) {\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n\n return {\n x: (minX + maxX) / 2,\n y: (minY + maxY) / 2,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\n/**\n * Sort PPOCRLabel array based on bounding box positions\n * Supports both traditional reading order (top-bottom, then left-right)\n * and SinoNom reading order (right-left columns, top-bottom within each column)\n * @param annotations - Array of PPOCR annotations to sort\n * @param verticalSort - Vertical sort order: 'none', 'top-bottom', 'bottom-top'\n * @param horizontalSort - Horizontal sort order: 'none', 'ltr', 'rtl'\n * @returns Sorted array (or original array if both sorts are 'none')\n */\nexport function sortBoundingBoxes(\n annotations: PPOCRLabel,\n verticalSort: VerticalSortOrder,\n horizontalSort: HorizontalSortOrder,\n): PPOCRLabel {\n if (\n verticalSort === SORT_VERTICAL_NONE &&\n horizontalSort === SORT_HORIZONTAL_NONE\n ) {\n return annotations;\n }\n\n // Create a copy to avoid mutating the original array\n const sorted = [...annotations];\n\n // Detect if this is vertical text (SinoNom style) or horizontal text (Arabic/Hebrew style)\n // by checking if most boxes are taller than they are wide\n const isVerticalText =\n sorted.length > 0 &&\n (() => {\n const verticalCount = sorted.filter((ann) => {\n const center = getBoundingBoxCenter(ann.points);\n return center.height > center.width * 1.5; // At least 1.5x taller than wide\n }).length;\n return verticalCount > sorted.length / 2; // More than half are vertical\n })();\n\n // For RTL with vertical sorting and vertical text (SinoNom):\n // Group into columns first, then sort within each column\n if (\n horizontalSort === SORT_HORIZONTAL_RTL &&\n verticalSort !== SORT_VERTICAL_NONE &&\n isVerticalText\n ) {\n // Calculate centers for all annotations\n const annotationsWithCenters = sorted.map((ann) => ({\n annotation: ann,\n center: getBoundingBoxCenter(ann.points),\n }));\n\n // Group annotations into columns based on x-position\n const columns: (typeof annotationsWithCenters)[] = [];\n\n for (const item of annotationsWithCenters) {\n let addedToColumn = false;\n\n for (const column of columns) {\n // Check if this annotation belongs to an existing column\n const avgX =\n column.reduce((sum, c) => sum + c.center.x, 0) / column.length;\n if (Math.abs(item.center.x - avgX) < GROUPING_TOLERANCE) {\n column.push(item);\n addedToColumn = true;\n break;\n }\n }\n\n if (!addedToColumn) {\n columns.push([item]);\n }\n }\n\n // Sort columns right-to-left\n columns.sort((colA, colB) => {\n const avgXA = colA.reduce((sum, c) => sum + c.center.x, 0) / colA.length;\n const avgXB = colB.reduce((sum, c) => sum + c.center.x, 0) / colB.length;\n return avgXB - avgXA; // Right to left\n });\n\n // Sort within each column top-to-bottom or bottom-to-top\n for (const column of columns) {\n column.sort((a, b) => {\n return verticalSort === SORT_VERTICAL_TOP_BOTTOM\n ? a.center.y - b.center.y\n : b.center.y - a.center.y;\n });\n }\n\n // Flatten back to a single array\n return columns.flat().map((item) => item.annotation);\n }\n\n // For all other cases, use simple sort with priority\n sorted.sort((a, b) => {\n const centerA = getBoundingBoxCenter(a.points);\n const centerB = getBoundingBoxCenter(b.points);\n\n // Apply vertical sorting first (if specified)\n if (verticalSort !== SORT_VERTICAL_NONE) {\n const yDiff =\n verticalSort === SORT_VERTICAL_TOP_BOTTOM\n ? centerA.y - centerB.y\n : centerB.y - centerA.y;\n\n // If there's a significant difference in y-position, return that\n if (Math.abs(yDiff) > GROUPING_TOLERANCE) {\n return yDiff;\n }\n }\n\n // Apply horizontal sorting (if specified and y-positions are similar or not sorting vertically)\n if (horizontalSort !== SORT_HORIZONTAL_NONE) {\n return horizontalSort === SORT_HORIZONTAL_LTR\n ? centerA.x - centerB.x\n : centerB.x - centerA.x;\n }\n\n return 0;\n });\n\n return sorted;\n}\n","import type {\n HorizontalSortOrder,\n ShapeNormalizeOption,\n VerticalSortOrder,\n} from '@/constants';\nimport { type Point, roundPoints, transformPoints } from '@/lib/geometry';\nimport type { PPOCRLabel } from '@/lib/schema';\nimport { sortBoundingBoxes } from '@/lib/sort';\n\n/**\n * Common enhancement options shared across formats\n */\nexport interface EnhancementOptions {\n sortVertical?: VerticalSortOrder;\n sortHorizontal?: HorizontalSortOrder;\n normalizeShape?: ShapeNormalizeOption;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\n/**\n * Apply all enhancement transformations to PPOCRLabel data\n */\nexport function enhancePPOCRLabel(\n data: PPOCRLabel,\n options: EnhancementOptions,\n): PPOCRLabel {\n const {\n sortVertical,\n sortHorizontal,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = 0,\n } = options;\n\n // Apply sorting first\n let enhanced = data;\n if (sortVertical && sortHorizontal) {\n enhanced = sortBoundingBoxes(enhanced, sortVertical, sortHorizontal);\n }\n\n // Apply shape transformations\n if (normalizeShape || widthIncrement !== 0 || heightIncrement !== 0) {\n enhanced = enhanced.map((annotation) => {\n let points = transformPoints(annotation.points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Apply precision rounding\n points = roundPoints(points, precision);\n\n return {\n ...annotation,\n points,\n };\n });\n }\n\n return enhanced;\n}\n\n/**\n * Type guard to check if enhancement options are provided\n */\nexport function hasEnhancementOptions(options: EnhancementOptions): boolean {\n return !!(\n options.sortVertical ||\n options.sortHorizontal ||\n options.normalizeShape ||\n options.widthIncrement !== 0 ||\n options.heightIncrement !== 0\n );\n}\n","import * as turf from '@turf/turf';\nimport { type ShapeNormalizeOption } from '@/constants';\nimport { type EnhancementOptions, enhancePPOCRLabel } from '@/lib/enhance';\nimport { type Point, roundPoints, transformPoints } from '@/lib/geometry';\nimport {\n type FullOCRLabelStudio,\n type MinOCRLabelStudio,\n type PPOCRLabel,\n} from '@/lib/schema';\n\nexport interface ConversionOptions {\n baseImageDir?: string;\n normalizeShape?: ShapeNormalizeOption;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nexport const labelStudioToPPOCR = async (\n data: FullOCRLabelStudio,\n options?: ConversionOptions,\n): Promise<Map<string, PPOCRLabel>> => {\n const {\n baseImageDir,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = 0,\n } = options || {};\n const resultMap = new Map<string, PPOCRLabel>();\n\n for (const task of data) {\n // Extract image path from data.ocr (full path with URL) or file_upload (just filename)\n let imagePath = task.file_upload || '';\n if (task.data.ocr) {\n // Extract path from URL: http://localhost:8081/ch/image.jpg -> ch/image.jpg\n const urlPath = task.data.ocr.replace(/^https?:\\/\\/[^/]+\\//, '');\n imagePath = decodeURIComponent(urlPath);\n }\n\n // Apply baseImageDir if provided\n if (baseImageDir) {\n imagePath = `${baseImageDir}/${task.file_upload || imagePath.split('/').pop() || imagePath}`;\n }\n\n const imageAnnotations: PPOCRLabel = [];\n\n // Process each annotation in the task\n for (const annotation of task.annotations) {\n // Group result items by their ID to avoid duplicates\n // (polygon, labels, and textarea share the same ID)\n const groupedById = new Map<string, typeof annotation.result>();\n\n for (const resultItem of annotation.result) {\n const { id } = resultItem;\n if (!groupedById.has(id)) {\n groupedById.set(id, []);\n }\n groupedById.get(id)!.push(resultItem);\n }\n\n // Process each group of result items (with same ID)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for (const [_, resultItems] of groupedById) {\n let points: number[][] | undefined;\n let transcription = '';\n\n // Process all result items in this group to extract points and transcription\n for (const resultItem of resultItems) {\n // Extract points from different value types\n if ('points' in resultItem.value && resultItem.value.points) {\n // Polygon/polyline with percentage points - convert to absolute\n const { points: valuePoints } = resultItem.value;\n const { original_width, original_height } = resultItem;\n\n // Convert percentage coordinates to absolute pixels\n points = valuePoints.map(([x, y]) => [\n ((x ?? 0) * original_width) / 100,\n ((y ?? 0) * original_height) / 100,\n ]);\n } else if (\n 'x' in resultItem.value &&\n 'y' in resultItem.value &&\n 'width' in resultItem.value &&\n 'height' in resultItem.value\n ) {\n // Rectangle - convert to 4 corner points\n const { x, y, width, height } = resultItem.value;\n const { original_width, original_height } = resultItem;\n\n // Convert normalized values to absolute coordinates\n const absX = (x * original_width) / 100;\n const absY = (y * original_height) / 100;\n const absWidth = (width * original_width) / 100;\n const absHeight = (height * original_height) / 100;\n\n points = [\n [absX, absY],\n [absX + absWidth, absY],\n [absX + absWidth, absY + absHeight],\n [absX, absY + absHeight],\n ];\n }\n\n // Extract transcription from text field\n if (\n 'text' in resultItem.value &&\n Array.isArray(resultItem.value.text)\n ) {\n transcription = resultItem.value.text[0] || '';\n }\n }\n\n // If we have points, create a PPOCRLabel entry\n if (points && points.length > 0) {\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Round points to specified precision\n points = roundPoints(points as Point[], precision);\n\n // Calculate dt_score based on polygon area\n let dt_score = 1.0;\n try {\n const firstPoint = points[0];\n if (firstPoint) {\n const polygon = turf.polygon([points.concat([firstPoint])]);\n const area = turf.area(polygon);\n dt_score = Math.min(1.0, Math.max(0.5, area / 10000));\n }\n } catch {\n dt_score = 0.8;\n }\n\n imageAnnotations.push({\n transcription,\n points,\n dt_score,\n });\n }\n }\n }\n\n if (imageAnnotations.length > 0) {\n resultMap.set(imagePath, imageAnnotations);\n }\n }\n\n return resultMap;\n};\n\nexport const minLabelStudioToPPOCR = async (\n data: MinOCRLabelStudio,\n options?: ConversionOptions,\n): Promise<Map<string, PPOCRLabel>> => {\n const {\n baseImageDir,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = 0,\n } = options || {};\n const resultMap = new Map<string, PPOCRLabel>();\n\n for (const item of data) {\n // Extract image path from ocr URL\n let imagePath = item.ocr || '';\n if (imagePath) {\n // Extract path from URL: http://localhost:8081/ch/image.jpg -> ch/image.jpg\n imagePath = decodeURIComponent(\n imagePath.replace(/^https?:\\/\\/[^/]+\\//, ''),\n );\n }\n\n // Apply baseImageDir if provided\n if (baseImageDir) {\n imagePath = `${baseImageDir}/${imagePath.split('/').pop() || imagePath}`;\n }\n\n // Process each bbox/poly with its corresponding transcription\n const numAnnotations = Math.max(\n item.poly?.length || 0,\n item.bbox?.length || 0,\n item.transcription?.length || 0,\n );\n\n for (let i = 0; i < numAnnotations; i++) {\n let points: number[][] | undefined;\n\n // Use poly if available, otherwise convert from bbox\n if (item.poly && item.poly.length > i && item.poly[i]) {\n const poly = item.poly[i];\n if (poly) {\n const { points: polyPoints } = poly;\n points = polyPoints;\n }\n } else if (item.bbox && item.bbox.length > i && item.bbox[i]) {\n const bbox = item.bbox[i];\n if (bbox) {\n const { x, y, width, height } = bbox;\n\n // Convert bbox to 4 corner points\n points = [\n [x, y],\n [x + width, y],\n [x + width, y + height],\n [x, y + height],\n ];\n }\n }\n\n // Skip if no geometry data for this annotation\n if (!points) {\n continue;\n }\n\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Round points to specified precision\n points = roundPoints(points as Point[], precision);\n\n // Get transcription text for this annotation\n const transcription =\n item.transcription && item.transcription.length > i\n ? item.transcription[i]\n : '';\n\n // Calculate dt_score based on polygon area\n let dt_score = 1.0;\n try {\n const firstPoint = points[0];\n if (firstPoint) {\n const polygon = turf.polygon([points.concat([firstPoint])]);\n const area = turf.area(polygon);\n dt_score = Math.min(1.0, Math.max(0.5, area / 10000));\n }\n } catch {\n dt_score = 0.8;\n }\n\n const annotation = {\n transcription: transcription ?? '',\n points,\n dt_score,\n };\n\n // Group by image path\n if (!resultMap.has(imagePath)) {\n resultMap.set(imagePath, []);\n }\n resultMap.get(imagePath)!.push(annotation);\n }\n }\n\n return resultMap;\n};\n\n/**\n * Enhance Label Studio data (both Full and Min formats) with sorting, normalization, and resizing\n */\nexport const enhanceLabelStudioData = async (\n data: FullOCRLabelStudio | MinOCRLabelStudio,\n isFull: boolean,\n options: EnhancementOptions,\n): Promise<FullOCRLabelStudio | MinOCRLabelStudio> => {\n const {\n sortVertical,\n sortHorizontal,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = 0,\n } = options;\n\n if (isFull) {\n const fullData = data as FullOCRLabelStudio;\n return fullData.map((task) => ({\n ...task,\n annotations: task.annotations.map((annotation) => {\n // Group result items by their ID\n const groupedById = new Map<string, typeof annotation.result>();\n\n for (const resultItem of annotation.result) {\n const { id } = resultItem;\n if (!groupedById.has(id)) {\n groupedById.set(id, []);\n }\n groupedById.get(id)!.push(resultItem);\n }\n\n // Process each group and enhance\n const enhancedResult: typeof annotation.result = [];\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for (const [_, resultItems] of groupedById) {\n // Collect all items in group to extract points\n let ppocrAnnotations: PPOCRLabel = [];\n\n for (const resultItem of resultItems) {\n let points: number[][] | undefined;\n\n // Extract points\n if ('points' in resultItem.value && resultItem.value.points) {\n const { points: valuePoints } = resultItem.value;\n const { original_width, original_height } = resultItem;\n\n points = valuePoints.map(([x, y]) => [\n ((x ?? 0) * original_width) / 100,\n ((y ?? 0) * original_height) / 100,\n ]);\n } else if (\n 'x' in resultItem.value &&\n 'y' in resultItem.value &&\n 'width' in resultItem.value &&\n 'height' in resultItem.value\n ) {\n const { x, y, width, height } = resultItem.value;\n const { original_width, original_height } = resultItem;\n\n const absX = (x * original_width) / 100;\n const absY = (y * original_height) / 100;\n const absWidth = (width * original_width) / 100;\n const absHeight = (height * original_height) / 100;\n\n points = [\n [absX, absY],\n [absX + absWidth, absY],\n [absX + absWidth, absY + absHeight],\n [absX, absY + absHeight],\n ];\n }\n\n if (points) {\n ppocrAnnotations.push({\n transcription: '',\n points: points as Point[],\n dt_score: 1.0,\n });\n }\n }\n\n // Apply enhancements\n if (ppocrAnnotations.length > 0) {\n ppocrAnnotations = enhancePPOCRLabel(ppocrAnnotations, {\n sortVertical,\n sortHorizontal,\n normalizeShape,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n // Convert back to Label Studio format\n for (let i = 0; i < resultItems.length; i++) {\n const resultItem = resultItems[i]!;\n const enhanced = ppocrAnnotations[i];\n\n if (!enhanced) {\n enhancedResult.push(resultItem);\n continue;\n }\n\n // Update the points in the result item\n if ('points' in resultItem.value && resultItem.value.points) {\n const { original_width, original_height } = resultItem;\n\n enhancedResult.push({\n ...resultItem,\n value: {\n ...resultItem.value,\n points: enhanced.points.map(\n ([x, y]) =>\n [\n ((x ?? 0) / original_width) * 100,\n ((y ?? 0) / original_height) * 100,\n ] as [number, number],\n ),\n },\n });\n } else if (\n 'x' in resultItem.value &&\n 'y' in resultItem.value &&\n 'width' in resultItem.value &&\n 'height' in resultItem.value\n ) {\n // Convert back to bbox format\n const { original_width, original_height } = resultItem;\n const xs = enhanced.points.map(([x]) => x ?? 0);\n const ys = enhanced.points.map(([, y]) => y ?? 0);\n const minX = Math.min(...xs);\n const maxX = Math.max(...xs);\n const minY = Math.min(...ys);\n const maxY = Math.max(...ys);\n\n enhancedResult.push({\n ...resultItem,\n value: {\n ...resultItem.value,\n x: (minX / original_width) * 100,\n y: (minY / original_height) * 100,\n width: ((maxX - minX) / original_width) * 100,\n height: ((maxY - minY) / original_height) * 100,\n },\n });\n } else {\n enhancedResult.push(resultItem);\n }\n }\n } else {\n enhancedResult.push(...resultItems);\n }\n }\n\n return {\n ...annotation,\n result: enhancedResult,\n };\n }),\n }));\n } else {\n // Handle MinOCRLabelStudio format\n const minData = data as MinOCRLabelStudio;\n return minData.map((item) => {\n // Collect all points from poly/bbox\n let ppocrAnnotations: PPOCRLabel = [];\n\n const numAnnotations = Math.max(\n item.poly?.length || 0,\n item.bbox?.length || 0,\n item.transcription?.length || 0,\n );\n\n for (let i = 0; i < numAnnotations; i++) {\n let points: number[][] | undefined;\n\n if (item.poly && item.poly.length > i && item.poly[i]) {\n const { points: polyPoints } = item.poly[i]!;\n points = polyPoints;\n } else if (item.bbox && item.bbox.length > i && item.bbox[i]) {\n const { x, y, width, height } = item.bbox[i]!;\n points = [\n [x, y],\n [x + width, y],\n [x + width, y + height],\n [x, y + height],\n ];\n }\n\n if (points) {\n ppocrAnnotations.push({\n transcription:\n item.transcription && item.transcription.length > i\n ? (item.transcription[i] ?? '')\n : '',\n points: points as Point[],\n dt_score: 1.0,\n });\n }\n }\n\n // Apply enhancements\n if (ppocrAnnotations.length > 0) {\n ppocrAnnotations = enhancePPOCRLabel(ppocrAnnotations, {\n sortVertical,\n sortHorizontal,\n normalizeShape,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n // Convert back to min format\n const newPoly = ppocrAnnotations.map((ann) => ({\n points: ann.points,\n }));\n\n // Return updated item with poly (omit bbox)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { bbox: _, ...itemWithoutBbox } = item;\n return {\n ...itemWithoutBbox,\n poly: newPoly,\n };\n }\n\n return item;\n }) as MinOCRLabelStudio;\n }\n};\n","import z from 'zod';\n\nexport const FullOCRLabelStudioSchema = z.array(\n z.object({\n id: z.number(),\n annotations: z.array(\n z.object({\n id: z.number(),\n completed_by: z.number(),\n result: z.array(\n z.union([\n // Most specific rectangle variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base rectangle without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Most specific polygon variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base polygon without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n ]),\n ),\n was_cancelled: z.boolean(),\n ground_truth: z.boolean(),\n created_at: z.string(),\n updated_at: z.string(),\n draft_created_at: z.string(),\n lead_time: z.number(),\n prediction: z.object({}),\n result_count: z.number(),\n unique_id: z.string(),\n import_id: z.null(),\n last_action: z.null(),\n bulk_created: z.boolean(),\n task: z.number(),\n project: z.number(),\n updated_by: z.number(),\n parent_prediction: z.null(),\n parent_annotation: z.null(),\n last_created_by: z.null(),\n }),\n ),\n file_upload: z.string(),\n drafts: z.array(\n z.object({\n id: z.number(),\n user: z.string(),\n created_username: z.string(),\n created_ago: z.string(),\n result: z.array(\n z.union([\n // Most specific rectangle variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base rectangle without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Most specific polygon variants first (with text or labels)\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n text: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n labels: z.array(z.string()),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n // Base polygon without text or labels\n z.object({\n original_width: z.number(),\n original_height: z.number(),\n image_rotation: z.number(),\n value: z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n }),\n id: z.string(),\n from_name: z.string(),\n to_name: z.string(),\n type: z.string(),\n origin: z.string(),\n }),\n ]),\n ),\n lead_time: z.number(),\n was_postponed: z.boolean(),\n import_id: z.null(),\n created_at: z.string(),\n updated_at: z.string(),\n task: z.number(),\n annotation: z.number(),\n }),\n ),\n predictions: z.array(z.unknown()),\n data: z.object({ ocr: z.string() }),\n meta: z.object({}),\n created_at: z.string(),\n updated_at: z.string(),\n allow_skip: z.boolean(),\n inner_id: z.number(),\n total_annotations: z.number(),\n cancelled_annotations: z.number(),\n total_predictions: z.number(),\n comment_count: z.number(),\n unresolved_comment_count: z.number(),\n last_comment_updated_at: z.null(),\n project: z.number(),\n updated_by: z.number(),\n comment_authors: z.array(z.unknown()),\n }),\n);\n\nexport const MinOCRLabelStudioSchema = z.array(\n z.object({\n ocr: z.string(),\n id: z.number(),\n bbox: z\n .array(\n z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n original_width: z.number(),\n original_height: z.number(),\n }),\n )\n .optional()\n .default([]),\n label: z\n .array(\n z.union([\n z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n rotation: z.number(),\n labels: z.array(z.string()),\n original_width: z.number(),\n original_height: z.number(),\n }),\n z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n labels: z.array(z.string()),\n original_width: z.number(),\n original_height: z.number(),\n }),\n ]),\n )\n .optional()\n .default([]),\n transcription: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .transform((val) => {\n if (!val) return [];\n return Array.isArray(val) ? val : [val];\n }),\n poly: z\n .array(\n z.object({\n points: z.array(z.array(z.number())),\n closed: z.boolean(),\n original_width: z.number(),\n original_height: z.number(),\n }),\n )\n .optional()\n .default([]),\n annotator: z.number(),\n annotation_id: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n lead_time: z.number(),\n }),\n);\n\nexport const PPOCRLabelSchema = z.array(\n z.object({\n transcription: z.string(),\n points: z.array(z.array(z.number())),\n dt_score: z.number().optional(), // Detection score (from PaddleOCR)\n difficult: z.boolean().optional(), // Difficult flag (from PPOCRLabel tool)\n }),\n);\n\nexport type FullOCRLabelStudio = z.infer<typeof FullOCRLabelStudioSchema>;\nexport type MinOCRLabelStudio = z.infer<typeof MinOCRLabelStudioSchema>;\nexport type PPOCRLabel = z.infer<typeof PPOCRLabelSchema>;\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport chalk from 'chalk';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_LABEL_STUDIO_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n type HorizontalSortOrder,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n type ShapeNormalizeOption,\n type VerticalSortOrder,\n} from '@/constants';\nimport type { LocalContext } from '@/context';\nimport { enhanceLabelStudioData } from '@/lib/label-studio';\nimport {\n type FullOCRLabelStudio,\n FullOCRLabelStudioSchema,\n type MinOCRLabelStudio,\n MinOCRLabelStudioSchema,\n} from '@/lib/schema';\n\ninterface CommandFlags {\n outDir?: string;\n sortVertical?: string;\n sortHorizontal?: string;\n normalizeShape?: string;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nconst isLabelStudioFullJSON = (\n data: unknown,\n): {\n isFull: boolean;\n data: FullOCRLabelStudio | MinOCRLabelStudio;\n} => {\n // Try parsing as full format array\n const parsedFull = FullOCRLabelStudioSchema.safeParse(data);\n if (parsedFull.success) {\n return { isFull: true, data: parsedFull.data };\n }\n\n // Try parsing as single full format object (wrap in array)\n if (!Array.isArray(data) && typeof data === 'object' && data !== null) {\n const parsedSingleFull = FullOCRLabelStudioSchema.safeParse([data]);\n if (parsedSingleFull.success) {\n return { isFull: true, data: parsedSingleFull.data };\n }\n }\n\n // Try parsing as min format\n const parsedMin = MinOCRLabelStudioSchema.safeParse(data);\n if (parsedMin.success) {\n return { isFull: false, data: parsedMin.data };\n }\n\n throw new Error('Input data is not valid Label Studio JSON format.');\n};\n\nexport async function enhanceLabelStudio(\n this: LocalContext,\n flags: CommandFlags,\n ...inputDirs: string[]\n): Promise<void> {\n const {\n outDir = OUTPUT_BASE_DIR,\n sortVertical = DEFAULT_SORT_VERTICAL,\n sortHorizontal = DEFAULT_SORT_HORIZONTAL,\n normalizeShape = DEFAULT_SHAPE_NORMALIZE,\n widthIncrement = DEFAULT_WIDTH_INCREMENT,\n heightIncrement = DEFAULT_HEIGHT_INCREMENT,\n precision = DEFAULT_LABEL_STUDIO_PRECISION,\n } = flags;\n\n // Create output directory if it doesn't exist\n await mkdir(outDir, { recursive: true });\n\n for (const inputDir of inputDirs) {\n console.log(chalk.blue(`Processing input directory: ${inputDir}`));\n\n const files = await readdir(inputDir);\n\n for (const file of files) {\n if (!file.endsWith('.json')) {\n continue;\n }\n\n const filePath = join(inputDir, file);\n console.log(chalk.gray(`Processing file: ${file}`));\n\n try {\n const fileData = await readFile(filePath, 'utf-8');\n const labelStudioData = JSON.parse(fileData);\n\n const { data, isFull } = isLabelStudioFullJSON(labelStudioData);\n\n // Apply enhancements\n const enhanced = await enhanceLabelStudioData(data, isFull, {\n sortVertical: sortVertical as VerticalSortOrder,\n sortHorizontal: sortHorizontal as HorizontalSortOrder,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n // Write enhanced data\n const outputFilePath = join(outDir, file);\n await writeFile(\n outputFilePath,\n JSON.stringify(enhanced, null, 2),\n 'utf-8',\n );\n console.log(chalk.green(`✓ Enhanced file saved: ${outputFilePath}`));\n } catch (error) {\n console.error(\n chalk.red(`Error processing file ${file}:`),\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n }\n\n console.log(chalk.green('\\n✓ Enhancement complete!'));\n}\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport chalk from 'chalk';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_PPOCR_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n type HorizontalSortOrder,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n type ShapeNormalizeOption,\n type VerticalSortOrder,\n} from '@/constants';\nimport type { LocalContext } from '@/context';\nimport { enhancePPOCRLabel } from '@/lib/enhance';\nimport { PPOCRLabelSchema } from '@/lib/schema';\n\ninterface CommandFlags {\n outDir?: string;\n sortVertical?: string;\n sortHorizontal?: string;\n normalizeShape?: string;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nexport async function enhancePPOCR(\n this: LocalContext,\n flags: CommandFlags,\n ...inputDirs: string[]\n): Promise<void> {\n const {\n outDir = OUTPUT_BASE_DIR,\n sortVertical = DEFAULT_SORT_VERTICAL,\n sortHorizontal = DEFAULT_SORT_HORIZONTAL,\n normalizeShape = DEFAULT_SHAPE_NORMALIZE,\n widthIncrement = DEFAULT_WIDTH_INCREMENT,\n heightIncrement = DEFAULT_HEIGHT_INCREMENT,\n precision = DEFAULT_PPOCR_PRECISION,\n } = flags;\n\n // Create output directory if it doesn't exist\n await mkdir(outDir, { recursive: true });\n\n for (const inputDir of inputDirs) {\n console.log(chalk.blue(`Processing input directory: ${inputDir}`));\n\n const files = await readdir(inputDir);\n\n for (const file of files) {\n if (!file.endsWith('.txt')) {\n continue;\n }\n\n const filePath = join(inputDir, file);\n console.log(chalk.gray(`Processing file: ${file}`));\n\n try {\n const fileData = await readFile(filePath, 'utf-8');\n const lines = fileData.trim().split('\\n');\n\n // Parse PPOCRLabelV2 format and enhance each line\n const enhancedLines: string[] = [];\n\n for (const line of lines) {\n const parts = line.split('\\t');\n\n if (parts.length !== 2) {\n throw new Error(`Invalid PPOCRLabelV2 format in line: ${line}`);\n }\n\n const [imagePath, annotationsStr] = parts;\n const annotations = JSON.parse(annotationsStr!);\n\n // Validate annotations\n PPOCRLabelSchema.parse(annotations);\n\n // Apply enhancements\n const enhanced = enhancePPOCRLabel(annotations, {\n sortVertical: sortVertical as VerticalSortOrder,\n sortHorizontal: sortHorizontal as HorizontalSortOrder,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n // Validate enhanced data\n PPOCRLabelSchema.parse(enhanced);\n\n // Format as: image_path<tab>[{annotations}]\n const jsonArray = JSON.stringify(enhanced);\n enhancedLines.push(`${imagePath}\\t${jsonArray}`);\n }\n\n // Write enhanced data\n const outputFilePath = join(outDir, file);\n await writeFile(outputFilePath, enhancedLines.join('\\n'), 'utf-8');\n console.log(chalk.green(`✓ Enhanced file saved: ${outputFilePath}`));\n } catch (error) {\n console.error(\n chalk.red(`Error processing file ${file}:`),\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n }\n\n console.log(chalk.green('\\n✓ Enhancement complete!'));\n}\n","import { randomUUID } from 'node:crypto';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport sizeOf from 'image-size';\nimport {\n DEFAULT_LABEL_NAME,\n DEFAULT_LABEL_STUDIO_PRECISION,\n type ShapeNormalizeOption,\n} from '@/constants';\nimport { type Point, roundToPrecision, transformPoints } from '@/lib/geometry';\nimport {\n type FullOCRLabelStudio,\n type MinOCRLabelStudio,\n type PPOCRLabel,\n} from '@/lib/schema';\n\nexport type ToLabelStudioOptions = {\n imagePath: string;\n baseServerUrl: string;\n inputDir?: string;\n toFullJson?: boolean;\n taskId?: number;\n labelName?: string;\n normalizeShape?: ShapeNormalizeOption;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n};\n\nexport const ppocrToLabelStudio = async (\n data: PPOCRLabel,\n options: ToLabelStudioOptions,\n): Promise<FullOCRLabelStudio | MinOCRLabelStudio> => {\n const {\n imagePath,\n baseServerUrl,\n inputDir,\n toFullJson = true,\n taskId = 1,\n labelName = DEFAULT_LABEL_NAME,\n normalizeShape,\n widthIncrement = 0,\n heightIncrement = 0,\n precision = DEFAULT_LABEL_STUDIO_PRECISION,\n } = options || {};\n\n if (toFullJson) {\n return ppocrToFullLabelStudio(\n data,\n imagePath,\n baseServerUrl,\n inputDir,\n taskId,\n labelName,\n normalizeShape,\n widthIncrement,\n heightIncrement,\n precision,\n );\n } else {\n return ppocrToMinLabelStudio(\n data,\n imagePath,\n baseServerUrl,\n inputDir,\n labelName,\n normalizeShape,\n widthIncrement,\n heightIncrement,\n precision,\n );\n }\n};\n\nexport const ppocrToFullLabelStudio = (\n data: PPOCRLabel,\n imagePath: string,\n baseServerUrl: string,\n inputDir?: string,\n taskId: number = 1,\n labelName: string = DEFAULT_LABEL_NAME,\n normalizeShape?: ShapeNormalizeOption,\n widthIncrement: number = 0,\n heightIncrement: number = 0,\n precision: number = DEFAULT_LABEL_STUDIO_PRECISION,\n): FullOCRLabelStudio => {\n const newBaseServerUrl =\n baseServerUrl.replace(/\\/+$/, '') + (baseServerUrl === '' ? '' : '/');\n\n const now = new Date().toISOString();\n\n // Get actual image dimensions from the image file\n let original_width = 1920;\n let original_height = 1080;\n\n // Resolve absolute path to image file\n const resolvedImagePath = inputDir ? join(inputDir, imagePath) : imagePath;\n\n if (!existsSync(resolvedImagePath)) {\n throw new Error(`Image file not found: ${resolvedImagePath}`);\n }\n\n const buffer = readFileSync(resolvedImagePath);\n const dimensions = sizeOf(buffer);\n if (!dimensions.width || !dimensions.height) {\n throw new Error(\n `Failed to read image dimensions from: ${resolvedImagePath}`,\n );\n }\n original_width = dimensions.width;\n original_height = dimensions.height;\n\n // Extract filename from imagePath for file_upload (just the filename)\n const fileName = imagePath.split('/').pop() || imagePath;\n\n // Group all PPOCRLabel items into a single task with one annotation\n const result: FullOCRLabelStudio = [\n {\n id: taskId,\n annotations: [\n {\n id: taskId,\n completed_by: 1,\n result: data\n .map((item) => {\n let { points } = item;\n\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Generate a single ID for all three related annotations\n const annotationId = randomUUID().slice(0, 10);\n const polygonPoints = points.map(([x, y]) => [\n roundToPrecision(((x ?? 0) / original_width) * 100, precision),\n roundToPrecision(((y ?? 0) / original_height) * 100, precision),\n ]);\n\n // Create result items: polygon, labels, and textarea\n return [\n // 1. Polygon geometry only\n {\n original_width,\n original_height,\n image_rotation: 0,\n value: {\n points: polygonPoints,\n closed: true,\n },\n id: annotationId,\n from_name: 'poly',\n to_name: 'image',\n type: 'polygon',\n origin: 'manual',\n },\n // 2. Labels with polygon geometry\n {\n original_width,\n original_height,\n image_rotation: 0,\n value: {\n points: polygonPoints,\n closed: true,\n labels: [labelName],\n },\n id: annotationId,\n from_name: 'label',\n to_name: 'image',\n type: 'labels',\n origin: 'manual',\n },\n // 3. Textarea with polygon geometry and text\n {\n original_width,\n original_height,\n image_rotation: 0,\n value: {\n points: polygonPoints,\n closed: true,\n text: [item.transcription],\n },\n id: annotationId,\n from_name: 'transcription',\n to_name: 'image',\n type: 'textarea',\n origin: 'manual',\n },\n ];\n })\n .flat(),\n was_cancelled: false,\n ground_truth: false,\n created_at: now,\n updated_at: now,\n draft_created_at: now,\n lead_time: 0,\n prediction: {},\n result_count: data.length * 3,\n unique_id: randomUUID(),\n import_id: null,\n last_action: null,\n bulk_created: false,\n task: taskId,\n project: 1,\n updated_by: 1,\n parent_prediction: null,\n parent_annotation: null,\n last_created_by: null,\n },\n ],\n file_upload: fileName,\n drafts: [],\n predictions: [],\n data: { ocr: `${newBaseServerUrl}${imagePath}` },\n meta: {},\n created_at: now,\n updated_at: now,\n allow_skip: false,\n inner_id: taskId,\n total_annotations: 1,\n cancelled_annotations: 0,\n total_predictions: 0,\n comment_count: 0,\n unresolved_comment_count: 0,\n last_comment_updated_at: null,\n project: 1,\n updated_by: 1,\n comment_authors: [],\n },\n ];\n\n return result;\n};\n\nexport const ppocrToMinLabelStudio = (\n data: PPOCRLabel,\n imagePath: string,\n baseServerUrl: string,\n inputDir?: string,\n labelName: string = 'text',\n normalizeShape?: ShapeNormalizeOption,\n widthIncrement: number = 0,\n heightIncrement: number = 0,\n precision: number = DEFAULT_LABEL_STUDIO_PRECISION,\n): MinOCRLabelStudio => {\n const newBaseServerUrl =\n baseServerUrl.replace(/\\/+$/, '') + (baseServerUrl === '' ? '' : '/');\n\n const now = new Date().toISOString();\n\n // Get actual image dimensions from the image file\n let original_width = 1920;\n let original_height = 1080;\n\n // Resolve absolute path to image file\n const resolvedImagePath = inputDir ? join(inputDir, imagePath) : imagePath;\n\n if (!existsSync(resolvedImagePath)) {\n throw new Error(`Image file not found: ${resolvedImagePath}`);\n }\n\n const buffer = readFileSync(resolvedImagePath);\n const dimensions = sizeOf(buffer);\n if (!dimensions.width || !dimensions.height) {\n throw new Error(\n `Failed to read image dimensions from: ${resolvedImagePath}`,\n );\n }\n original_width = dimensions.width;\n original_height = dimensions.height;\n\n return data.map((item, index) => {\n let { points } = item;\n\n // Apply geometry transformations\n points = transformPoints(points as Point[], {\n normalizeShape,\n widthIncrement,\n heightIncrement,\n });\n\n // Round coordinates based on precision first\n const roundedPoints = points.map(\n ([x, y]) =>\n [\n roundToPrecision(x ?? 0, precision),\n roundToPrecision(y ?? 0, precision),\n ] as [number, number],\n );\n\n // Calculate bbox from rounded points\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const point of roundedPoints) {\n const [x, y] = point;\n if (x !== undefined && y !== undefined) {\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n return {\n ocr: encodeURI(`${newBaseServerUrl}${imagePath}`),\n id: index + 1,\n bbox: [\n {\n x: minX,\n y: minY,\n width: width,\n height: height,\n rotation: 0,\n original_width,\n original_height,\n },\n ],\n label: [\n {\n points: roundedPoints,\n closed: true,\n labels: [labelName],\n original_width,\n original_height,\n },\n ],\n transcription: [item.transcription],\n poly: [\n {\n points: roundedPoints,\n closed: true,\n original_width,\n original_height,\n },\n ],\n annotator: 1,\n annotation_id: index + 1,\n created_at: now,\n updated_at: now,\n lead_time: 0,\n };\n });\n};\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport chalk from 'chalk';\nimport {\n DEFAULT_BASE_SERVER_URL,\n DEFAULT_CREATE_FILE_LIST_FOR_SERVING,\n DEFAULT_CREATE_FILE_PER_IMAGE,\n DEFAULT_FILE_LIST_NAME,\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_LABEL_NAME,\n DEFAULT_LABEL_STUDIO_FULL_JSON,\n DEFAULT_LABEL_STUDIO_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n type HorizontalSortOrder,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n type ShapeNormalizeOption,\n type VerticalSortOrder,\n} from '@/constants';\nimport type { LocalContext } from '@/context';\nimport { ppocrToLabelStudio } from '@/lib/ppocr-label';\nimport { type PPOCRLabel, PPOCRLabelSchema } from '@/lib/schema';\nimport { sortBoundingBoxes } from '@/lib/sort';\n\ninterface CommandFlags {\n outDir?: string;\n defaultLabelName?: string;\n toFullJson?: boolean;\n createFilePerImage?: boolean;\n createFileListForServing?: boolean;\n fileListName?: string;\n baseServerUrl?: string;\n sortVertical?: string;\n sortHorizontal?: string;\n normalizeShape?: string;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nexport async function convertToLabelStudio(\n this: LocalContext,\n flags: CommandFlags,\n ...inputDirs: string[]\n): Promise<void> {\n const {\n outDir = OUTPUT_BASE_DIR,\n defaultLabelName = DEFAULT_LABEL_NAME,\n toFullJson = DEFAULT_LABEL_STUDIO_FULL_JSON,\n createFilePerImage = DEFAULT_CREATE_FILE_PER_IMAGE,\n createFileListForServing = DEFAULT_CREATE_FILE_LIST_FOR_SERVING,\n fileListName = DEFAULT_FILE_LIST_NAME,\n baseServerUrl = DEFAULT_BASE_SERVER_URL,\n sortVertical = DEFAULT_SORT_VERTICAL,\n sortHorizontal = DEFAULT_SORT_HORIZONTAL,\n normalizeShape = DEFAULT_SHAPE_NORMALIZE,\n widthIncrement = DEFAULT_WIDTH_INCREMENT,\n heightIncrement = DEFAULT_HEIGHT_INCREMENT,\n precision = DEFAULT_LABEL_STUDIO_PRECISION,\n } = flags;\n\n // NOTE: Ensure baseServerUrl ends with a single slash, but keeps empty string\n // as is\n const newBaseServerUrl =\n baseServerUrl.replace(/\\/+$/, '') + (baseServerUrl === '' ? '' : '/');\n\n // Create output directory if it doesn't exist\n await mkdir(outDir, { recursive: true });\n\n for (const inputDir of inputDirs) {\n console.log(chalk.blue(`Processing input directory: ${inputDir}`));\n\n const files = await readdir(inputDir);\n\n for (const file of files) {\n if (!file.endsWith('.txt')) {\n continue;\n }\n\n const filePath = join(inputDir, file);\n console.log(chalk.gray(`Processing file: ${file}`));\n\n try {\n const fileData = await readFile(filePath, 'utf-8');\n const lines = fileData.trim().split('\\n');\n\n // Parse PPOCRLabelV2 format: <filename>\\t<json_array_of_annotations>\n // Group by filename since each line represents one image file with its annotations\n const imageDataMap = new Map<string, PPOCRLabel>();\n\n for (const line of lines) {\n const parts = line.split('\\t');\n\n if (parts.length !== 2) {\n throw new Error(`Invalid PPOCRLabelV2 format in line: ${line}`);\n }\n const [imagePath, annotationsStr] = parts;\n const annotations = JSON.parse(annotationsStr!);\n\n // Each annotation already has the structure: {transcription, points, dt_score}\n // Validate each annotation\n PPOCRLabelSchema.parse(annotations);\n\n imageDataMap.set(imagePath!, annotations);\n }\n\n // Convert each image's annotations to Label Studio format\n const allLabelStudioData = [];\n const fileList: string[] = [];\n let taskId = 1;\n\n for (const [imagePath, ppocrData] of imageDataMap.entries()) {\n // Sort annotations if requested\n const sortedPpocrData = sortBoundingBoxes(\n ppocrData,\n sortVertical as VerticalSortOrder,\n sortHorizontal as HorizontalSortOrder,\n );\n\n // Update imagePath to use baseServerUrl if createFileListForServing is enabled\n const finalImagePath = createFileListForServing\n ? encodeURI(`${newBaseServerUrl}${imagePath}`)\n : imagePath;\n\n const labelStudioData = await ppocrToLabelStudio(sortedPpocrData, {\n toFullJson,\n imagePath,\n baseServerUrl: newBaseServerUrl,\n inputDir,\n taskId,\n labelName: defaultLabelName,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n if (toFullJson) {\n allLabelStudioData.push(labelStudioData[0]);\n } else {\n allLabelStudioData.push(...labelStudioData);\n }\n\n // Create individual file per image if requested\n if (createFilePerImage) {\n const imageBaseName = imagePath\n .replace(/\\//g, '_')\n .replace(/\\.[^.]+$/, '');\n const individualOutputPath = join(\n outDir,\n `${imageBaseName}_${toFullJson ? 'full' : 'min'}.json`,\n );\n await writeFile(\n individualOutputPath,\n JSON.stringify(\n toFullJson ? labelStudioData[0] : labelStudioData,\n null,\n 2,\n ),\n 'utf-8',\n );\n console.log(\n chalk.gray(\n ` ✓ Created individual file: ${individualOutputPath}`,\n ),\n );\n }\n\n // Add to file list for serving\n if (createFileListForServing) {\n fileList.push(finalImagePath);\n }\n\n taskId++;\n }\n\n // Write combined output file\n const baseName = file.replace('.txt', '');\n const outputPath = join(\n outDir,\n `${baseName}_${toFullJson ? 'full' : 'min'}.json`,\n );\n await writeFile(\n outputPath,\n JSON.stringify(allLabelStudioData, null, 2),\n 'utf-8',\n );\n\n console.log(chalk.green(`✓ Converted ${file} -> ${outputPath}`));\n\n // Create file list for serving if requested\n if (createFileListForServing && fileList.length > 0) {\n const fileListPath = join(outDir, fileListName);\n await writeFile(fileListPath, fileList.join('\\n'), 'utf-8');\n console.log(\n chalk.green(\n `✓ Created file list: ${fileListPath} (${fileList.length} files)`,\n ),\n );\n }\n } catch (error) {\n console.error(\n chalk.red(`✗ Failed to process ${file}:`),\n error instanceof Error ? error.message : error,\n );\n }\n }\n }\n\n console.log(chalk.green('\\n✓ Conversion completed!'));\n}\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport chalk from 'chalk';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_PPOCR_FILE_NAME,\n DEFAULT_PPOCR_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n type HorizontalSortOrder,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n type ShapeNormalizeOption,\n type VerticalSortOrder,\n} from '@/constants';\nimport type { LocalContext } from '@/context';\nimport { labelStudioToPPOCR, minLabelStudioToPPOCR } from '@/lib/label-studio';\nimport {\n type FullOCRLabelStudio,\n FullOCRLabelStudioSchema,\n type MinOCRLabelStudio,\n MinOCRLabelStudioSchema,\n PPOCRLabelSchema,\n} from '@/lib/schema';\nimport { sortBoundingBoxes } from '@/lib/sort';\n\ninterface CommandFlags {\n outDir?: string;\n fileName?: string;\n baseImageDir?: string;\n sortVertical?: string;\n sortHorizontal?: string;\n normalizeShape?: string;\n widthIncrement?: number;\n heightIncrement?: number;\n precision?: number;\n}\n\nconst isLabelStudioFullJSON = (\n data: unknown,\n): {\n isFull: boolean;\n data: FullOCRLabelStudio | MinOCRLabelStudio;\n} => {\n // Try parsing as full format array\n const parsedFull = FullOCRLabelStudioSchema.safeParse(data);\n if (parsedFull.success) {\n return { isFull: true, data: parsedFull.data };\n }\n\n // Try parsing as single full format object (wrap in array)\n if (!Array.isArray(data) && typeof data === 'object' && data !== null) {\n const parsedSingleFull = FullOCRLabelStudioSchema.safeParse([data]);\n if (parsedSingleFull.success) {\n return { isFull: true, data: parsedSingleFull.data };\n }\n }\n\n // Try parsing as min format\n const parsedMin = MinOCRLabelStudioSchema.safeParse(data);\n if (parsedMin.success) {\n return { isFull: false, data: parsedMin.data };\n }\n\n throw new Error('Input data is not valid Label Studio JSON format.');\n};\n\nexport async function convertToPPOCR(\n this: LocalContext,\n flags: CommandFlags,\n ...inputDirs: string[]\n): Promise<void> {\n const {\n outDir = `${OUTPUT_BASE_DIR}`,\n fileName = DEFAULT_PPOCR_FILE_NAME,\n baseImageDir,\n sortVertical = DEFAULT_SORT_VERTICAL,\n sortHorizontal = DEFAULT_SORT_HORIZONTAL,\n normalizeShape = DEFAULT_SHAPE_NORMALIZE,\n widthIncrement = DEFAULT_WIDTH_INCREMENT,\n heightIncrement = DEFAULT_HEIGHT_INCREMENT,\n precision = DEFAULT_PPOCR_PRECISION,\n } = flags;\n\n // Create output directory if it doesn't exist\n await mkdir(outDir, { recursive: true });\n\n for (const inputDir of inputDirs) {\n console.log(chalk.blue(`Processing input directory: ${inputDir}`));\n\n const files = await readdir(inputDir);\n\n for (const file of files) {\n if (!file.endsWith('.json')) {\n continue;\n }\n\n const filePath = join(inputDir, file);\n console.log(chalk.gray(`Processing file: ${file}`));\n\n try {\n const fileData = await readFile(filePath, 'utf-8');\n const labelStudioData = JSON.parse(fileData);\n\n const { data, isFull } = isLabelStudioFullJSON(labelStudioData);\n\n // Convert based on format type\n const ppocrDataMap = isFull\n ? await labelStudioToPPOCR(data as FullOCRLabelStudio, {\n baseImageDir,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n })\n : await minLabelStudioToPPOCR(data as MinOCRLabelStudio, {\n baseImageDir,\n normalizeShape:\n normalizeShape !== SHAPE_NORMALIZE_NONE\n ? (normalizeShape as ShapeNormalizeOption)\n : undefined,\n widthIncrement,\n heightIncrement,\n precision,\n });\n\n // Format output as PPOCR label format: image_path<tab>[{JSON array}]\n const outputLines: string[] = [];\n for (const [imagePath, annotations] of ppocrDataMap.entries()) {\n // Sort annotations if requested\n const sortedAnnotations = sortBoundingBoxes(\n annotations,\n sortVertical as VerticalSortOrder,\n sortHorizontal as HorizontalSortOrder,\n );\n\n // Validate each annotation group\n PPOCRLabelSchema.parse(sortedAnnotations);\n\n // Format as: image_path<tab>[{annotations}]\n const jsonArray = JSON.stringify(sortedAnnotations);\n outputLines.push(`${imagePath}\\t${jsonArray}`);\n }\n\n // Write to output file\n const baseName = file.replace('.json', '');\n const outputPath = join(outDir, `${baseName}_${fileName}`);\n await writeFile(outputPath, outputLines.join('\\n'), 'utf-8');\n\n console.log(chalk.green(`✓ Converted ${file} -> ${outputPath}`));\n } catch (error) {\n console.error(\n chalk.red(`✗ Failed to process ${file}:`),\n error instanceof Error ? error.message : error,\n );\n }\n }\n }\n\n console.log(chalk.green('\\n✓ Conversion completed!'));\n}\n","#!/usr/bin/env node\nimport { proposeCompletions } from '@stricli/core';\nimport { app } from '@/app';\nimport { buildContext } from '@/context';\n\n(async () => {\n const inputs = process.argv.slice(3);\n if (process.env.COMP_LINE?.endsWith(' ')) {\n inputs.push('');\n }\n await proposeCompletions(app, inputs, buildContext(process));\n try {\n for (const { completion } of await proposeCompletions(\n app,\n inputs,\n buildContext(process),\n )) {\n process.stdout.write(`${completion}\\n`);\n }\n } catch {\n // ignore\n }\n})();\n","import {\n buildInstallCommand,\n buildUninstallCommand,\n} from '@stricli/auto-complete';\nimport { buildApplication, buildRouteMap } from '@stricli/core';\nimport { description, version } from '@/../package.json';\nimport { enhanceLabelStudioCommand } from '@/commands/enhance-labelstudio/command';\nimport { enhancePPOCRCommand } from '@/commands/enhance-ppocr/command';\nimport { toLabelStudioCommand } from '@/commands/toLabelStudio/command';\nimport { toPPOCRCommand } from '@/commands/toPPOCR/commands';\n\nconst routes = buildRouteMap({\n routes: {\n toLabelStudio: toLabelStudioCommand,\n toPPOCR: toPPOCRCommand,\n 'enhance-labelstudio': enhanceLabelStudioCommand,\n 'enhance-ppocr': enhancePPOCRCommand,\n install: buildInstallCommand('label-studio-converter', {\n bash: '__label-studio-converter_bash_complete',\n }),\n uninstall: buildUninstallCommand('label-studio-converter', { bash: true }),\n },\n docs: {\n brief: description,\n hideRoute: {\n install: true,\n uninstall: true,\n },\n },\n});\n\nexport const app = buildApplication(routes, {\n name: 'label-studio-converter',\n versionInfo: {\n currentVersion: version,\n },\n});\n","{\n \"name\": \"label-studio-converter\",\n \"version\": \"1.2.0\",\n \"author\": \"DuckyMomo20012\",\n \"description\": \"Convert between Label Studio OCR format and PPOCRLabelv2 format\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/DuckyMomo20012/label-studio-converter.git\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"liturgical\"\n ],\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"bin\": {\n \"label-studio-converter\": \"./dist/cli.js\",\n \"__label-studio-converter_bash_complete\": \"./dist/bash-complete.js\"\n },\n \"scripts\": {\n \"prepare\": \"husky\",\n \"type-check\": \"tsc --noEmit\",\n \"lint\": \"eslint src/\",\n \"lint:fix\": \"eslint src/ --fix\",\n \"build\": \"tsc && tsup\",\n \"test\": \"vitest\",\n \"test:ui\": \"vitest --ui\",\n \"test:run\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\",\n \"check-exports\": \"attw --pack . --ignore-rules=cjs-resolves-to-esm\",\n \"check-all\": \"pnpm run type-check && pnpm run lint && pnpm run test:run\",\n \"prepublish\": \"pnpm run build && pnpm run check-exports && pnpm run check-all\",\n \"postinstall\": \"npx @stricli/auto-complete@latest install label-studio-converter --bash __label-studio-converter_bash_complete\"\n },\n \"dependencies\": {\n \"@stricli/auto-complete\": \"1.2.4\",\n \"@stricli/core\": \"1.2.4\",\n \"@turf/turf\": \"7.3.1\",\n \"chalk\": \"5.6.2\",\n \"es-toolkit\": \"1.43.0\",\n \"image-size\": \"2.0.2\",\n \"zod\": \"4.2.1\"\n },\n \"devDependencies\": {\n \"@arethetypeswrong/cli\": \"0.18.2\",\n \"@babel/core\": \"7.28.5\",\n \"@commitlint/cli\": \"20.2.0\",\n \"@commitlint/config-conventional\": \"20.2.0\",\n \"@types/node\": \"24.10.4\",\n \"@typescript-eslint/eslint-plugin\": \"8.51.0\",\n \"@typescript-eslint/parser\": \"8.51.0\",\n \"@vitest/eslint-plugin\": \"1.6.4\",\n \"@vitest/ui\": \"4.0.16\",\n \"eslint\": \"9.39.2\",\n \"eslint-config-prettier\": \"10.1.8\",\n \"eslint-import-resolver-typescript\": \"4.4.4\",\n \"eslint-plugin-import\": \"2.32.0\",\n \"eslint-plugin-prettier\": \"5.5.4\",\n \"globals\": \"16.5.0\",\n \"husky\": \"9.1.7\",\n \"lint-staged\": \"16.2.7\",\n \"prettier\": \"3.7.4\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"5.9.3\",\n \"vitest\": \"4.0.16\"\n }\n}\n","import { buildCommand } from '@stricli/core';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_LABEL_STUDIO_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n SHAPE_NORMALIZE_RECTANGLE,\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_BOTTOM_TOP,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\n\nexport const enhanceLabelStudioCommand = buildCommand({\n loader: async () => {\n const { enhanceLabelStudio } = await import('./impl');\n return enhanceLabelStudio;\n },\n parameters: {\n positional: {\n kind: 'array',\n parameter: {\n brief: 'Input directories containing Label Studio JSON files',\n parse: String,\n },\n minimum: 1,\n },\n flags: {\n outDir: {\n kind: 'parsed',\n brief: `Output directory. Default: \"${OUTPUT_BASE_DIR}\"`,\n parse: String,\n optional: true,\n },\n sortVertical: {\n kind: 'parsed',\n brief: `Sort bounding boxes vertically. Options: \"${SORT_VERTICAL_NONE}\", \"${SORT_VERTICAL_TOP_BOTTOM}\", \"${SORT_VERTICAL_BOTTOM_TOP}\". Default: \"${DEFAULT_SORT_VERTICAL}\"`,\n parse: String,\n optional: true,\n },\n sortHorizontal: {\n kind: 'parsed',\n brief: `Sort bounding boxes horizontally. Options: \"${SORT_HORIZONTAL_NONE}\", \"${SORT_HORIZONTAL_LTR}\", \"${SORT_HORIZONTAL_RTL}\". Default: \"${DEFAULT_SORT_HORIZONTAL}\"`,\n parse: String,\n optional: true,\n },\n normalizeShape: {\n kind: 'parsed',\n brief: `Normalize diamond-like shapes to axis-aligned rectangles. Options: \"${SHAPE_NORMALIZE_NONE}\", \"${SHAPE_NORMALIZE_RECTANGLE}\". Default: \"${DEFAULT_SHAPE_NORMALIZE}\"`,\n parse: String,\n optional: true,\n },\n widthIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_WIDTH_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n heightIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_HEIGHT_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n precision: {\n kind: 'parsed',\n brief: `Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: ${DEFAULT_LABEL_STUDIO_PRECISION}`,\n parse: Number,\n optional: true,\n },\n },\n },\n docs: {\n brief:\n 'Enhance Label Studio files with sorting, normalization, and resizing',\n },\n});\n","import { buildCommand } from '@stricli/core';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_PPOCR_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n SHAPE_NORMALIZE_RECTANGLE,\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_BOTTOM_TOP,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\n\nexport const enhancePPOCRCommand = buildCommand({\n loader: async () => {\n const { enhancePPOCR } = await import('./impl');\n return enhancePPOCR;\n },\n parameters: {\n positional: {\n kind: 'array',\n parameter: {\n brief: 'Input directories containing PPOCRLabel files',\n parse: String,\n },\n minimum: 1,\n },\n flags: {\n outDir: {\n kind: 'parsed',\n brief: `Output directory. Default: \"${OUTPUT_BASE_DIR}\"`,\n parse: String,\n optional: true,\n },\n sortVertical: {\n kind: 'parsed',\n brief: `Sort bounding boxes vertically. Options: \"${SORT_VERTICAL_NONE}\", \"${SORT_VERTICAL_TOP_BOTTOM}\", \"${SORT_VERTICAL_BOTTOM_TOP}\". Default: \"${DEFAULT_SORT_VERTICAL}\"`,\n parse: String,\n optional: true,\n },\n sortHorizontal: {\n kind: 'parsed',\n brief: `Sort bounding boxes horizontally. Options: \"${SORT_HORIZONTAL_NONE}\", \"${SORT_HORIZONTAL_LTR}\", \"${SORT_HORIZONTAL_RTL}\". Default: \"${DEFAULT_SORT_HORIZONTAL}\"`,\n parse: String,\n optional: true,\n },\n normalizeShape: {\n kind: 'parsed',\n brief: `Normalize diamond-like shapes to axis-aligned rectangles. Options: \"${SHAPE_NORMALIZE_NONE}\", \"${SHAPE_NORMALIZE_RECTANGLE}\". Default: \"${DEFAULT_SHAPE_NORMALIZE}\"`,\n parse: String,\n optional: true,\n },\n widthIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_WIDTH_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n heightIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_HEIGHT_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n precision: {\n kind: 'parsed',\n brief: `Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: ${DEFAULT_PPOCR_PRECISION} (integers)`,\n parse: Number,\n optional: true,\n },\n },\n },\n docs: {\n brief: 'Enhance PPOCRLabel files with sorting, normalization, and resizing',\n },\n});\n","import { buildCommand } from '@stricli/core';\nimport {\n DEFAULT_BASE_SERVER_URL,\n DEFAULT_CREATE_FILE_LIST_FOR_SERVING,\n DEFAULT_CREATE_FILE_PER_IMAGE,\n DEFAULT_FILE_LIST_NAME,\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_LABEL_NAME,\n DEFAULT_LABEL_STUDIO_FULL_JSON,\n DEFAULT_LABEL_STUDIO_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n SHAPE_NORMALIZE_RECTANGLE,\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_BOTTOM_TOP,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\n\nexport const toLabelStudioCommand = buildCommand({\n loader: async () => {\n const { convertToLabelStudio } = await import('./impl');\n return convertToLabelStudio;\n },\n parameters: {\n positional: {\n kind: 'array',\n parameter: {\n brief: 'Input directories containing PPOCRLabel files',\n parse: String,\n },\n minimum: 1,\n },\n flags: {\n outDir: {\n kind: 'parsed',\n brief: `Output directory. Default: \"${OUTPUT_BASE_DIR}\"`,\n parse: String,\n optional: true,\n },\n defaultLabelName: {\n kind: 'parsed',\n brief: `Default label name for text annotations. Default: \"${DEFAULT_LABEL_NAME}\"`,\n parse: String,\n optional: true,\n },\n toFullJson: {\n kind: 'boolean',\n brief: `Convert to Full OCR Label Studio format. Default: \"${DEFAULT_LABEL_STUDIO_FULL_JSON}\"`,\n optional: true,\n },\n createFilePerImage: {\n kind: 'boolean',\n brief: `Create a separate Label Studio JSON file for each image. Default: \"${DEFAULT_CREATE_FILE_PER_IMAGE}\"`,\n optional: true,\n },\n createFileListForServing: {\n kind: 'boolean',\n brief: `Create a file list for serving in Label Studio. Default: \"${DEFAULT_CREATE_FILE_LIST_FOR_SERVING}\"`,\n optional: true,\n },\n fileListName: {\n kind: 'parsed',\n brief: `Name of the file list for serving. Default: \"${DEFAULT_FILE_LIST_NAME}\"`,\n parse: String,\n optional: true,\n },\n baseServerUrl: {\n kind: 'parsed',\n brief: `Base server URL for constructing image URLs in the file list. Default: \"${DEFAULT_BASE_SERVER_URL}\"`,\n parse: String,\n optional: true,\n },\n sortVertical: {\n kind: 'parsed',\n brief: `Sort bounding boxes vertically. Options: \"${SORT_VERTICAL_NONE}\", \"${SORT_VERTICAL_TOP_BOTTOM}\", \"${SORT_VERTICAL_BOTTOM_TOP}\". Default: \"${DEFAULT_SORT_VERTICAL}\"`,\n parse: String,\n optional: true,\n },\n sortHorizontal: {\n kind: 'parsed',\n brief: `Sort bounding boxes horizontally. Options: \"${SORT_HORIZONTAL_NONE}\", \"${SORT_HORIZONTAL_LTR}\", \"${SORT_HORIZONTAL_RTL}\". Default: \"${DEFAULT_SORT_HORIZONTAL}\"`,\n parse: String,\n optional: true,\n },\n normalizeShape: {\n kind: 'parsed',\n brief: `Normalize diamond-like shapes to axis-aligned rectangles. Options: \"${SHAPE_NORMALIZE_NONE}\", \"${SHAPE_NORMALIZE_RECTANGLE}\". Default: \"${DEFAULT_SHAPE_NORMALIZE}\"`,\n parse: String,\n optional: true,\n },\n widthIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_WIDTH_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n heightIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_HEIGHT_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n precision: {\n kind: 'parsed',\n brief: `Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: ${DEFAULT_LABEL_STUDIO_PRECISION}`,\n parse: Number,\n optional: true,\n },\n },\n },\n docs: {\n brief: 'Convert PPOCRLabel files to Label Studio format',\n },\n});\n","import { buildCommand } from '@stricli/core';\nimport {\n DEFAULT_HEIGHT_INCREMENT,\n DEFAULT_PPOCR_FILE_NAME,\n DEFAULT_PPOCR_PRECISION,\n DEFAULT_SHAPE_NORMALIZE,\n DEFAULT_SORT_HORIZONTAL,\n DEFAULT_SORT_VERTICAL,\n DEFAULT_WIDTH_INCREMENT,\n OUTPUT_BASE_DIR,\n SHAPE_NORMALIZE_NONE,\n SHAPE_NORMALIZE_RECTANGLE,\n SORT_HORIZONTAL_LTR,\n SORT_HORIZONTAL_NONE,\n SORT_HORIZONTAL_RTL,\n SORT_VERTICAL_BOTTOM_TOP,\n SORT_VERTICAL_NONE,\n SORT_VERTICAL_TOP_BOTTOM,\n} from '@/constants';\n\nexport const toPPOCRCommand = buildCommand({\n loader: async () => {\n const { convertToPPOCR } = await import('./impl');\n return convertToPPOCR;\n },\n parameters: {\n positional: {\n kind: 'array',\n parameter: {\n brief: 'Input directories containing Label Studio files',\n parse: String,\n },\n minimum: 1,\n },\n flags: {\n outDir: {\n kind: 'parsed',\n brief: `Output directory. Default: \"${OUTPUT_BASE_DIR}\"`,\n parse: String,\n optional: true,\n },\n fileName: {\n kind: 'parsed',\n brief: `Output PPOCR file name. Default: \"${DEFAULT_PPOCR_FILE_NAME}\"`,\n parse: String,\n optional: true,\n },\n baseImageDir: {\n kind: 'parsed',\n brief:\n 'Base directory path to prepend to image filenames in output (e.g., \"ch\" or \"images/ch\")',\n parse: String,\n optional: true,\n },\n sortVertical: {\n kind: 'parsed',\n brief: `Sort bounding boxes vertically. Options: \"${SORT_VERTICAL_NONE}\", \"${SORT_VERTICAL_TOP_BOTTOM}\", \"${SORT_VERTICAL_BOTTOM_TOP}\". Default: \"${DEFAULT_SORT_VERTICAL}\"`,\n parse: String,\n optional: true,\n },\n sortHorizontal: {\n kind: 'parsed',\n brief: `Sort bounding boxes horizontally. Options: \"${SORT_HORIZONTAL_NONE}\", \"${SORT_HORIZONTAL_LTR}\", \"${SORT_HORIZONTAL_RTL}\". Default: \"${DEFAULT_SORT_HORIZONTAL}\"`,\n parse: String,\n optional: true,\n },\n normalizeShape: {\n kind: 'parsed',\n brief: `Normalize diamond-like shapes to axis-aligned rectangles. Options: \"${SHAPE_NORMALIZE_NONE}\", \"${SHAPE_NORMALIZE_RECTANGLE}\". Default: \"${DEFAULT_SHAPE_NORMALIZE}\"`,\n parse: String,\n optional: true,\n },\n widthIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_WIDTH_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n heightIncrement: {\n kind: 'parsed',\n brief: `Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: ${DEFAULT_HEIGHT_INCREMENT}`,\n parse: Number,\n optional: true,\n },\n precision: {\n kind: 'parsed',\n brief: `Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: ${DEFAULT_PPOCR_PRECISION} (integers)`,\n parse: Number,\n optional: true,\n },\n },\n },\n docs: {\n brief: 'Convert Label Studio files to PPOCRLabel format',\n },\n});\n","import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { StricliAutoCompleteContext } from '@stricli/auto-complete';\nimport type { CommandContext } from '@stricli/core';\n\nexport interface LocalContext\n extends CommandContext, StricliAutoCompleteContext {\n readonly process: NodeJS.Process;\n // ...\n}\n\nexport function buildContext(process: NodeJS.Process): LocalContext {\n return {\n process,\n os,\n fs,\n path,\n };\n}\n"],"mappings":"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","names":["normalizeShape","normalizeShape","polygon","area","z","normalizeShape","chalk","impl_exports","normalizeShape","chalk","import_promises","import_path","import_chalk","init_impl","normalizeShape","sizeOf","impl_exports","normalizeShape","chalk","import_promises","import_path","import_chalk","init_impl","impl_exports","normalizeShape","chalk","isLabelStudioFullJSON","import_promises","import_path","import_chalk","init_impl","import_core","import_core","enhanceLabelStudio","import_core","enhancePPOCR","import_core","convertToLabelStudio","import_core","convertToPPOCR","import_node_fs","import_node_path","process","os","fs","path"]}