{
  "inspection": "ZIP member comparison and XML structural counts; read-only",
  "scope": "Existing educational artifacts; does not establish visual identity or regulatory conformity",
  "original": {
    "file": "서식원본-식품한류전략과제보고.hwpx",
    "sha256": "ea797b3330fae2b66f8669996c6c4a66212fcdb9b1a80229d700230ebcdfe5c5",
    "entries": 16,
    "sections": {
      "Contents/section0.xml": {
        "p": 39,
        "tbl": 3,
        "pic": 2,
        "t": 9
      },
      "Contents/section1.xml": {
        "p": 291,
        "tbl": 12,
        "pic": 1,
        "t": 316
      }
    },
    "xml_parse_errors": []
  },
  "result": {
    "file": "11_서식복제샘플_발효식품육성전략.hwpx",
    "sha256": "60182d35b38984ebc7874c45194954c6388a8f68659c20a8397a67e3cc5b28d4",
    "entries": 16,
    "sections": {
      "Contents/section0.xml": {
        "p": 39,
        "tbl": 3,
        "pic": 2,
        "t": 9
      },
      "Contents/section1.xml": {
        "p": 291,
        "tbl": 12,
        "pic": 1,
        "t": 299
      }
    },
    "xml_parse_errors": []
  },
  "checks": {
    "header_identical": true,
    "binary_entries_compared": 3,
    "binary_entries_identical": true,
    "entry_names_identical": true,
    "changed_entries": [
      "Contents/section0.xml",
      "Contents/section1.xml",
      "Preview/PrvImage.png",
      "Preview/PrvText.txt"
    ]
  },
  "replacement_map_entries": {
    "COVER": 1,
    "BODY": 121
  },
  "code": [
    {
      "file": "12_rewrite_hwpx.py",
      "start_line": 169,
      "end_line": 183,
      "text": "    if isinstance(spec, str):\n        spec = [(first.get(\"charPrIDRef\"), spec)]\n    insert_at = list(p).index(first)\n    lsa = p.find(P + \"linesegarray\")      # 원본 줄 배치 정보 제거 → 한글이 새로 계산\n    if lsa is not None:\n        p.remove(lsa)\n    for r in text_runs:\n        for t in r.findall(P + \"t\"):\n            r.remove(t)\n        if len(r) == 0:          # 순수 텍스트 run이면 제거\n            p.remove(r)\n    for i, (cid, text) in enumerate(spec):\n        run = etree.Element(P + \"run\", charPrIDRef=cid)\n        t = etree.SubElement(run, P + \"t\")\n        t.text = text"
    },
    {
      "file": "12_rewrite_hwpx.py",
      "start_line": 213,
      "end_line": 232,
      "text": "    sec1 = process_section(zin.read(\"Contents/section1.xml\"), BODY)\n    new_files[\"Contents/section0.xml\"] = sec0\n    new_files[\"Contents/section1.xml\"] = sec1\n    new_files[\"Preview/PrvText.txt\"] = (plain_text(sec0) + \"\\n\" + plain_text(sec1))[:2000].encode(\"utf-8\")\n\n    buf = io.BytesIO()\n    with zipfile.ZipFile(buf, \"w\") as zout:\n        # mimetype는 반드시 첫 항목·무압축\n        zout.writestr(zipfile.ZipInfo(\"mimetype\"), zin.read(\"mimetype\"), compress_type=zipfile.ZIP_STORED)\n        for n in names:\n            if n == \"mimetype\":\n                continue\n            data = new_files.get(n, zin.read(n))\n            zout.writestr(n, data, compress_type=zipfile.ZIP_DEFLATED)\n    with open(DST, \"wb\") as f:\n        f.write(buf.getvalue())\n    print(\"saved:\", DST, len(buf.getvalue()), \"bytes\")\n    print(\"replaced paragraphs:\", len(COVER), \"+\", len(BODY))\n\n"
    },
    {
      "file": "thresholds.py",
      "start_line": 17,
      "end_line": 25,
      "text": "# ── 온도 (시설 오이 기준 예시) ─────────────────────────────\nCOLD = 12          # 이 온도 미만이면 저온 스트레스\nHOT = 30           # 이 온도 초과면 고온\nVERY_HOT = 35      # 이 온도 초과면 심한 고온\n\nCOLD_HOURS_ALERT = 24    # 저온이 이 시간 이상이면 소견에 올림\nHOT_HOURS_ALERT = 12     # 고온이 이 시간 이상이면 소견에 올림\n\n# ── 습도 ──────────────────────────────────────────────────"
    },
    {
      "file": "analyze.py",
      "start_line": 318,
      "end_line": 327,
      "text": "    pct_cold = R[\"hrs_cold\"] / total * 100 if total else 0\n    if R[\"hrs_cold\"] >= T.COLD_HOURS_ALERT:\n        out.append((\"serious\", \"야간 저온 노출\",\n                    f\"생육 하한 {T.COLD}℃ 미만이 <b>{R['hrs_cold']}시간</b>\"\n                    f\"(전체의 {pct_cold:.0f}%) 발생했습니다. \"\n                    f\"기간 최저기온은 {R['cold_day']:%m월 %d일} <b>{R['t_min']:.1f}℃</b>였습니다.\"\n                    + vs(\"hrs_cold\", \"시간\", 0.10)))\n    else:\n        out.append((\"good\", \"야간 온도 관리\",\n                    f\"생육 하한 {T.COLD}℃ 미만이 {R['hrs_cold']}시간으로 적었습니다.\"))"
    }
  ]
}
