/* ============================================================
   DETAILED P&ID TOOLKIT
   ISA-style clickable valves/instruments + SVG-only fittings,
   signal lines, line numbers, vessels, and the PIDSheet shell
   (header + zoom + KEY SYMBOLS legend + scroll/scale canvas).
   ============================================================ */
const hh = React.createElement;

/* media colours (shared with master P&ID) */
window.MED = window.MED || {
  biogas: "#F2941F", percolate: "#C98A5A", air: "#2A9DE0",
  heat_s: "#d33a2c", heat_r: "#6E97C4", water: "#3D8BE0", digestate: "#5fb478",
};

/* ---- clickable ISA VALVE (iso / control / check-act / butterfly) ---- */
function PValve({ d, x, y, vtype = "iso", lbl, size = 28 }) {
  const { open } = useApp();
  const c = window.devColor(d);
  const w = size, hgt = size * 0.62;
  const cx = w / 2;
  const glyph = [];
  // bowtie body
  glyph.push(hh("polygon", { key: "b1", points: `2,2 ${cx},${hgt / 2} 2,${hgt - 2}`, fill: c, stroke: "#0a1830", strokeWidth: 1 }));
  glyph.push(hh("polygon", { key: "b2", points: `${w - 2},2 ${cx},${hgt / 2} ${w - 2},${hgt - 2}`, fill: c, stroke: "#0a1830", strokeWidth: 1 }));
  if (vtype === "control") {
    // diaphragm actuator on stem
    glyph.push(hh("line", { key: "st", x1: cx, y1: hgt / 2, x2: cx, y2: -10, stroke: c, strokeWidth: 1.6 }));
    glyph.push(hh("path", { key: "dia", d: `M ${cx - 9} -10 Q ${cx} -20 ${cx + 9} -10 Z`, fill: "rgba(6,15,31,0.85)", stroke: c, strokeWidth: 1.4 }));
  } else if (vtype === "motor") {
    // motor-operated: M box on stem
    glyph.push(hh("line", { key: "st", x1: cx, y1: hgt / 2, x2: cx, y2: -8, stroke: c, strokeWidth: 1.6 }));
    glyph.push(hh("rect", { key: "mb", x: cx - 7, y: -18, width: 14, height: 10, rx: 2, fill: "rgba(6,15,31,0.85)", stroke: c, strokeWidth: 1.2 }));
    glyph.push(hh("text", { key: "mt", x: cx, y: -10, fill: c, textAnchor: "middle", style: { font: "700 7px var(--font-mono)" } }, "M"));
  } else {
    // solenoid/iso: small stem cap
    glyph.push(hh("line", { key: "st", x1: cx, y1: hgt / 2, x2: cx, y2: -6, stroke: c, strokeWidth: 1.4 }));
    glyph.push(hh("rect", { key: "sc", x: cx - 5, y: -12, width: 10, height: 7, rx: 1, fill: "rgba(6,15,31,0.85)", stroke: c, strokeWidth: 1.1 }));
    glyph.push(hh("text", { key: "sl", x: cx, y: -6.2, fill: c, textAnchor: "middle", style: { font: "700 5.5px var(--font-mono)" } }, "S"));
  }
  return (
    <div style={{ position: "absolute", left: x, top: y, transform: "translate(-50%,-50%)", cursor: "pointer", zIndex: 5 }} onClick={() => open(d)} title={d.tag}>
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
        <svg width={w} height={hgt + 22} viewBox={`0 -24 ${w} ${hgt + 26}`} style={{ overflow: "visible", filter: d.travelling ? "drop-shadow(0 0 4px " + c + ")" : "none" }}>{glyph}</svg>
        <div className="mono" style={{ fontSize: 8.5, color: "var(--hud-text-2)", marginTop: -2, background: "rgba(6,15,31,.75)", padding: "0 3px", borderRadius: 2, whiteSpace: "nowrap" }}>{lbl || d.tag.replace(/^\d+-/, "")}</div>
      </div>
    </div>
  );
}

/* ---- clickable PUMP / motor (centrifugal ISA) ---- */
function PPump({ d, x, y, lbl, kind }) {
  const { open } = useApp();
  const c = window.devColor(d);
  const letter = kind || (d.sub === "fan" ? "V" : d.sub === "compressor" ? "C" : d.sub === "blower" ? "B" : d.sub === "agitator" ? "A" : d.isGenset ? "G" : "P");
  return (
    <div style={{ position: "absolute", left: x, top: y, transform: "translate(-50%,-50%)", cursor: "pointer", zIndex: 5 }} onClick={() => open(d)} title={d.tag}>
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
        <div style={{ position: "relative", width: 34, height: 34 }}>
          <svg width="34" height="34" viewBox="0 0 34 34">
            <circle cx="17" cy="17" r="14" fill="rgba(6,15,31,0.85)" stroke={c} strokeWidth="2" />
            <polygon points="11,9 11,25 26,17" fill={c} opacity="0.85" />
            {d.running && <path d="M17 3 A14 14 0 0 1 31 17" stroke={c} strokeWidth="1.8" fill="none" strokeLinecap="round" style={{ transformOrigin: "17px 17px", animation: "spin 2.2s linear infinite" }} />}
          </svg>
        </div>
        <div className="mono" style={{ fontSize: 8.5, color: "var(--hud-text-2)", marginTop: 1, background: "rgba(6,15,31,.75)", padding: "0 3px", borderRadius: 2, whiteSpace: "nowrap" }}>{lbl || d.tag.replace(/^\d+-/, "")}</div>
      </div>
    </div>
  );
}

/* ---- clickable INSTRUMENT (ISA balloon + live value) ---- */
function PInst({ d, x, y, mounted = "field", showVal = true }) {
  const { open } = useApp();
  const c = window.devColor(d);
  const parts = d.tag.split("-");
  const code = parts[1] || "XT", num = parts[2] || "";
  const q = window.qualOf(d);
  return (
    <div style={{ position: "absolute", left: x, top: y, transform: "translate(-50%,-50%)", cursor: "pointer", zIndex: 6 }} onClick={() => open(d)} title={d.tag}>
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
        <div style={{ width: 32, height: 32, borderRadius: "50%", border: "1.7px solid " + c, background: "rgba(6,15,31,0.9)", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", lineHeight: 1, position: "relative" }}>
          {mounted === "panel" && <div style={{ position: "absolute", left: 1, right: 1, top: "50%", height: 1, background: c, opacity: 0.7 }}></div>}
          <span className="mono" style={{ fontWeight: 700, fontSize: 9.5, color: c }}>{code}</span>
          <span className="mono" style={{ fontSize: 7, color: "var(--hud-text-3)" }}>{num}</span>
        </div>
        {showVal && <div className={"lv" + (q === "alarm" ? " al" : q === "warn" ? " hi" : "")} style={{ marginTop: 2, padding: "0px 4px" }}>
          <span className="n" style={{ fontSize: 9.5 }}>{fmtNum(d.v, d.fmt)}</span><span className="u" style={{ fontSize: 7.5 }}>{d.unit}</span>
        </div>}
      </div>
    </div>
  );
}

/* ============================================================
   SVG-ONLY FITTINGS (decorative P&ID detail) — return elements
   ============================================================ */
let _fk = 0;
const fk = () => "f" + (_fk++);

/* process line + optional animated flow + line number tag */
function PLine(pts, color, opts) {
  opts = opts || {};
  const d = pts.map((p, i) => (i ? "L" : "M") + p[0] + " " + p[1]).join(" ");
  const k = fk();
  const els = [hh("path", { key: k + "a", d, fill: "none", stroke: color, strokeWidth: opts.w || 2.2, strokeLinejoin: "round", strokeLinecap: "round", opacity: 0.95, strokeDasharray: opts.dash || null })];
  if (opts.flow) els.push(hh("path", { key: k + "f", d, fill: "none", stroke: "#eaf4ff", strokeWidth: 2, className: "flow" + (color === window.MED.biogas ? " gas" : ""), strokeLinecap: "round", opacity: 0.7 }));
  return els;
}
/* flow direction arrow */
function arrow(x, y, dir, color) {
  const r = { e: "0", w: "180", n: "270", s: "90" }[dir] || "0";
  return hh("path", { key: fk(), d: "M -5 -4 L 4 0 L -5 4 Z", transform: `translate(${x} ${y}) rotate(${r})`, fill: color, opacity: 0.9 });
}
/* line-number tag on a pipe */
function lineTag(x, y, text, color) {
  const w = text.length * 5.6 + 8;
  return hh("g", { key: fk() },
    hh("rect", { x: x - w / 2, y: y - 7, width: w, height: 13, rx: 2, fill: "rgba(6,15,31,0.9)", stroke: (color || "#33507a"), strokeWidth: 0.8, opacity: 0.95 }),
    hh("text", { x, y: y + 2.5, fill: "#9db2cc", textAnchor: "middle", style: { font: "600 8px var(--font-mono)" } }, text)
  );
}

/* ============================================================
   PIPE LINE NUMBER — real P&ID convention
   DN<size> - <fluid> - L<no> - <material>  (+ optional insulation
   sub-line  Ø<od> - <fluid> - L<no> - PS/AL ).  Coloured per fluid.
   f = { dn, od, fl, num, mat, ins }
   opts = { color, vert, mid }
   ============================================================ */
window.FLUID_COL = {
  P1: window.MED.percolate, P2: window.MED.biogas, AA: window.MED.air,
  WW: window.MED.digestate, AS: "#c46cc4", WM: "#e6a3c4",
  P3: "#5fb478", P4: "#b07a4a", EG: "#caa05a", GF: "#F2941F",
};
function pipeTag(x, y, f, opts) {
  opts = opts || {};
  const col = opts.color || window.FLUID_COL[f.fl] || "#9db2cc";
  const main = `DN${f.dn} - ${f.fl} - ${f.num} - ${f.mat}`;
  const ins = f.od ? `Ø${f.od} - ${f.fl} - ${f.num} - ${f.ins || "PS/AL"}` : null;
  const lines = ins ? [[ins, "#7cc49a"], [main, col]] : [[main, col]];
  const chW = 4.55, padX = 5, lh = 10;
  const w = Math.max(...lines.map(l => l[0].length)) * chW + padX * 2;
  const hgt = lines.length * lh + 5;
  const mid = opts.mid;
  const rx = mid ? -w / 2 : 0;
  const tx = mid ? 0 : padX;
  return hh("g", { key: fk(), transform: `translate(${x} ${y})` + (opts.vert ? " rotate(-90)" : "") },
    hh("rect", { x: rx, y: -hgt / 2, width: w, height: hgt, rx: 2.5, fill: "rgba(4,12,24,0.85)", stroke: col, strokeWidth: 0.7, opacity: 0.92 }),
    ...lines.map((l, i) => hh("text", {
      key: "t" + i, x: tx, y: -hgt / 2 + lh * (i + 0.72) + 1.5, fill: l[1],
      textAnchor: mid ? "middle" : "start",
      style: { font: "600 7.6px var(--font-mono)", letterSpacing: "0.005em" }
    }, l[0]))
  );
}
/* elevation flag (blue triangle + height in mm), as on the drawing */
function elevFlag(x, y, val, opts) {
  opts = opts || {};
  const left = opts.left;
  return hh("g", { key: fk(), transform: `translate(${x} ${y})` },
    hh("path", { d: "M -5 -4.5 L 5 -4.5 L 0 4 Z", fill: "#2f6fd0", stroke: "#5b9fd0", strokeWidth: 0.6 }),
    hh("text", { x: left ? -9 : 9, y: 1.5, fill: "#7fb2e6", textAnchor: left ? "end" : "start", style: { font: "600 8px var(--font-mono)" } }, val)
  );
}
/* check valve (non-return) */
function checkV(x, y, dir, color) {
  const r = dir === "v" ? 90 : 0;
  return hh("g", { key: fk(), transform: `translate(${x} ${y}) rotate(${r})` },
    hh("polygon", { points: "-9,-7 -9,7 6,0", fill: "none", stroke: color, strokeWidth: 1.6 }),
    hh("line", { x1: 6, y1: -8, x2: 6, y2: 8, stroke: color, strokeWidth: 1.8 })
  );
}
/* safety / relief valve (PSV, angle + spring) */
function psv(x, y, color) {
  return hh("g", { key: fk(), transform: `translate(${x} ${y})` },
    hh("polygon", { points: "-8,4 8,4 0,-6", fill: "none", stroke: color, strokeWidth: 1.5 }),
    hh("line", { x1: 0, y1: -6, x2: 0, y2: -16, stroke: color, strokeWidth: 1.4 }),
    hh("path", { d: "M -5 -16 l 10 -3 l -10 -3 l 10 -3", fill: "none", stroke: color, strokeWidth: 1.3 }),
    hh("text", { x: 12, y: -8, fill: color, style: { font: "600 8px var(--font-mono)" } }, "PSV")
  );
}
/* reducer */
function reducer(x, y, color) {
  return hh("polygon", { key: fk(), points: `${x},${y - 7} ${x + 14},${y - 4} ${x + 14},${y + 4} ${x},${y + 7}`, fill: "none", stroke: color || "#5b6b7d", strokeWidth: 1.4 });
}
/* strainer / filter */
function strainer(x, y, color) {
  return hh("g", { key: fk(), transform: `translate(${x} ${y})` },
    hh("polygon", { points: "-9,-7 9,-7 9,7 -9,7", fill: "none", stroke: color, strokeWidth: 1.3 }),
    hh("line", { x1: -9, y1: 7, x2: 9, y2: -7, stroke: color, strokeWidth: 1.1 })
  );
}
/* flame arrestor */
function flameArr(x, y, color) {
  return hh("g", { key: fk(), transform: `translate(${x} ${y})` },
    hh("rect", { x: -10, y: -8, width: 20, height: 16, rx: 2, fill: "rgba(6,15,31,0.8)", stroke: color, strokeWidth: 1.3 }),
    hh("path", { d: "M -6 6 v-12 M 0 6 v-12 M 6 6 v-12", stroke: color, strokeWidth: 1, opacity: 0.7 })
  );
}
/* instrument signal line (dashed) connecting bubble to tap */
function sig(pts, kind) {
  const d = pts.map((p, i) => (i ? "L" : "M") + p[0] + " " + p[1]).join(" ");
  const els = [hh("path", { key: fk(), d, fill: "none", stroke: "#6781a6", strokeWidth: 1, strokeDasharray: "4 3", opacity: 0.7 })];
  if (kind === "elec") {
    // small perpendicular ticks for electric signal — approximate with dots
    els.push(hh("path", { key: fk(), d, fill: "none", stroke: "#6781a6", strokeWidth: 1, strokeDasharray: "0.5 7", strokeLinecap: "round", opacity: 0.9 }));
  }
  return els;
}
/* equipment room / building */
function eqroom(x, y, w, hgt, label, opts) {
  opts = opts || {};
  return hh("g", { key: fk() },
    hh("rect", { x, y, width: w, height: hgt, rx: 4, fill: opts.fill || "rgba(13,31,60,0.4)", stroke: opts.stroke || "rgba(122,160,209,0.3)", strokeWidth: 1.2, strokeDasharray: opts.dash ? "5 4" : null }),
    label ? hh("text", { x: x + 8, y: y + 15, fill: opts.lc || "#8fb4e6", style: { font: "700 9.5px var(--font-mono)", letterSpacing: "0.05em" } }, label) : null
  );
}
/* vessel / tank with level */
function vessel(x, y, w, hgt, label, tag, level, color) {
  const els = [
    hh("rect", { key: fk(), x, y, width: w, height: hgt, rx: 5, fill: "rgba(13,31,60,0.6)", stroke: "rgba(122,160,209,0.42)", strokeWidth: 1.4 }),
  ];
  if (level != null) {
    const lh = (hgt - 4) * level / 100;
    els.push(hh("rect", { key: fk(), x: x + 2, y: y + hgt - 2 - lh, width: w - 4, height: lh, rx: 2, fill: color || window.MED.water, opacity: 0.3 }));
    els.push(hh("line", { key: fk(), x1: x + 2, y1: y + hgt - 2 - lh, x2: x + w - 2, y2: y + hgt - 2 - lh, stroke: color || window.MED.water, strokeWidth: 1.4, opacity: 0.7 }));
  }
  if (label) els.push(hh("text", { key: fk(), x: x + w / 2, y: y - 6, fill: "#8fb4e6", textAnchor: "middle", style: { font: "700 9px var(--font-mono)" } }, label));
  if (tag) els.push(hh("text", { key: fk(), x: x + w / 2, y: y + hgt + 13, fill: "#647a98", textAnchor: "middle", style: { font: "600 8px var(--font-mono)" } }, tag));
  return hh("g", { key: fk() }, ...els);
}
function txt(x, y, s, size, col, anchor) {
  return hh("text", { key: fk(), x, y, fill: col || "#647a98", textAnchor: anchor || "start", style: { font: `600 ${size || 9}px var(--font-mono)` } }, s);
}

/* ============================================================
   PIDSheet — shared sheet shell (header + zoom + legend + canvas)
   ============================================================ */
/* KEY LINES — fluid colour codes used by the line-number tags */
function LineKey() {
  const { t } = useApp();
  const F = window.FLUID_COL;
  const items = [["fl_p1", F.P1], ["fl_p2", F.P2], ["fl_aa", F.AA], ["fl_ww", F.WW], ["fl_as", F.AS], ["fl_wm", F.WM], ["fl_eg", F.EG]];
  return (
    <div className="legend">
      {items.map(([k, c]) => (
        <span className="lg" key={k}><span style={{ width: 16, height: 0, borderTop: "2.5px solid " + c, display: "inline-block" }}></span>{t(k)}</span>
      ))}
    </div>
  );
}

function SymLegend() {  const { t } = useApp();
  const items = [
    ["l_iso", '<polygon points="2,2 9,7 2,12" fill="none" stroke="#9db2cc" stroke-width="1.4"/><polygon points="16,2 9,7 16,12" fill="none" stroke="#9db2cc" stroke-width="1.4"/>'],
    ["l_ctrl", '<polygon points="2,5 9,9 2,13" fill="none" stroke="#9db2cc" stroke-width="1.3"/><polygon points="16,5 9,9 16,13" fill="none" stroke="#9db2cc" stroke-width="1.3"/><line x1="9" y1="9" x2="9" y2="1" stroke="#9db2cc" stroke-width="1.3"/><path d="M5 1 Q9 -3 13 1 Z" fill="none" stroke="#9db2cc" stroke-width="1.2"/>'],
    ["l_check", '<polygon points="2,2 2,12 13,7" fill="none" stroke="#9db2cc" stroke-width="1.4"/><line x1="13" y1="1" x2="13" y2="13" stroke="#9db2cc" stroke-width="1.6"/>'],
    ["l_psv", '<polygon points="1,11 13,11 7,3 " fill="none" stroke="#9db2cc" stroke-width="1.3"/><line x1="7" y1="3" x2="7" y2="-3" stroke="#9db2cc" stroke-width="1.2"/>'],
    ["l_inst", '<circle cx="8" cy="7" r="6.5" fill="none" stroke="#9db2cc" stroke-width="1.3"/>'],
    ["l_elec", '<line x1="0" y1="7" x2="16" y2="7" stroke="#9db2cc" stroke-width="1.2" stroke-dasharray="3 2"/>'],
  ];
  return (
    <div className="legend">
      {items.map(([k, g]) => (
        <span className="lg" key={k}><svg width="18" height="15" viewBox="-2 -4 22 20" dangerouslySetInnerHTML={{ __html: g }} />{t(k)}</span>
      ))}
    </div>
  );
}

/* ============================================================
   usePanZoom — AutoCAD-style navigation:
   wheel = zoom toward cursor, drag = pan (grab/grabbing).
   Returns { zoom, pan, bind, preset, dragging }.
   ============================================================ */
function usePanZoom(W, H, fit) {
  const [zoom, setZoom] = React.useState(fit);
  const [pan, setPan] = React.useState({ x: 12, y: 12 });
  const [dragging, setDragging] = React.useState(false);
  const vp = React.useRef(null);
  const st = React.useRef({ zoom: fit, pan: { x: 12, y: 12 } });
  st.current.zoom = zoom; st.current.pan = pan;
  const clamp = z => Math.max(0.18, Math.min(5, z));

  React.useEffect(() => {
    const el = vp.current; if (!el) return;
    const onWheel = (e) => {
      e.preventDefault();
      const r = el.getBoundingClientRect();
      const cx = e.clientX - r.left, cy = e.clientY - r.top;
      const { zoom: z, pan: p } = st.current;
      const nz = clamp(z * Math.exp(-e.deltaY * 0.0016));
      setPan({ x: cx - (cx - p.x) / z * nz, y: cy - (cy - p.y) / z * nz });
      setZoom(nz);
    };
    el.addEventListener("wheel", onWheel, { passive: false });
    return () => el.removeEventListener("wheel", onWheel);
  }, []);

  const drag = React.useRef(null);
  const onPointerDown = (e) => {
    if (e.button !== 0) return;
    drag.current = { x: e.clientX, y: e.clientY, pan: { ...st.current.pan }, moved: false, id: e.pointerId, el: e.currentTarget };
  };
  const onPointerMove = (e) => {
    const d = drag.current; if (!d) return;
    const dx = e.clientX - d.x, dy = e.clientY - d.y;
    if (!d.moved) {
      if (Math.hypot(dx, dy) < 3) return;
      d.moved = true; setDragging(true);
      try { d.el.setPointerCapture(d.id); } catch (_) {}
    }
    setPan({ x: d.pan.x + dx, y: d.pan.y + dy });
  };
  const endDrag = () => { drag.current = null; setDragging(false); };

  const preset = (z) => {
    const el = vp.current;
    const w = el ? el.clientWidth : W * fit, hh2 = el ? el.clientHeight : H * fit;
    const nz = clamp(z);
    setZoom(nz);
    setPan({ x: Math.max(12, (w - W * nz) / 2), y: Math.max(12, Math.min(12, (hh2 - H * nz) / 2)) });
  };
  const bind = {
    ref: vp, onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerLeave: endDrag,
    style: { cursor: dragging ? "grabbing" : "grab", touchAction: "none" },
  };
  return { zoom, pan, bind, preset, dragging };
}
window.usePanZoom = usePanZoom;

function PIDSheet({ titleKey, sub, tag, W, H, defaultZoom = 0.82, svg, overlays }) {
  const { t } = useApp();
  const pz = usePanZoom(W, H, defaultZoom);
  const zoom = pz.zoom;
  return (
    <div className="page" style={{ padding: 0, display: "flex", flexDirection: "column", overflow: "hidden" }}>
      <div style={{ padding: "16px 22px 10px" }}>
        <PageHead titleKey={titleKey} sub={sub} tag={tag} />
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "0 22px 12px", flexWrap: "wrap" }}>
        <div className="modetog">
          {[["50%", 0.5], ["75%", 0.75], ["100%", 1], [t("zoom_fit"), defaultZoom]].map(([l, z]) => (
            <button key={l} className={Math.abs(zoom - z) < 0.001 ? "on auto" : ""} onClick={() => pz.preset(z)}>{l}</button>
          ))}
        </div>
        <span className="mono" style={{ fontSize: 10, color: "var(--hud-text-3)", whiteSpace: "nowrap" }}>{t("cad_hint")}</span>
        <div style={{ width: 1, height: 22, background: "var(--hud-line)" }}></div>
        <span className="eyebrow">{t("key_lines")}</span>
        <LineKey />
        <div style={{ width: 1, height: 22, background: "var(--hud-line)" }}></div>
        <span className="eyebrow">{t("key_symbols")}</span>
        <SymLegend />
      </div>
      <div {...pz.bind} style={{ ...pz.bind.style, flex: 1, position: "relative", overflow: "hidden", background: "#04101f", borderTop: "1px solid var(--hud-line)" }}>
        <div style={{ position: "absolute", left: 0, top: 0, width: W, height: H, transformOrigin: "0 0", transform: `translate(${pz.pan.x}px, ${pz.pan.y}px) scale(${zoom})` }}>
          <svg width={W} height={H} style={{ position: "absolute", inset: 0 }}>
            <defs>
              <pattern id="pidsg" width="38" height="38" patternUnits="userSpaceOnUse"><path d="M38 0H0V38" fill="none" stroke="rgba(122,160,209,0.05)" strokeWidth="1" /></pattern>
              <pattern id="mass2" width="7" height="7" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="7" stroke="rgba(160,140,110,0.4)" strokeWidth="1.3" /></pattern>
            </defs>
            <rect width={W} height={H} fill="url(#pidsg)" />
            {svg}
          </svg>
          {overlays}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PValve, PPump, PInst, PLine, arrow, lineTag, pipeTag, elevFlag, checkV, psv, reducer, strainer, flameArr, sig, eqroom, vessel, txt, PIDSheet });
