{"id":4644,"date":"2025-01-19T20:54:00","date_gmt":"2025-01-19T15:24:00","guid":{"rendered":"https:\/\/rajmedical.co.in\/?p=4644"},"modified":"2026-07-19T20:54:31","modified_gmt":"2026-07-19T15:24:31","slug":"pdf-compressor","status":"publish","type":"post","link":"https:\/\/rajmedical.co.in\/hi\/pdf-compressor\/","title":{"rendered":"PDF Compressor"},"content":{"rendered":"<!doctype html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"utf-8\"\/>\r\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"\/>\r\n<title>Press \u2014 PDF compressor<\/title>\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Big+Shoulders+Display:wght@600;700;800&family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600&display=swap\" rel=\"stylesheet\">\r\n<style>\r\n\r\n  :root{\r\n    --bg: #1c1b19;\r\n    --panel: #242220;\r\n    --panel-2: #2b2925;\r\n    --border: #3a3733;\r\n    --paper: #f2ede4;\r\n    --paper-dim: #c9c2b4;\r\n    --steel: #8fa3a8;\r\n    --steel-dim: #6c7a7e;\r\n    --safelight: #ff6a2b;\r\n    --safelight-dim: #c9531f;\r\n    --good: #6fcf7a;\r\n    --warn: #ffb84d;\r\n    --radius: 4px;\r\n  }\r\n  *{ box-sizing: border-box; }\r\n  html,body{ margin:0; padding:0; }\r\n  .wrap{\r\n    background: var(--bg);\r\n    color: var(--paper);\r\n    font-family: 'IBM Plex Sans', sans-serif;\r\n    -webkit-font-smoothing: antialiased;\r\n    min-height: 100vh;\r\n  }\r\n  .mono{ font-family: 'IBM Plex Mono', monospace; }\r\n  a{ color: inherit; }\r\n  button{ font-family: inherit; }\r\n  ::selection{ background: var(--safelight); color: #1c1b19; }\r\n\r\n  :focus-visible{ outline: 2px solid var(--safelight); outline-offset: 2px; }\r\n\r\n  .wrap{\r\n    max-width: 980px;\r\n    margin: 0 auto;\r\n    padding: 56px 24px 80px;\r\n  }\r\n\r\n  \/* ---------- Header ---------- *\/\r\n  header{ margin-bottom: 40px; }\r\n  .eyebrow{\r\n    font-size: 11px;\r\n    letter-spacing: 0.16em;\r\n    text-transform: uppercase;\r\n    color: var(--steel);\r\n    margin: 0 0 10px;\r\n  }\r\n  .eyebrow .dot{ color: var(--safelight); }\r\n  h1.wordmark{\r\n    font-family: 'Big Shoulders Display', sans-serif;\r\n    font-weight: 800;\r\n    font-size: clamp(56px, 11vw, 96px);\r\n    line-height: 0.86;\r\n    letter-spacing: -0.01em;\r\n    margin: 0 0 16px;\r\n    color: var(--paper);\r\n    opacity: 0;\r\n    transform: translateY(10px);\r\n    animation: rise 0.6s ease forwards;\r\n  }\r\n  h1.wordmark span{ color: var(--safelight); }\r\n  @keyframes rise{ to{ opacity:1; transform: translateY(0); } }\r\n  .tagline{\r\n    font-size: 16px;\r\n    line-height: 1.55;\r\n    color: var(--paper-dim);\r\n    max-width: 52ch;\r\n    margin: 0;\r\n  }\r\n\r\n  \/* ---------- Dropzone ---------- *\/\r\n  .dropzone{\r\n    position: relative;\r\n    border: 2px dashed var(--border);\r\n    border-radius: var(--radius);\r\n    padding: 64px 24px;\r\n    text-align: center;\r\n    cursor: pointer;\r\n    transition: border-color 0.15s ease, background-color 0.15s ease;\r\n    margin-bottom: 28px;\r\n  }\r\n  .dropzone:hover{ border-color: #545049; }\r\n  .dropzone.active{\r\n    border-color: var(--safelight);\r\n    background: rgba(255,106,43,0.06);\r\n  }\r\n  .dropzone .corner{\r\n    position: absolute;\r\n    width: 18px; height: 18px;\r\n    border: 0 solid var(--safelight);\r\n    opacity: 0.85;\r\n  }\r\n  .dropzone .corner.tl{ top:10px; left:10px; border-top-width:2px; border-left-width:2px; }\r\n  .dropzone .corner.tr{ top:10px; right:10px; border-top-width:2px; border-right-width:2px; }\r\n  .dropzone .corner.bl{ bottom:10px; left:10px; border-bottom-width:2px; border-left-width:2px; }\r\n  .dropzone .corner.br{ bottom:10px; right:10px; border-bottom-width:2px; border-right-width:2px; }\r\n  .dropzone svg{ color: var(--steel); margin-bottom: 14px; }\r\n  .dropzone .dz-title{ font-size: 19px; font-weight: 500; margin: 0 0 8px; color: var(--paper); }\r\n  .dropzone .dz-sub{ font-size: 12px; color: var(--steel); letter-spacing: 0.02em; }\r\n  .dropzone input[type=file]{ display:none; }\r\n\r\n  \/* ---------- Global stats \/ controls bar ---------- *\/\r\n  .statsbar{\r\n    display:none;\r\n    background: var(--panel);\r\n    border: 1px solid var(--border);\r\n    border-radius: var(--radius);\r\n    padding: 14px 18px;\r\n    margin-bottom: 20px;\r\n    align-items: center;\r\n    justify-content: space-between;\r\n    gap: 16px;\r\n    flex-wrap: wrap;\r\n  }\r\n  .statsbar.show{ display:flex; }\r\n  .statsbar .totals{ font-size: 13px; color: var(--paper-dim); }\r\n  .statsbar .totals b{ color: var(--paper); font-weight: 600; }\r\n  .statsbar .totals .pct{ color: var(--good); font-weight: 600; }\r\n  .statsbar .actions{ display:flex; gap:8px; flex-wrap: wrap; align-items:center; }\r\n\r\n  select.mini, .num-input{\r\n    background: var(--panel-2);\r\n    border: 1px solid var(--border);\r\n    color: var(--paper);\r\n    font-family: 'IBM Plex Mono', monospace;\r\n    font-size: 12px;\r\n    padding: 6px 8px;\r\n    border-radius: var(--radius);\r\n  }\r\n\r\n  .btn{\r\n    font-family: 'IBM Plex Mono', monospace;\r\n    font-size: 11px;\r\n    letter-spacing: 0.06em;\r\n    text-transform: uppercase;\r\n    padding: 8px 14px;\r\n    border-radius: var(--radius);\r\n    border: 1px solid var(--border);\r\n    background: transparent;\r\n    color: var(--paper-dim);\r\n    cursor: pointer;\r\n    transition: all 0.12s ease;\r\n  }\r\n  .btn:hover{ border-color: var(--steel); color: var(--paper); }\r\n  .btn.primary{\r\n    background: var(--safelight);\r\n    border-color: var(--safelight);\r\n    color: #1c1503;\r\n    font-weight: 600;\r\n  }\r\n  .btn.primary:hover{ background: #ff7d45; }\r\n  .btn:disabled{ opacity:0.35; cursor: not-allowed; }\r\n\r\n  \/* ---------- Cards ---------- *\/\r\n  .cards{ display:flex; flex-direction: column; gap: 16px; }\r\n  .card{\r\n    background: var(--panel);\r\n    border: 1px solid var(--border);\r\n    border-radius: var(--radius);\r\n    padding: 18px;\r\n    position: relative;\r\n    opacity: 0;\r\n    transform: translateY(6px);\r\n    animation: cardin 0.25s ease forwards;\r\n  }\r\n  @keyframes cardin{ to{ opacity:1; transform: translateY(0); } }\r\n  .card.skeleton .card-grid{ opacity: 0.4; }\r\n  .card.error{ border-color: var(--safelight-dim); }\r\n  .card .remove{\r\n    position:absolute; top:12px; right:12px;\r\n    background:none; border:none; color: var(--steel-dim);\r\n    font-size: 18px; line-height:1; cursor:pointer; padding: 4px;\r\n  }\r\n  .card .remove:hover{ color: var(--safelight); }\r\n\r\n  .card-grid{\r\n    display:grid;\r\n    grid-template-columns: 150px 1fr;\r\n    gap: 20px;\r\n  }\r\n  @media (max-width: 640px){\r\n    .card-grid{ grid-template-columns: 1fr; }\r\n  }\r\n\r\n  .thumb-wrap{\r\n    width:100%;\r\n    aspect-ratio: 1\/1;\r\n    border-radius: 2px;\r\n    border: 1px solid var(--border);\r\n    overflow:hidden;\r\n    background-image:\r\n      linear-gradient(45deg, #2b2925 25%, transparent 25%),\r\n      linear-gradient(-45deg, #2b2925 25%, transparent 25%),\r\n      linear-gradient(45deg, transparent 75%, #2b2925 75%),\r\n      linear-gradient(-45deg, transparent 75%, #2b2925 75%);\r\n    background-size: 16px 16px;\r\n    background-position: 0 0, 0 8px, 8px -8px, -8px 0px;\r\n    background-color: #1f1e1b;\r\n  }\r\n  .thumb-wrap img{ width:100%; height:100%; object-fit: contain; display:block; }\r\n\r\n  .card-head{ display:flex; align-items:flex-start; justify-content:space-between; gap: 10px; margin-bottom: 14px; padding-right: 20px; }\r\n  .card-name{ font-size: 13px; color: var(--paper); word-break: break-all; margin: 0 0 6px; }\r\n  .pill-row{ display:flex; gap:8px; flex-wrap: wrap; align-items:center; }\r\n  .pill{\r\n    font-size: 10px;\r\n    letter-spacing: 0.05em;\r\n    text-transform: uppercase;\r\n    border: 1px solid var(--steel-dim);\r\n    color: var(--steel);\r\n    padding: 2px 6px;\r\n    border-radius: 2px;\r\n  }\r\n  .meta-text{ font-size: 11px; color: var(--steel); }\r\n\r\n  \/* Quality control *\/\r\n  .ctrl-block{ margin-bottom: 16px; }\r\n  .ctrl-label{\r\n    font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;\r\n    color: var(--steel); display:flex; justify-content: space-between; margin-bottom: 8px;\r\n  }\r\n  .ctrl-label .val{ color: var(--paper); }\r\n  input[type=range]{\r\n    -webkit-appearance: none;\r\n    width: 100%;\r\n    height: 4px;\r\n    background: var(--border);\r\n    border-radius: 2px;\r\n    margin: 0;\r\n  }\r\n  input[type=range]::-webkit-slider-thumb{\r\n    -webkit-appearance: none;\r\n    width: 15px; height: 15px;\r\n    border-radius: 50%;\r\n    background: var(--safelight);\r\n    cursor: pointer;\r\n    border: 2px solid #1c1b19;\r\n    box-shadow: 0 0 0 1px var(--safelight);\r\n  }\r\n  input[type=range]::-moz-range-thumb{\r\n    width: 15px; height: 15px;\r\n    border-radius: 50%;\r\n    background: var(--safelight);\r\n    cursor: pointer;\r\n    border: 2px solid #1c1b19;\r\n  }\r\n  .stops-row{\r\n    display:flex; justify-content: space-between;\r\n    margin-top: 6px;\r\n    font-size: 10px;\r\n    color: var(--steel-dim);\r\n    font-family: 'IBM Plex Mono', monospace;\r\n  }\r\n  .stops-row span{ flex: 1; text-align:center; }\r\n  .stops-row span:first-child{ text-align:left; }\r\n  .stops-row span:last-child{ text-align:right; }\r\n  .stops-row span.active{ color: var(--safelight); font-weight: 600; }\r\n\r\n  \/* Format chips *\/\r\n  .chip-row{ display:flex; gap:8px; flex-wrap: wrap; }\r\n  .chip{\r\n    flex: 1 1 90px;\r\n    position: relative;\r\n    border: 1px solid var(--border);\r\n    background: var(--panel-2);\r\n    border-radius: var(--radius);\r\n    padding: 8px 10px;\r\n    text-align:left;\r\n    cursor: pointer;\r\n    transition: border-color 0.12s ease, background-color 0.12s ease;\r\n  }\r\n  .chip:hover:not(:disabled){ border-color: var(--steel); }\r\n  .chip.active{ border-color: var(--safelight); background: rgba(255,106,43,0.08); }\r\n  .chip:disabled{ opacity: 0.32; cursor: not-allowed; }\r\n  .chip .fmt{ display:block; font-family:'IBM Plex Mono', monospace; font-size: 11px; font-weight:600; letter-spacing:0.04em; color: var(--paper); text-transform: uppercase; }\r\n  .chip .sz{ display:block; font-family:'IBM Plex Mono', monospace; font-size: 11px; color: var(--steel); margin-top:3px; }\r\n  .chip.active .fmt{ color: var(--safelight); }\r\n  .chip .badge{\r\n    position:absolute; top:-7px; right:6px;\r\n    font-size: 8px; letter-spacing: 0.05em; text-transform: uppercase;\r\n    background: var(--good); color: #0e1f10; padding: 1px 4px; border-radius: 2px; font-weight:700;\r\n  }\r\n\r\n  \/* Resize row *\/\r\n  .resize-row{ display:flex; align-items:center; gap:10px; margin-top: 14px; font-size: 12px; color: var(--paper-dim); flex-wrap: wrap; }\r\n  .resize-row label.cb{ display:flex; align-items:center; gap:7px; cursor:pointer; }\r\n  input[type=checkbox]{\r\n    appearance: none; width:15px; height:15px; border:1px solid var(--steel-dim); border-radius:2px;\r\n    background: var(--panel-2); cursor:pointer; position: relative; flex-shrink:0;\r\n  }\r\n  input[type=checkbox]:checked{ background: var(--safelight); border-color: var(--safelight); }\r\n  input[type=checkbox]:checked::after{\r\n    content:''; position:absolute; left:4px; top:1px; width:4px; height:8px;\r\n    border: solid #1c1b19; border-width: 0 2px 2px 0; transform: rotate(45deg);\r\n  }\r\n  .resize-row .num-input{ width: 80px; }\r\n  .resize-fields{ display:flex; align-items:center; gap:8px; }\r\n  .resize-fields[hidden]{ display:none; }\r\n\r\n  \/* Result row *\/\r\n  .result-row{\r\n    margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border);\r\n    display:flex; align-items:center; justify-content: space-between; gap: 14px; flex-wrap: wrap;\r\n  }\r\n  .result-figures{ display:flex; align-items:baseline; gap: 12px; flex-wrap: wrap; }\r\n  .fig{ }\r\n  .fig .flabel{ font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--steel); display:block; margin-bottom: 3px; }\r\n  .fig .fval{ font-family: 'IBM Plex Mono', monospace; font-size: 14px; color: var(--steel); }\r\n  .fig.out .fval{ font-family: 'Big Shoulders Display', sans-serif; font-size: 26px; font-weight: 700; color: var(--paper); }\r\n  .arrow{ color: var(--steel-dim); font-size: 16px; }\r\n  .pct-badge{\r\n    font-family: 'IBM Plex Mono', monospace; font-size: 12px; font-weight: 600;\r\n    padding: 3px 8px; border-radius: 3px;\r\n  }\r\n  .pct-badge.down{ color: var(--good); background: rgba(111,207,122,0.12); }\r\n  .pct-badge.up{ color: var(--warn); background: rgba(255,184,77,0.12); }\r\n\r\n  .err-msg{ font-size: 13px; color: var(--warn); margin: 4px 0 0; }\r\n\r\n  \/* ---------- Footer ---------- *\/\r\n  footer{ margin-top: 56px; text-align:center; }\r\n  footer p{ font-size: 11px; color: var(--steel-dim); letter-spacing: 0.02em; line-height:1.6; }\r\n\r\n  @media (prefers-reduced-motion: reduce){\r\n    *{ animation: none !important; transition: none !important; }\r\n  }\r\n\r\n  .engine-bar{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:12px 16px;margin-bottom:20px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;}\r\n  .engine-badge{font-family:'IBM Plex Mono',monospace;font-size:11px;font-weight:700;letter-spacing:.08em;padding:4px 9px;border-radius:3px;flex-shrink:0;}\r\n  .engine-badge.gs{background:rgba(111,207,122,.15);color:var(--good);border:1px solid var(--good);}\r\n  .engine-badge.js{background:var(--panel-2);color:var(--steel);border:1px solid var(--border);}\r\n  #engineDetail{font-size:12px;flex:1;}\r\n  .how-box{background:var(--panel-2);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;margin-bottom:20px;font-size:12px;color:var(--steel);line-height:1.7;}\r\n  .how-box b{color:var(--paper-dim);}\r\n  .how-box code{font-family:'IBM Plex Mono',monospace;font-size:11px;background:var(--panel);border:1px solid var(--border);padding:1px 5px;border-radius:2px;color:var(--paper-dim);}\r\n  .preset-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:18px;}\r\n  @media(max-width:560px){.preset-grid{grid-template-columns:1fr;}}\r\n  .preset-btn{background:var(--panel-2);border:1px solid var(--border);border-radius:var(--radius);padding:14px 12px;text-align:left;cursor:pointer;transition:border-color .12s,background .12s;}\r\n  .preset-btn:hover{border-color:var(--steel);}\r\n  .preset-btn.active{border-color:var(--safelight);background:rgba(255,106,43,.08);}\r\n  .preset-btn .p-name{display:block;font-family:'IBM Plex Mono',monospace;font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--paper);margin-bottom:5px;}\r\n  .preset-btn.active .p-name{color:var(--safelight);}\r\n  .preset-btn .p-desc{display:block;font-size:12px;color:var(--steel);line-height:1.45;margin-bottom:5px;}\r\n  .preset-btn .p-spec{display:block;font-family:'IBM Plex Mono',monospace;font-size:10px;color:var(--steel-dim);}\r\n  .controls-panel{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:18px;margin-bottom:20px;}\r\n  .section-label{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--steel);margin:0 0 14px;}\r\n  .toggle-list{display:flex;gap:18px;flex-wrap:wrap;padding-top:14px;border-top:1px solid var(--border);}\r\n  .toggle-item{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--paper-dim);cursor:pointer;}\r\n  .pdf-queue{display:flex;flex-direction:column;gap:14px;margin-bottom:20px;}\r\n  .pdf-card{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:18px;opacity:0;transform:translateY(6px);animation:cardin .25s ease forwards;}\r\n  .pdf-card.processing{border-color:var(--safelight);}\r\n  .pdf-card.done{border-color:var(--good);}\r\n  .pdf-card.error{border-color:var(--warn);}\r\n  .pdf-card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:10px;}\r\n  .pdf-card-name{font-size:14px;color:var(--paper);margin:0 0 5px;word-break:break-all;}\r\n  .prog-track{height:3px;background:var(--border);border-radius:2px;overflow:hidden;margin-bottom:6px;}\r\n  .prog-fill{height:100%;background:var(--safelight);border-radius:2px;width:0%;transition:width .18s ease;}\r\n  .prog-text{font-family:'IBM Plex Mono',monospace;font-size:11px;color:var(--steel);margin-bottom:8px;}\r\n  .result-bar{display:flex;gap:24px;align-items:flex-end;flex-wrap:wrap;padding-top:14px;border-top:1px solid var(--border);}\r\n  .r-fig .r-label{font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--steel);display:block;margin-bottom:4px;}\r\n  .r-fig .r-val{font-family:'IBM Plex Mono',monospace;font-size:17px;font-weight:600;line-height:1;color:var(--paper);}\r\n  .r-fig .r-val.muted{color:var(--steel-dim);font-size:14px;}\r\n  .r-fig .r-val.good{color:var(--good);}\r\n  .r-fig .r-val.warn{color:var(--warn);}\r\n  .r-fig .r-sub{font-family:'IBM Plex Mono',monospace;font-size:10px;color:var(--steel-dim);margin-top:5px;line-height:1.55;max-width:400px;}\r\n  .batch-bar{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:14px 18px;display:none;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:20px;}\r\n  .batch-bar.show{display:flex;}\r\n  #batchStatus{font-family:'IBM Plex Mono',monospace;font-size:12px;color:var(--steel);}\r\n  #batchStatus b{color:var(--paper);}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n<div class=\"wrap\">\r\n  <header>\r\n    <p class=\"eyebrow\"><span class=\"dot\">\u25cf<\/span> client-side photo lab<\/p>\r\n    <h1 class=\"wordmark\">PRE<span>SS<\/span><\/h1>\r\n    <p class=\"tagline\">Dual-pass compression \u2014 runs both per-image recompression and full-page rasterisation, then keeps whichever result is smaller. Works on text PDFs, image PDFs and scans.<\/p>\r\n  <\/header>\r\n<!-- \r\n  <div class=\"engine-bar\">\r\n    <span class=\"engine-badge js\" id=\"engineBadge\">JS<\/span>\r\n    <span id=\"engineDetail\" style=\"color:var(--steel);\">Initialising\u2026<\/span>\r\n  <\/div>\r\n\r\n  <div class=\"how-box\">\r\n    <b>How the dual-pass works:<\/b><br>\r\n    <b>Pass A \u2014 per-image:<\/b> Finds every embedded JPEG, PNG-style and LZW image, downsamples to the target DPI and re-encodes at target quality. Leaves text and vectors untouched.<br>\r\n    <b>Pass B \u2014 rasterise:<\/b> Renders each page via pdf.js at the target DPI, encodes as JPEG and builds a new PDF. Works on text PDFs too \u2014 text becomes high-quality pixels.<br>\r\n    The smaller of Pass A and Pass B is downloaded. If neither beats the original, metadata is stripped and the original is returned. When Ghostscript WASM loads (green badge), it replaces both passes with a single Ghostscript run.\r\n  <\/div>\r\n -->\r\n  <div class=\"controls-panel\">\r\n    <p class=\"section-label\">Compression level<\/p>\r\n    <div class=\"preset-grid\" id=\"presetGrid\">\r\n      <button class=\"preset-btn\" data-idx=\"0\">\r\n        <span class=\"p-name\">Recommended<\/span>\r\n        <span class=\"p-desc\">Best quality\/size ratio.<\/span>\r\n        <span class=\"p-spec\">150 dpi \u00b7 JPEG 76%<\/span>\r\n      <\/button>\r\n      <button class=\"preset-btn active\" data-idx=\"1\">\r\n        <span class=\"p-name\">Strong<\/span>\r\n        <span class=\"p-desc\">Significant reduction.<\/span>\r\n        <span class=\"p-spec\">120 dpi \u00b7 JPEG 62%<\/span>\r\n      <\/button>\r\n      <button class=\"preset-btn\" data-idx=\"2\">\r\n        <span class=\"p-name\">Maximum<\/span>\r\n        <span class=\"p-desc\">Smallest file.<\/span>\r\n        <span class=\"p-spec\">96 dpi \u00b7 JPEG 45%<\/span>\r\n      <\/button>\r\n    <\/div>\r\n    <div class=\"toggle-list\">\r\n      <label class=\"toggle-item\"><input type=\"checkbox\" id=\"compStreamsChk\" checked\/> Compress streams<\/label>\r\n      <label class=\"toggle-item\"><input type=\"checkbox\" id=\"removeOptChk\"\/> Remove bookmarks<\/label>\r\n      <label class=\"toggle-item\"><input type=\"checkbox\" id=\"removeAnnChk\"\/> Remove annotations<\/label>\r\n      <label class=\"toggle-item\"><input type=\"checkbox\" id=\"metaOnlyChk\"\/> Metadata only<\/label>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <section class=\"dropzone\" id=\"dz\" tabindex=\"0\" role=\"button\" aria-label=\"Upload PDFs\">\r\n    <span class=\"corner tl\"><\/span><span class=\"corner tr\"><\/span><span class=\"corner bl\"><\/span><span class=\"corner br\"><\/span>\r\n    <svg width=\"34\" height=\"34\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\">\r\n      <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\"\/>\r\n      <path d=\"M14 2v6h6\"\/><path d=\"M12 11v6M9 14l3-3 3 3\"\/>\r\n    <\/svg>\r\n    <p class=\"dz-title\">Drop PDFs here, or click to browse<\/p>\r\n    <p class=\"dz-sub mono\">Multiple files \u2014 nothing saves in our server.<\/p>\r\n    <input type=\"file\" id=\"fileInput\" accept=\"application\/pdf\" multiple\/>\r\n  <\/section>\r\n\r\n  <div class=\"batch-bar\" id=\"batchBar\">\r\n    <div id=\"batchStatus\">\u2014<\/div>\r\n    <div style=\"display:flex;gap:8px;flex-wrap:wrap;\">\r\n      <button class=\"btn\" id=\"dlAllBtn\" disabled>Download all (.zip)<\/button>\r\n      <button class=\"btn\" id=\"clearBtn\">Clear all<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"pdf-queue\" id=\"pdfQueue\"><\/div>\r\n\r\n  <footer>\r\n    <p> <!-- Pass A: pdf-lib + pako \u2014 per-image recompression, stream deflation<br>\r\n       Pass B: pdf.js + pdf-lib \u2014 full-page rasterisation at target DPI<br>\r\n       GS mode: Ghostscript 9.56 WASM \u2014 font subsetting, all image types<br> -->\r\n       No file ever saves in our server.<\/p>\r\n  <\/footer>\r\n<\/div>\r\n\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jszip\/3.10.1\/jszip.min.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pako\/2.1.0\/pako.min.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf-lib\/1.17.1\/pdf-lib.min.js\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/2.16.105\/pdf.min.js\"><\/script>\r\n<script>\r\nif(typeof pdfjsLib!=='undefined')pdfjsLib.GlobalWorkerOptions.workerSrc='https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/2.16.105\/pdf.worker.min.js';\r\n<\/script>\r\n<script>\r\n(function(){\r\n\"use strict\";\r\n\r\nvar PRESETS=[\r\n  {id:'recommended',name:'Recommended',dpi:150,q:0.76,gs:'recommended'},\r\n  {id:'strong',     name:'Strong',     dpi:120,q:0.62,gs:'strong'},\r\n  {id:'maximum',    name:'Maximum',    dpi:96, q:0.45,gs:'maximum'}\r\n];\r\nvar activePreset=1;\r\nvar cards=new Map(),order=[];\r\n\r\n\/\/ GS WASM state (no Workers, plain <script> tag)\r\nvar gsModule=null,gsState='idle',gsWaiters=[];\r\nvar GS_SOURCES=[\r\n  'https:\/\/cdn.jsdelivr.net\/npm\/ghostscript-wasm@0.1.0\/dist\/ghostscript.js',\r\n  'https:\/\/unpkg.com\/ghostscript-wasm@0.1.0\/dist\/ghostscript.js'\r\n];\r\n\r\n\/\/ \u2500\u2500\u2500 Utils \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction fmtB(b){if(!b&&b!==0)return'\u2014';if(b<1024)return b+' B';var u=['KB','MB','GB'],v=b,i=-1;do{v\/=1024;i++;}while(v>=1024&&i<u.length-1);return v.toFixed(v<10?2:1)+' '+u[i];}\r\nfunction uid(){return'c'+Math.random().toString(36).slice(2,9)+Date.now().toString(36);}\r\nfunction baseName(n){var i=n.lastIndexOf('.');return i>0?n.slice(0,i):n;}\r\nfunction esc(s){var d=document.createElement('div');d.textContent=s;return d.innerHTML;}\r\nfunction trigDl(url,name){var a=document.createElement('a');a.href=url;a.download=name;document.body.appendChild(a);a.click();a.remove();}\r\nfunction pctSaved(o,n){return((1-(n\/o))*100);}\r\nfunction pn(s){return PDFLib.PDFName.of(s);}\r\nfunction numE(d,k){try{var v=d.get(pn(k));return v?v.asNumber():null;}catch(e){return null;}}\r\nfunction hasPako(){return typeof pako!=='undefined';}\r\nfunction hasPdfjsLib(){return typeof pdfjsLib!=='undefined';}\r\n\r\n\/\/ \u2500\u2500\u2500 Engine badge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction setUI(badge,detail,col){\r\n  var b=document.getElementById('engineBadge'),d=document.getElementById('engineDetail');\r\n  if(b){b.textContent=badge;b.className='engine-badge '+(badge==='GS'?'gs':'js');}\r\n  if(d){d.textContent=detail;d.style.color=col||'var(--steel)';}\r\n}\r\n\r\n\/\/ \u2500\u2500\u2500 Load GS WASM via <script> tag (no Worker \/ no blob: URL) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction loadScript(src){\r\n  return new Promise(function(resolve,reject){\r\n    if(document.querySelector('script[src=\"'+src+'\"]')){resolve();return;}\r\n    var s=document.createElement('script');s.src=src;\r\n    s.onload=resolve;s.onerror=function(){reject(new Error('load failed: '+src));};\r\n    document.head.appendChild(s);\r\n  });\r\n}\r\nasync function initGhostscript(){\r\n  if(gsState==='ready')return true;\r\n  if(gsState==='failed')return false;\r\n  if(gsState==='loading')return new Promise(function(r){gsWaiters.push(r);});\r\n  gsState='loading';\r\n  setUI('JS','Loading Ghostscript WASM (~12 MB, cached after first load)\u2026');\r\n  for(var i=0;i<GS_SOURCES.length;i++){\r\n    try{\r\n      await loadScript(GS_SOURCES[i]);\r\n      var factory=window.ghostscript||window.createGhostscript||window.Ghostscript||window.GhostscriptModule;\r\n      if(typeof factory!=='function')throw new Error('No factory');\r\n      setUI('JS','Initialising Ghostscript\u2026');\r\n      gsModule=await factory();\r\n      if(!gsModule||!gsModule.FS||!gsModule.callMain)throw new Error('Bad module');\r\n      gsState='ready';\r\n      setUI('GS','Ghostscript WASM ready \u2014 ilovepdf-level compression active','var(--good)');\r\n      gsWaiters.forEach(function(f){f(true);});gsWaiters=[];\r\n      return true;\r\n    }catch(e){console.warn('[Press] GS source failed:',GS_SOURCES[i],e.message);}\r\n  }\r\n  gsState='failed';\r\n  setUI('JS','Ghostscript WASM unavailable \u2014 dual-pass browser engine active');\r\n  gsWaiters.forEach(function(f){f(false);});gsWaiters=[];\r\n  return false;\r\n}\r\nasync function compressViaGS(pdfBytes,presetId){\r\n  var presets={\r\n    recommended:{s:'\/ebook', c:150,g:150,m:300},\r\n    strong:     {s:'\/ebook', c:100,g:100,m:200},\r\n    maximum:    {s:'\/screen',c:72, g:72, m:150}\r\n  };\r\n  var p=presets[presetId]||presets.recommended;\r\n  var inp='\/gs_in_'+Date.now()+'.pdf',out='\/gs_out_'+Date.now()+'.pdf';\r\n  gsModule.FS.writeFile(inp,pdfBytes);\r\n  gsModule.callMain([\r\n    '-dBATCH','-dNOPAUSE','-q','-sDEVICE=pdfwrite','-dCompatibilityLevel=1.4',\r\n    '-dPDFSETTINGS='+p.s,'-dEmbedAllFonts=true','-dSubsetFonts=true',\r\n    '-dDownsampleColorImages=true','-dDownsampleGrayImages=true','-dDownsampleMonoImages=true',\r\n    '-dColorImageDownsampleType=\/Bicubic','-dGrayImageDownsampleType=\/Bicubic',\r\n    '-dColorImageResolution='+p.c,'-dGrayImageResolution='+p.g,'-dMonoImageResolution='+p.m,\r\n    '-dAutoRotatePages=\/None','-sOutputFile='+out,inp\r\n  ]);\r\n  var result=null;\r\n  try{result=gsModule.FS.readFile(out);}catch(e){}\r\n  try{gsModule.FS.unlink(inp);}catch(e){}\r\n  try{gsModule.FS.unlink(out);}catch(e){}\r\n  return result;\r\n}\r\n\r\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n\/\/ PASS A \u2014 Page rasterisation (works for ALL PDF types, including text)\r\n\/\/ Renders every page via pdf.js at target DPI \u2192 JPEG \u2192 new PDF\r\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\nasync function compressViaRasterisation(pdfBytes, dpi, quality, onP){\r\n  if(!hasPdfjsLib()) return null;\r\n  var scale=dpi\/72;\r\n  onP(5,'Loading pages for rasterisation\u2026');\r\n  var pjsDoc=await pdfjsLib.getDocument({data:pdfBytes.slice()}).promise;\r\n  var n=pjsDoc.numPages;\r\n  var newDoc=await PDFLib.PDFDocument.create();\r\n\r\n  for(var i=1;i<=n;i++){\r\n    onP(5+Math.round(((i-1)\/n)*85),'Rasterising page '+i+' of '+n+'\u2026');\r\n    var page=await pjsDoc.getPage(i);\r\n    var vpOrig=page.getViewport({scale:1}); \/\/ physical size in CSS pts \u2248 PDF pts\r\n    var vpRender=page.getViewport({scale:scale});\r\n    var canvas=document.createElement('canvas');\r\n    canvas.width=Math.ceil(vpRender.width);\r\n    canvas.height=Math.ceil(vpRender.height);\r\n    var ctx=canvas.getContext('2d');\r\n    ctx.fillStyle='#ffffff';ctx.fillRect(0,0,canvas.width,canvas.height);\r\n    await page.render({canvasContext:ctx,viewport:vpRender}).promise;\r\n    \/\/ Re-encode as JPEG at target quality\r\n    var blob=await new Promise(function(res){\r\n      canvas.toBlob(function(b){res(b);},'image\/jpeg',quality);\r\n    });\r\n    var imgBytes=new Uint8Array(await blob.arrayBuffer());\r\n    var emb=await newDoc.embedJpg(imgBytes);\r\n    var np=newDoc.addPage([vpOrig.width,vpOrig.height]);\r\n    np.drawImage(emb,{x:0,y:0,width:vpOrig.width,height:vpOrig.height});\r\n  }\r\n  onP(93,'Saving rasterised PDF\u2026');\r\n  var bytes=await newDoc.save({useObjectStreams:true});\r\n  onP(100,'Done');\r\n  return bytes;\r\n}\r\n\r\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n\/\/ PASS B \u2014 Per-image recompression (better for PDFs with vector text)\r\n\/\/ Finds embedded images, recompresses them, leaves text as vectors\r\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\nfunction isRawStream(o){return o&&o.dict&&(o.contents instanceof Uint8Array);}\r\nfunction isImgStream(o){if(!isRawStream(o))return false;try{var s=o.dict.get(pn('Subtype'));return s&&s.encodedName==='\/Image';}catch(e){return false;}}\r\nfunction getFilter(dict){try{var f=dict.get(pn('Filter'));if(!f)return null;if(f.encodedName)return f.encodedName.slice(1);if(f.array){if(f.array.length===1)return f.array[0].encodedName.slice(1);return'MULTI';}}catch(e){}return null;}\r\nfunction hasFilter(o){try{return!!o.dict.get(pn('Filter'));}catch(e){return false;}}\r\nfunction getChannels(dict,ctx){try{var cs=dict.get(pn('ColorSpace'));if(!cs)return 3;if(cs.encodedName){var n=cs.encodedName;if(n==='\/DeviceGray'||n==='\/G')return 1;if(n==='\/DeviceCMYK'||n==='\/CMYK')return 4;return 3;}if(cs.array&&cs.array.length>=1){var f=cs.array[0];if(f.encodedName==='\/ICCBased'){try{var icc=ctx.lookup(cs.array[1]);return numE(icc.dict,'N')||3;}catch(x){}}if(f.encodedName==='\/DeviceGray')return 1;if(f.encodedName==='\/DeviceCMYK')return 4;}}catch(e){}return 3;}\r\nfunction paethP(a,b,c){var p=a+b-c,pa=Math.abs(p-a),pb=Math.abs(p-b),pc=Math.abs(p-c);if(pa<=pb&&pa<=pc)return a;if(pb<=pc)return b;return c;}\r\nfunction undoPng(raw,cols,ch,bpc){var bpp=Math.ceil(ch*bpc\/8),rowB=Math.ceil(cols*ch*bpc\/8),rows=Math.floor(raw.length\/(1+rowB)),out=new Uint8Array(rows*rowB);for(var r=0;r<rows;r++){var fb=raw[r*(1+rowB)],src=r*(1+rowB)+1,dst=r*rowB,prev=r>0?out.slice(dst-rowB,dst):new Uint8Array(rowB);switch(fb){case 0:out.set(raw.slice(src,src+rowB),dst);break;case 1:for(var i=0;i<rowB;i++){var a1=i>=bpp?out[dst+i-bpp]:0;out[dst+i]=(raw[src+i]+a1)&0xFF;}break;case 2:for(var i=0;i<rowB;i++)out[dst+i]=(raw[src+i]+prev[i])&0xFF;break;case 3:for(var i=0;i<rowB;i++){var a2=i>=bpp?out[dst+i-bpp]:0;out[dst+i]=(raw[src+i]+Math.floor((a2+prev[i])\/2))&0xFF;}break;case 4:for(var i=0;i<rowB;i++){var a3=i>=bpp?out[dst+i-bpp]:0,b3=prev[i],c3=i>=bpp?prev[i-bpp]:0;out[dst+i]=(raw[src+i]+paethP(a3,b3,c3))&0xFF;}break;default:out.set(raw.slice(src,src+rowB),dst);}}return out;}\r\nfunction undoTiff(raw,cols,ch){var out=new Uint8Array(raw.length),rb=cols*ch,rows=Math.floor(raw.length\/rb);for(var r=0;r<rows;r++){var off=r*rb;for(var i=0;i<rb;i++){var p=i>=ch?out[off+i-ch]:0;out[off+i]=(raw[off+i]+p)&0xFF;}}return out;}\r\nfunction inflateFlate(bytes,dict){if(!hasPako())return null;var inf;try{inf=pako.inflate(bytes);}catch(e){return null;}var pred=1,cols=1,ch=3,bpc=8;try{var dp=dict.get(pn('DecodeParms'));if(dp&&dp.get){var pv=dp.get(pn('Predictor'));if(pv)pred=pv.asNumber();var cv=dp.get(pn('Colors'));if(cv)ch=cv.asNumber();var bv=dp.get(pn('BitsPerComponent'));if(bv)bpc=bv.asNumber();var colv=dp.get(pn('Columns'));if(colv)cols=colv.asNumber();}}catch(e){}if(pred===1||pred===10)return inf;if(pred===2)return undoTiff(inf,cols,ch);if(pred>=10)return undoPng(inf,cols,ch,bpc);return inf;}\r\nfunction lzwDecode(input){try{var ECL=257,CLEAR=256,table=[],pos=0,buf=0,bufBits=0,bits=9,dictSize=258;for(var i=0;i<256;i++)table[i]=String.fromCharCode(i);table[CLEAR]='';table[ECL]='';function readCode(){while(bufBits<bits){if(pos>=input.length)return-1;buf=(buf<<8)|input[pos++];bufBits+=8;}var code=(buf>>(bufBits-bits))&((1<<bits)-1);bufBits-=bits;return code;}var code=readCode();if(code===CLEAR)code=readCode();var w=table[code]||'',out=[w];while(true){code=readCode();if(code<0||code===ECL)break;if(code===CLEAR){bits=9;table.length=258;dictSize=258;var c2=readCode();w=table[c2]||'';out.push(w);continue;}var entry=code<dictSize?table[code]:w+w[0];out.push(entry);table[dictSize++]=w+entry[0];w=entry;if(dictSize===(1<<bits)-1&&bits<12)bits++;}var str=out.join(''),bytes=new Uint8Array(str.length);for(var j=0;j<str.length;j++)bytes[j]=str.charCodeAt(j)&0xFF;return bytes;}catch(e){return null;}}\r\nfunction px2canvas(px,w,h,ch){var c=document.createElement('canvas');c.width=w;c.height=h;var ctx=c.getContext('2d'),id=ctx.createImageData(w,h),d=id.data,n=w*h;if(ch===1){for(var i=0;i<n;i++){var v=px[i];d[i*4]=v;d[i*4+1]=v;d[i*4+2]=v;d[i*4+3]=255;}}else if(ch===3){for(var i=0;i<n;i++){d[i*4]=px[i*3];d[i*4+1]=px[i*3+1];d[i*4+2]=px[i*3+2];d[i*4+3]=255;}}else if(ch===4){for(var i=0;i<n;i++){var c2=px[i*4]\/255,m=px[i*4+1]\/255,y2=px[i*4+2]\/255,k=px[i*4+3]\/255;d[i*4]=Math.round(255*(1-c2)*(1-k));d[i*4+1]=Math.round(255*(1-m)*(1-k));d[i*4+2]=Math.round(255*(1-y2)*(1-k));d[i*4+3]=255;}}else return null;ctx.putImageData(id,0,0);return c;}\r\nfunction decodeJpeg(bytes){return new Promise(function(res){try{var b=new Blob([bytes],{type:'image\/jpeg'}),u=URL.createObjectURL(b),img=new Image();img.onload=function(){URL.revokeObjectURL(u);res(img);};img.onerror=function(){URL.revokeObjectURL(u);res(null);};img.src=u;}catch(e){res(null);}});}\r\nfunction toJpeg(canvas,q){return new Promise(function(res){try{canvas.toBlob(function(b){res(b||null);},'image\/jpeg',q);}catch(e){res(null);}});}\r\n\r\nfunction buildPageMap(doc,ctx){var map=new Map();function scanRes(res,pw,ph){if(!res||!res.get)return;try{var xo=res.get(pn('XObject'));if(!xo||!xo.entries)return;xo.entries().forEach(function(kv){var ref=kv[1];if(!ref||ref.objectNumber==null)return;if(!map.has(ref.objectNumber))map.set(ref.objectNumber,{pw:pw,ph:ph});try{var xobj=ctx.lookup(ref);if(!xobj||!xobj.dict)return;var sub=xobj.dict.get(pn('Subtype'));if(sub&&sub.encodedName==='\/Form'){var ir=xobj.dict.get(pn('Resources'));if(ir)scanRes(ir,pw,ph);}}catch(e){}});}catch(e){}}try{doc.getPages().forEach(function(page){var pw=page.getWidth(),ph=page.getHeight();try{var res=page.node.get(pn('Resources'));scanRes(res,pw,ph);}catch(e){}});}catch(e){}return map;}\r\n\r\nfunction replaceImg(ctx,ref,obj,nb,nw,nh){var nd=PDFLib.PDFDict.withContext(ctx);try{if(obj.dict.has(pn('Type')))nd.set(pn('Type'),obj.dict.get(pn('Type')));}catch(e){}nd.set(pn('Subtype'),pn('Image'));nd.set(pn('Width'),ctx.obj(nw));nd.set(pn('Height'),ctx.obj(nh));nd.set(pn('BitsPerComponent'),ctx.obj(8));nd.set(pn('Filter'),pn('DCTDecode'));nd.set(pn('Length'),ctx.obj(nb.length));nd.set(pn('ColorSpace'),pn('DeviceRGB'));try{if(obj.dict.has(pn('SMask')))nd.set(pn('SMask'),obj.dict.get(pn('SMask')));}catch(e){}if(typeof PDFLib.PDFRawStream!=='undefined'){ctx.assign(ref,PDFLib.PDFRawStream.of(nd,nb));}else{obj.dict=nd;var w=new Uint8Array(nb.length);w.set(nb);try{Object.defineProperty(obj,'contents',{value:w,writable:true,configurable:true});}catch(e){}}}\r\n\r\nasync function compressImgObj(ctx,ref,obj,dpi,q,pageMap){\r\n  var dict=obj.dict,W=numE(dict,'Width'),H=numE(dict,'Height');\r\n  if(!W||!H||W<8||H<8)return false;\r\n  var bpc=numE(dict,'BitsPerComponent');if(bpc&&bpc<=1)return false;\r\n  if(dict.get(pn('ImageMask')))return false;\r\n  var fn=getFilter(dict);if(!fn||fn==='MULTI')return false;\r\n  var origSize=obj.contents.length;\r\n\r\n  \/\/ Always downsample to target DPI regardless of current DPI\r\n  \/\/ (don't skip images that look \"OK\" \u2014 force quality reduction)\r\n  var pw=595,ph=842;\r\n  try{var info=pageMap.get(ref.objectNumber);if(info){pw=info.pw;ph=info.ph;}}catch(e){}\r\n  var rendDpiW=W\/(pw\/72),rendDpiH=H\/(ph\/72),rendDpi=Math.min(rendDpiW,rendDpiH);\r\n  \/\/ Always target dpi, even if image is already at that DPI (quality reduction still helps)\r\n  var targetDpi=Math.min(dpi, rendDpi); \/\/ don't upscale\r\n  var scale=targetDpi\/Math.max(rendDpi,1);\r\n  var tw=Math.max(8,Math.round(W*scale)),th=Math.max(8,Math.round(H*scale));\r\n\r\n  var srcCanvas=null;\r\n  if(fn==='DCTDecode'||fn==='DCT'){\r\n    var img=await decodeJpeg(obj.contents);if(!img)return false;\r\n    var c=document.createElement('canvas');c.width=tw;c.height=th;\r\n    var c2=c.getContext('2d');c2.fillStyle='#fff';c2.fillRect(0,0,tw,th);\r\n    c2.drawImage(img,0,0,tw,th);srcCanvas=c;\r\n  }else if((fn==='FlateDecode'||fn==='Fl')&&hasPako()){\r\n    var ch=getChannels(dict,ctx),px=inflateFlate(obj.contents,dict);\r\n    if(!px||px.length<W*H*ch*0.85)return false;\r\n    var c3=px2canvas(px,W,H,ch);if(!c3)return false;\r\n    if(tw!==W||th!==H){var s=document.createElement('canvas');s.width=tw;s.height=th;s.getContext('2d').drawImage(c3,0,0,tw,th);c3=s;}\r\n    srcCanvas=c3;\r\n  }else if(fn==='LZWDecode'||fn==='LZW'){\r\n    var ch2=getChannels(dict,ctx),raw=lzwDecode(obj.contents);\r\n    if(!raw||raw.length<W*H*ch2*0.85)return false;\r\n    var c4=px2canvas(raw,W,H,ch2);if(!c4)return false;\r\n    if(tw!==W||th!==H){var s2=document.createElement('canvas');s2.width=tw;s2.height=th;s2.getContext('2d').drawImage(c4,0,0,tw,th);c4=s2;}\r\n    srcCanvas=c4;\r\n  }\r\n  if(!srcCanvas)return false;\r\n  var blob=await toJpeg(srcCanvas,q);if(!blob)return false;\r\n  var newBytes=new Uint8Array(await blob.arrayBuffer());\r\n  \/\/ Write unconditionally \u2014 downsampled images are always better\r\n  replaceImg(ctx,ref,obj,newBytes,tw,th);\r\n  return true;\r\n}\r\n\r\nfunction compressStream(ctx,ref,obj){if(!hasPako()||!obj.contents||obj.contents.length<256||hasFilter(obj)||isImgStream(obj))return false;try{var comp=pako.deflate(obj.contents,{level:9});if(comp.length>=obj.contents.length)return false;var nd=PDFLib.PDFDict.withContext(ctx);obj.dict.entries().forEach(function(kv){nd.set(kv[0],kv[1]);});nd.set(pn('Filter'),pn('FlateDecode'));nd.set(pn('Length'),ctx.obj(comp.length));nd.delete(pn('DecodeParms'));if(typeof PDFLib.PDFRawStream!=='undefined'){ctx.assign(ref,PDFLib.PDFRawStream.of(nd,comp));}else{obj.dict=nd;var w=new Uint8Array(comp.length);w.set(comp);try{Object.defineProperty(obj,'contents',{value:w,writable:true,configurable:true});}catch(e){}}return true;}catch(e){return false;}}\r\n\r\nfunction stripMeta(doc,settings){\r\n  try{doc.setTitle('');doc.setAuthor('');doc.setSubject('');doc.setKeywords([]);doc.setProducer('Press');doc.setCreator('Press');}catch(e){}\r\n  try{var cat=doc.catalog;['Metadata','PieceInfo','SpiderInfo','OutputIntents','Legal'].forEach(function(k){try{if(cat.has(pn(k)))cat.delete(pn(k));}catch(e){}});try{var nm=cat.get(pn('Names'));if(nm&&nm.has&&nm.has(pn('EmbeddedFiles')))nm.delete(pn('EmbeddedFiles'));}catch(e){}if(settings&&settings.removeOptional){['Outlines','Threads','Trans','JavaScript'].forEach(function(k){try{if(cat.has(pn(k)))cat.delete(pn(k));}catch(e){} });}}catch(e){}\r\n  try{doc.getPages().forEach(function(page){['Thumb','Trans','PieceInfo'].forEach(function(k){try{if(page.node.has(pn(k)))page.node.delete(pn(k));}catch(e){}});if(settings&&settings.removeAnnotations){try{if(page.node.has(pn('Annots')))page.node.delete(pn('Annots'));}catch(e){}}});}catch(e){}\r\n}\r\n\r\nasync function compressViaPerImage(pdfBytes,preset,settings,onP){\r\n  onP(3,'Loading document\u2026');\r\n  var doc=await PDFLib.PDFDocument.load(pdfBytes,{ignoreEncryption:true});\r\n  var ctx=doc.context;\r\n  onP(8,'Stripping metadata\u2026');\r\n  stripMeta(doc,settings);\r\n  var all=Array.from(ctx.enumerateIndirectObjects());\r\n  var imgs=all.filter(function(e){return isImgStream(e[1]);});\r\n  var strs=all.filter(function(e){return isRawStream(e[1])&&!isImgStream(e[1])&&!hasFilter(e[1])&&e[1].contents.length>256;});\r\n  var imgCount=0;\r\n  if(!settings.metaOnly&&imgs.length>0){\r\n    var pageMap=buildPageMap(doc,ctx);\r\n    for(var i=0;i<imgs.length;i++){\r\n      onP(8+Math.round((i\/imgs.length)*72),'Image '+(i+1)+' of '+imgs.length+'\u2026');\r\n      var ok=await compressImgObj(ctx,imgs[i][0],imgs[i][1],preset.dpi,preset.q,pageMap);\r\n      if(ok)imgCount++;\r\n    }\r\n  }\r\n  var streamCount=0;\r\n  if(settings.compStreams){onP(82,'Compressing streams\u2026');for(var j=0;j<strs.length;j++)if(compressStream(ctx,strs[j][0],strs[j][1]))streamCount++;}\r\n  onP(93,'Saving\u2026');\r\n  var bytes=await doc.save({useObjectStreams:true,addDefaultPage:false});\r\n  onP(100,'Done');\r\n  return{bytes:bytes,imgCount:imgCount,streamCount:streamCount,method:'per-image'};\r\n}\r\n\r\n\/\/ \u2500\u2500\u2500 Progress \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction setP(id,p,t){var pf=document.getElementById('pf-'+id),pt=document.getElementById('pt-'+id),pw=document.getElementById('pw-'+id);if(pw)pw.style.display='';if(pf)pf.style.width=p+'%';if(pt)pt.textContent=t;}\r\nfunction hideP(id){var pw=document.getElementById('pw-'+id);if(pw)pw.style.display='none';}\r\n\r\n\/\/ \u2500\u2500\u2500 Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction addCard(file){\r\n  var id=uid(),card={id:id,file:file,name:file.name,base:baseName(file.name),originalSize:file.size,pdfBytes:null,resultBlob:null,resultURL:null,el:null,busy:false};\r\n  cards.set(id,card);order.push(id);\r\n  var el=document.createElement('div');el.className='pdf-card';\r\n  el.innerHTML=\r\n    '<div class=\"pdf-card-head\">'+\r\n      '<div><p class=\"pdf-card-name\">'+esc(file.name)+'<\/p>'+\r\n      '<div class=\"pill-row\" id=\"info-'+id+'\"><span class=\"meta-text mono\">Reading\u2026<\/span><\/div><\/div>'+\r\n      '<button style=\"background:none;border:none;color:var(--steel-dim);font-size:18px;cursor:pointer;padding:4px;\" data-act=\"rm\">\u00d7<\/button>'+\r\n    '<\/div>'+\r\n    '<div id=\"pw-'+id+'\" style=\"display:none;margin:10px 0 0;\">'+\r\n      '<div class=\"prog-track\"><div class=\"prog-fill\" id=\"pf-'+id+'\"><\/div><\/div>'+\r\n      '<div class=\"prog-text\" id=\"pt-'+id+'\"><\/div>'+\r\n    '<\/div>'+\r\n    '<div class=\"result-bar\" id=\"rb-'+id+'\" style=\"display:none;\"><\/div>'+\r\n    '<div style=\"margin-top:13px;display:flex;gap:8px;flex-wrap:wrap;\">'+\r\n      '<button class=\"btn primary\" id=\"cb-'+id+'\" disabled>Compress<\/button>'+\r\n      '<button class=\"btn\" id=\"db-'+id+'\" style=\"display:none;\" disabled>Download<\/button>'+\r\n    '<\/div>';\r\n  document.getElementById('pdfQueue').appendChild(el);\r\n  card.el=el;\r\n  el.querySelector('[data-act=\"rm\"]').addEventListener('click',function(){removeCard(id);});\r\n  document.getElementById('batchBar').classList.add('show');\r\n  file.arrayBuffer().then(function(buf){\r\n    card.pdfBytes=new Uint8Array(buf);\r\n    return PDFLib.PDFDocument.load(card.pdfBytes,{ignoreEncryption:true});\r\n  }).then(function(doc){\r\n    var n=doc.getPageCount();\r\n    document.getElementById('info-'+id).innerHTML=\r\n      '<span class=\"pill\">PDF<\/span>'+\r\n      '<span class=\"meta-text mono\">'+n+(n===1?' page':' pages')+'<\/span>'+\r\n      '<span class=\"meta-text mono\">'+fmtB(file.size)+'<\/span>';\r\n    var cb=document.getElementById('cb-'+id);cb.disabled=false;\r\n    cb.addEventListener('click',function(){compressCard(card);});\r\n    updateBatch();\r\n  }).catch(function(e){\r\n    document.getElementById('info-'+id).innerHTML='<span style=\"color:var(--warn)\">'+esc(e.message)+'<\/span>';\r\n    updateBatch();\r\n  });\r\n}\r\n\r\nasync function compressCard(card){\r\n  if(card.busy)return;\r\n  card.busy=true;\r\n  var preset=PRESETS[activePreset];\r\n  var settings={\r\n    metaOnly:document.getElementById('metaOnlyChk').checked,\r\n    compStreams:document.getElementById('compStreamsChk').checked,\r\n    removeOptional:document.getElementById('removeOptChk').checked,\r\n    removeAnnotations:document.getElementById('removeAnnChk').checked\r\n  };\r\n  var cb=document.getElementById('cb-'+card.id),db=document.getElementById('db-'+card.id),rb=document.getElementById('rb-'+card.id);\r\n  cb.disabled=true;db.style.display='none';rb.style.display='none';\r\n  card.el.classList.remove('done','error');card.el.classList.add('processing');\r\n\r\n  var finalBytes,notes=[],usedMethod;\r\n\r\n  try{\r\n    if(gsState==='ready'&&!settings.metaOnly){\r\n      \/\/ \u2500\u2500 Ghostscript WASM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n      setP(card.id,10,'Compressing with Ghostscript WASM\u2026');\r\n      var gsOut=await compressViaGS(card.pdfBytes,preset.gs);\r\n      if(gsOut&&gsOut.length>0&&gsOut.length<card.originalSize){\r\n        finalBytes=gsOut; usedMethod='ghostscript';\r\n        notes.push('Ghostscript WASM \u00b7 '+preset.name);\r\n        setP(card.id,100,'Done');\r\n      } else {\r\n        \/\/ GS didn't help \u2014 fall through to dual-pass\r\n        usedMethod='dual';\r\n      }\r\n    }\r\n\r\n    if(!finalBytes&&!settings.metaOnly){\r\n      \/\/ \u2500\u2500 Dual-pass: run BOTH approaches, pick the smaller result \u2500\u2500\u2500\u2500\u2500\r\n      setP(card.id,3,'Pass A \u2014 per-image recompression\u2026');\r\n      var resA=await compressViaPerImage(card.pdfBytes,preset,settings,function(p,t){\r\n        setP(card.id,3+Math.round(p*0.45),'Pass A: '+t);\r\n      });\r\n\r\n      var resB=null;\r\n      if(hasPdfjsLib()){\r\n        setP(card.id,50,'Pass B \u2014 page rasterisation at '+preset.dpi+' dpi\u2026');\r\n        var rasBytes=await compressViaRasterisation(card.pdfBytes,preset.dpi,preset.q,function(p,t){\r\n          setP(card.id,50+Math.round(p*0.45),'Pass B: '+t);\r\n        });\r\n        resB=rasBytes;\r\n      }\r\n\r\n      \/\/ Pick the winner\r\n      var aSize=resA.bytes.length, bSize=resB?resB.length:Infinity;\r\n      if(bSize<aSize&&bSize<card.originalSize){\r\n        finalBytes=resB; usedMethod='rasterise';\r\n        notes.push('Page rasterisation at '+preset.dpi+' dpi \u00b7 JPEG '+Math.round(preset.q*100)+'%');\r\n      } else if(aSize<card.originalSize){\r\n        finalBytes=resA.bytes; usedMethod='per-image';\r\n        if(resA.imgCount)notes.push(resA.imgCount+' images recompressed');\r\n        if(resA.streamCount)notes.push(resA.streamCount+' streams deflated');\r\n      } else {\r\n        \/\/ Neither pass helped \u2014 metadata strip only\r\n        finalBytes=resA.bytes; usedMethod='meta-only';\r\n        notes.push('No image compression possible \u2014 metadata stripped only');\r\n      }\r\n    }\r\n\r\n    if(!finalBytes||settings.metaOnly){\r\n      \/\/ Meta-only pass\r\n      setP(card.id,30,'Stripping metadata\u2026');\r\n      var doc2=await PDFLib.PDFDocument.load(card.pdfBytes,{ignoreEncryption:true});\r\n      stripMeta(doc2,settings);\r\n      var b2=await doc2.save({useObjectStreams:true});\r\n      finalBytes=b2.length<card.originalSize?b2:card.pdfBytes;\r\n      if(!usedMethod){usedMethod='meta';notes.push('Metadata stripped');}\r\n      setP(card.id,100,'Done');\r\n    }\r\n\r\n    var blob=new Blob([finalBytes],{type:'application\/pdf'});\r\n    if(card.resultURL)URL.revokeObjectURL(card.resultURL);\r\n    card.resultBlob=blob;card.resultURL=URL.createObjectURL(blob);\r\n    hideP(card.id);\r\n    card.el.classList.remove('processing');card.el.classList.add('done');\r\n\r\n    var saved=pctSaved(card.originalSize,blob.size);\r\n    var sc=saved>1?'good':saved<0?'warn':'';\r\n    var savedStr=saved>0.1?('\u2212'+saved.toFixed(1)+'%'):saved<0?('+'+Math.abs(saved).toFixed(1)+'%'):'\u2248 0%';\r\n    if(notes.length===0)notes.push(usedMethod||'compressed');\r\n\r\n    rb.style.display='';\r\n    rb.innerHTML=\r\n      '<div class=\"r-fig\"><span class=\"r-label\">Original<\/span><span class=\"r-val muted mono\">'+fmtB(card.originalSize)+'<\/span><\/div>'+\r\n      '<div class=\"r-fig\"><span class=\"r-label\">Compressed<\/span><span class=\"r-val mono\">'+fmtB(blob.size)+'<\/span><\/div>'+\r\n      '<div class=\"r-fig\"><span class=\"r-label\">Saved<\/span><span class=\"r-val '+sc+' mono\">'+savedStr+'<\/span>'+\r\n        '<div class=\"r-sub\">'+esc(notes.join(' \u00b7 '))+'<\/div><\/div>';\r\n\r\n    db.style.display='';db.disabled=false;db.textContent='Download';\r\n    db.onclick=function(){trigDl(card.resultURL,card.base+'-compressed.pdf');};\r\n    cb.disabled=false;cb.textContent='Re-compress';\r\n  }catch(e){\r\n    hideP(card.id);card.el.classList.remove('processing');card.el.classList.add('error');\r\n    rb.style.display='';\r\n    rb.innerHTML='<span style=\"color:var(--warn);font-size:12px;\">Error: '+esc(e.message)+'<\/span>';\r\n    cb.disabled=false;console.error(e);\r\n  }\r\n  card.busy=false;updateBatch();\r\n}\r\n\r\nfunction removeCard(id){var card=cards.get(id);if(!card)return;if(card.resultURL)URL.revokeObjectURL(card.resultURL);if(card.el&&card.el.parentNode)card.el.parentNode.removeChild(card.el);cards.delete(id);order=order.filter(function(x){return x!==id;});updateBatch();if(!cards.size)document.getElementById('batchBar').classList.remove('show');}\r\nfunction updateBatch(){var n=cards.size,ready=0,totO=0,totC=0;cards.forEach(function(c){totO+=c.originalSize||0;if(c.resultBlob){ready++;totC+=c.resultBlob.size;}else totC+=c.originalSize||0;});var el=document.getElementById('batchStatus');if(!el)return;var txt='<b>'+n+(n===1?' file':' files')+'<\/b>  \u00b7  '+fmtB(totO);if(ready>0){var s=pctSaved(totO,totC);txt+='  \u2192  '+fmtB(totC)+'  <span style=\"color:var(--good)\">\u2212'+Math.abs(s).toFixed(1)+'%<\/span>';}el.innerHTML=txt;document.getElementById('dlAllBtn').disabled=ready===0;}\r\nasync function downloadAll(){if(typeof JSZip==='undefined'){alert('JSZip not loaded.');return;}var zip=new JSZip(),any=false,used={};cards.forEach(function(c){if(!c.resultBlob)return;var n=c.base+'-compressed.pdf';if(used[n]){used[n]++;n=c.base+'-compressed-'+used[n]+'.pdf';}else used[n]=1;zip.file(n,c.resultBlob);any=true;});if(!any){alert('Nothing compressed yet.');return;}var content=await zip.generateAsync({type:'blob'});var url=URL.createObjectURL(content);trigDl(url,'press-compressed.zip');setTimeout(function(){URL.revokeObjectURL(url);},5000);}\r\n\r\n\/\/ \u2500\u2500\u2500 Init \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction wireDropzone(){\r\n  var dz=document.getElementById('dz'),inp=document.getElementById('fileInput');\r\n  function handle(files){Array.from(files).filter(function(f){return f.type==='application\/pdf'||\/\\.pdf$\/i.test(f.name);}).forEach(addCard);}\r\n  dz.addEventListener('click',function(){inp.click();});\r\n  dz.addEventListener('keydown',function(e){if(e.key==='Enter'||e.key===' '){e.preventDefault();inp.click();}});\r\n  inp.addEventListener('change',function(){if(inp.files.length)handle(inp.files);inp.value='';});\r\n  ['dragenter','dragover'].forEach(function(ev){dz.addEventListener(ev,function(e){e.preventDefault();dz.classList.add('active');});});\r\n  ['dragleave','drop'].forEach(function(ev){dz.addEventListener(ev,function(e){e.preventDefault();dz.classList.remove('active');});});\r\n  dz.addEventListener('drop',function(e){if(e.dataTransfer&&e.dataTransfer.files.length)handle(e.dataTransfer.files);});\r\n}\r\nfunction init(){\r\n  document.querySelectorAll('.preset-btn').forEach(function(btn,idx){\r\n    btn.addEventListener('click',function(){\r\n      activePreset=idx;\r\n      document.querySelectorAll('.preset-btn').forEach(function(b,i){b.classList.toggle('active',i===idx);});\r\n    });\r\n  });\r\n  document.getElementById('metaOnlyChk').addEventListener('change',function(){\r\n    var on=this.checked;\r\n    document.getElementById('presetGrid').style.opacity=on?'0.35':'1';\r\n    document.getElementById('presetGrid').style.pointerEvents=on?'none':'';\r\n  });\r\n  document.getElementById('dlAllBtn').addEventListener('click',downloadAll);\r\n  document.getElementById('clearBtn').addEventListener('click',function(){Array.from(order).forEach(removeCard);});\r\n  wireDropzone();\r\n  setUI('JS','Loading Ghostscript WASM in background \u2014 browser dual-pass engine active now');\r\n  initGhostscript().catch(function(){});\r\n}\r\ndocument.addEventListener('DOMContentLoaded',init);\r\n})();\r\n\r\n<\/script>\r\n<\/body>\r\n<\/html>\r\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_eb_attr":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[76],"tags":[],"class_list":["post-4644","post","type-post","status-publish","format-standard","hentry","category-tools"],"_links":{"self":[{"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/posts\/4644","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/comments?post=4644"}],"version-history":[{"count":3,"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/posts\/4644\/revisions"}],"predecessor-version":[{"id":4648,"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/posts\/4644\/revisions\/4648"}],"wp:attachment":[{"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/media?parent=4644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/categories?post=4644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rajmedical.co.in\/hi\/wp-json\/wp\/v2\/tags?post=4644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}