{
  "version": 1,
  "id": "scn_quality_control_blueprint",
  "slug": "quality-control",
  "name": "Live quality control",
  "icon": "camera.metering.spot",
  "tint": "#AD7543",
  "settings": {
    "description": "Watch a cable line, inspect a surface mark, and keep the evidence with the operator’s next step.",
    "welcomeSuggestions": [
      {
        "label": "Inspect this run",
        "prompt": "Look at the sample inspection camera, line measurements and machine view. What do the surface marks show, and what remains uncertain? Do not control any equipment."
      },
      {
        "label": "Record a finding",
        "prompt": "Help me write an inspection finding for this sample run. Ask for my observation, then keep it with the evidence in this scene."
      },
      {
        "label": "Use our equipment",
        "prompt": "Help me connect our own camera and line measurements to this inspection scene. Start by asking which sources and equipment we use."
      }
    ]
  },
  "assets": [
    {
      "id": "camera",
      "type": "daslab/webview",
      "name": "Inspection camera",
      "fields": {
        "html": "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<style>\n*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden}body{font:11px/1.5 Inter,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;background:#181e20;color:#e5e8e5;display:flex;flex-direction:column}header{height:48px;padding:0 15px;display:flex;align-items:center;justify-content:space-between;gap:8px;flex-shrink:0;border-bottom:1px solid #ffffff13}header strong{font-size:12px;font-weight:550;letter-spacing:-.2px}header small{font:8px ui-monospace,monospace;color:#94aaa4}.status{display:flex;align-items:center;gap:5px;font-size:9px;color:#9cb7a7}.status i{height:5px;width:5px;background:#9cbea3;border-radius:50%}.viewport{position:relative;flex:1;min-height:0;overflow:hidden}.viewport>canvas{display:block;width:100%;height:100%;touch-action:pan-y}.hud{position:absolute;left:13px;right:13px;top:12px;display:flex;justify-content:space-between;font:8px ui-monospace,monospace;letter-spacing:.04em;color:#b5c3bf;pointer-events:none}.foot{position:absolute;bottom:12px;left:13px;right:13px;display:flex;justify-content:space-between;align-items:center;font:8px ui-monospace,monospace;color:#a8b8b2;pointer-events:none}.target{position:absolute;left:calc(50% - 47px);top:calc(50% - 35px);width:94px;height:70px;border:1px solid #d4a063;box-shadow:0 0 0 1px #0004;display:none;pointer-events:none}.target:before{content:'SURFACE MARK';position:absolute;top:-19px;left:-1px;background:#d4a063;color:#202321;font:7px ui-monospace,monospace;white-space:nowrap;padding:3px 5px}.evidence{height:118px;flex-shrink:0;border-top:1px solid #ffffff18;background:#202729;display:grid;grid-template-columns:111px minmax(0,1fr);align-items:center;gap:13px;padding:13px 15px}.evidence canvas{width:111px;height:77px;border:1px solid #b287524f;object-fit:cover}.evidence b{font-size:11px;font-weight:500;display:block;color:#e1d0b7}.evidence small{font-size:9px;color:#8fa29b;display:block;margin-top:4px}.evidence .tag{font:8px ui-monospace,monospace;display:block;color:#c0955f;margin-bottom:4px}.waiting{grid-column:1/-1;display:flex;align-items:center;gap:12px;color:#8ea49a}.waiting span{display:block;width:27px;height:27px;border:1px solid #60786b;border-radius:50%;text-align:center;line-height:25px;color:#adc0b2}.waiting b{font-size:11px;color:#b8c8be;font-weight:400}.waiting small{font-size:9px;margin-top:3px}.machine{background:#eef0ea;color:#414d49}.machine header{height:38px;border-color:#dce2d9;padding:0 12px}.machine header strong{font-size:11px}.machine .status{color:#73867a}.machine .viewport{cursor:grab}.machine .hud{font:8px ui-monospace,monospace;color:#7f8d82;top:9px;left:11px;right:11px}.machine .foot{color:#73816f;font-size:8px;bottom:9px;left:11px;right:11px}.machine .evidence{display:none}.machine .target{display:none!important}.error{position:absolute;inset:0;display:grid;place-content:center;padding:20px;text-align:center;color:#85988d;font-size:11px}.error:empty{display:none}button{font:inherit;border:1px solid #53695f;background:#263c31;color:#dbe8df;padding:5px 9px;border-radius:4px;cursor:pointer}button:focus-visible{outline:2px solid #d4a063;outline-offset:3px}.orbit-hint{position:absolute;bottom:9px;right:11px;color:#899184;font:8px ui-monospace,monospace}.machine .foot{right:70px}@media(max-width:300px){header{padding:0 11px}.evidence{padding:10px 11px;grid-template-columns:80px minmax(0,1fr);gap:10px;height:104px}.evidence canvas{width:80px;height:66px}.evidence b{font-size:10px}.evidence small{font-size:8px}}\n</style></head><body>\n<header><strong id=\"title\">Inspection camera</strong><span class=\"status\"><i></i><span id=\"status\">Running</span></span></header>\n<div class=\"viewport\" id=\"viewport\"><div class=\"hud\"><span id=\"source\">CAM 02 · SURFACE</span><span id=\"time\">14:32:00</span></div><div class=\"target\" id=\"target\"></div><div class=\"foot\"><span id=\"location\">GUIDE 02 · INSPECTION STATION</span><span id=\"counter\"></span></div><div class=\"error\" id=\"error\"></div></div>\n<div class=\"evidence\" id=\"evidence\"></div>\n<script>\n(function(){\n  var d=window.__DASLAB_WIDGET_DATA__||{},replay=window.__DASLAB_REPLAY__===true,elapsed=Number(d.elapsed)||0,draw=null;\n  var machine=d.view==='machine',el=id=>document.getElementById(id),pending=false,phase='';\n  document.body.classList.toggle('machine',machine);\n  el('title').textContent=machine?'Machine view':'Inspection camera';\n  el('source').textContent=machine?'CABLE LINE 02':'CAM 02 · SURFACE';\n  if(machine){el('time').textContent='';el('viewport').insertAdjacentHTML('beforeend','<span class=\"orbit-hint\">Drag to orbit</span>')}\n  function requestDraw(){if(pending||!draw)return;pending=true;requestAnimationFrame(()=>{pending=false;draw(elapsed)})}\n  addEventListener('message',e=>{if(!replay||e.source!==parent||e.origin!==location.origin||e.data?.type!=='daslab:replay-clock')return;if(e.data.data)d=e.data.data;elapsed=Math.max(0,Number(e.data.elapsed)||0)/1000;requestDraw()});\n  init().catch(()=>{el('error').textContent='The station view could not load. Reload to try again.'});\n  async function init(){\n    // Self-hosted, pinned three.js r160 (MIT); the same station geometry serves\n    // the inspection lens and the orbitable machine view.\n    var host=replay?location.origin:'https://daslab.run';\n    var THREE=await import(host+'/replay/quality-control/three.module.js');\n    var mount=el('viewport'),renderer=new THREE.WebGLRenderer({antialias:true,alpha:false,preserveDrawingBuffer:true});\n    renderer.setPixelRatio(Math.min(devicePixelRatio,1.7));renderer.shadowMap.enabled=true;renderer.shadowMap.type=THREE.PCFSoftShadowMap;renderer.toneMapping=THREE.ACESFilmicToneMapping;renderer.toneMappingExposure=machine?1.35:1.45;mount.prepend(renderer.domElement);\n    var scene=new THREE.Scene();scene.background=new THREE.Color(machine?0xeef0ea:0x172022);\n    scene.add(new THREE.HemisphereLight(0xeaf2ed,0x3b4542,2.4));\n    function light(x,y,z,power,color){var l=new THREE.DirectionalLight(color,power);l.position.set(x,y,z);l.castShadow=true;l.shadow.mapSize.set(1024,1024);l.shadow.camera.left=-3;l.shadow.camera.right=3;l.shadow.camera.top=3;l.shadow.camera.bottom=-3;scene.add(l)}\n    light(2,4,3,3,0xf9e8d0);light(-2,2,-2,1.5,0xc7dfe0);\n    var silver=new THREE.MeshStandardMaterial({color:0xa3aeac,metalness:.68,roughness:.32}),dark=new THREE.MeshStandardMaterial({color:0x303c3e,metalness:.55,roughness:.5}),black=new THREE.MeshStandardMaterial({color:0x242b2b,roughness:.75}),amber=new THREE.MeshStandardMaterial({color:0xbd7940,metalness:.45,roughness:.38}),blue=new THREE.MeshStandardMaterial({color:0x486a6a,metalness:.4,roughness:.4});\n    var station=new THREE.Group();scene.add(station);var rollers=[],marks=[],ridges=[];\n    function box(w,h,l,x,y,z,mat){var m=new THREE.Mesh(new THREE.BoxGeometry(w,h,l),mat);m.position.set(x,y,z);m.castShadow=true;m.receiveShadow=true;station.add(m);return m}\n    function cylinder(r,len,x,y,z,mat,axis){var m=new THREE.Mesh(new THREE.CylinderGeometry(r,r,len,32),mat);if(axis==='x')m.rotation.z=Math.PI/2;if(axis==='z')m.rotation.x=Math.PI/2;m.position.set(x,y,z);m.castShadow=true;m.receiveShadow=true;station.add(m);return m}\n    // A compact extrusion gantry, rollers, cable, three camera positions and\n    // a local vision node, following the existing cable-line twin.\n    box(.76,.09,2.65,0,.28,0,dark);\n    for(var x of[-.42,.42]){box(.045,.045,2.2,x,.13,0,silver);box(.045,.045,2.2,x,1.17,0,silver);for(var z of[-1,1]){box(.045,1.1,.045,x,.66,z,silver);box(.11,.035,.11,x,.1,z,black);box(.007,.98,.012,x+.026,.66,z,dark)}}\n    for(var z of[-1,1])box(.89,.045,.045,0,1.17,z,silver);\n    for(var z=-1.15;z<=1.15;z+=.23){var roller=cylinder(.05,.64,0,.375,z,silver,'x');rollers.push(roller);for(var x of[-.29,.29])cylinder(.058,.024,x,.375,z,black,'x')}\n    var cableMat=new THREE.MeshStandardMaterial({color:0xb77742,metalness:.57,roughness:.47});\n    cylinder(.047,3.3,0,.465,0,cableMat,'z');\n    // Fine spiral texture makes forward movement readable at camera scale.\n    for(var i=0;i<88;i++){var ring=new THREE.Mesh(new THREE.TorusGeometry(.047,.00065,3,40),dark);ring.position.set(0,.465,i*.038-1.65);station.add(ring);ridges.push(ring)}\n    var guide=box(.19,.024,.105,0,.54,.06,silver);box(.31,.06,.2,0,.305,.06,dark);\n    for(var z of[-.65,0,.65]){box(.27,.035,.035,.22,1.08,z,silver);box(.11,.09,.085,.13,.99,z,blue);cylinder(.032,.075,.13,.91,z,black);var lens=cylinder(.025,.009,.13,.87,z,new THREE.MeshStandardMaterial({color:0x95c9bd,emissive:0x1a4638,roughness:.12}));}\n    box(.13,.19,.23,.51,.67,.69,blue);for(var i=0;i<6;i++)box(.145,.01,.23,.51,.61+i*.022,.69,dark);\n    var floor=new THREE.Mesh(new THREE.PlaneGeometry(20,20),new THREE.MeshStandardMaterial({color:machine?0xe5e9df:0x202b2d,roughness:.93}));floor.rotation.x=-Math.PI/2;floor.position.y=.069;floor.receiveShadow=true;scene.add(floor);\n    var grid=new THREE.GridHelper(8,40,machine?0xc8d2c3:0x2b3939,machine?0xdce2d7:0x263433);grid.position.y=.071;scene.add(grid);\n    var markMat=new THREE.MeshStandardMaterial({color:0x533527,roughness:.9});\n    var scar=new THREE.Shape();scar.moveTo(-.003,-.065);for(var p of[[.004,-.046],[.001,-.02],[.012,.009],[.008,.017],[.014,.057],[.003,.068],[-.001,.029],[-.01,.006],[-.004,-.019],[-.009,-.044]])scar.lineTo(p[0],p[1]);scar.closePath();\n    var scarGeometry=new THREE.ShapeGeometry(scar);scarGeometry.rotateX(-Math.PI/2);\n    for(var i=0;i<3;i++){var m=new THREE.Mesh(scarGeometry,markMat);m.position.set(0,.514,0);station.add(m);marks.push(m)}\n    var highlight=new THREE.Mesh(new THREE.BoxGeometry(.24,.105,.16),new THREE.MeshBasicMaterial({color:0xd79449,transparent:true,opacity:.18,depthWrite:false}));highlight.position.copy(guide.position);station.add(highlight);\n    var edges=new THREE.LineSegments(new THREE.EdgesGeometry(highlight.geometry),new THREE.LineBasicMaterial({color:0xc6863e}));edges.position.copy(highlight.position);station.add(edges);\n    var camera=new THREE.PerspectiveCamera(machine?37:32,1,.005,50),angle=.78,tilt=.59;\n    if(machine){camera.position.set(2,1.85,2.5);camera.lookAt(0,.6,0)}else{camera.position.set(.29,.99,.73);camera.lookAt(0,.445,.22);scene.fog=new THREE.Fog(0x172022,2.1,5)}\n    var capture=document.createElement('canvas');capture.width=320;capture.height=210;capture.setAttribute('aria-label','Captured surface mark at 14:32:08');var captured=false;\n    function pose(t){\n      ridges.forEach((m,i)=>m.position.z=((i*.038+t*.3)%3.34)-1.67);\n      marks.forEach((m,i)=>{var when=(d.marks||[8,10.4,12.7])[i];m.visible=t>=when&&t<when+3.2;m.position.z=.22+(t-when)*.3;});\n      var check=!!d.inspectionStation;guide.material=machine&&check?amber:silver;highlight.visible=edges.visible=machine&&check;\n      if(machine){var radius=3.9;camera.position.set(Math.sin(angle)*radius,tilt*radius,Math.cos(angle)*radius);camera.lookAt(0,.62,0)}\n    }\n    function paint(t){pose(t);renderer.render(scene,camera)}\n    function resize(){var w=mount.clientWidth,h=mount.clientHeight;if(!w||!h)return;renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();requestDraw()}\n    draw=function(t){\n      var noticed=!!d.detected;\n      if(noticed&&!captured&&!machine){\n        paint(8);var point=marks[0].position.clone().project(camera),cw=renderer.domElement.width,ch=renderer.domElement.height;\n        var px=(point.x+1)/2*cw,py=(1-point.y)/2*ch,sw=cw*.65,sh=sw*210/320,sx=Math.max(0,Math.min(cw-sw,px-sw/2)),sy=Math.max(0,Math.min(ch-sh,py-sh/2));\n        var ctx=capture.getContext('2d');ctx.drawImage(renderer.domElement,sx,sy,sw,sh,0,0,320,210);ctx.strokeStyle='#d9a566';ctx.lineWidth=2;ctx.strokeRect((px-sx)/sw*320-27,(py-sy)/sh*210-24,54,48);captured=true;\n      }\n      paint(t);\n      el('time').textContent=machine?'':('14:32:'+String(Math.floor(t)%60).padStart(2,'0'));\n      el('counter').textContent=machine?'':(1240+t*.3).toFixed(1)+' m';\n      var visibleMark=marks.find(m=>m.visible&&m.position.z<.8);\n      el('target').style.display=noticed&&visibleMark&&!machine?'block':'none';\n      if(visibleMark&&!machine){var p=visibleMark.position.clone().project(camera);el('target').style.left=((p.x+1)/2*mount.clientWidth-47)+'px';el('target').style.top=((1-p.y)/2*mount.clientHeight-35)+'px'}\n      el('status').textContent=machine?(d.inspectionStation?'Guide 02':'3 cameras'):'Running';\n      el('location').textContent=machine?(d.operatorObservation?'GUIDE WEAR REPORTED':d.inspectionStation?'CHECK GUIDE 02':'INSPECTION STATION'):'GUIDE 02 · '+(d.run||'RUN-024');\n      if(phase!==String(noticed)){phase=String(noticed);el('evidence').replaceChildren();if(noticed){el('evidence').append(capture);var detail=document.createElement('div');detail.innerHTML='<span class=\"tag\">CAPTURED · 14:32:08</span><b>Repeated surface marks</b><small>Frame kept with this run.</small>';el('evidence').append(detail)}else el('evidence').innerHTML='<div class=\"waiting\"><span>✓</span><div><b>Watching the cable surface</b><small>Camera frames and measurements stay together.</small></div></div>'}\n      if(!noticed)captured=false;\n      document.body.dataset.elapsed=String(t);document.body.dataset.phase=d.phase||'watch';\n    };\n    if(machine){var drag=null;renderer.domElement.addEventListener('pointerdown',e=>{drag={x:e.clientX,y:e.clientY,a:angle,t:tilt};renderer.domElement.setPointerCapture(e.pointerId)});renderer.domElement.addEventListener('pointermove',e=>{if(!drag)return;angle=drag.a+(e.clientX-drag.x)*.009;tilt=Math.max(.22,Math.min(1.15,drag.t+(e.clientY-drag.y)*.004));requestDraw()});renderer.domElement.addEventListener('pointerup',()=>drag=null);renderer.domElement.addEventListener('pointercancel',()=>drag=null);}\n    new ResizeObserver(resize).observe(mount);resize();requestDraw();\n    if(!replay){\n      d.detected=true;d.inspectionStation=true;\n      if(!matchMedia('(prefers-reduced-motion: reduce)').matches)setInterval(()=>{if(!document.hidden){elapsed=8+(Date.now()/1000)%8;requestDraw()}},70);\n    }\n  }\n})();\n</script></body></html>\n",
        "data": {
          "line": "Cable line 02",
          "run": "RUN-024",
          "camera": "Camera 02",
          "phase": "notice",
          "elapsed": 12,
          "sample": true,
          "diameterTarget": 2.4,
          "speed": 18,
          "marks": [
            8,
            10.4,
            12.7
          ],
          "samples": [
            {
              "t": -24,
              "diameter": 2.4,
              "speed": 17.96
            },
            {
              "t": -23,
              "diameter": 2.391,
              "speed": 18.05
            },
            {
              "t": -22,
              "diameter": 2.401,
              "speed": 18.11
            },
            {
              "t": -21,
              "diameter": 2.405,
              "speed": 18.11
            },
            {
              "t": -20,
              "diameter": 2.393,
              "speed": 18.03
            },
            {
              "t": -19,
              "diameter": 2.391,
              "speed": 17.94
            },
            {
              "t": -18,
              "diameter": 2.403,
              "speed": 17.88
            },
            {
              "t": -17,
              "diameter": 2.403,
              "speed": 17.9
            },
            {
              "t": -16,
              "diameter": 2.393,
              "speed": 17.97
            },
            {
              "t": -15,
              "diameter": 2.398,
              "speed": 18.06
            },
            {
              "t": -14,
              "diameter": 2.41,
              "speed": 18.12
            },
            {
              "t": -13,
              "diameter": 2.404,
              "speed": 18.1
            },
            {
              "t": -12,
              "diameter": 2.395,
              "speed": 18.02
            },
            {
              "t": -11,
              "diameter": 2.404,
              "speed": 17.93
            },
            {
              "t": -10,
              "diameter": 2.41,
              "speed": 17.88
            },
            {
              "t": -9,
              "diameter": 2.398,
              "speed": 17.9
            },
            {
              "t": -8,
              "diameter": 2.393,
              "speed": 17.99
            },
            {
              "t": -7,
              "diameter": 2.404,
              "speed": 18.08
            },
            {
              "t": -6,
              "diameter": 2.404,
              "speed": 18.12
            },
            {
              "t": -5,
              "diameter": 2.391,
              "speed": 18.09
            },
            {
              "t": -4,
              "diameter": 2.393,
              "speed": 18.01
            },
            {
              "t": -3,
              "diameter": 2.405,
              "speed": 17.92
            },
            {
              "t": -2,
              "diameter": 2.4,
              "speed": 17.88
            },
            {
              "t": -1,
              "diameter": 2.391,
              "speed": 17.91
            },
            {
              "t": 0,
              "diameter": 2.4,
              "speed": 18
            },
            {
              "t": 1,
              "diameter": 2.409,
              "speed": 18.09
            },
            {
              "t": 2,
              "diameter": 2.4,
              "speed": 18.12
            },
            {
              "t": 3,
              "diameter": 2.395,
              "speed": 18.08
            },
            {
              "t": 4,
              "diameter": 2.407,
              "speed": 17.99
            },
            {
              "t": 5,
              "diameter": 2.409,
              "speed": 17.91
            },
            {
              "t": 6,
              "diameter": 2.396,
              "speed": 17.88
            },
            {
              "t": 7,
              "diameter": 2.396,
              "speed": 17.92
            },
            {
              "t": 8,
              "diameter": 2.407,
              "speed": 18.01
            },
            {
              "t": 9,
              "diameter": 2.402,
              "speed": 18.1
            },
            {
              "t": 10,
              "diameter": 2.39,
              "speed": 18.12
            },
            {
              "t": 11,
              "diameter": 2.396,
              "speed": 18.07
            },
            {
              "t": 12,
              "diameter": 2.405,
              "speed": 17.98
            },
            {
              "t": 13,
              "diameter": 2.396,
              "speed": 17.9
            },
            {
              "t": 14,
              "diameter": 2.39,
              "speed": 17.88
            },
            {
              "t": 15,
              "diameter": 2.402,
              "speed": 17.94
            },
            {
              "t": 16,
              "diameter": 2.407,
              "speed": 18.03
            },
            {
              "t": 17,
              "diameter": 2.397,
              "speed": 18.1
            },
            {
              "t": 18,
              "diameter": 2.397,
              "speed": 18.12
            },
            {
              "t": 19,
              "diameter": 2.409,
              "speed": 18.06
            },
            {
              "t": 20,
              "diameter": 2.407,
              "speed": 17.97
            },
            {
              "t": 21,
              "diameter": 2.395,
              "speed": 17.89
            },
            {
              "t": 22,
              "diameter": 2.399,
              "speed": 17.89
            },
            {
              "t": 23,
              "diameter": 2.409,
              "speed": 17.95
            },
            {
              "t": 24,
              "diameter": 2.4,
              "speed": 18.04
            },
            {
              "t": 25,
              "diameter": 2.39,
              "speed": 18.11
            },
            {
              "t": 26,
              "diameter": 2.399,
              "speed": 18.11
            },
            {
              "t": 27,
              "diameter": 2.405,
              "speed": 18.05
            },
            {
              "t": 28,
              "diameter": 2.393,
              "speed": 17.95
            },
            {
              "t": 29,
              "diameter": 2.391,
              "speed": 17.89
            },
            {
              "t": 30,
              "diameter": 2.404,
              "speed": 17.89
            },
            {
              "t": 31,
              "diameter": 2.405,
              "speed": 17.96
            },
            {
              "t": 32,
              "diameter": 2.394,
              "speed": 18.05
            },
            {
              "t": 33,
              "diameter": 2.398,
              "speed": 18.11
            },
            {
              "t": 34,
              "diameter": 2.41,
              "speed": 18.11
            },
            {
              "t": 35,
              "diameter": 2.404,
              "speed": 18.03
            },
            {
              "t": 36,
              "diameter": 2.395,
              "speed": 17.94
            },
            {
              "t": 37,
              "diameter": 2.403,
              "speed": 17.88
            },
            {
              "t": 38,
              "diameter": 2.409,
              "speed": 17.9
            },
            {
              "t": 39,
              "diameter": 2.398,
              "speed": 17.97
            },
            {
              "t": 40,
              "diameter": 2.392,
              "speed": 18.07
            },
            {
              "t": 41,
              "diameter": 2.403,
              "speed": 18.12
            },
            {
              "t": 42,
              "diameter": 2.403,
              "speed": 18.1
            },
            {
              "t": 43,
              "diameter": 2.391,
              "speed": 18.02
            },
            {
              "t": 44,
              "diameter": 2.393,
              "speed": 17.93
            }
          ],
          "view": "camera"
        }
      },
      "layout": {
        "sortOrder": 0,
        "size": "large"
      }
    },
    {
      "id": "signals",
      "type": "daslab/webview",
      "name": "Line measurements",
      "fields": {
        "html": "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<style>\n*{box-sizing:border-box}html,body{margin:0;height:100%}body{font:11px/1.5 Inter,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;background:#fbfaf6;color:#43514a;overflow:auto;scrollbar-width:thin}header{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #e7e8df}header strong{font-size:11px;font-weight:550}header small{font:8px ui-monospace,monospace;color:#8d9689}main{padding:10px 12px}.metrics{display:grid;grid-template-columns:1fr 1fr;gap:10px}.metric small{font-size:8px;color:#82907d;display:block;margin-bottom:2px}.metric strong{font-size:22px;line-height:1.1;font-weight:450;letter-spacing:-.5px}.metric em{font-style:normal;font-size:8px;margin-left:4px;color:#8d9785}.chart{height:71px;position:relative;margin-top:5px}.chart canvas{width:100%;height:100%;display:block}.chart-label{display:flex;justify-content:space-between;font:7px ui-monospace,monospace;color:#8d9687}.finding{margin-top:10px;border-top:1px solid #e5e7dd;padding-top:9px;display:flex;gap:8px;align-items:flex-start}.dot{width:6px;height:6px;flex-shrink:0;border-radius:50%;margin-top:5px;background:#91a488}.finding b{font-size:10px;font-weight:550;display:block}.finding p{font-size:9px;line-height:1.5;margin:3px 0 0;color:#8a907f}.finding.warn .dot{background:#c89351}.finding.warn b{color:#966c37}.finding.kept .dot{background:#7b9a8c}.finding.kept b{color:#547563}.receipt{font:8px ui-monospace,monospace;color:#8b9687;margin-top:5px}.entry{margin-top:12px;border-top:1px solid #e5e7dd;padding-top:10px}.entry label{font-size:9px;display:block;margin-bottom:5px;color:#7c8d7a}.entry textarea{width:100%;min-height:66px;padding:8px;border:1px solid #d9dfd2;border-radius:5px;font:11px/1.5 inherit;color:#445747;background:#fffefa;resize:vertical}.entry small{display:block;font-size:8px;color:#8b9687;margin-top:4px}.entry[hidden]{display:none}textarea:focus-visible{outline:2px solid #315fc5;outline-offset:2px}@media(max-height:240px){main{padding:8px 12px}.metric strong{font-size:20px}.chart{height:50px;margin-top:2px}.finding{margin-top:7px;padding-top:7px}.finding p{font-size:8px}.chart-label{font-size:6px}.receipt{font-size:7px}}\n</style></head><body>\n<header><strong>Line measurements</strong><small id=\"run\">RUN-024</small></header>\n<main><div class=\"metrics\"><div class=\"metric\"><small>Diameter</small><strong id=\"diameter\">2.40</strong><em>mm</em></div><div class=\"metric\"><small>Line speed</small><strong id=\"speed\">18.0</strong><em>m/min</em></div></div><div class=\"chart\"><canvas id=\"chart\" aria-label=\"Diameter history and captured surface marks\"></canvas></div><div class=\"chart-label\"><span>DIAMETER · LAST 24 SEC</span><span id=\"range\">± 0.04 mm</span></div><div class=\"finding\" id=\"finding\"><i class=\"dot\"></i><div><b id=\"state\">Within range</b><p id=\"detail\">Watching for a change in the surface.</p><div class=\"receipt\" id=\"receipt\"></div></div></div><div class=\"entry\" id=\"entry\" hidden><label for=\"note\">Your inspection note</label><textarea id=\"note\" placeholder=\"What did you find? What should happen next?\"></textarea><small id=\"saved\">Saved with this run as you type.</small></div></main>\n<script>\n(function(){\n var d=window.__DASLAB_WIDGET_DATA__||{},replay=window.__DASLAB_REPLAY__===true,t=Number(d.elapsed)||0,el=id=>document.getElementById(id),canvas=el('chart'),pending=false;\n el('run').textContent=d.run||'RUN-024';\n function paint(){\n  pending=false;var sample=(d.samples||[]).filter(s=>s.t<=t).at(-1)||{diameter:2.4,speed:18};\n  el('diameter').textContent=Number(sample.diameter).toFixed(2);el('speed').textContent=Number(sample.speed).toFixed(1);\n  var kept=!!d.inspection,observed=!!d.operatorObservation,detected=!!d.detected;\n  el('finding').className='finding '+(kept?'kept':detected?'warn':'');\n  el('state').textContent=kept?'Inspection queued':observed?'Guide wear reported':d.askedOperator?'Waiting for Sam':detected?'Surface marks detected':'Within range';\n  el('detail').textContent=kept?'Run flagged. Sam will inspect the guide at the next planned pause.':observed?'Sam found a small burr on the guide.':d.askedOperator?'Check guide 02. Diameter and speed remain steady.':detected?'Repeated marks. Diameter and speed remain steady.':'Watching the surface as the run continues.';\n  el('receipt').textContent=kept?'QC-018 · EVIDENCE + OPERATOR NOTE':'';\n  var box=canvas.getBoundingClientRect(),w=box.width,h=box.height,ratio=Math.min(devicePixelRatio,2);canvas.width=w*ratio;canvas.height=h*ratio;\n  var c=canvas.getContext('2d');c.scale(ratio,ratio);var left=t-24,xx=v=>(v-left)/24*w,yy=v=>h/2-(v-2.4)/.1*h;\n  c.fillStyle='#edf1e8';c.fillRect(0,yy(2.44),w,yy(2.36)-yy(2.44));\n  c.strokeStyle='#dce3d3';c.lineWidth=.7;for(var v of[2.36,2.4,2.44]){c.beginPath();c.moveTo(0,yy(v));c.lineTo(w,yy(v));c.stroke()}\n  for(var mark of d.marks||[]){if(mark>t||mark<left)continue;c.strokeStyle='#c69a61';c.setLineDash([2,3]);c.beginPath();c.moveTo(xx(mark),6);c.lineTo(xx(mark),h-3);c.stroke();c.setLineDash([]);c.fillStyle='#c18b46';c.beginPath();c.arc(xx(mark),5,2.5,0,Math.PI*2);c.fill()}\n  c.strokeStyle='#76948b';c.lineWidth=1.7;c.lineJoin='round';c.beginPath();var points=(d.samples||[]).filter(s=>s.t>=left&&s.t<=t);points.forEach((s,i)=>i?c.lineTo(xx(s.t),yy(s.diameter)):c.moveTo(xx(s.t),yy(s.diameter)));c.stroke();\n  if(points.length){var last=points.at(-1);c.fillStyle='#537d70';c.beginPath();c.arc(xx(last.t),yy(last.diameter),2.5,0,Math.PI*2);c.fill()}\n  document.body.dataset.elapsed=String(t);document.body.dataset.phase=d.phase||'notice';\n }\n function update(){if(pending)return;pending=true;requestAnimationFrame(paint)}\n addEventListener('message',e=>{if(!replay||e.source!==parent||e.origin!==location.origin||e.data?.type!=='daslab:replay-clock')return;if(e.data.data)d=e.data.data;t=Math.max(0,Number(e.data.elapsed)||0)/1000;update()});\n new ResizeObserver(update).observe(canvas.parentElement);\n if(!replay){d.detected=true;el('entry').hidden=false;var key='asset:inspection:'+(d.run||'RUN-024')+':note';try{el('note').value=localStorage.getItem(key)||''}catch(e){}el('note').oninput=()=>{try{localStorage.setItem(key,el('note').value);el('saved').textContent='Saved with this run.'}catch(e){el('saved').textContent='Could not save. Keep a copy of your note.'}}}\n update();\n})();\n</script></body></html>\n",
        "data": {
          "line": "Cable line 02",
          "run": "RUN-024",
          "camera": "Camera 02",
          "phase": "notice",
          "elapsed": 12,
          "sample": true,
          "diameterTarget": 2.4,
          "speed": 18,
          "marks": [
            8,
            10.4,
            12.7
          ],
          "samples": [
            {
              "t": -24,
              "diameter": 2.4,
              "speed": 17.96
            },
            {
              "t": -23,
              "diameter": 2.391,
              "speed": 18.05
            },
            {
              "t": -22,
              "diameter": 2.401,
              "speed": 18.11
            },
            {
              "t": -21,
              "diameter": 2.405,
              "speed": 18.11
            },
            {
              "t": -20,
              "diameter": 2.393,
              "speed": 18.03
            },
            {
              "t": -19,
              "diameter": 2.391,
              "speed": 17.94
            },
            {
              "t": -18,
              "diameter": 2.403,
              "speed": 17.88
            },
            {
              "t": -17,
              "diameter": 2.403,
              "speed": 17.9
            },
            {
              "t": -16,
              "diameter": 2.393,
              "speed": 17.97
            },
            {
              "t": -15,
              "diameter": 2.398,
              "speed": 18.06
            },
            {
              "t": -14,
              "diameter": 2.41,
              "speed": 18.12
            },
            {
              "t": -13,
              "diameter": 2.404,
              "speed": 18.1
            },
            {
              "t": -12,
              "diameter": 2.395,
              "speed": 18.02
            },
            {
              "t": -11,
              "diameter": 2.404,
              "speed": 17.93
            },
            {
              "t": -10,
              "diameter": 2.41,
              "speed": 17.88
            },
            {
              "t": -9,
              "diameter": 2.398,
              "speed": 17.9
            },
            {
              "t": -8,
              "diameter": 2.393,
              "speed": 17.99
            },
            {
              "t": -7,
              "diameter": 2.404,
              "speed": 18.08
            },
            {
              "t": -6,
              "diameter": 2.404,
              "speed": 18.12
            },
            {
              "t": -5,
              "diameter": 2.391,
              "speed": 18.09
            },
            {
              "t": -4,
              "diameter": 2.393,
              "speed": 18.01
            },
            {
              "t": -3,
              "diameter": 2.405,
              "speed": 17.92
            },
            {
              "t": -2,
              "diameter": 2.4,
              "speed": 17.88
            },
            {
              "t": -1,
              "diameter": 2.391,
              "speed": 17.91
            },
            {
              "t": 0,
              "diameter": 2.4,
              "speed": 18
            },
            {
              "t": 1,
              "diameter": 2.409,
              "speed": 18.09
            },
            {
              "t": 2,
              "diameter": 2.4,
              "speed": 18.12
            },
            {
              "t": 3,
              "diameter": 2.395,
              "speed": 18.08
            },
            {
              "t": 4,
              "diameter": 2.407,
              "speed": 17.99
            },
            {
              "t": 5,
              "diameter": 2.409,
              "speed": 17.91
            },
            {
              "t": 6,
              "diameter": 2.396,
              "speed": 17.88
            },
            {
              "t": 7,
              "diameter": 2.396,
              "speed": 17.92
            },
            {
              "t": 8,
              "diameter": 2.407,
              "speed": 18.01
            },
            {
              "t": 9,
              "diameter": 2.402,
              "speed": 18.1
            },
            {
              "t": 10,
              "diameter": 2.39,
              "speed": 18.12
            },
            {
              "t": 11,
              "diameter": 2.396,
              "speed": 18.07
            },
            {
              "t": 12,
              "diameter": 2.405,
              "speed": 17.98
            },
            {
              "t": 13,
              "diameter": 2.396,
              "speed": 17.9
            },
            {
              "t": 14,
              "diameter": 2.39,
              "speed": 17.88
            },
            {
              "t": 15,
              "diameter": 2.402,
              "speed": 17.94
            },
            {
              "t": 16,
              "diameter": 2.407,
              "speed": 18.03
            },
            {
              "t": 17,
              "diameter": 2.397,
              "speed": 18.1
            },
            {
              "t": 18,
              "diameter": 2.397,
              "speed": 18.12
            },
            {
              "t": 19,
              "diameter": 2.409,
              "speed": 18.06
            },
            {
              "t": 20,
              "diameter": 2.407,
              "speed": 17.97
            },
            {
              "t": 21,
              "diameter": 2.395,
              "speed": 17.89
            },
            {
              "t": 22,
              "diameter": 2.399,
              "speed": 17.89
            },
            {
              "t": 23,
              "diameter": 2.409,
              "speed": 17.95
            },
            {
              "t": 24,
              "diameter": 2.4,
              "speed": 18.04
            },
            {
              "t": 25,
              "diameter": 2.39,
              "speed": 18.11
            },
            {
              "t": 26,
              "diameter": 2.399,
              "speed": 18.11
            },
            {
              "t": 27,
              "diameter": 2.405,
              "speed": 18.05
            },
            {
              "t": 28,
              "diameter": 2.393,
              "speed": 17.95
            },
            {
              "t": 29,
              "diameter": 2.391,
              "speed": 17.89
            },
            {
              "t": 30,
              "diameter": 2.404,
              "speed": 17.89
            },
            {
              "t": 31,
              "diameter": 2.405,
              "speed": 17.96
            },
            {
              "t": 32,
              "diameter": 2.394,
              "speed": 18.05
            },
            {
              "t": 33,
              "diameter": 2.398,
              "speed": 18.11
            },
            {
              "t": 34,
              "diameter": 2.41,
              "speed": 18.11
            },
            {
              "t": 35,
              "diameter": 2.404,
              "speed": 18.03
            },
            {
              "t": 36,
              "diameter": 2.395,
              "speed": 17.94
            },
            {
              "t": 37,
              "diameter": 2.403,
              "speed": 17.88
            },
            {
              "t": 38,
              "diameter": 2.409,
              "speed": 17.9
            },
            {
              "t": 39,
              "diameter": 2.398,
              "speed": 17.97
            },
            {
              "t": 40,
              "diameter": 2.392,
              "speed": 18.07
            },
            {
              "t": 41,
              "diameter": 2.403,
              "speed": 18.12
            },
            {
              "t": 42,
              "diameter": 2.403,
              "speed": 18.1
            },
            {
              "t": 43,
              "diameter": 2.391,
              "speed": 18.02
            },
            {
              "t": 44,
              "diameter": 2.393,
              "speed": 17.93
            }
          ],
          "view": "signals"
        }
      },
      "layout": {
        "sortOrder": 1,
        "size": "large"
      }
    },
    {
      "id": "machine",
      "type": "daslab/webview",
      "name": "Machine view",
      "fields": {
        "html": "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<style>\n*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden}body{font:11px/1.5 Inter,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;background:#181e20;color:#e5e8e5;display:flex;flex-direction:column}header{height:48px;padding:0 15px;display:flex;align-items:center;justify-content:space-between;gap:8px;flex-shrink:0;border-bottom:1px solid #ffffff13}header strong{font-size:12px;font-weight:550;letter-spacing:-.2px}header small{font:8px ui-monospace,monospace;color:#94aaa4}.status{display:flex;align-items:center;gap:5px;font-size:9px;color:#9cb7a7}.status i{height:5px;width:5px;background:#9cbea3;border-radius:50%}.viewport{position:relative;flex:1;min-height:0;overflow:hidden}.viewport>canvas{display:block;width:100%;height:100%;touch-action:pan-y}.hud{position:absolute;left:13px;right:13px;top:12px;display:flex;justify-content:space-between;font:8px ui-monospace,monospace;letter-spacing:.04em;color:#b5c3bf;pointer-events:none}.foot{position:absolute;bottom:12px;left:13px;right:13px;display:flex;justify-content:space-between;align-items:center;font:8px ui-monospace,monospace;color:#a8b8b2;pointer-events:none}.target{position:absolute;left:calc(50% - 47px);top:calc(50% - 35px);width:94px;height:70px;border:1px solid #d4a063;box-shadow:0 0 0 1px #0004;display:none;pointer-events:none}.target:before{content:'SURFACE MARK';position:absolute;top:-19px;left:-1px;background:#d4a063;color:#202321;font:7px ui-monospace,monospace;white-space:nowrap;padding:3px 5px}.evidence{height:118px;flex-shrink:0;border-top:1px solid #ffffff18;background:#202729;display:grid;grid-template-columns:111px minmax(0,1fr);align-items:center;gap:13px;padding:13px 15px}.evidence canvas{width:111px;height:77px;border:1px solid #b287524f;object-fit:cover}.evidence b{font-size:11px;font-weight:500;display:block;color:#e1d0b7}.evidence small{font-size:9px;color:#8fa29b;display:block;margin-top:4px}.evidence .tag{font:8px ui-monospace,monospace;display:block;color:#c0955f;margin-bottom:4px}.waiting{grid-column:1/-1;display:flex;align-items:center;gap:12px;color:#8ea49a}.waiting span{display:block;width:27px;height:27px;border:1px solid #60786b;border-radius:50%;text-align:center;line-height:25px;color:#adc0b2}.waiting b{font-size:11px;color:#b8c8be;font-weight:400}.waiting small{font-size:9px;margin-top:3px}.machine{background:#eef0ea;color:#414d49}.machine header{height:38px;border-color:#dce2d9;padding:0 12px}.machine header strong{font-size:11px}.machine .status{color:#73867a}.machine .viewport{cursor:grab}.machine .hud{font:8px ui-monospace,monospace;color:#7f8d82;top:9px;left:11px;right:11px}.machine .foot{color:#73816f;font-size:8px;bottom:9px;left:11px;right:11px}.machine .evidence{display:none}.machine .target{display:none!important}.error{position:absolute;inset:0;display:grid;place-content:center;padding:20px;text-align:center;color:#85988d;font-size:11px}.error:empty{display:none}button{font:inherit;border:1px solid #53695f;background:#263c31;color:#dbe8df;padding:5px 9px;border-radius:4px;cursor:pointer}button:focus-visible{outline:2px solid #d4a063;outline-offset:3px}.orbit-hint{position:absolute;bottom:9px;right:11px;color:#899184;font:8px ui-monospace,monospace}.machine .foot{right:70px}@media(max-width:300px){header{padding:0 11px}.evidence{padding:10px 11px;grid-template-columns:80px minmax(0,1fr);gap:10px;height:104px}.evidence canvas{width:80px;height:66px}.evidence b{font-size:10px}.evidence small{font-size:8px}}\n</style></head><body>\n<header><strong id=\"title\">Inspection camera</strong><span class=\"status\"><i></i><span id=\"status\">Running</span></span></header>\n<div class=\"viewport\" id=\"viewport\"><div class=\"hud\"><span id=\"source\">CAM 02 · SURFACE</span><span id=\"time\">14:32:00</span></div><div class=\"target\" id=\"target\"></div><div class=\"foot\"><span id=\"location\">GUIDE 02 · INSPECTION STATION</span><span id=\"counter\"></span></div><div class=\"error\" id=\"error\"></div></div>\n<div class=\"evidence\" id=\"evidence\"></div>\n<script>\n(function(){\n  var d=window.__DASLAB_WIDGET_DATA__||{},replay=window.__DASLAB_REPLAY__===true,elapsed=Number(d.elapsed)||0,draw=null;\n  var machine=d.view==='machine',el=id=>document.getElementById(id),pending=false,phase='';\n  document.body.classList.toggle('machine',machine);\n  el('title').textContent=machine?'Machine view':'Inspection camera';\n  el('source').textContent=machine?'CABLE LINE 02':'CAM 02 · SURFACE';\n  if(machine){el('time').textContent='';el('viewport').insertAdjacentHTML('beforeend','<span class=\"orbit-hint\">Drag to orbit</span>')}\n  function requestDraw(){if(pending||!draw)return;pending=true;requestAnimationFrame(()=>{pending=false;draw(elapsed)})}\n  addEventListener('message',e=>{if(!replay||e.source!==parent||e.origin!==location.origin||e.data?.type!=='daslab:replay-clock')return;if(e.data.data)d=e.data.data;elapsed=Math.max(0,Number(e.data.elapsed)||0)/1000;requestDraw()});\n  init().catch(()=>{el('error').textContent='The station view could not load. Reload to try again.'});\n  async function init(){\n    // Self-hosted, pinned three.js r160 (MIT); the same station geometry serves\n    // the inspection lens and the orbitable machine view.\n    var host=replay?location.origin:'https://daslab.run';\n    var THREE=await import(host+'/replay/quality-control/three.module.js');\n    var mount=el('viewport'),renderer=new THREE.WebGLRenderer({antialias:true,alpha:false,preserveDrawingBuffer:true});\n    renderer.setPixelRatio(Math.min(devicePixelRatio,1.7));renderer.shadowMap.enabled=true;renderer.shadowMap.type=THREE.PCFSoftShadowMap;renderer.toneMapping=THREE.ACESFilmicToneMapping;renderer.toneMappingExposure=machine?1.35:1.45;mount.prepend(renderer.domElement);\n    var scene=new THREE.Scene();scene.background=new THREE.Color(machine?0xeef0ea:0x172022);\n    scene.add(new THREE.HemisphereLight(0xeaf2ed,0x3b4542,2.4));\n    function light(x,y,z,power,color){var l=new THREE.DirectionalLight(color,power);l.position.set(x,y,z);l.castShadow=true;l.shadow.mapSize.set(1024,1024);l.shadow.camera.left=-3;l.shadow.camera.right=3;l.shadow.camera.top=3;l.shadow.camera.bottom=-3;scene.add(l)}\n    light(2,4,3,3,0xf9e8d0);light(-2,2,-2,1.5,0xc7dfe0);\n    var silver=new THREE.MeshStandardMaterial({color:0xa3aeac,metalness:.68,roughness:.32}),dark=new THREE.MeshStandardMaterial({color:0x303c3e,metalness:.55,roughness:.5}),black=new THREE.MeshStandardMaterial({color:0x242b2b,roughness:.75}),amber=new THREE.MeshStandardMaterial({color:0xbd7940,metalness:.45,roughness:.38}),blue=new THREE.MeshStandardMaterial({color:0x486a6a,metalness:.4,roughness:.4});\n    var station=new THREE.Group();scene.add(station);var rollers=[],marks=[],ridges=[];\n    function box(w,h,l,x,y,z,mat){var m=new THREE.Mesh(new THREE.BoxGeometry(w,h,l),mat);m.position.set(x,y,z);m.castShadow=true;m.receiveShadow=true;station.add(m);return m}\n    function cylinder(r,len,x,y,z,mat,axis){var m=new THREE.Mesh(new THREE.CylinderGeometry(r,r,len,32),mat);if(axis==='x')m.rotation.z=Math.PI/2;if(axis==='z')m.rotation.x=Math.PI/2;m.position.set(x,y,z);m.castShadow=true;m.receiveShadow=true;station.add(m);return m}\n    // A compact extrusion gantry, rollers, cable, three camera positions and\n    // a local vision node, following the existing cable-line twin.\n    box(.76,.09,2.65,0,.28,0,dark);\n    for(var x of[-.42,.42]){box(.045,.045,2.2,x,.13,0,silver);box(.045,.045,2.2,x,1.17,0,silver);for(var z of[-1,1]){box(.045,1.1,.045,x,.66,z,silver);box(.11,.035,.11,x,.1,z,black);box(.007,.98,.012,x+.026,.66,z,dark)}}\n    for(var z of[-1,1])box(.89,.045,.045,0,1.17,z,silver);\n    for(var z=-1.15;z<=1.15;z+=.23){var roller=cylinder(.05,.64,0,.375,z,silver,'x');rollers.push(roller);for(var x of[-.29,.29])cylinder(.058,.024,x,.375,z,black,'x')}\n    var cableMat=new THREE.MeshStandardMaterial({color:0xb77742,metalness:.57,roughness:.47});\n    cylinder(.047,3.3,0,.465,0,cableMat,'z');\n    // Fine spiral texture makes forward movement readable at camera scale.\n    for(var i=0;i<88;i++){var ring=new THREE.Mesh(new THREE.TorusGeometry(.047,.00065,3,40),dark);ring.position.set(0,.465,i*.038-1.65);station.add(ring);ridges.push(ring)}\n    var guide=box(.19,.024,.105,0,.54,.06,silver);box(.31,.06,.2,0,.305,.06,dark);\n    for(var z of[-.65,0,.65]){box(.27,.035,.035,.22,1.08,z,silver);box(.11,.09,.085,.13,.99,z,blue);cylinder(.032,.075,.13,.91,z,black);var lens=cylinder(.025,.009,.13,.87,z,new THREE.MeshStandardMaterial({color:0x95c9bd,emissive:0x1a4638,roughness:.12}));}\n    box(.13,.19,.23,.51,.67,.69,blue);for(var i=0;i<6;i++)box(.145,.01,.23,.51,.61+i*.022,.69,dark);\n    var floor=new THREE.Mesh(new THREE.PlaneGeometry(20,20),new THREE.MeshStandardMaterial({color:machine?0xe5e9df:0x202b2d,roughness:.93}));floor.rotation.x=-Math.PI/2;floor.position.y=.069;floor.receiveShadow=true;scene.add(floor);\n    var grid=new THREE.GridHelper(8,40,machine?0xc8d2c3:0x2b3939,machine?0xdce2d7:0x263433);grid.position.y=.071;scene.add(grid);\n    var markMat=new THREE.MeshStandardMaterial({color:0x533527,roughness:.9});\n    var scar=new THREE.Shape();scar.moveTo(-.003,-.065);for(var p of[[.004,-.046],[.001,-.02],[.012,.009],[.008,.017],[.014,.057],[.003,.068],[-.001,.029],[-.01,.006],[-.004,-.019],[-.009,-.044]])scar.lineTo(p[0],p[1]);scar.closePath();\n    var scarGeometry=new THREE.ShapeGeometry(scar);scarGeometry.rotateX(-Math.PI/2);\n    for(var i=0;i<3;i++){var m=new THREE.Mesh(scarGeometry,markMat);m.position.set(0,.514,0);station.add(m);marks.push(m)}\n    var highlight=new THREE.Mesh(new THREE.BoxGeometry(.24,.105,.16),new THREE.MeshBasicMaterial({color:0xd79449,transparent:true,opacity:.18,depthWrite:false}));highlight.position.copy(guide.position);station.add(highlight);\n    var edges=new THREE.LineSegments(new THREE.EdgesGeometry(highlight.geometry),new THREE.LineBasicMaterial({color:0xc6863e}));edges.position.copy(highlight.position);station.add(edges);\n    var camera=new THREE.PerspectiveCamera(machine?37:32,1,.005,50),angle=.78,tilt=.59;\n    if(machine){camera.position.set(2,1.85,2.5);camera.lookAt(0,.6,0)}else{camera.position.set(.29,.99,.73);camera.lookAt(0,.445,.22);scene.fog=new THREE.Fog(0x172022,2.1,5)}\n    var capture=document.createElement('canvas');capture.width=320;capture.height=210;capture.setAttribute('aria-label','Captured surface mark at 14:32:08');var captured=false;\n    function pose(t){\n      ridges.forEach((m,i)=>m.position.z=((i*.038+t*.3)%3.34)-1.67);\n      marks.forEach((m,i)=>{var when=(d.marks||[8,10.4,12.7])[i];m.visible=t>=when&&t<when+3.2;m.position.z=.22+(t-when)*.3;});\n      var check=!!d.inspectionStation;guide.material=machine&&check?amber:silver;highlight.visible=edges.visible=machine&&check;\n      if(machine){var radius=3.9;camera.position.set(Math.sin(angle)*radius,tilt*radius,Math.cos(angle)*radius);camera.lookAt(0,.62,0)}\n    }\n    function paint(t){pose(t);renderer.render(scene,camera)}\n    function resize(){var w=mount.clientWidth,h=mount.clientHeight;if(!w||!h)return;renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();requestDraw()}\n    draw=function(t){\n      var noticed=!!d.detected;\n      if(noticed&&!captured&&!machine){\n        paint(8);var point=marks[0].position.clone().project(camera),cw=renderer.domElement.width,ch=renderer.domElement.height;\n        var px=(point.x+1)/2*cw,py=(1-point.y)/2*ch,sw=cw*.65,sh=sw*210/320,sx=Math.max(0,Math.min(cw-sw,px-sw/2)),sy=Math.max(0,Math.min(ch-sh,py-sh/2));\n        var ctx=capture.getContext('2d');ctx.drawImage(renderer.domElement,sx,sy,sw,sh,0,0,320,210);ctx.strokeStyle='#d9a566';ctx.lineWidth=2;ctx.strokeRect((px-sx)/sw*320-27,(py-sy)/sh*210-24,54,48);captured=true;\n      }\n      paint(t);\n      el('time').textContent=machine?'':('14:32:'+String(Math.floor(t)%60).padStart(2,'0'));\n      el('counter').textContent=machine?'':(1240+t*.3).toFixed(1)+' m';\n      var visibleMark=marks.find(m=>m.visible&&m.position.z<.8);\n      el('target').style.display=noticed&&visibleMark&&!machine?'block':'none';\n      if(visibleMark&&!machine){var p=visibleMark.position.clone().project(camera);el('target').style.left=((p.x+1)/2*mount.clientWidth-47)+'px';el('target').style.top=((1-p.y)/2*mount.clientHeight-35)+'px'}\n      el('status').textContent=machine?(d.inspectionStation?'Guide 02':'3 cameras'):'Running';\n      el('location').textContent=machine?(d.operatorObservation?'GUIDE WEAR REPORTED':d.inspectionStation?'CHECK GUIDE 02':'INSPECTION STATION'):'GUIDE 02 · '+(d.run||'RUN-024');\n      if(phase!==String(noticed)){phase=String(noticed);el('evidence').replaceChildren();if(noticed){el('evidence').append(capture);var detail=document.createElement('div');detail.innerHTML='<span class=\"tag\">CAPTURED · 14:32:08</span><b>Repeated surface marks</b><small>Frame kept with this run.</small>';el('evidence').append(detail)}else el('evidence').innerHTML='<div class=\"waiting\"><span>✓</span><div><b>Watching the cable surface</b><small>Camera frames and measurements stay together.</small></div></div>'}\n      if(!noticed)captured=false;\n      document.body.dataset.elapsed=String(t);document.body.dataset.phase=d.phase||'watch';\n    };\n    if(machine){var drag=null;renderer.domElement.addEventListener('pointerdown',e=>{drag={x:e.clientX,y:e.clientY,a:angle,t:tilt};renderer.domElement.setPointerCapture(e.pointerId)});renderer.domElement.addEventListener('pointermove',e=>{if(!drag)return;angle=drag.a+(e.clientX-drag.x)*.009;tilt=Math.max(.22,Math.min(1.15,drag.t+(e.clientY-drag.y)*.004));requestDraw()});renderer.domElement.addEventListener('pointerup',()=>drag=null);renderer.domElement.addEventListener('pointercancel',()=>drag=null);}\n    new ResizeObserver(resize).observe(mount);resize();requestDraw();\n    if(!replay){\n      d.detected=true;d.inspectionStation=true;\n      if(!matchMedia('(prefers-reduced-motion: reduce)').matches)setInterval(()=>{if(!document.hidden){elapsed=8+(Date.now()/1000)%8;requestDraw()}},70);\n    }\n  }\n})();\n</script></body></html>\n",
        "data": {
          "line": "Cable line 02",
          "run": "RUN-024",
          "camera": "Camera 02",
          "phase": "notice",
          "elapsed": 12,
          "sample": true,
          "diameterTarget": 2.4,
          "speed": 18,
          "marks": [
            8,
            10.4,
            12.7
          ],
          "samples": [
            {
              "t": -24,
              "diameter": 2.4,
              "speed": 17.96
            },
            {
              "t": -23,
              "diameter": 2.391,
              "speed": 18.05
            },
            {
              "t": -22,
              "diameter": 2.401,
              "speed": 18.11
            },
            {
              "t": -21,
              "diameter": 2.405,
              "speed": 18.11
            },
            {
              "t": -20,
              "diameter": 2.393,
              "speed": 18.03
            },
            {
              "t": -19,
              "diameter": 2.391,
              "speed": 17.94
            },
            {
              "t": -18,
              "diameter": 2.403,
              "speed": 17.88
            },
            {
              "t": -17,
              "diameter": 2.403,
              "speed": 17.9
            },
            {
              "t": -16,
              "diameter": 2.393,
              "speed": 17.97
            },
            {
              "t": -15,
              "diameter": 2.398,
              "speed": 18.06
            },
            {
              "t": -14,
              "diameter": 2.41,
              "speed": 18.12
            },
            {
              "t": -13,
              "diameter": 2.404,
              "speed": 18.1
            },
            {
              "t": -12,
              "diameter": 2.395,
              "speed": 18.02
            },
            {
              "t": -11,
              "diameter": 2.404,
              "speed": 17.93
            },
            {
              "t": -10,
              "diameter": 2.41,
              "speed": 17.88
            },
            {
              "t": -9,
              "diameter": 2.398,
              "speed": 17.9
            },
            {
              "t": -8,
              "diameter": 2.393,
              "speed": 17.99
            },
            {
              "t": -7,
              "diameter": 2.404,
              "speed": 18.08
            },
            {
              "t": -6,
              "diameter": 2.404,
              "speed": 18.12
            },
            {
              "t": -5,
              "diameter": 2.391,
              "speed": 18.09
            },
            {
              "t": -4,
              "diameter": 2.393,
              "speed": 18.01
            },
            {
              "t": -3,
              "diameter": 2.405,
              "speed": 17.92
            },
            {
              "t": -2,
              "diameter": 2.4,
              "speed": 17.88
            },
            {
              "t": -1,
              "diameter": 2.391,
              "speed": 17.91
            },
            {
              "t": 0,
              "diameter": 2.4,
              "speed": 18
            },
            {
              "t": 1,
              "diameter": 2.409,
              "speed": 18.09
            },
            {
              "t": 2,
              "diameter": 2.4,
              "speed": 18.12
            },
            {
              "t": 3,
              "diameter": 2.395,
              "speed": 18.08
            },
            {
              "t": 4,
              "diameter": 2.407,
              "speed": 17.99
            },
            {
              "t": 5,
              "diameter": 2.409,
              "speed": 17.91
            },
            {
              "t": 6,
              "diameter": 2.396,
              "speed": 17.88
            },
            {
              "t": 7,
              "diameter": 2.396,
              "speed": 17.92
            },
            {
              "t": 8,
              "diameter": 2.407,
              "speed": 18.01
            },
            {
              "t": 9,
              "diameter": 2.402,
              "speed": 18.1
            },
            {
              "t": 10,
              "diameter": 2.39,
              "speed": 18.12
            },
            {
              "t": 11,
              "diameter": 2.396,
              "speed": 18.07
            },
            {
              "t": 12,
              "diameter": 2.405,
              "speed": 17.98
            },
            {
              "t": 13,
              "diameter": 2.396,
              "speed": 17.9
            },
            {
              "t": 14,
              "diameter": 2.39,
              "speed": 17.88
            },
            {
              "t": 15,
              "diameter": 2.402,
              "speed": 17.94
            },
            {
              "t": 16,
              "diameter": 2.407,
              "speed": 18.03
            },
            {
              "t": 17,
              "diameter": 2.397,
              "speed": 18.1
            },
            {
              "t": 18,
              "diameter": 2.397,
              "speed": 18.12
            },
            {
              "t": 19,
              "diameter": 2.409,
              "speed": 18.06
            },
            {
              "t": 20,
              "diameter": 2.407,
              "speed": 17.97
            },
            {
              "t": 21,
              "diameter": 2.395,
              "speed": 17.89
            },
            {
              "t": 22,
              "diameter": 2.399,
              "speed": 17.89
            },
            {
              "t": 23,
              "diameter": 2.409,
              "speed": 17.95
            },
            {
              "t": 24,
              "diameter": 2.4,
              "speed": 18.04
            },
            {
              "t": 25,
              "diameter": 2.39,
              "speed": 18.11
            },
            {
              "t": 26,
              "diameter": 2.399,
              "speed": 18.11
            },
            {
              "t": 27,
              "diameter": 2.405,
              "speed": 18.05
            },
            {
              "t": 28,
              "diameter": 2.393,
              "speed": 17.95
            },
            {
              "t": 29,
              "diameter": 2.391,
              "speed": 17.89
            },
            {
              "t": 30,
              "diameter": 2.404,
              "speed": 17.89
            },
            {
              "t": 31,
              "diameter": 2.405,
              "speed": 17.96
            },
            {
              "t": 32,
              "diameter": 2.394,
              "speed": 18.05
            },
            {
              "t": 33,
              "diameter": 2.398,
              "speed": 18.11
            },
            {
              "t": 34,
              "diameter": 2.41,
              "speed": 18.11
            },
            {
              "t": 35,
              "diameter": 2.404,
              "speed": 18.03
            },
            {
              "t": 36,
              "diameter": 2.395,
              "speed": 17.94
            },
            {
              "t": 37,
              "diameter": 2.403,
              "speed": 17.88
            },
            {
              "t": 38,
              "diameter": 2.409,
              "speed": 17.9
            },
            {
              "t": 39,
              "diameter": 2.398,
              "speed": 17.97
            },
            {
              "t": 40,
              "diameter": 2.392,
              "speed": 18.07
            },
            {
              "t": 41,
              "diameter": 2.403,
              "speed": 18.12
            },
            {
              "t": 42,
              "diameter": 2.403,
              "speed": 18.1
            },
            {
              "t": 43,
              "diameter": 2.391,
              "speed": 18.02
            },
            {
              "t": 44,
              "diameter": 2.393,
              "speed": 17.93
            }
          ],
          "view": "machine"
        }
      },
      "layout": {
        "sortOrder": 2,
        "size": "large"
      }
    },
    {
      "id": "guide",
      "type": "daslab/note",
      "name": "Make this inspection yours",
      "fields": {
        "content": "# Make this inspection yours\n\nThree cells bring the same run together: **Inspection camera**, **Line measurements**, and **Machine view**. The starting scene uses a rendered cable-line sample and sample measurements. No camera, sensor or machine account is connected.\n\nLook at the captured surface mark, compare it with the measurements, and add your own observation in **Line measurements**. Your inspection note is saved with the cell. Ask Daslab to help you investigate, or invite an operator into a job with their @username.\n\nThe sample’s diameter and speed remain within their usual range. A surface mark is a reason to inspect the guide; it does not establish the cause on its own. Keep that distinction in your finding.\n\nTo use your equipment, bring a camera and its measurements into the scene. Ask Daslab to adapt these views around your sources, thresholds and station layout. Start with observation and a team handoff. Add an equipment action only after its connection, permissions and review step are configured.\n\nKeep the same scene across runs. Preserve captured evidence and operator observations so the next person can see what was checked and what remains open.\n"
      },
      "layout": {
        "sortOrder": 3,
        "size": "medium"
      }
    }
  ],
  "meta": {
    "author": "Daslab",
    "license": "MIT"
  }
}
