diff --git a/docs/도면분석.md b/docs/도면분석.md index e8a0c1f..fd6225e 100644 --- a/docs/도면분석.md +++ b/docs/도면분석.md @@ -65,6 +65,9 @@ - 화면: `src/ModelViewer.jsx`와 `src/App.jsx`. 끌어서 회전, 휠 확대/축소, Shift/오른쪽 끌기로 이동, 전체·평면·정면·측면·A-A·B-B 시점을 제공한다. - 객체는 단일 중심선 모델에 구조선 114개와 삽입 블록 윤곽 40개, 총 154개 객체를 구성했다(단면 구조선 114개와 삽입 블록 윤곽 40개). 원본선 단위 선택·숨김과 MAJR/MINR/블록 윤곽 그룹 숨김을 지원한다. - 화면의 면은 검토용 열린 표면 모델이다. 구조선 사이를 연결했으며 모든 두께/접합을 확정한 닫힌 체적이나 실사 렌더링은 아니다. +- `scripts/render_block8_drawing_views.py`는 DXF 도면 영역의 선·문자를 잘라 평면도, 상부평면도, 종단면도, A-A, B-B SVG 이미지 5개와 픽셀-CAD 좌표 연결값을 만든다. 뷰어에서 현재 보기와 도면 종류를 연결하고 투명도를 조절할 수 있다. +- A-A/B-B 이미지는 각 끝 측점의 단면 평면에 놓고, 종단면 이미지는 STA 주석과 EL 주석으로 길이·높이를 변환해 구조물 측면에 놓는다. 평면도는 DXF 좌표를 모델 좌표에 대응시키며, 상부평면도 표기는 도면 간 35m 배치 차이를 이동해 단일 모델 위에 포개고 화면 표시용 EL 108.8m에 둔다. +- 이들은 도면 요소를 3D 화면의 기준 평면에 투영한 검토용 이미지다. 평면의 표시 높이와 종단면의 측면 이격은 보이도록 둔 시각화 위치이며 실제 부재나 설계 고도를 뜻하지 않는다. DXF 글꼴 및 일부 블록 표현은 SVG에서 단순화될 수 있다. - 실행: `npm run dev`. 분석 파일과 작업 로그는 화면 상단 링크에서 연다. ## 검증 결과 diff --git a/public/BLOCK8_모델웹페이지.html b/public/BLOCK8_모델웹페이지.html index 12d7d4b..8c0c9e3 100644 --- a/public/BLOCK8_모델웹페이지.html +++ b/public/BLOCK8_모델웹페이지.html @@ -6,19 +6,20 @@ 광터지하차도 BLOCK8 3D 모델 -
- + +`+e.stack}}var Ge=Object.prototype.hasOwnProperty,Ke=t.unstable_scheduleCallback,qe=t.unstable_cancelCallback,Je=t.unstable_shouldYield,Ye=t.unstable_requestPaint,Xe=t.unstable_now,Ze=t.unstable_getCurrentPriorityLevel,Qe=t.unstable_ImmediatePriority,$e=t.unstable_UserBlockingPriority,et=t.unstable_NormalPriority,tt=t.unstable_LowPriority,nt=t.unstable_IdlePriority,rt=t.log,it=t.unstable_setDisableYieldValue,at=null,ot=null;function st(e){if(typeof rt==`function`&&it(e),ot&&typeof ot.setStrictMode==`function`)try{ot.setStrictMode(at,e)}catch{}}var ct=Math.clz32?Math.clz32:dt,lt=Math.log,ut=Math.LN2;function dt(e){return e>>>=0,e===0?32:31-(lt(e)/ut|0)|0}var ft=256,pt=262144,mt=4194304;function ht(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&-e;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function gt(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=ht(n))):i=ht(o):i=ht(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=ht(n))):i=ht(o)):i=ht(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function _t(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function vt(e,t){t&8&&(t|=t&32);var n=e.entangledLanes;if(n!==0)for(e=e.entanglements,n&=t;0n;n++)t.push(e);return t}function St(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ct(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0=Sr),Tr=` `,Er=!1;function Dr(e,t){switch(e){case`keyup`:return br.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Or(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var kr=!1;function Ar(e,t){switch(e){case`compositionend`:return Or(t);case`keypress`:return t.which===32?(Er=!0,Tr):null;case`textInput`:return e=t.data,e===Tr&&Er?null:e;default:return null}}function jr(e,t){if(kr)return e===`compositionend`||!xr&&Dr(e,t)?(e=Un(),Hn=Vn=Bn=null,kr=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=ei(n)}}function ni(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?ni(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function ri(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=$r(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=$r(e.document)}return t}function ii(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var ai=Ln&&`documentMode`in document&&11>=document.documentMode,oi=null,si=null,ci=null,li=!1;function ui(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;li||oi==null||oi!==$r(r)||(r=oi,`selectionStart`in r&&ii(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),ci&&Qr(ci,r)||(ci=r,r=Jf(si,`onSelect`),0>=o,i-=o,oa=1<<32-ct(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),j&&ca(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),j&&ca(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return j&&ca(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&(_=v.alternate,_!==null&&h.delete(_.key===null?g:_.key)),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),j&&ca(a,g),u}function _(e,r,o,c){if(typeof o==`object`&&o&&o.type===ae&&o.key===null&&o.props.ref===void 0&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case re:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===ae){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),_o(c,o),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===me&&lo(l)===r.type){n(e,r.sibling),c=a(r,o.props),_o(c,o),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}o.type===ae?(c=qi(o.props.children,e.mode,c,o.key),_o(c,o),c.return=e,e=c):(c=Ki(o.type,o.key,o.props,null,e.mode,c),_o(c,o),c.return=e,e=c)}return s(e);case ie:a:{for(l=o.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=Xi(o,e.mode,c),c.return=e,e=c}return s(e);case me:return o=lo(o),_(e,r,o,c)}if(we(o))return h(e,r,o,c);if(xe(o)){if(l=xe(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return _(e,r,go(o),c);if(o.$$typeof===le)return _(e,r,Fa(e,o),c);vo(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=Ji(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{ho=0;var i=_(e,t,n,r);return mo=null,i}catch(t){if(t===ro||t===ao)throw t;var a=Hi(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var bo=yo(!0),xo=yo(!1),So=!1;function Co(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function wo(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function To(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Eo(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,W&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=zi(e),Ri(e,null,n),t}return Fi(e,r,t,n),zi(e)}function Do(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Tt(e,n)}}function Oo(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n}else e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var ko=!1;function Ao(){if(ko){var e=Ja;if(e!==null)throw e}}function jo(e,t,n,r){ko=!1;var i=e.updateQueue;So=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(q&f)===f:(r&f)===f){f!==0&&f===qa&&(ko=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,h=s;f=t;var g=n;switch(h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(g,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(g,d,f):m,f==null)break a;d=T({},d,f);break a;case 2:So=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),sd|=o,e.lanes=o,e.memoizedState=d}}function Mo(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function No(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=E.T,s={};s.types=o===null?null:o.types,E.T=s,gc(e,!1,t,n);try{var c=i(),l=E.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?hc(e,t,Za(c,r),jd(e)):hc(e,t,r,jd(e))}catch(n){hc(e,t,{then:function(){},status:`rejected`,reason:n},jd())}finally{D.p=a,o!==null&&s.types!==null&&(o.types=s.types),E.T=o}}function ac(){}function oc(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=sc(e).queue;ic(e,a,t,Te,n===null?ac:function(){return cc(e),n(r)})}function sc(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:Te,baseState:Te,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:_s,lastRenderedState:Te},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:_s,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function cc(e){var t=sc(e);t.next===null&&(t=e.alternate.memoizedState),hc(e,t.next.queue,{},jd())}function lc(){return Pa(sh)}function uc(){return L().memoizedState}function dc(){return L().memoizedState}function fc(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=jd();e=To(n);var r=Eo(t,e,n);r!==null&&(Pd(r,t,n),Do(r,t,n)),t={cache:Ba()},e.payload=t;return}t=t.return}}function pc(e,t,n){var r=jd();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},_c(e)?vc(t,n):(n=Ii(e,t,n,r),n!==null&&(Pd(n,e,r),yc(n,t,r)))}function mc(e,t,n){hc(e,t,n,jd())}function hc(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(_c(e))vc(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Zr(s,o))return Fi(e,t,i,0),G===null&&Pi(),!1}catch{}if(n=Ii(e,t,i,r),n!==null)return Pd(n,e,r),yc(n,t,r),!0}return!1}function gc(e,t,n,r){if(r={lane:2,revertLane:Pf(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},_c(e)){if(t)throw Error(i(479))}else t=Ii(e,n,r,2),t!==null&&Pd(t,e,2)}function _c(e){var t=e.alternate;return e===N||t!==null&&t===N}function vc(e,t){Qo=Zo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function yc(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Tt(e,n)}}var bc={readContext:Pa,use:hs,useCallback:I,useContext:I,useEffect:I,useImperativeHandle:I,useLayoutEffect:I,useInsertionEffect:I,useMemo:I,useReducer:I,useRef:I,useState:I,useDebugValue:I,useDeferredValue:I,useTransition:I,useSyncExternalStore:I,useId:I,useHostTransitionStatus:I,useFormState:I,useActionState:I,useOptimistic:I,useMemoCache:I,useCacheRefresh:I,useEffectEvent:I},xc={readContext:Pa,use:hs,useCallback:function(e,t){return fs().memoizedState=[e,t===void 0?null:t],e},useContext:Pa,useEffect:Gs,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),Us(4194308,4,Zs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Us(4194308,4,e,t)},useInsertionEffect:function(e,t){Us(4,2,e,t)},useMemo:function(e,t){var n=fs();t=t===void 0?null:t;var r=e();if($o){st(!0);try{e()}finally{st(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=fs();if(n!==void 0){var i=n(t);if($o){st(!0);try{n(t)}finally{st(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=pc.bind(null,N,e),[r.memoizedState,e]},useRef:function(e){var t=fs();return e={current:e},t.memoizedState=e},useState:function(e){e=Ds(e);var t=e.queue,n=mc.bind(null,N,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:$s,useDeferredValue:function(e,t){return nc(fs(),e,t)},useTransition:function(){var e=Ds(!1);return e=ic.bind(null,N,e.queue,!0,!1),fs().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=N,a=fs();if(j){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),G===null)throw Error(i(349));q&127||Ss(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,Gs(ws.bind(null,r,o,e),[e]),r.flags|=2048,Vs(9,{destroy:void 0},Cs.bind(null,r,o,n,t),null),n},useId:function(){var e=fs(),t=G.identifierPrefix;if(j){var n=sa,r=oa;n=(r&~(1<<32-ct(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=es++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[Mt]=t,o[Nt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(np(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&_l(t)}}return B(t),t.subtreeFlags&=-33554433,vl(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&_l(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=Me.current,ba(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=pa,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[Mt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||ep(e.nodeValue,n)),e||_a(t,!0)}else e=lp(e).createTextNode(r),e[Mt]=t,t.stateNode=e}return B(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=ba(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[Mt]=t}else xa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;B(t),e=!1}else n=Sa(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Go(t),t):(Go(t),null);if(t.flags&128)throw Error(i(558))}return B(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=ba(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[Mt]=t}else xa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;B(t),a=!1}else a=Sa(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(Go(t),t):(Go(t),null)}return Go(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),bl(t,t.updateQueue),B(t),null);case 4:return Fe(),e===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,B(t),null;case 10:return Oa(t.type),B(t),null;case 19:if(Jo(t),r=t.memoizedState,r===null)return B(t),null;if(a=!!(t.flags&128),o=r.rendering,o===null){if(a)xl(r,!1);else{if(Y!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=Yo(e),o!==null){for(t.flags|=128,xl(r,!1),e=o.updateQueue,t.updateQueue=e,bl(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)Gi(n,e),n=n.sibling;return qo(t,Ko.current&1|2),j&&ca(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Xe()>_d&&(t.flags|=128,a=!0,xl(r,!1),t.lanes=4194304)}}else{if(!a){if(e=Yo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,bl(t,e),xl(r,!0),r.tail===null&&r.tailMode!==`collapsed`&&r.tailMode!==`visible`&&!o.alternate&&!j)return B(t),null}else 2*Xe()-r.renderingStartTime>_d&&n!==536870912&&(t.flags|=128,a=!0,xl(r,!1),t.lanes=4194304)}r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}if(r.tail!==null){e=r.tail;a:{for(n=e;n!==null;){if(n.alternate!==null){n=!1;break a}n=n.sibling}n=!0}return r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Xe(),e.sibling=null,o=Ko.current,o=a?o&1|2:o&1,r.tailMode===`visible`||r.tailMode===`collapsed`||!n||j?qo(t,o):(n=o,O(zo,t),O(Ko,n),Bo===null&&(Bo=t)),j&&ca(t,r.treeForkCount),e}return B(t),null;case 22:case 23:return Go(t),Ro(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(B(t),t.subtreeFlags&6&&(t.flags|=8192)):B(t),n=t.updateQueue,n!==null&&bl(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&ke($a),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Oa(M),B(t),null;case 25:return null;case 30:return t.flags|=33554432,B(t),null}throw Error(i(156,t.tag))}function Cl(e,t){switch(da(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Oa(M),Fe(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Le(t),null;case 31:if(t.memoizedState!==null){if(Go(t),t.alternate===null)throw Error(i(340));xa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Go(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));xa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Jo(t),e=t.flags,e&65536?(t.flags=e&-65537|128,e=t.memoizedState,e!==null&&(e.rendering=null,e.tail=null),t.flags|=4,t):null;case 4:return Fe(),null;case 10:return Oa(t.type),null;case 22:case 23:return Go(t),Ro(),e!==null&&ke($a),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Oa(M),null;case 25:return null;default:return null}}function wl(e,t){switch(da(t),t.tag){case 3:Oa(M),Fe();break;case 26:case 27:case 5:Le(t);break;case 4:Fe();break;case 31:t.memoizedState!==null&&Go(t);break;case 13:Go(t);break;case 19:Jo(t);break;case 10:Oa(t.type);break;case 22:case 23:Go(t),Ro(),e!==null&&ke($a);break;case 24:Oa(M)}}function Tl(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function El(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Dl(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{No(t,n)}catch(t){Z(e,e.return,t)}}}function Ol(e,t,n){n.props=Oc(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function kl(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:var i=e.stateNode,a=Di(e.memoizedProps,i);(i.ref===null||i.ref.name!==a)&&(i.ref=Pp(a)),r=i.ref;break;case 7:if(e.stateNode===null){var o=new Fp(e);h(e.child,!1,Qp,o,void 0,void 0),e.stateNode=o}r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Al(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}}function jl(e,t){if((e.tag===5||e.tag===27||e.tag===6)&&e.alternate===null&&t!==null)for(var n=0;n title`))),np(r,t,n),r[Mt]=e,Kt(r),t=r;break a;case`link`:if(o=Gm(`link`,`href`,a).get(t+(n.href||``))){for(s=0;sg&&(o=g,g=h,h=o);var _=ti(s,h),v=ti(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,E.T=null,n=wd,wd=null;var o=bd,s=Sd;if(X=0,xd=bd=null,Sd=0,W&6)throw Error(i(331));var c=W;if(W|=4,Zu(o.current),Uu(o,o.current,s,n),W=c,Df(0,!1),ot&&typeof ot.onPostCommitFiberRoot==`function`)try{ot.onPostCommitFiberRoot(at,o)}catch{}return!0}finally{D.p=a,E.T=r,uf(e,t)}}function pf(e,t,n){t=Qi(n,t),t=Pc(e.stateNode,t,2),e=Eo(e,t,2),e!==null&&(St(e,2),Ef(e))}function Z(e,t,n){if(e.tag===3)pf(e,e,n);else for(;t!==null;){if(t.tag===3){pf(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(yd===null||!yd.has(r))){e=Qi(n,e),n=Fc(2),r=Eo(t,n,2),r!==null&&(Ic(n,r,t,e),St(r,2),Ef(r));break}}t=t.return}}function mf(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new td;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(ad=!0,i.add(n),e=hf.bind(null,e,t,n),t.then(e,e))}function hf(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,G===e&&(q&n)===n&&(Y===4||Y===3&&(q&62914560)===q&&300>Xe()-hd?W&2?ld|=n:Vd(e,0):ld|=n,dd===q&&(dd=0)),Ef(e)}function gf(e,t){t===0&&(t=bt()),e=Li(e,t),e!==null&&(St(e,t),Ef(e))}function _f(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),gf(e,n)}function vf(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),gf(e,n)}function yf(e,t){return Ke(e,t)}var bf=null,xf=null,Sf=!1,Cf=!1,wf=!1,Tf=0;function Ef(e){e!==xf&&e.next===null&&(xf===null?bf=xf=e:xf=xf.next=e),Cf=!0,Sf||(Sf=!0,Nf())}function Df(e,t){if(!wf&&Cf){wf=!0;do for(var n=!1,r=bf;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-ct(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,Mf(r,a))}else a=q,a=gt(r,r===G?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||_t(r,a)||(n=!0,Mf(r,a))}r=r.next}while(n);wf=!1}}function Of(){kf()}function kf(){Cf=Sf=!1;var e=0;Tf!==0&&hp()&&(e=Tf);for(var t=Xe(),n=null,r=bf;r!==null;){var i=r.next,a=Af(r,t);a===0?(r.next=null,n===null?bf=i:n.next=i,i===null&&(xf=n)):(n=r,(e!==0||a&3)&&(Cf=!0)),r=i}X!==0&&X!==5||Df(e,!1),Tf!==0&&(Tf=0)}function Af(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&ap(d)&&(c=c.responseEnd,o+=u*(c$m){s.length=o;break}f=new Promise(jp.bind(f)),s.push(f)}}}if(0`u`?null:document;function Tm(e,t,n){var r=wm;if(r&&typeof t==`string`&&t){var i=pn(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),ym.has(i)||(ym.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),np(t,`link`,e),Kt(t),r.head.appendChild(t)))}}function Em(e){xm.D(e),Tm(`dns-prefetch`,e,null)}function Dm(e,t){xm.C(e,t),Tm(`preconnect`,e,t)}function Om(e,t,n){xm.L(e,t,n);var r=wm;if(r&&e&&t){var i=`link[rel="preload"][as="`+pn(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+pn(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+pn(n.imageSizes)+`"]`)):i+=`[href="`+pn(e)+`"]`;var a=i;switch(t){case`style`:a=Pm(e);break;case`script`:a=Rm(e)}if(!(vm.has(a)||(e=T({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),vm.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(Fm(a))||t===`script`&&r.querySelector(zm(a))))){var o=r.createElement(`link`);np(o,`link`,e),t===`style`&&(o[Bt]=!0,o.onload=o.onerror=function(){qt(o)}),Kt(o),r.head.appendChild(o)}}}function km(e,t){xm.m(e,t);var n=wm;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+pn(r)+`"][href="`+pn(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Rm(e)}if(!vm.has(a)&&(e=T({rel:`modulepreload`,href:e},t),vm.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(zm(a)))return}r=n.createElement(`link`),np(r,`link`,e),Kt(r),n.head.appendChild(r)}}}function Am(e,t,n){xm.S(e,t,n);var r=wm;if(r&&e){var i=Gt(r).hoistableStyles,a=Pm(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(Fm(a)))s.loading=5;else{e=T({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=vm.get(a))&&Hm(e,n);var c=o=r.createElement(`link`);Kt(c),np(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Vm(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function jm(e,t){xm.X(e,t);var n=wm;if(n&&e){var r=Gt(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=T({src:e,async:!0},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Kt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Mm(e,t){xm.M(e,t);var n=wm;if(n&&e){var r=Gt(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=T({src:e,async:!0,type:`module`},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Kt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Nm(e,t,n,r){var a=(a=Me.current)?bm(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(n=Pm(n.href),t=Gt(a).hoistableStyles,r=t.get(n),r||(r={type:`style`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Pm(n.href);var o=Gt(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(Fm(e)))?o._p||(s.instance=o,s.state.loading=5):(o=vm.get(e),o||(o={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},vm.set(e,o)),Lm(a,e,o,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(n=Rm(n),t=Gt(a).hoistableScripts,r=t.get(n),r||(r={type:`script`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Pm(e){return`href="`+pn(e)+`"`}function Fm(e){return`link[rel="stylesheet"][`+e+`]`}function Im(e){return T({},e,{"data-precedence":e.precedence,precedence:null})}function Lm(e,t,n,r){if(t=e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)){if(!0!==t[Bt]){r.loading=1;return}}else t=e.createElement(`link`),t[Bt]=!0,t.onload=t.onerror=qt.bind(null,t),np(t,`link`,n),Kt(t),e.head.appendChild(t);r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2})}function Rm(e){return`[src="`+pn(e)+`"]`}function zm(e){return`script[async]`+e}function Bm(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+pn(n.href)+`"]`);if(r)return t.instance=r,Kt(r),r;var a=T({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Kt(r),np(r,`style`,a),Vm(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Pm(n.href);var o=e.querySelector(Fm(a));if(o)return t.state.loading|=4,t.instance=o,Kt(o),o;r=Im(n),(a=vm.get(a))&&Hm(r,a),o=(e.ownerDocument||e).createElement(`link`),Kt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),np(o,`link`,r),t.state.loading|=4,Vm(o,n.precedence,e),t.instance=o;case`script`:return o=Rm(n.src),(a=e.querySelector(zm(o)))?(t.instance=a,Kt(a),a):(r=n,(a=vm.get(o))&&(r=T({},n),Um(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Kt(a),np(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Vm(r,n.precedence,e));return t.instance}function Vm(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function qm(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Jm(e,t){return e===`img`&&t.src!=null&&t.src!==``&&t.onLoad==null&&t.loading!==`lazy`}function Ym(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Xm(e){return(e.width||100)*(e.height||100)*(typeof devicePixelRatio==`number`?devicePixelRatio:1)*.25}function Zm(e,t){typeof t.decode==`function`&&(e.imgCount++,t.complete||(e.imgBytes+=Xm(t),e.suspenseyImages.push(t)),e=rh.bind(e),t.decode().then(e,e))}function Qm(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Pm(r.href),a=t.querySelector(Fm(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=nh.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Kt(a);return}a=t.ownerDocument||t,r=Im(r),(i=vm.get(i))&&Hm(r,i),a=a.createElement(`link`),Kt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),np(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=nh.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var $m=0;function eh(e,t){return e.stylesheets&&e.count===0&&ah(e,e.stylesheets),0$m?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function th(e){if(e.count===0&&(e.imgCount===0||!e.waitingForImages)){if(e.stylesheets)ah(e,e.stylesheets);else if(e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}}}function nh(){this.count--,th(this)}function rh(){this.imgCount--,th(this)}var ih=null;function ah(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ih=new Map,t.forEach(oh,e),ih=null,nh.call(e))}function oh(e,t){if(!(t.state.loading&4)){var n=ih.get(e);if(n)var r=n.get(null);else{n=new Map,ih.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<`u`&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE==`function`)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=c(u(),1),v=g(),y={source:`광터지하차도_BLOCK8.dxf`,unit:`m`,coordinateNote:`CAD 좌표 차이를 치수 문자열로 검산해 mm로 해석. 표고는 종단/단면 EL 주석에 연결.`,sections:[{id:`A-A`,station:319,centerEL:102.09406315800001,topEL:107.215,baseTopEL:101.777,baseBottomEL:100.877,sourceHandles:[`STA.0K+319.000`,`CS-CNTL center mark`,`EL.102.094`,`EL.107.215`,`EL.100.877`]},{id:`B-B`,station:339,centerEL:101.51670949600002,topEL:107.857,baseTopEL:101.292,baseBottomEL:100.392,sourceHandles:[`STA.0K+339.000`,`CS-CNTL center mark`,`EL.101.517`,`EL.107.857`,`EL.100.392`]}],sectionStationRange:[319,339],modelStationRange:[319.01,338.99],modelLength:19.98,sectionTrim:.01,sectionLineCount:{"CS-CONC-MAJR":108,"CS-CONC-MINR":6},expandedBlock:{name:`A$C2017021411375356`,layerCounts:{"CS-CONC-MAJR":18,"CS-CONC-MINR":0},curveCount:2,insertCount:4},profileWidth:{dimensionText:20.3,outerLineEnvelope:20.5,status:`dimension value and outer contour differ; retain separately`},units:[{id:`alignment-1`,name:`BLOCK8 기준 중심선`,center:[-17.5,1700],planOrigin:[1231533.514405643,-78753.23558031511],radius:1700,startAngle:269.6633030368886,endAngle:270.33669696314513,length:19.979999999384816,centerlineHandle:`101568`,boundaryHandles:[`21199`,`21200`],parts:[{id:`alignment-1-major-001`,name:`CS-CONC-MAJR 구조선 001`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20894`,`21099`],entityType:`LINE`,a:[[-10.25,100.777],[-10.25,101.777]],b:[[-10.25,100.292],[-10.25,101.292]]},{id:`alignment-1-major-002`,name:`CS-CONC-MAJR 구조선 002`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20895`,`21100`],entityType:`LINE`,a:[[-10.25,101.777],[-10.15,101.777]],b:[[-10.25,101.292],[-10.15,101.292]]},{id:`alignment-1-major-003`,name:`CS-CONC-MAJR 구조선 003`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20897`,`21102`],entityType:`LINE`,a:[[-10.25,100.777],[10.25,100.777]],b:[[-10.25,100.292],[10.25,100.292]]},{id:`alignment-1-major-004`,name:`CS-CONC-MAJR 구조선 004`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20879`,`21084`],entityType:`LINE`,a:[[-10.15,100.877],[-10.15,101.777]],b:[[-10.15,100.392],[-10.15,101.292]]},{id:`alignment-1-major-005`,name:`CS-CONC-MAJR 구조선 005`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20896`,`21101`],entityType:`LINE`,a:[[-10.15,100.877],[-10.15,101.777]],b:[[-10.15,100.392],[-10.15,101.292]]},{id:`alignment-1-major-006`,name:`CS-CONC-MAJR 구조선 006`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20878`,`21083`],entityType:`LINE`,a:[[-10.15,101.777],[-9.75,106.215]],b:[[-10.15,101.292],[-9.75,106.857]]},{id:`alignment-1-major-007`,name:`CS-CONC-MAJR 구조선 007`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20786`,`20990`],entityType:`LINE`,a:[[-10.15,100.877],[-9.25,100.877]],b:[[-10.15,100.392],[-9.25,100.392]]},{id:`alignment-1-major-008`,name:`CS-CONC-MAJR 구조선 008`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20890`,`21095`],entityType:`LINE`,a:[[-10.15,100.877],[10.15,100.877]],b:[[-10.15,100.392],[10.15,100.392]]},{id:`alignment-1-major-009`,name:`CS-CONC-MAJR 구조선 009`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20877`,`21082`],entityType:`LINE`,a:[[-9.75,106.215],[-9.75,107.215]],b:[[-9.75,106.857],[-9.75,107.857]]},{id:`alignment-1-major-010`,name:`CS-CONC-MAJR 구조선 010`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20876`,`21081`],entityType:`LINE`,a:[[-9.75,107.215],[-9.25,107.215]],b:[[-9.75,107.857],[-9.25,107.857]]},{id:`alignment-1-major-011`,name:`CS-CONC-MAJR 구조선 011`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20880`,`21085`],entityType:`LINE`,a:[[-9.25,102.94906300006062],[-9.25,107.215]],b:[[-9.25,102.37170900006055],[-9.25,107.857]]},{id:`alignment-1-major-012`,name:`CS-CONC-MAJR 구조선 012`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20787`,`20991`],entityType:`LINE`,a:[[-9.25,100.877],[-.5,100.877]],b:[[-9.25,100.392],[-.5,100.392]]},{id:`alignment-1-major-013`,name:`CS-CONC-MAJR 구조선 013`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20791`,`20995`],entityType:`LINE`,a:[[-8.25,101.89906300000008],[-8.2,101.89906300000008]],b:[[-8.25,101.32170900000003],[-8.2,101.32170900000003]]},{id:`alignment-1-major-014`,name:`CS-CONC-MAJR 구조선 014`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20792`,`20996`],entityType:`LINE`,a:[[-8.2,101.577],[-8.2,101.89906300000008]],b:[[-8.2,101.092],[-8.2,101.32170900000003]]},{id:`alignment-1-major-015`,name:`CS-CONC-MAJR 구조선 015`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20793`,`20997`],entityType:`LINE`,a:[[-8.2,101.577],[-7.8,101.577]],b:[[-8.2,101.092],[-7.8,101.092]]},{id:`alignment-1-major-016`,name:`CS-CONC-MAJR 구조선 016`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20794`,`20998`],entityType:`LINE`,a:[[-7.8,101.577],[-7.8,101.89906300000008]],b:[[-7.8,101.092],[-7.8,101.32170900000003]]},{id:`alignment-1-major-017`,name:`CS-CONC-MAJR 구조선 017`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20795`,`20999`],entityType:`LINE`,a:[[-7.8,101.89906300000008],[-7.75,101.89906300000008]],b:[[-7.8,101.32170900000003],[-7.75,101.32170900000003]]},{id:`alignment-1-major-018`,name:`CS-CONC-MAJR 구조선 018`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20797`,`21001`],entityType:`LINE`,a:[[-7.75,101.86906300000008],[-7.75,101.94906300000008]],b:[[-7.75,101.29170900000004],[-7.75,101.37170900000004]]},{id:`alignment-1-major-019`,name:`CS-CONC-MAJR 구조선 019`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20821`,`21026`],entityType:`LINE`,a:[[-7.75,101.86906300000008],[-7.75,101.94906300000008]],b:[[-7.75,101.29170900000004],[-7.75,101.37170900000004]]},{id:`alignment-1-major-020`,name:`CS-CONC-MAJR 구조선 020`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20796`,`21000`],entityType:`LINE`,a:[[-7.75,101.89906300000008],[-7.75,101.94906300000008]],b:[[-7.75,101.32170900000003],[-7.75,101.37170900000004]]},{id:`alignment-1-major-021`,name:`CS-CONC-MAJR 구조선 021`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20798`,`21002`],entityType:`LINE`,a:[[-7.75,101.86906300000008],[-7.5,101.87406300000008]],b:[[-7.75,101.29170900000004],[-7.5,101.29670900000004]]},{id:`alignment-1-major-022`,name:`CS-CONC-MAJR 구조선 022`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20813`,`21018`],entityType:`LINE`,a:[[-7.75,101.87906300000009],[-7.5,101.88406300000008]],b:[[-7.75,101.30170900000003],[-7.5,101.30670900000003]]},{id:`alignment-1-major-023`,name:`CS-CONC-MAJR 구조선 023`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20814`,`21019`],entityType:`LINE`,a:[[-7.75,101.88906300000008],[-7.5,101.89406300000009]],b:[[-7.75,101.31170900000004],[-7.5,101.31670900000003]]},{id:`alignment-1-major-024`,name:`CS-CONC-MAJR 구조선 024`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20815`,`21020`],entityType:`LINE`,a:[[-7.75,101.89906300000008],[-7.5,101.90406300000008]],b:[[-7.75,101.32170900000003],[-7.5,101.32670900000004]]},{id:`alignment-1-major-025`,name:`CS-CONC-MAJR 구조선 025`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20816`,`21021`],entityType:`LINE`,a:[[-7.75,101.90906300000009],[-7.5,101.91406300000008]],b:[[-7.75,101.33170900000003],[-7.5,101.33670900000003]]},{id:`alignment-1-major-026`,name:`CS-CONC-MAJR 구조선 026`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20817`,`21022`],entityType:`LINE`,a:[[-7.75,101.91906300000008],[-7.5,101.92406300000009]],b:[[-7.75,101.34170900000004],[-7.5,101.34670900000003]]},{id:`alignment-1-major-027`,name:`CS-CONC-MAJR 구조선 027`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20818`,`21023`],entityType:`LINE`,a:[[-7.75,101.92906300000008],[-7.5,101.93406300000008]],b:[[-7.75,101.35170900000003],[-7.5,101.35670900000004]]},{id:`alignment-1-major-028`,name:`CS-CONC-MAJR 구조선 028`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20819`,`21024`],entityType:`LINE`,a:[[-7.75,101.93906300000009],[-7.5,101.94406300000009]],b:[[-7.75,101.36170900000003],[-7.5,101.36670900000003]]},{id:`alignment-1-major-029`,name:`CS-CONC-MAJR 구조선 029`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20820`,`21025`],entityType:`LINE`,a:[[-7.75,101.94906300000008],[-7.5,101.95406300000008]],b:[[-7.75,101.37170900000004],[-7.5,101.37670900000003]]},{id:`alignment-1-major-030`,name:`CS-CONC-MAJR 구조선 030`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20822`,`21027`],entityType:`LINE`,a:[[-7.5,101.87406300000008],[-7.5,101.95406300000008]],b:[[-7.5,101.29670900000004],[-7.5,101.37670900000003]]},{id:`alignment-1-major-031`,name:`CS-CONC-MAJR 구조선 031`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20831`,`21036`],entityType:`LINE`,a:[[-7.5,101.87406300000008],[-7.5,101.95406300000008]],b:[[-7.5,101.29670900000004],[-7.5,101.37670900000003]]},{id:`alignment-1-major-032`,name:`CS-CONC-MAJR 구조선 032`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20799`,`21003`],entityType:`LINE`,a:[[-7.5,101.87406300000008],[-1,102.00406300000009]],b:[[-7.5,101.29670900000004],[-1,101.42670900000003]]},{id:`alignment-1-major-033`,name:`CS-CONC-MAJR 구조선 033`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20823`,`21028`],entityType:`LINE`,a:[[-7.5,101.88406300000008],[-1,102.01406300000008]],b:[[-7.5,101.30670900000003],[-1,101.43670900000004]]},{id:`alignment-1-major-034`,name:`CS-CONC-MAJR 구조선 034`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20824`,`21029`],entityType:`LINE`,a:[[-7.5,101.89406300000009],[-1,102.02406300000008]],b:[[-7.5,101.31670900000003],[-1,101.44670900000003]]},{id:`alignment-1-major-035`,name:`CS-CONC-MAJR 구조선 035`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20825`,`21030`],entityType:`LINE`,a:[[-7.5,101.90406300000008],[-1,102.03406300000009]],b:[[-7.5,101.32670900000004],[-1,101.45670900000003]]},{id:`alignment-1-major-036`,name:`CS-CONC-MAJR 구조선 036`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20826`,`21031`],entityType:`LINE`,a:[[-7.5,101.91406300000008],[-1,102.04406300000008]],b:[[-7.5,101.33670900000003],[-1,101.46670900000004]]},{id:`alignment-1-major-037`,name:`CS-CONC-MAJR 구조선 037`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20827`,`21032`],entityType:`LINE`,a:[[-7.5,101.92406300000009],[-1,102.05406300000008]],b:[[-7.5,101.34670900000003],[-1,101.47670900000003]]},{id:`alignment-1-major-038`,name:`CS-CONC-MAJR 구조선 038`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20828`,`21033`],entityType:`LINE`,a:[[-7.5,101.93406300000008],[-1,102.06406300000009]],b:[[-7.5,101.35670900000004],[-1,101.48670900000003]]},{id:`alignment-1-major-039`,name:`CS-CONC-MAJR 구조선 039`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20829`,`21034`],entityType:`LINE`,a:[[-7.5,101.94406300000009],[-1,102.07406300000008]],b:[[-7.5,101.36670900000003],[-1,101.49670900000004]]},{id:`alignment-1-major-040`,name:`CS-CONC-MAJR 구조선 040`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20830`,`21035`],entityType:`LINE`,a:[[-7.5,101.95406300000008],[-1,102.08406300000009]],b:[[-7.5,101.37670900000003],[-1,101.50670900000003]]},{id:`alignment-1-major-041`,name:`CS-CONC-MAJR 구조선 041`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20832`,`21037`],entityType:`LINE`,a:[[-1,102.00406300000009],[-1,102.08406300000009]],b:[[-1,101.42670900000003],[-1,101.50670900000003]]},{id:`alignment-1-major-042`,name:`CS-CONC-MAJR 구조선 042`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20841`,`21046`],entityType:`LINE`,a:[[-1,102.00406300000009],[-1,102.08406300000009]],b:[[-1,101.42670900000003],[-1,101.50670900000003]]},{id:`alignment-1-major-043`,name:`CS-CONC-MAJR 구조선 043`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20800`,`21004`],entityType:`LINE`,a:[[-1,102.00406300000009],[-.5,102.01406300000008]],b:[[-1,101.42670900000003],[-.5,101.43670900000004]]},{id:`alignment-1-major-044`,name:`CS-CONC-MAJR 구조선 044`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20833`,`21038`],entityType:`LINE`,a:[[-1,102.01406300000008],[-.5,102.02406300000008]],b:[[-1,101.43670900000004],[-.5,101.44670900000003]]},{id:`alignment-1-major-045`,name:`CS-CONC-MAJR 구조선 045`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20834`,`21039`],entityType:`LINE`,a:[[-1,102.02406300000008],[-.5,102.03406300000009]],b:[[-1,101.44670900000003],[-.5,101.45670900000003]]},{id:`alignment-1-major-046`,name:`CS-CONC-MAJR 구조선 046`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20835`,`21040`],entityType:`LINE`,a:[[-1,102.03406300000009],[-.5,102.04406300000008]],b:[[-1,101.45670900000003],[-.5,101.46670900000004]]},{id:`alignment-1-major-047`,name:`CS-CONC-MAJR 구조선 047`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20836`,`21041`],entityType:`LINE`,a:[[-1,102.04406300000008],[-.5,102.05406300000008]],b:[[-1,101.46670900000004],[-.5,101.47670900000003]]},{id:`alignment-1-major-048`,name:`CS-CONC-MAJR 구조선 048`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20837`,`21042`],entityType:`LINE`,a:[[-1,102.05406300000008],[-.5,102.06406300000009]],b:[[-1,101.47670900000003],[-.5,101.48670900000003]]},{id:`alignment-1-major-049`,name:`CS-CONC-MAJR 구조선 049`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20838`,`21043`],entityType:`LINE`,a:[[-1,102.06406300000009],[-.5,102.07406300000008]],b:[[-1,101.48670900000003],[-.5,101.49670900000004]]},{id:`alignment-1-major-050`,name:`CS-CONC-MAJR 구조선 050`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20839`,`21044`],entityType:`LINE`,a:[[-1,102.07406300000008],[-.5,102.08406300000009]],b:[[-1,101.49670900000004],[-.5,101.50670900000003]]},{id:`alignment-1-major-051`,name:`CS-CONC-MAJR 구조선 051`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20840`,`21045`],entityType:`LINE`,a:[[-1,102.08406300000009],[-.5,102.09406300000008]],b:[[-1,101.50670900000003],[-.5,101.51670900000003]]},{id:`alignment-1-major-052`,name:`CS-CONC-MAJR 구조선 052`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20801`,`21005`],entityType:`LINE`,a:[[-.5,101.777],[-.5,102.01406300000008]],b:[[-.5,101.292],[-.5,101.43670900000004]]},{id:`alignment-1-major-053`,name:`CS-CONC-MAJR 구조선 053`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20874`,`21047`],entityType:`LINE`,a:[[-.5,101.777],[-.5,102.277]],b:[[-.5,101.43670900000004],[-.5,101.51670900000003]]},{id:`alignment-1-major-054`,name:`CS-CONC-MAJR 구조선 054`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20842`,`21079`],entityType:`LINE`,a:[[-.5,102.01406300000008],[-.5,102.09406300000008]],b:[[-.5,101.292],[-.5,101.792]]},{id:`alignment-1-major-055`,name:`CS-CONC-MAJR 구조선 055`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20788`,`20992`],entityType:`LINE`,a:[[-.5,100.877],[.5,100.877]],b:[[-.5,100.392],[.5,100.392]]},{id:`alignment-1-major-056`,name:`CS-CONC-MAJR 구조선 056`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20873`,`21078`],entityType:`LINE`,a:[[-.5,102.277],[.5,102.277]],b:[[-.5,101.792],[.5,101.792]]},{id:`alignment-1-major-057`,name:`CS-CONC-MAJR 구조선 057`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20809`,`21014`],entityType:`LINE`,a:[[.5,101.777],[.5,102.01406300000008]],b:[[.5,101.292],[.5,101.43670900000004]]},{id:`alignment-1-major-058`,name:`CS-CONC-MAJR 구조선 058`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20875`,`21056`],entityType:`LINE`,a:[[.5,101.777],[.5,102.277]],b:[[.5,101.43670900000004],[.5,101.51670900000003]]},{id:`alignment-1-major-059`,name:`CS-CONC-MAJR 구조선 059`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20851`,`21080`],entityType:`LINE`,a:[[.5,102.01406300000008],[.5,102.09406300000008]],b:[[.5,101.292],[.5,101.792]]},{id:`alignment-1-major-060`,name:`CS-CONC-MAJR 구조선 060`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20810`,`21015`],entityType:`LINE`,a:[[.5,102.01406300000008],[1,102.00406300000009]],b:[[.5,101.43670900000004],[1,101.42670900000003]]},{id:`alignment-1-major-061`,name:`CS-CONC-MAJR 구조선 061`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20843`,`21048`],entityType:`LINE`,a:[[.5,102.02406300000008],[1,102.01406300000008]],b:[[.5,101.44670900000003],[1,101.43670900000004]]},{id:`alignment-1-major-062`,name:`CS-CONC-MAJR 구조선 062`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20844`,`21049`],entityType:`LINE`,a:[[.5,102.03406300000009],[1,102.02406300000008]],b:[[.5,101.45670900000003],[1,101.44670900000003]]},{id:`alignment-1-major-063`,name:`CS-CONC-MAJR 구조선 063`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20845`,`21050`],entityType:`LINE`,a:[[.5,102.04406300000008],[1,102.03406300000009]],b:[[.5,101.46670900000004],[1,101.45670900000003]]},{id:`alignment-1-major-064`,name:`CS-CONC-MAJR 구조선 064`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20846`,`21051`],entityType:`LINE`,a:[[.5,102.05406300000008],[1,102.04406300000008]],b:[[.5,101.47670900000003],[1,101.46670900000004]]},{id:`alignment-1-major-065`,name:`CS-CONC-MAJR 구조선 065`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20847`,`21052`],entityType:`LINE`,a:[[.5,102.06406300000009],[1,102.05406300000008]],b:[[.5,101.48670900000003],[1,101.47670900000003]]},{id:`alignment-1-major-066`,name:`CS-CONC-MAJR 구조선 066`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20848`,`21053`],entityType:`LINE`,a:[[.5,102.07406300000008],[1,102.06406300000009]],b:[[.5,101.49670900000004],[1,101.48670900000003]]},{id:`alignment-1-major-067`,name:`CS-CONC-MAJR 구조선 067`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20849`,`21054`],entityType:`LINE`,a:[[.5,102.08406300000009],[1,102.07406300000008]],b:[[.5,101.50670900000003],[1,101.49670900000004]]},{id:`alignment-1-major-068`,name:`CS-CONC-MAJR 구조선 068`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20850`,`21055`],entityType:`LINE`,a:[[.5,102.09406300000008],[1,102.08406300000009]],b:[[.5,101.51670900000003],[1,101.50670900000003]]},{id:`alignment-1-major-069`,name:`CS-CONC-MAJR 구조선 069`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20789`,`20993`],entityType:`LINE`,a:[[.5,100.877],[9.25,100.877]],b:[[.5,100.392],[9.25,100.392]]},{id:`alignment-1-major-070`,name:`CS-CONC-MAJR 구조선 070`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20852`,`21057`],entityType:`LINE`,a:[[1,102.00406300000009],[1,102.08406300000009]],b:[[1,101.42670900000003],[1,101.50670900000003]]},{id:`alignment-1-major-071`,name:`CS-CONC-MAJR 구조선 071`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20861`,`21066`],entityType:`LINE`,a:[[1,102.00406300000009],[1,102.08406300000009]],b:[[1,101.42670900000003],[1,101.50670900000003]]},{id:`alignment-1-major-072`,name:`CS-CONC-MAJR 구조선 072`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20811`,`21016`],entityType:`LINE`,a:[[1,102.00406300000009],[7.5,101.87406300000008]],b:[[1,101.42670900000003],[7.5,101.29670900000004]]},{id:`alignment-1-major-073`,name:`CS-CONC-MAJR 구조선 073`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20853`,`21058`],entityType:`LINE`,a:[[1,102.01406300000008],[7.5,101.88406300000008]],b:[[1,101.43670900000004],[7.5,101.30670900000003]]},{id:`alignment-1-major-074`,name:`CS-CONC-MAJR 구조선 074`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20854`,`21059`],entityType:`LINE`,a:[[1,102.02406300000008],[7.5,101.89406300000009]],b:[[1,101.44670900000003],[7.5,101.31670900000003]]},{id:`alignment-1-major-075`,name:`CS-CONC-MAJR 구조선 075`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20855`,`21060`],entityType:`LINE`,a:[[1,102.03406300000009],[7.5,101.90406300000008]],b:[[1,101.45670900000003],[7.5,101.32670900000004]]},{id:`alignment-1-major-076`,name:`CS-CONC-MAJR 구조선 076`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20856`,`21061`],entityType:`LINE`,a:[[1,102.04406300000008],[7.5,101.91406300000008]],b:[[1,101.46670900000004],[7.5,101.33670900000003]]},{id:`alignment-1-major-077`,name:`CS-CONC-MAJR 구조선 077`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20857`,`21062`],entityType:`LINE`,a:[[1,102.05406300000008],[7.5,101.92406300000009]],b:[[1,101.47670900000003],[7.5,101.34670900000003]]},{id:`alignment-1-major-078`,name:`CS-CONC-MAJR 구조선 078`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20858`,`21063`],entityType:`LINE`,a:[[1,102.06406300000009],[7.5,101.93406300000008]],b:[[1,101.48670900000003],[7.5,101.35670900000004]]},{id:`alignment-1-major-079`,name:`CS-CONC-MAJR 구조선 079`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20859`,`21064`],entityType:`LINE`,a:[[1,102.07406300000008],[7.5,101.94406300000009]],b:[[1,101.49670900000004],[7.5,101.36670900000003]]},{id:`alignment-1-major-080`,name:`CS-CONC-MAJR 구조선 080`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20860`,`21065`],entityType:`LINE`,a:[[1,102.08406300000009],[7.5,101.95406300000008]],b:[[1,101.50670900000003],[7.5,101.37670900000003]]},{id:`alignment-1-major-081`,name:`CS-CONC-MAJR 구조선 081`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20862`,`21067`],entityType:`LINE`,a:[[7.5,101.87406300000008],[7.5,101.95406300000008]],b:[[7.5,101.29670900000004],[7.5,101.37670900000003]]},{id:`alignment-1-major-082`,name:`CS-CONC-MAJR 구조선 082`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20871`,`21076`],entityType:`LINE`,a:[[7.5,101.87406300000008],[7.5,101.95406300000008]],b:[[7.5,101.29670900000004],[7.5,101.37670900000003]]},{id:`alignment-1-major-083`,name:`CS-CONC-MAJR 구조선 083`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20812`,`21017`],entityType:`LINE`,a:[[7.5,101.87406300000008],[7.75,101.86906300000008]],b:[[7.5,101.29670900000004],[7.75,101.29170900000004]]},{id:`alignment-1-major-084`,name:`CS-CONC-MAJR 구조선 084`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20863`,`21068`],entityType:`LINE`,a:[[7.5,101.88406300000008],[7.75,101.87906300000009]],b:[[7.5,101.30670900000003],[7.75,101.30170900000003]]},{id:`alignment-1-major-085`,name:`CS-CONC-MAJR 구조선 085`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20864`,`21069`],entityType:`LINE`,a:[[7.5,101.89406300000009],[7.75,101.88906300000008]],b:[[7.5,101.31670900000003],[7.75,101.31170900000004]]},{id:`alignment-1-major-086`,name:`CS-CONC-MAJR 구조선 086`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20865`,`21070`],entityType:`LINE`,a:[[7.5,101.90406300000008],[7.75,101.89906300000008]],b:[[7.5,101.32670900000004],[7.75,101.32170900000003]]},{id:`alignment-1-major-087`,name:`CS-CONC-MAJR 구조선 087`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20866`,`21071`],entityType:`LINE`,a:[[7.5,101.91406300000008],[7.75,101.90906300000009]],b:[[7.5,101.33670900000003],[7.75,101.33170900000003]]},{id:`alignment-1-major-088`,name:`CS-CONC-MAJR 구조선 088`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20867`,`21072`],entityType:`LINE`,a:[[7.5,101.92406300000009],[7.75,101.91906300000008]],b:[[7.5,101.34670900000003],[7.75,101.34170900000004]]},{id:`alignment-1-major-089`,name:`CS-CONC-MAJR 구조선 089`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20868`,`21073`],entityType:`LINE`,a:[[7.5,101.93406300000008],[7.75,101.92906300000008]],b:[[7.5,101.35670900000004],[7.75,101.35170900000003]]},{id:`alignment-1-major-090`,name:`CS-CONC-MAJR 구조선 090`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20869`,`21074`],entityType:`LINE`,a:[[7.5,101.94406300000009],[7.75,101.93906300000009]],b:[[7.5,101.36670900000003],[7.75,101.36170900000003]]},{id:`alignment-1-major-091`,name:`CS-CONC-MAJR 구조선 091`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20870`,`21075`],entityType:`LINE`,a:[[7.5,101.95406300000008],[7.75,101.94906300000008]],b:[[7.5,101.37670900000003],[7.75,101.37170900000004]]},{id:`alignment-1-major-092`,name:`CS-CONC-MAJR 구조선 092`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20802`,`21006`],entityType:`LINE`,a:[[7.75,101.86906300000008],[7.75,101.94906300000008]],b:[[7.75,101.29170900000004],[7.75,101.37170900000004]]},{id:`alignment-1-major-093`,name:`CS-CONC-MAJR 구조선 093`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20872`,`21077`],entityType:`LINE`,a:[[7.75,101.86906300000008],[7.75,101.94906300000008]],b:[[7.75,101.29170900000004],[7.75,101.37170900000004]]},{id:`alignment-1-major-094`,name:`CS-CONC-MAJR 구조선 094`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20803`,`21007`],entityType:`LINE`,a:[[7.75,101.89906300000008],[7.75,101.94906300000008]],b:[[7.75,101.32170900000003],[7.75,101.37170900000004]]},{id:`alignment-1-major-095`,name:`CS-CONC-MAJR 구조선 095`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20804`,`21008`],entityType:`LINE`,a:[[7.75,101.89906300000008],[7.8,101.89906300000008]],b:[[7.75,101.32170900000003],[7.8,101.32170900000003]]},{id:`alignment-1-major-096`,name:`CS-CONC-MAJR 구조선 096`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20805`,`21009`],entityType:`LINE`,a:[[7.8,101.577],[7.8,101.89906300000008]],b:[[7.8,101.092],[7.8,101.32170900000003]]},{id:`alignment-1-major-097`,name:`CS-CONC-MAJR 구조선 097`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20806`,`21010`],entityType:`LINE`,a:[[7.8,101.577],[8.2,101.577]],b:[[7.8,101.092],[8.2,101.092]]},{id:`alignment-1-major-098`,name:`CS-CONC-MAJR 구조선 098`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20807`,`21011`],entityType:`LINE`,a:[[8.2,101.577],[8.2,101.89906300000008]],b:[[8.2,101.092],[8.2,101.32170900000003]]},{id:`alignment-1-major-099`,name:`CS-CONC-MAJR 구조선 099`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20808`,`21012`],entityType:`LINE`,a:[[8.2,101.89906300000008],[8.25,101.89906300000008]],b:[[8.2,101.32170900000003],[8.25,101.32170900000003]]},{id:`alignment-1-major-100`,name:`CS-CONC-MAJR 구조선 100`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20885`,`21090`],entityType:`LINE`,a:[[9.25,102.94906300006062],[9.25,107.215]],b:[[9.25,102.37170900006055],[9.25,107.857]]},{id:`alignment-1-major-101`,name:`CS-CONC-MAJR 구조선 101`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20881`,`21086`],entityType:`LINE`,a:[[9.25,107.215],[9.75,107.215]],b:[[9.25,107.857],[9.75,107.857]]},{id:`alignment-1-major-102`,name:`CS-CONC-MAJR 구조선 102`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20790`,`20994`],entityType:`LINE`,a:[[9.25,100.877],[10.15,100.877]],b:[[9.25,100.392],[10.15,100.392]]},{id:`alignment-1-major-103`,name:`CS-CONC-MAJR 구조선 103`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20882`,`21087`],entityType:`LINE`,a:[[9.75,106.215],[9.75,107.215]],b:[[9.75,106.857],[9.75,107.857]]},{id:`alignment-1-major-104`,name:`CS-CONC-MAJR 구조선 104`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20883`,`21088`],entityType:`LINE`,a:[[9.75,106.215],[10.15,101.777]],b:[[9.75,106.857],[10.15,101.292]]},{id:`alignment-1-major-105`,name:`CS-CONC-MAJR 구조선 105`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20884`,`21089`],entityType:`LINE`,a:[[10.15,100.877],[10.15,101.777]],b:[[10.15,100.392],[10.15,101.292]]},{id:`alignment-1-major-106`,name:`CS-CONC-MAJR 구조선 106`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20893`,`21098`],entityType:`LINE`,a:[[10.15,100.877],[10.15,101.777]],b:[[10.15,100.392],[10.15,101.292]]},{id:`alignment-1-major-107`,name:`CS-CONC-MAJR 구조선 107`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20892`,`21097`],entityType:`LINE`,a:[[10.15,101.777],[10.25,101.777]],b:[[10.15,101.292],[10.25,101.292]]},{id:`alignment-1-major-108`,name:`CS-CONC-MAJR 구조선 108`,layer:`CS-CONC-MAJR`,group:`major`,sourceHandles:[`20891`,`21096`],entityType:`LINE`,a:[[10.25,100.777],[10.25,101.777]],b:[[10.25,100.292],[10.25,101.292]]},{id:`alignment-1-minor-001`,name:`CS-CONC-MINR 구조선 001`,layer:`CS-CONC-MINR`,group:`minor`,sourceHandles:[`58096`,`58102`],entityType:`LINE`,a:[[-7.75,101.777],[-7.75,101.86906300000008]],b:[[-7.75,101.29170900000004],[-7.75,101.292]]},{id:`alignment-1-minor-002`,name:`CS-CONC-MINR 구조선 002`,layer:`CS-CONC-MINR`,group:`minor`,sourceHandles:[`58097`,`58103`],entityType:`LINE`,a:[[-7.75,101.777],[-.5,101.777]],b:[[-7.75,101.292],[-.5,101.292]]},{id:`alignment-1-minor-003`,name:`CS-CONC-MINR 구조선 003`,layer:`CS-CONC-MINR`,group:`minor`,sourceHandles:[`58095`,`58101`],entityType:`LINE`,a:[[-.5,101.777],[-.5,102.01406300000008]],b:[[-.5,101.292],[-.5,101.43670900000004]]},{id:`alignment-1-minor-004`,name:`CS-CONC-MINR 구조선 004`,layer:`CS-CONC-MINR`,group:`minor`,sourceHandles:[`58099`,`58105`],entityType:`LINE`,a:[[.5,101.777],[.5,102.01406300000008]],b:[[.5,101.292],[.5,101.43670900000004]]},{id:`alignment-1-minor-005`,name:`CS-CONC-MINR 구조선 005`,layer:`CS-CONC-MINR`,group:`minor`,sourceHandles:[`58100`,`58106`],entityType:`LINE`,a:[[.5,101.777],[7.75,101.777]],b:[[.5,101.292],[7.75,101.292]]},{id:`alignment-1-minor-006`,name:`CS-CONC-MINR 구조선 006`,layer:`CS-CONC-MINR`,group:`minor`,sourceHandles:[`58098`,`58104`],entityType:`LINE`,a:[[7.75,101.777],[7.75,101.86906300000008]],b:[[7.75,101.29170900000004],[7.75,101.292]]},{id:`alignment-1-insert-left-01`,name:`블록 내부 윤곽 left 01`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F0`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.525000000260537,104.01906300006063],[-8.525000000260537,102.95356300000195]],b:[[-8.525000000260537,103.44170900006057],[-8.525000000260537,102.3762090000019]]},{id:`alignment-1-insert-left-02`,name:`블록 내부 윤곽 left 02`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F1`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.525000000260537,102.95356300000195],[-8.46500000002305,102.95356300000195]],b:[[-8.525000000260537,102.3762090000019],[-8.46500000002305,102.3762090000019]]},{id:`alignment-1-insert-left-03`,name:`블록 내부 윤곽 left 03`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F2`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.46500000002305,102.95356300000195],[-8.46500000002305,104.01906300006063]],b:[[-8.46500000002305,102.3762090000019],[-8.46500000002305,103.44170900006057]]},{id:`alignment-1-insert-left-04`,name:`블록 내부 윤곽 left 04`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F3`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`ARC`,a:[[-8.465000000022584,104.01906300006063],[-8.465576441612793,104.02491570974436],[-8.467283614056418,104.0305435030772],[-8.470055911673699,104.03573010711743],[-8.473786796621978,104.0402762035805],[-8.478332893084968,104.04400708852882],[-8.483519497125176,104.0467793861461],[-8.489147290457971,104.04848655858963],[-8.495000000141793,104.04906300017983],[-8.500852709825617,104.04848655858963],[-8.50648050315841,104.0467793861461],[-8.51166710719862,104.04400708852882],[-8.516213203661609,104.0402762035805],[-8.51994408860989,104.03573010711743],[-8.52271638622717,104.0305435030772],[-8.524423558670794,104.02491570974436],[-8.525000000261004,104.01906300006063]],b:[[-8.465000000022584,103.44170900006057],[-8.465576441612793,103.4475617097443],[-8.467283614056418,103.45318950307714],[-8.470055911673699,103.45837610711737],[-8.473786796621978,103.46292220358046],[-8.478332893084968,103.46665308852876],[-8.483519497125176,103.46942538614604],[-8.489147290457971,103.47113255858959],[-8.495000000141793,103.47170900017977],[-8.500852709825617,103.47113255858959],[-8.50648050315841,103.46942538614604],[-8.51166710719862,103.46665308852876],[-8.516213203661609,103.46292220358046],[-8.51994408860989,103.45837610711737],[-8.52271638622717,103.45318950307714],[-8.524423558670794,103.4475617097443],[-8.525000000261004,103.44170900006057]]},{id:`alignment-1-insert-left-05`,name:`블록 내부 윤곽 left 05`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F4`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.450000000023051,102.95356300000195],[-8.540000000023051,102.95356300000195]],b:[[-8.450000000023051,102.3762090000019],[-8.540000000023051,102.3762090000019]]},{id:`alignment-1-insert-left-06`,name:`블록 내부 윤곽 left 06`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F5`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.540000000023051,102.95356300000195],[-8.540000000023051,102.94906300006062]],b:[[-8.540000000023051,102.3762090000019],[-8.540000000023051,102.37170900006056]]},{id:`alignment-1-insert-left-07`,name:`블록 내부 윤곽 left 07`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F6`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.540000000023051,102.94906300006062],[-8.450000000023051,102.94906300006062]],b:[[-8.540000000023051,102.37170900006056],[-8.450000000023051,102.37170900006056]]},{id:`alignment-1-insert-left-08`,name:`블록 내부 윤곽 left 08`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F7`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.450000000023051,102.94906300006062],[-8.450000000023051,102.95356300000195]],b:[[-8.450000000023051,102.37170900006056],[-8.450000000023051,102.3762090000019]]},{id:`alignment-1-insert-left-09`,name:`블록 내부 윤곽 left 09`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F8`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`ARC`,a:[[-8.52500000002305,104.01906300006063],[-8.52442355843517,104.01321029040014],[-8.522716385998297,104.00758249708967],[-8.519944088392192,104.00239589307003],[-8.51621320345858,103.99784979662503],[-8.511667107013754,103.99411891169156],[-8.506480502994032,103.99134661408529],[-8.50085270968359,103.98963944164854],[-8.495000000023051,103.98906300006063],[-8.48914729036251,103.98963944164854],[-8.483519497052068,103.99134661408529],[-8.478332893032348,103.99411891169156],[-8.47378679658752,103.99784979662503],[-8.470055911653908,104.00239589307003],[-8.467283614047803,104.00758249708967],[-8.465576441610931,104.01321029040014],[-8.46500000002305,104.01906300006063]],b:[[-8.52500000002305,103.44170900006057],[-8.52442355843517,103.43585629040008],[-8.522716385998297,103.43022849708962],[-8.519944088392192,103.42504189306999],[-8.51621320345858,103.42049579662498],[-8.511667107013754,103.4167649116915],[-8.506480502994032,103.41399261408523],[-8.50085270968359,103.41228544164848],[-8.495000000023051,103.41170900006057],[-8.48914729036251,103.41228544164848],[-8.483519497052068,103.41399261408523],[-8.478332893032348,103.4167649116915],[-8.47378679658752,103.42049579662498],[-8.470055911653908,103.42504189306999],[-8.467283614047803,103.43022849708962],[-8.465576441610931,103.43585629040008],[-8.46500000002305,103.44170900006057]]},{id:`alignment-1-insert-left-10`,name:`블록 내부 윤곽 left 10`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F9`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.25000000002305,101.94906300000008],[-8.25000000002305,102.07406300000008]],b:[[-8.25000000002305,101.37170900000004],[-8.25000000002305,101.49670900000004]]},{id:`alignment-1-insert-left-11`,name:`블록 내부 윤곽 left 11`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FA`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.25000000002305,102.07406300000008],[-8.370000000023051,102.24906300000009]],b:[[-8.25000000002305,101.49670900000004],[-8.370000000023051,101.67170900000004]]},{id:`alignment-1-insert-left-12`,name:`블록 내부 윤곽 left 12`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FB`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.370000000023051,102.24906300000009],[-8.42000000002305,102.94906300006062]],b:[[-8.370000000023051,101.67170900000004],[-8.42000000002305,102.37170900006056]]},{id:`alignment-1-insert-left-13`,name:`블록 내부 윤곽 left 13`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FC`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.42000000002305,102.94906300006062],[-9.25000000002305,102.94906300006062]],b:[[-8.42000000002305,102.37170900006056],[-9.25000000002305,102.37170900006056]]},{id:`alignment-1-insert-left-14`,name:`블록 내부 윤곽 left 14`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FD`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.80000000002305,102.88806300000148],[-9.200000000023051,102.88806300000148]],b:[[-8.80000000002305,102.31070900000142],[-9.200000000023051,102.31070900000142]]},{id:`alignment-1-insert-left-15`,name:`블록 내부 윤곽 left 15`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FE`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-9.200000000023051,102.88806300000148],[-9.200000000023051,102.94806300000381]],b:[[-9.200000000023051,102.31070900000142],[-9.200000000023051,102.37070900000376]]},{id:`alignment-1-insert-left-16`,name:`블록 내부 윤곽 left 16`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FF`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.80000000002305,102.94806300000381],[-9.25000000002305,102.94806300000381]],b:[[-8.80000000002305,102.37070900000376],[-9.25000000002305,102.37070900000376]]},{id:`alignment-1-insert-left-17`,name:`블록 내부 윤곽 left 17`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155700`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-9.150000000260537,102.88806300000148],[-9.150000000260537,102.58806300000148]],b:[[-9.150000000260537,102.31070900000142],[-9.150000000260537,102.01070900000143]]},{id:`alignment-1-insert-left-18`,name:`블록 내부 윤곽 left 18`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155701`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-9.150000000260537,102.58806300000148],[-8.85000000002305,102.58806300000148]],b:[[-9.150000000260537,102.01070900000143],[-8.85000000002305,102.01070900000143]]},{id:`alignment-1-insert-left-19`,name:`블록 내부 윤곽 left 19`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155702`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.85000000002305,102.58806300000148],[-8.85000000002305,102.88806300000148]],b:[[-8.85000000002305,102.01070900000143],[-8.85000000002305,102.31070900000142]]},{id:`alignment-1-insert-left-20`,name:`블록 내부 윤곽 left 20`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155703`,sourceInsertHandles:[`15DF7D`,`15DF7F`],entityType:`LINE`,a:[[-8.80000000002305,102.94806300000381],[-8.80000000002305,102.88806300000148]],b:[[-8.80000000002305,102.37070900000376],[-8.80000000002305,102.31070900000142]]},{id:`alignment-1-insert-right-01`,name:`블록 내부 윤곽 right 01`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F0`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.525000000259606,104.01906300006063],[8.525000000259606,102.95356300000195]],b:[[8.525000000259606,103.44170900006057],[8.525000000259606,102.3762090000019]]},{id:`alignment-1-insert-right-02`,name:`블록 내부 윤곽 right 02`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F1`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.525000000259606,102.95356300000195],[8.465000000022119,102.95356300000195]],b:[[8.525000000259606,102.3762090000019],[8.465000000022119,102.3762090000019]]},{id:`alignment-1-insert-right-03`,name:`블록 내부 윤곽 right 03`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F2`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.465000000022119,102.95356300000195],[8.465000000022119,104.01906300006063]],b:[[8.465000000022119,102.3762090000019],[8.465000000022119,103.44170900006057]]},{id:`alignment-1-insert-right-04`,name:`블록 내부 윤곽 right 04`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F3`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`ARC`,a:[[8.465000000021654,104.01906300006063],[8.465576441611862,104.02491570974436],[8.467283614055486,104.0305435030772],[8.470055911672768,104.03573010711743],[8.473786796621047,104.0402762035805],[8.478332893084037,104.04400708852882],[8.483519497124245,104.0467793861461],[8.48914729045704,104.04848655858963],[8.495000000140863,104.04906300017983],[8.500852709824684,104.04848655858963],[8.50648050315748,104.0467793861461],[8.511667107197688,104.04400708852882],[8.516213203660678,104.0402762035805],[8.519944088608957,104.03573010711743],[8.52271638622624,104.0305435030772],[8.524423558669863,104.02491570974436],[8.525000000260071,104.01906300006063]],b:[[8.465000000021654,103.44170900006057],[8.465576441611862,103.4475617097443],[8.467283614055486,103.45318950307714],[8.470055911672768,103.45837610711737],[8.473786796621047,103.46292220358046],[8.478332893084037,103.46665308852876],[8.483519497124245,103.46942538614604],[8.48914729045704,103.47113255858959],[8.495000000140863,103.47170900017977],[8.500852709824684,103.47113255858959],[8.50648050315748,103.46942538614604],[8.511667107197688,103.46665308852876],[8.516213203660678,103.46292220358046],[8.519944088608957,103.45837610711737],[8.52271638622624,103.45318950307714],[8.524423558669863,103.4475617097443],[8.525000000260071,103.44170900006057]]},{id:`alignment-1-insert-right-05`,name:`블록 내부 윤곽 right 05`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F4`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.450000000022118,102.95356300000195],[8.540000000022118,102.95356300000195]],b:[[8.450000000022118,102.3762090000019],[8.540000000022118,102.3762090000019]]},{id:`alignment-1-insert-right-06`,name:`블록 내부 윤곽 right 06`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F5`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.540000000022118,102.95356300000195],[8.540000000022118,102.94906300006062]],b:[[8.540000000022118,102.3762090000019],[8.540000000022118,102.37170900006056]]},{id:`alignment-1-insert-right-07`,name:`블록 내부 윤곽 right 07`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F6`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.540000000022118,102.94906300006062],[8.450000000022118,102.94906300006062]],b:[[8.540000000022118,102.37170900006056],[8.450000000022118,102.37170900006056]]},{id:`alignment-1-insert-right-08`,name:`블록 내부 윤곽 right 08`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F7`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.450000000022118,102.94906300006062],[8.450000000022118,102.95356300000195]],b:[[8.450000000022118,102.37170900006056],[8.450000000022118,102.3762090000019]]},{id:`alignment-1-insert-right-09`,name:`블록 내부 윤곽 right 09`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F8`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`ARC`,a:[[8.52500000002212,104.01906300006063],[8.524423558434238,104.01321029040014],[8.522716385997366,104.00758249708967],[8.519944088391261,104.00239589307003],[8.51621320345765,103.99784979662503],[8.511667107012821,103.99411891169156],[8.506480502993101,103.99134661408529],[8.500852709682658,103.98963944164854],[8.495000000022118,103.98906300006063],[8.48914729036158,103.98963944164854],[8.483519497051137,103.99134661408529],[8.478332893031416,103.99411891169156],[8.473786796586587,103.99784979662503],[8.470055911652977,104.00239589307003],[8.467283614046872,104.00758249708967],[8.465576441609999,104.01321029040014],[8.465000000022119,104.01906300006063]],b:[[8.52500000002212,103.44170900006057],[8.524423558434238,103.43585629040008],[8.522716385997366,103.43022849708962],[8.519944088391261,103.42504189306999],[8.51621320345765,103.42049579662498],[8.511667107012821,103.4167649116915],[8.506480502993101,103.41399261408523],[8.500852709682658,103.41228544164848],[8.495000000022118,103.41170900006057],[8.48914729036158,103.41228544164848],[8.483519497051137,103.41399261408523],[8.478332893031416,103.4167649116915],[8.473786796586587,103.42049579662498],[8.470055911652977,103.42504189306999],[8.467283614046872,103.43022849708962],[8.465576441609999,103.43585629040008],[8.465000000022119,103.44170900006057]]},{id:`alignment-1-insert-right-10`,name:`블록 내부 윤곽 right 10`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556F9`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.25000000002212,101.94906300000008],[8.25000000002212,102.07406300000008]],b:[[8.25000000002212,101.37170900000004],[8.25000000002212,101.49670900000004]]},{id:`alignment-1-insert-right-11`,name:`블록 내부 윤곽 right 11`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FA`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.25000000002212,102.07406300000008],[8.370000000022118,102.24906300000009]],b:[[8.25000000002212,101.49670900000004],[8.370000000022118,101.67170900000004]]},{id:`alignment-1-insert-right-12`,name:`블록 내부 윤곽 right 12`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FB`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.370000000022118,102.24906300000009],[8.42000000002212,102.94906300006062]],b:[[8.370000000022118,101.67170900000004],[8.42000000002212,102.37170900006056]]},{id:`alignment-1-insert-right-13`,name:`블록 내부 윤곽 right 13`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FC`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.42000000002212,102.94906300006062],[9.25000000002212,102.94906300006062]],b:[[8.42000000002212,102.37170900006056],[9.25000000002212,102.37170900006056]]},{id:`alignment-1-insert-right-14`,name:`블록 내부 윤곽 right 14`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FD`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.800000000022118,102.88806300000148],[9.200000000022118,102.88806300000148]],b:[[8.800000000022118,102.31070900000142],[9.200000000022118,102.31070900000142]]},{id:`alignment-1-insert-right-15`,name:`블록 내부 윤곽 right 15`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FE`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[9.200000000022118,102.88806300000148],[9.200000000022118,102.94806300000381]],b:[[9.200000000022118,102.31070900000142],[9.200000000022118,102.37070900000376]]},{id:`alignment-1-insert-right-16`,name:`블록 내부 윤곽 right 16`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`1556FF`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.800000000022118,102.94806300000381],[9.25000000002212,102.94806300000381]],b:[[8.800000000022118,102.37070900000376],[9.25000000002212,102.37070900000376]]},{id:`alignment-1-insert-right-17`,name:`블록 내부 윤곽 right 17`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155700`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[9.150000000259606,102.88806300000148],[9.150000000259606,102.58806300000148]],b:[[9.150000000259606,102.31070900000142],[9.150000000259606,102.01070900000143]]},{id:`alignment-1-insert-right-18`,name:`블록 내부 윤곽 right 18`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155701`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[9.150000000259606,102.58806300000148],[8.850000000022119,102.58806300000148]],b:[[9.150000000259606,102.01070900000143],[8.850000000022119,102.01070900000143]]},{id:`alignment-1-insert-right-19`,name:`블록 내부 윤곽 right 19`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155702`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.850000000022119,102.58806300000148],[8.850000000022119,102.88806300000148]],b:[[8.850000000022119,102.01070900000143],[8.850000000022119,102.31070900000142]]},{id:`alignment-1-insert-right-20`,name:`블록 내부 윤곽 right 20`,layer:`CS-CONC-MAJR`,group:`insert`,sourceHandle:`155703`,sourceInsertHandles:[`15DF7E`,`15DF80`],entityType:`LINE`,a:[[8.800000000022118,102.94806300000381],[8.800000000022118,102.88806300000148]],b:[[8.800000000022118,102.37070900000376],[8.800000000022118,102.31070900000142]]}]}]},b={plan:{title:`평면도`,pixelSize:[1400,1160],cadBounds:{xMin:1195e3,xMax:123e4,yMin:-9e4,yMax:-61e3},placement:{kind:`plan`,xOffset:0,displayEL:108.8}},"upper-plan":{title:`상부평면도`,pixelSize:[1400,1097],cadBounds:{xMin:123e4,xMax:1267e3,yMin:-9e4,yMax:-61e3},placement:{kind:`plan`,xOffset:-35e3,displayEL:108.8}},longitudinal:{title:`종단면도`,pixelSize:[1400,741],cadBounds:{xMin:1213e3,xMax:1247e3,yMin:-108e3,yMax:-9e4},placement:{kind:`longitudinal`,stationCad:[1218301.059683612,1241698.059683612],elevationOffset:205.2898,lateralOffset:15}},"section-a":{title:`단면 A-A · STA. 0K+319.000`,pixelSize:[1400,831],cadBounds:{xMin:128e4,xMax:1312e3,yMin:-83e3,yMax:-64e3},placement:{kind:`section`,stationT:-.0005005005,cadXCenter:1296487.109248054,cadYBase:-78059.37855593952,baseEL:101.777}},"section-b":{title:`단면 B-B · STA. 0K+339.000`,pixelSize:[1400,831],cadBounds:{xMin:128e4,xMax:1312e3,yMin:-102e3,yMax:-83e3},placement:{kind:`section`,stationT:1.0005005005,cadXCenter:1296487.109248054,cadYBase:-97286.37855593952,baseEL:101.292}}},ee=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),x=o(((e,t)=>{t.exports=ee()}))(),S={yaw:-.66,pitch:.43,zoom:1,panX:0,panY:0},C={major:`#78917c`,minor:`#d0aa69`,insert:`#9a9074`},w=(e,t,n)=>Math.max(t,Math.min(n,e));function te(e,t,n,r,i){let a=(e.startAngle+(e.endAngle-e.startAngle)*i)*Math.PI/180,o=e.center[0]+e.radius*Math.cos(a),s=e.center[1]+e.radius*Math.sin(a),c=-Math.sin(a),l=-Math.cos(a),u=c,d=(.01+i*19.98)/20,f=t[r][0]+(n[r][0]-t[r][0])*d,p=t[r][1]+(n[r][1]-t[r][1])*d;return[o+f*l,p,s+f*u]}function T(e,t,n,r){let i=(e.startAngle+(e.endAngle-e.startAngle)*t)*Math.PI/180,a=e.center[0]+e.radius*Math.cos(i),o=e.center[1]+e.radius*Math.sin(i);return[a-n*Math.cos(i),r,o-n*Math.sin(i)]}function ne(e,t,n,r){let i=b[t],[a,o]=i.pixelSize,s=i.cadBounds,c=s.xMin+n/a*(s.xMax-s.xMin),l=s.yMax-r/o*(s.yMax-s.yMin),u=i.placement;if(u.kind===`plan`)return[(c+u.xOffset-e.planOrigin[0])/1e3,u.displayEL,(l-e.planOrigin[1])/1e3];if(u.kind===`section`){let t=(c-u.cadXCenter)/1e3,n=u.baseEL+(l-u.cadYBase)/1e3;return T(e,u.stationT,t,n)}let[d,f]=u.stationCad,p=(c-d)/(f-d),m=l/1e3+u.elevationOffset;return T(e,p,u.lateralOffset,m)}function re(e){return[1,3,5].map(t=>parseInt(e.slice(t,t+2),16))}function ie(e,t,n){let[r,i,a]=re(e).map(e=>Math.round(e*t));return`rgba(${r}, ${i}, ${a}, ${n})`}function ae(e,t){let n=!1;for(let r=0,i=t.length-1;re[1]!=c>e[1]&&e[0]<(s-a)*(e[1]-o)/(c-o||1)+a&&(n=!n)}return n}function oe({units:e,hidden:t,selected:n,onSelect:r,view:i,renderMode:a,resetToken:o,drawingVisible:s,drawing:c,drawingOpacity:l}){let u=(0,_.useRef)(null),d=(0,_.useRef)({...S}),f=(0,_.useRef)({}),p=(0,_.useRef)({units:e,hidden:t,selected:n,view:i,renderMode:a,onSelect:r,drawingVisible:s,drawing:c,drawingOpacity:l}),m=(0,_.useRef)(()=>{});return(0,_.useEffect)(()=>{p.current={units:e,hidden:t,selected:n,view:i,renderMode:a,onSelect:r,drawingVisible:s,drawing:c,drawingOpacity:l},m.current()},[e,t,n,i,a,r,s,c,l]),(0,_.useEffect)(()=>{let e={};for(let t of Object.keys(b)){let n=new Image;n.onload=()=>m.current(),n.src=window.BLOCK8_DRAWING_IMAGES?.[t]||`/drawing-images./BLOCK8_${t}.svg`,e[t]=n}f.current=e},[]),(0,_.useEffect)(()=>{let e=u.current,t=e.getContext(`2d`),n=[],r=null,i=null,a=!1,o=(e,t,n)=>{let r=d.current,i=e[1]-104,a=e[0]*Math.cos(r.yaw)-e[2]*Math.sin(r.yaw),o=e[0]*Math.sin(r.yaw)+e[2]*Math.cos(r.yaw),s=Math.min(t/66,n/24)*r.zoom;return[t/2+a*s+r.panX,n/2-(i*Math.cos(r.pitch)-o*Math.sin(r.pitch))*s+r.panY,i*Math.sin(r.pitch)+o*Math.cos(r.pitch)]},s=()=>{let r=e.getBoundingClientRect(),i=r.width,a=r.height;if(!i||!a)return;let s=Math.min(window.devicePixelRatio||1,2);(e.width!==Math.round(i*s)||e.height!==Math.round(a*s))&&(e.width=Math.round(i*s),e.height=Math.round(a*s)),t.setTransform(s,0,0,s,0,0);let{units:c,hidden:l,selected:u,renderMode:m,drawingVisible:h,drawing:g,drawingOpacity:_}=p.current,v=t.createLinearGradient(0,0,0,a);v.addColorStop(0,m?`#e8efea`:`#f8faf8`),v.addColorStop(1,m?`#cbd8cf`:`#e9efea`),t.fillStyle=v,t.fillRect(0,0,i,a);let y=(e,n,r,s=1)=>{let c=o(e,i,a),l=o(n,i,a);t.beginPath(),t.moveTo(c[0],c[1]),t.lineTo(l[0],l[1]),t.strokeStyle=r,t.lineWidth=s,t.stroke()};for(let e=-40;e<=40;e+=5)y([e,100.2,-22],[e,100.2,22],`#aab9ad38`,.6);for(let e=-20;e<=20;e+=5)y([-40,100.2,e],[40,100.2,e],`#aab9ad38`,.6);let ee=[];for(let e of c)for(let t of e.parts){if(l.has(t.id)||t.a.length!==t.b.length)continue;let n=C[t.group]||C.major,r=u?.unitId===e.id&&u?.partId===t.id;for(let s=0;s<8;s++){let c=s/8,l=(s+1)/8;for(let u=0;uo(e,i,a)),f=d.reduce((e,t)=>e+t[2],0)/d.length;ee.push({projected:d,part:t,unit:e,color:n,depth:f,active:r,shade:.82+.18*Math.abs(Math.sin(u*.73+s*.11))})}}}ee.sort((e,t)=>e.depth-t.depth),n=[];for(let e of ee)t.beginPath(),e.projected.forEach((e,n)=>n?t.lineTo(e[0],e[1]):t.moveTo(e[0],e[1])),t.closePath(),t.fillStyle=ie(e.active?`#d27c42`:e.color,m?e.shade:1,e.active?.92:e.part.group===`insert`?.58:.72),t.fill(),t.strokeStyle=e.active?`#9b4f20`:m?`#51675a99`:`#566b5b8c`,t.lineWidth=e.active?1.8:.65,t.stroke(),n.push(e);if(h&&g&&c.length){let e=f.current[g];if(e?.complete&&e.naturalWidth){let n=c[0],[r,s]=b[g].pixelSize,l=o(ne(n,g,0,0),i,a),u=o(ne(n,g,r,0),i,a),d=o(ne(n,g,0,s),i,a);t.save(),t.globalAlpha=_,t.globalCompositeOperation=`source-over`,t.transform((u[0]-l[0])/r,(u[1]-l[1])/r,(d[0]-l[0])/s,(d[1]-l[1])/s,l[0],l[1]),t.drawImage(e,0,0,r,s),t.restore()}}t.font=`11px sans-serif`,t.textAlign=`left`,t.fillStyle=`#68806d`,c.forEach(e=>{let n=o(te(e,[[0,104]],[[0,104]],0,0),i,a),r=o(te(e,[[0,104]],[[0,104]],0,1),i,a);t.fillText(`BLOCK8 중심선 · STA 319.010`,n[0]-5,n[1]-16),t.fillText(`STA 338.990`,r[0]-8,r[1]-14)}),t.fillStyle=`#6f8275`,t.fillText(`X·Z 평면: 도면 중심선 · Y: 표고 EL`,16,a-18),t.textAlign=`right`,t.fillText(`확대 ${Math.round(d.current.zoom*100)}%`,i-16,a-18)};m.current=s;let c=t=>{let n=e.getBoundingClientRect();return[t.clientX-n.left,t.clientY-n.top]},l=t=>{e.setPointerCapture(t.pointerId),r=c(t),i=r,a=!1,t.preventDefault()},h=e=>{if(r===null)return;let t=c(e),n=t[0]-i[0],o=t[1]-i[1];Math.hypot(t[0]-r[0],t[1]-r[1])>4&&(a=!0);let s=d.current;e.shiftKey||e.buttons===2||e.buttons===4?(s.panX+=n,s.panY+=o):(s.yaw+=n*.008,s.pitch=w(s.pitch+o*.006,-.4,1.45)),i=t,m.current()},g=e=>{if(r!==null){if(!a){let t=c(e);for(let e=n.length-1;e>=0;e--){let r=n[e];if(ae(t,r.projected)){p.current.onSelect({unitId:r.unit.id,partId:r.part.id});break}}}r=null,i=null}},_=e=>{e.preventDefault(),d.current.zoom=w(d.current.zoom*(e.deltaY<0?1.1:.9),.3,5),m.current()},v=e=>e.preventDefault(),y=new ResizeObserver(()=>m.current());return y.observe(e),e.addEventListener(`pointerdown`,l),e.addEventListener(`pointermove`,h),e.addEventListener(`pointerup`,g),e.addEventListener(`pointercancel`,g),e.addEventListener(`wheel`,_,{passive:!1}),e.addEventListener(`contextmenu`,v),s(),()=>{y.disconnect(),e.removeEventListener(`pointerdown`,l),e.removeEventListener(`pointermove`,h),e.removeEventListener(`pointerup`,g),e.removeEventListener(`pointercancel`,g),e.removeEventListener(`wheel`,_),e.removeEventListener(`contextmenu`,v)}},[]),(0,_.useEffect)(()=>{let e={전체:{yaw:-.66,pitch:.43},평면:{yaw:0,pitch:Math.PI/2},정면:{yaw:0,pitch:0},측면:{yaw:Math.PI/2,pitch:0},"A-A":{yaw:0,pitch:0},"B-B":{yaw:Math.PI,pitch:0}};d.current={...S,...e[i]},m.current()},[i,o]),(0,x.jsx)(`canvas`,{ref:u,className:`model-canvas`,"aria-label":`BLOCK8 도면 기반 3D 구조 모델. 끌어 회전하고 휠로 확대할 수 있습니다.`,tabIndex:0})}var se={major:`CS-CONC-MAJR 구조선`,minor:`CS-CONC-MINR 구조선`,insert:`블록 내부 콘크리트 윤곽`},ce=[`전체`,`평면`,`정면`,`측면`,`A-A`,`B-B`],le={plan:`평면도`,"upper-plan":`상부평면도`,longitudinal:`종단면도`,"section-a":`단면 A-A`,"section-b":`단면 B-B`},ue={전체:`plan`,평면:`plan`,정면:`section-a`,측면:`longitudinal`,"A-A":`section-a`,"B-B":`section-b`};function de(e,t,n){let r=e.flatMap(e=>[...e.a,...e.b].map(e=>e[n]));return r.length?[Math.min(...r),Math.max(...r)]:[0,0]}function fe(){let[e,t]=(0,_.useState)(`전체`),[n,r]=(0,_.useState)(!1),[i,a]=(0,_.useState)(!1),[o,s]=(0,_.useState)(`auto`),[c,l]=(0,_.useState)(.68),[u,d]=(0,_.useState)(new Set),[f,p]=(0,_.useState)(null),[m,h]=(0,_.useState)(`부재`),[g,v]=(0,_.useState)(``),[b,ee]=(0,_.useState)(0),S=(0,_.useMemo)(()=>y.units.flatMap(e=>e.parts.map(t=>({...t,unitId:e.id,unitName:e.name}))),[]),C=f?S.find(e=>e.id===f.partId&&e.unitId===f.unitId):null,w=f?y.units.find(e=>e.id===f.unitId):null,te=S.filter(e=>!u.has(e.id)).length,T=S.filter(e=>`${e.name} ${e.layer} ${e.unitName}`.toLowerCase().includes(g.toLowerCase())),ne=de(S,`a`,0),re=de(S,`a`,1),ie={major:S.filter(e=>e.group===`major`).length,minor:S.filter(e=>e.group===`minor`).length,insert:S.filter(e=>e.group===`insert`).length},ae=o===`auto`?ue[e]:o,fe=e=>d(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),pe=e=>d(t=>{let n=S.filter(t=>t.group===e).map(e=>e.id),r=n.some(e=>!t.has(e)),i=new Set(t);return n.forEach(e=>r?i.add(e):i.delete(e)),i});return(0,x.jsxs)(`main`,{className:`page-shell`,children:[(0,x.jsxs)(`header`,{className:`topbar`,children:[(0,x.jsxs)(`a`,{className:`brand`,href:`#top`,children:[(0,x.jsx)(`span`,{className:`brand-mark`,children:`B8`}),(0,x.jsx)(`span`,{children:`도면 모델 작업실`})]}),(0,x.jsx)(`span`,{className:`project-chip`,children:`광터지하차도 · BLOCK8`}),(0,x.jsxs)(`nav`,{className:`file-links`,"aria-label":`작업 자료`,children:[(0,x.jsx)(`a`,{href:`./analysis./BLOCK8_3D모델_미리보기.svg`,target:`_blank`,rel:`noreferrer`,children:`모델 이미지 ↗`}),(0,x.jsx)(`a`,{href:`./analysis/도면분석.md`,target:`_blank`,rel:`noreferrer`,children:`분석 파일 ↗`}),(0,x.jsx)(`a`,{href:`./BLOCK8_작업인수인계.md`,target:`_blank`,rel:`noreferrer`,children:`인수인계 파일 ↗`}),(0,x.jsx)(`a`,{href:`./BLOCK8_커밋기록.md`,target:`_blank`,rel:`noreferrer`,children:`커밋 기록 ↗`}),(0,x.jsx)(`a`,{href:`./BLOCK8_모델웹페이지.html`,target:`_blank`,rel:`noreferrer`,children:`단독 HTML ↗`}),(0,x.jsx)(`a`,{href:`./BLOCK8_소스코드_전달자료.zip`,download:!0,children:`전체 소스 ZIP ↓`}),(0,x.jsx)(`a`,{href:`./작업기록.txt`,target:`_blank`,rel:`noreferrer`,children:`작업 로그 ↗`}),(0,x.jsx)(`a`,{href:`./drawings/광터지하차도_BLOCK8.dxf`,download:!0,children:`원본 DXF ↓`})]})]}),(0,x.jsxs)(`section`,{className:`intro`,id:`top`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{className:`kicker`,children:`평면 중심선 · 종단 표고 · 단면 구조선을 연결한 검토 모델`}),(0,x.jsxs)(`h1`,{children:[`광터지하차도 `,(0,x.jsx)(`em`,{children:`BLOCK8`})]}),(0,x.jsx)(`p`,{children:`평면도·상부평면도는 같은 구조물의 표현으로 해석해 한 개 모델로 구성했습니다.`})]}),(0,x.jsxs)(`span`,{className:`status-pill`,children:[(0,x.jsx)(`i`,{}),` 단일 구조물 · 도면 대조 검토`]})]}),(0,x.jsxs)(`section`,{className:`metrics`,"aria-label":`주요 모델 기준값`,children:[(0,x.jsxs)(`article`,{children:[(0,x.jsx)(`small`,{children:`평면 중심선 길이`}),(0,x.jsxs)(`strong`,{children:[`19.980 `,(0,x.jsx)(`i`,{children:`m`})]}),(0,x.jsx)(`p`,{children:`중심선 원호와 양 끝 구조선 교점 간 계산`})]}),(0,x.jsxs)(`article`,{children:[(0,x.jsx)(`small`,{children:`단면 도면 표기 폭`}),(0,x.jsxs)(`strong`,{children:[`20.300 `,(0,x.jsx)(`i`,{children:`m`})]}),(0,x.jsx)(`p`,{children:`단면 치수 · 외곽 구조선 최대 폭은 20.500m`})]}),(0,x.jsxs)(`article`,{children:[(0,x.jsx)(`small`,{children:`벽체 상단 EL`}),(0,x.jsxs)(`strong`,{className:`el`,children:[`107.215 `,(0,x.jsx)(`i`,{children:`→`}),` 107.857`]}),(0,x.jsx)(`p`,{children:`STA 319.000 → 339.000`})]}),(0,x.jsxs)(`article`,{children:[(0,x.jsx)(`small`,{children:`중심 기준 EL`}),(0,x.jsxs)(`strong`,{className:`el`,children:[`102.094 `,(0,x.jsx)(`i`,{children:`→`}),` 101.517`]}),(0,x.jsx)(`p`,{children:`단면 중심 표시와 EL 주석 대조`})]})]}),(0,x.jsxs)(`div`,{className:`notice`,children:[(0,x.jsx)(`b`,{children:`검토 상태`}),(0,x.jsx)(`p`,{children:`단면 A-A/B-B 구조선과 내부 블록 윤곽을 한 구조물에 반영했습니다. 평면도와 상부평면도에 반복된 표현은 별도 구조물로 중복 생성하지 않았습니다.`})]}),(0,x.jsxs)(`section`,{className:`workspace`,children:[(0,x.jsxs)(`div`,{className:`viewer-card`,children:[(0,x.jsxs)(`div`,{className:`viewer-head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{className:`eyebrow`,children:`도면 구조선 기반 · 열린 표면 모델`}),(0,x.jsx)(`h2`,{children:`BLOCK8 3D 구조 보기`})]}),(0,x.jsxs)(`div`,{className:`viewer-actions`,children:[(0,x.jsxs)(`div`,{className:`segmented`,children:[(0,x.jsx)(`button`,{className:n?``:`active`,onClick:()=>r(!1),children:`기본 모델`}),(0,x.jsx)(`button`,{className:n?`active`:``,onClick:()=>r(!0),children:`명암 보기`})]}),(0,x.jsx)(`button`,{className:`drawing-toggle ${i?`active`:``}`,onClick:()=>a(e=>!e),children:i?`도면 숨김`:`도면 함께 보기`})]})]}),(0,x.jsxs)(`div`,{className:`viewbar`,children:[(0,x.jsx)(`div`,{className:`views`,children:ce.map(n=>(0,x.jsx)(`button`,{className:e===n?`active`:``,onClick:()=>t(n),children:n},n))}),(0,x.jsxs)(`span`,{children:[te,` / `,S.length,` 객체 표시`]})]}),(0,x.jsxs)(`div`,{className:`canvas-wrap ${n?`render-mode`:``}`,children:[(0,x.jsx)(oe,{units:y.units,hidden:u,selected:f,onSelect:p,view:e,renderMode:n,resetToken:b,drawingVisible:i,drawing:ae,drawingOpacity:c}),(0,x.jsx)(`span`,{className:`canvas-tag`,children:n?`명암을 더한 도면 검토 시각화 · 실사 렌더링 아님`:`평면도·상부평면도 공통 구조물 모델`})]}),i&&(0,x.jsxs)(`div`,{className:`drawing-controls`,children:[(0,x.jsxs)(`label`,{children:[`도면 선택`,(0,x.jsxs)(`select`,{value:o,onChange:e=>s(e.target.value),children:[(0,x.jsx)(`option`,{value:`auto`,children:`현재 보기와 연결`}),Object.entries(le).map(([e,t])=>(0,x.jsx)(`option`,{value:e,children:t},e))]})]}),(0,x.jsxs)(`label`,{className:`opacity-control`,children:[`도면 투명도`,(0,x.jsx)(`input`,{type:`range`,min:`0.25`,max:`0.95`,step:`0.05`,value:c,onChange:e=>l(Number(e.target.value))})]}),(0,x.jsx)(`span`,{children:`A-A/B-B는 해당 끝 측점 단면에 놓이며, 평면·종단 이미지는 CAD 좌표와 측점·EL 주석 기준으로 모델과 함께 투영됩니다. 평면 이미지는 화면 표시용 높이에 놓인 참고면입니다.`})]}),(0,x.jsxs)(`div`,{className:`viewer-foot`,children:[(0,x.jsx)(`span`,{children:`끌기: 회전 · 휠: 확대/축소 · Shift+끌기 또는 오른쪽 끌기: 이동`}),(0,x.jsx)(`button`,{onClick:()=>{t(`전체`),ee(e=>e+1),p(null)},children:`전체 보기 ↗`})]}),(0,x.jsx)(`div`,{className:`selection`,"aria-live":`polite`,children:C&&w?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`selection-title`,children:[(0,x.jsx)(`span`,{className:`eyebrow`,children:`선택한 구조선`}),(0,x.jsx)(`button`,{onClick:()=>p(null),"aria-label":`선택 해제`,children:`×`})]}),(0,x.jsx)(`h3`,{children:C.name}),(0,x.jsxs)(`div`,{className:`selection-grid`,children:[(0,x.jsxs)(`p`,{children:[`도면 레이어`,(0,x.jsx)(`strong`,{children:C.layer})]}),(0,x.jsxs)(`p`,{children:[`종단 연결 길이`,(0,x.jsxs)(`strong`,{children:[w.length.toFixed(3),` m`]})]}),(0,x.jsxs)(`p`,{children:[`단면 EL 범위`,(0,x.jsxs)(`strong`,{children:[Math.min(...C.a.concat(C.b).map(e=>e[1])).toFixed(3),` ~ `,Math.max(...C.a.concat(C.b).map(e=>e[1])).toFixed(3)]})]}),(0,x.jsxs)(`p`,{children:[`모델 대상`,(0,x.jsx)(`strong`,{children:w.name})]})]}),(0,x.jsxs)(`p`,{className:`source-note`,children:[`원본 HANDLE: `,(C.sourceHandles||[C.sourceHandle,...C.sourceInsertHandles||[]]).filter(Boolean).join(` / `)||`블록 내부 객체`,` · 이 표면은 닫힌 체적이 아닙니다.`]}),(0,x.jsx)(`button`,{className:`subtle`,onClick:()=>fe(C.id),children:u.has(C.id)?`선택 객체 표시`:`선택 객체 숨기기`})]}):(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`span`,{className:`selection-dot`}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`strong`,{children:`모델 표면을 선택하면 원본 레이어와 EL 범위를 확인할 수 있습니다.`}),(0,x.jsx)(`p`,{children:`옆 부재 목록에서 이름을 눌러 선택하거나 체크를 해제해 개별 객체를 숨길 수 있습니다.`})]})]})})]}),(0,x.jsxs)(`aside`,{className:`side-card`,children:[(0,x.jsx)(`div`,{className:`tabs`,children:[`부재`,`도면·검증`].map(e=>(0,x.jsx)(`button`,{className:m===e?`active`:``,onClick:()=>h(e),children:e},e))}),m===`부재`?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`panel-heading`,children:[(0,x.jsx)(`h2`,{children:`모델 객체`}),(0,x.jsxs)(`span`,{children:[te,` 표시`]})]}),(0,x.jsx)(`input`,{className:`search`,"aria-label":`모델 객체 검색`,placeholder:`레이어 또는 객체 이름 검색`,value:g,onChange:e=>v(e.target.value)}),(0,x.jsx)(`div`,{className:`group-toggles`,children:Object.entries(se).map(([e,t])=>{let n=S.filter(t=>t.group===e).filter(e=>!u.has(e.id)).length;return(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{className:`swatch ${e}`}),(0,x.jsxs)(`span`,{className:`group-label`,children:[t,(0,x.jsxs)(`small`,{children:[n,` / `,ie[e]]})]}),(0,x.jsx)(`button`,{onClick:()=>pe(e),children:n?`숨김`:`표시`})]},e)})}),(0,x.jsxs)(`div`,{className:`part-list`,children:[T.map(e=>(0,x.jsxs)(`div`,{className:`part-row ${f?.partId===e.id?`chosen`:``} ${u.has(e.id)?`is-hidden`:``}`,children:[(0,x.jsxs)(`button`,{onClick:()=>{p({unitId:e.unitId,partId:e.id}),h(`부재`)},title:e.name,children:[e.name,(0,x.jsx)(`small`,{children:`단일 구조물`})]}),(0,x.jsx)(`input`,{type:`checkbox`,"aria-label":`${e.name} 표시`,checked:!u.has(e.id),onChange:()=>fe(e.id)})]},e.id)),!T.length&&(0,x.jsx)(`p`,{className:`empty`,children:`검색 결과가 없습니다.`})]}),(0,x.jsx)(`p`,{className:`panel-note`,children:`단면 구조선은 원본 선 단위로 나누었습니다. 연결 면은 두 단면 사이의 계산 표면입니다.`})]}):(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`h2`,{className:`panel-title`,children:`도면 대조 및 추가 확인`}),(0,x.jsxs)(`ul`,{className:`checks`,children:[(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`b`,{children:`확인`}),(0,x.jsxs)(`span`,{children:[`측점 간격 19.980m`,(0,x.jsx)(`small`,{children:`중심선 원호와 CS-CONC-MAJR 끝선 교점으로 계산`})]})]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`b`,{children:`확인`}),(0,x.jsxs)(`span`,{children:[`단면 구조선 114개씩`,(0,x.jsx)(`small`,{children:`CS-CONC-MAJR 108 + CS-CONC-MINR 6`})]})]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`b`,{children:`확인`}),(0,x.jsxs)(`span`,{children:[`블록 내부 콘크리트`,(0,x.jsx)(`small`,{children:`A$C2017021411375356 내부 18선 + 2원호, 4개 삽입 참조`})]})]}),(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`b`,{children:`확인`}),(0,x.jsxs)(`span`,{children:[`도면 표현 연결`,(0,x.jsx)(`small`,{children:`평면도·상부평면도는 같은 구조물을 나타내며 모델은 한 개로 구성`})]})]}),(0,x.jsxs)(`li`,{className:`pending`,children:[(0,x.jsx)(`b`,{children:`검토`}),(0,x.jsxs)(`span`,{children:[`폭 20.300m / 외곽선 20.500m`,(0,x.jsx)(`small`,{children:`단면 치수와 외곽 구조선 범위 차이 0.200m`})]})]}),(0,x.jsxs)(`li`,{className:`pending`,children:[(0,x.jsx)(`b`,{children:`검토`}),(0,x.jsxs)(`span`,{children:[`기초 최저선과 EL 주석 차이`,(0,x.jsx)(`small`,{children:`모델 선 끝이 표기 기초 EL보다 0.100m 낮음`})]})]})]}),(0,x.jsxs)(`div`,{className:`source-links`,children:[(0,x.jsx)(`a`,{href:`./analysis/도면분석.md`,target:`_blank`,rel:`noreferrer`,children:`상세 도면 분석 열기 ↗`}),(0,x.jsx)(`a`,{href:`./작업기록.txt`,target:`_blank`,rel:`noreferrer`,children:`작업 로그 열기 ↗`}),(0,x.jsx)(`a`,{href:`./drawings/광터지하차도_BLOCK8.dxf`,download:!0,children:`원본 DXF 받기 ↓`})]}),(0,x.jsx)(`p`,{className:`panel-note`,children:`렌더링은 구조 검토용 시각화입니다. 실제 재료·폐합 체적을 나타내지 않습니다.`})]})]})]}),(0,x.jsxs)(`section`,{className:`bottom-grid`,children:[(0,x.jsxs)(`article`,{className:`info-card`,children:[(0,x.jsx)(`span`,{className:`eyebrow`,children:`단면 기준 A-A → B-B`}),(0,x.jsx)(`h2`,{children:`EL값과 폭 분할`}),(0,x.jsx)(`p`,{children:`중심 EL은 102.094 → 101.517m, 벽체 상단은 107.215 → 107.857m입니다. 표기 기초 하단은 100.877 → 100.392m입니다. 폭 치수는 0.9 + 8.75 + 1.0 + 8.75 + 0.9 = 20.300m입니다.`})]}),(0,x.jsxs)(`article`,{className:`info-card`,children:[(0,x.jsx)(`span`,{className:`eyebrow`,children:`모델 근거`}),(0,x.jsx)(`h2`,{children:`좌표 단위 검산`}),(0,x.jsxs)(`p`,{children:[`DXF의 단위 설정은 비어 있지만, 구조선 좌표 차 20,300과 도면 치수 20.300m가 맞아 좌표를 mm로 환산했습니다. 현재 범위 EL `,re[0].toFixed(3),`~`,re[1].toFixed(3),`m, 단면 외곽선 폭 `,ne[1]-ne[0]===0?`—`:`20.500`,`m입니다.`]})]})]}),(0,x.jsx)(`footer`,{children:`출처: BLOCK8 DXF · 3D 면은 두 단면 선형 보간 · 평면도와 상부평면도는 단일 구조물 기준`})]})}(0,v.createRoot)(document.getElementById(`root`)).render((0,x.jsx)(_.StrictMode,{children:(0,x.jsx)(fe,{})})); diff --git a/public/BLOCK8_소스코드_전달자료.zip b/public/BLOCK8_소스코드_전달자료.zip index 2c14689..b6b49d6 100644 Binary files a/public/BLOCK8_소스코드_전달자료.zip and b/public/BLOCK8_소스코드_전달자료.zip differ diff --git a/public/BLOCK8_작업인수인계.md b/public/BLOCK8_작업인수인계.md index 6de7e67..6a18447 100644 --- a/public/BLOCK8_작업인수인계.md +++ b/public/BLOCK8_작업인수인계.md @@ -34,10 +34,12 @@ DXF에는 단위가 지정되어 있지 않습니다 (`$INSUNITS=0`). 단면 좌 - `public/drawings/광터지하차도_BLOCK8.dxf` — 등록된 원본 DXF - `docs/도면분석.md` 및 `public/analysis/도면분석.md` — 도면 판독 및 값 근거 +- `public/drawing-images/` — DXF에서 추출한 평면·상부평면·종단·A-A/B-B 벡터 이미지 - `public/작업기록.txt` — 초기화 이후 작업 이력 - `src/model/block8.json` — 웹 뷰어가 읽는 모델 데이터 - `scripts/extract_block8_model.py` — DXF에서 모델 데이터를 다시 추출 - `scripts/render_block8_preview.py` — SVG 미리보기 생성 +- `scripts/render_block8_drawing_views.py` — 원본 DXF 도면 영역 이미지 생성 - `docs/BLOCK8_3D모델_미리보기.svg` — 모델 이미지 - `src/App.jsx`, `src/ModelViewer.jsx` — 웹 화면과 조작 기능 @@ -59,6 +61,8 @@ npm run build npm run lint python3 scripts/extract_block8_model.py python3 scripts/render_block8_preview.py +python3 scripts/render_block8_drawing_views.py +python3 scripts/build_standalone_html.py ``` ## 6. 검증 기록 @@ -76,3 +80,11 @@ python3 scripts/render_block8_preview.py - `e473a7c` 평면도와 상부평면도 모델을 하나로 통합 원격 저장소에는 푸시하지 않은 로컬 커밋 기록입니다. + +## 8. 도면 이미지 함께 보기 + +- `public/drawing-images/`에는 DXF에서 잘라낸 평면도, 상부평면도, 종단면도, A-A, B-B SVG 이미지가 있습니다. +- 웹 화면의 `도면 함께 보기`를 켜면 현재 뷰와 연결된 도면을 모델 화면 위에 참고 오버레이로 표시합니다. 도면 종류를 바꾸거나 투명도를 조절할 수 있습니다. +- 오버레이는 DXF 픽셀-CAD 좌표 변환으로 3D 기준면에 투영한 검토 이미지입니다. A-A/B-B는 끝 측점 단면에, 종단은 STA/EL 주석에 맞춰 모델 옆에 놓습니다. 평면도와 상부평면도는 같은 구조물이 되도록 도면 배치 차이를 보정하며, 평면 기준면의 EL과 종단의 측면 이격은 보기 위한 임시 위치입니다. 도면 글꼴 및 블록 표현은 SVG에서 단순화될 수 있으므로 최종 치수 검증용으로 사용하지 않습니다. +- DXF에서 벡터를 추출하는 명령: `python3 scripts/render_block8_drawing_views.py` +- 단독 HTML 갱신 순서: `npm run build` 후 `python3 scripts/build_standalone_html.py` diff --git a/public/analysis/도면분석.md b/public/analysis/도면분석.md index e8a0c1f..fd6225e 100644 --- a/public/analysis/도면분석.md +++ b/public/analysis/도면분석.md @@ -65,6 +65,9 @@ - 화면: `src/ModelViewer.jsx`와 `src/App.jsx`. 끌어서 회전, 휠 확대/축소, Shift/오른쪽 끌기로 이동, 전체·평면·정면·측면·A-A·B-B 시점을 제공한다. - 객체는 단일 중심선 모델에 구조선 114개와 삽입 블록 윤곽 40개, 총 154개 객체를 구성했다(단면 구조선 114개와 삽입 블록 윤곽 40개). 원본선 단위 선택·숨김과 MAJR/MINR/블록 윤곽 그룹 숨김을 지원한다. - 화면의 면은 검토용 열린 표면 모델이다. 구조선 사이를 연결했으며 모든 두께/접합을 확정한 닫힌 체적이나 실사 렌더링은 아니다. +- `scripts/render_block8_drawing_views.py`는 DXF 도면 영역의 선·문자를 잘라 평면도, 상부평면도, 종단면도, A-A, B-B SVG 이미지 5개와 픽셀-CAD 좌표 연결값을 만든다. 뷰어에서 현재 보기와 도면 종류를 연결하고 투명도를 조절할 수 있다. +- A-A/B-B 이미지는 각 끝 측점의 단면 평면에 놓고, 종단면 이미지는 STA 주석과 EL 주석으로 길이·높이를 변환해 구조물 측면에 놓는다. 평면도는 DXF 좌표를 모델 좌표에 대응시키며, 상부평면도 표기는 도면 간 35m 배치 차이를 이동해 단일 모델 위에 포개고 화면 표시용 EL 108.8m에 둔다. +- 이들은 도면 요소를 3D 화면의 기준 평면에 투영한 검토용 이미지다. 평면의 표시 높이와 종단면의 측면 이격은 보이도록 둔 시각화 위치이며 실제 부재나 설계 고도를 뜻하지 않는다. DXF 글꼴 및 일부 블록 표현은 SVG에서 단순화될 수 있다. - 실행: `npm run dev`. 분석 파일과 작업 로그는 화면 상단 링크에서 연다. ## 검증 결과 diff --git a/public/drawing-images/BLOCK8_longitudinal.svg b/public/drawing-images/BLOCK8_longitudinal.svg new file mode 100644 index 0000000..9f0bda5 --- /dev/null +++ b/public/drawing-images/BLOCK8_longitudinal.svg @@ -0,0 +1,4 @@ + +종단면도 · 원본 DXF 벡터 캡처 +(BLOCK8)10(L=20.119m)U-Type 구간(L=20.119m)10U-Type 구간20.099fck = 15 Mpa(Block8)9005.4386.338EL. 107.215EL. 101.777EL. 107.857EL. 101.292신축이음1019.98010STA. 0K+338.990신축이음STA. 0K+319.010신축이음버림콘크리트구체 콘크리트fck = 24 MPaVERT. SECT. MARKAHORI. SECT. MARKAVERT. SECT. MARKAHORI. SECT. MARKAVERT. SECT. MARKAHORI. SECT. MARKBVERT. SECT. MARKAHORI. SECT. MARKB종단면도S=1:100 + \ No newline at end of file diff --git a/public/drawing-images/BLOCK8_plan.svg b/public/drawing-images/BLOCK8_plan.svg new file mode 100644 index 0000000..6e07d68 --- /dev/null +++ b/public/drawing-images/BLOCK8_plan.svg @@ -0,0 +1,4 @@ + +평면도 · 원본 DXF 벡터 캡처 +선형중심109008.7501.0008.7509009008.7501.0008.750900S=-2.000%S=-2.000%(L=19.881m)1019.861신축이음STA. 0K+339.0001010(BLOCK8)U-Type 구간20.099STA. 0K+319.000신축이음평면도S=1:100fck = 24 MPa구체 콘크리트fck = 24 MPa구체 콘크리트(부제목)도면부명칭(타이틀)제 목도면주명칭(타이틀)(BLOCK8)광터지하차도 일반도(15) + \ No newline at end of file diff --git a/public/drawing-images/BLOCK8_section-a.svg b/public/drawing-images/BLOCK8_section-a.svg new file mode 100644 index 0000000..b1be820 --- /dev/null +++ b/public/drawing-images/BLOCK8_section-a.svg @@ -0,0 +1,4 @@ + +단면 A-A · STA. 0K+319.000 · 원본 DXF 벡터 캡처 +S=-2.000%900500900S=-2.000%9004.2461.1921009008.7501.0008.75090020.3005008.7501.0008.75050019.500100100EL. 107.215EL. 100.877STA. 0K+319.000EL. 102.0941.0001001009004.4381.0006.3389004.4381.0006.338단면 A-AS=1:100fck = 15 Mpa버림콘크리트 + \ No newline at end of file diff --git a/public/drawing-images/BLOCK8_section-b.svg b/public/drawing-images/BLOCK8_section-b.svg new file mode 100644 index 0000000..ae2d0a6 --- /dev/null +++ b/public/drawing-images/BLOCK8_section-b.svg @@ -0,0 +1,4 @@ + +단면 B-B · STA. 0K+339.000 · 원본 DXF 벡터 캡처 +S=-2.000%1.1925.373900900500900S=-2.000%20.3001001.000EL. 101.517STA. 0K+339.000EL. 100.392EL. 107.85710010019.5005008.7501.0008.75050020.3009008.7501.0008.7509001001009005.5651.0007.4659005.5651.0007.465단면 B-BS=1:100fck = 15 Mpa버림콘크리트 + \ No newline at end of file diff --git a/public/drawing-images/BLOCK8_upper-plan.svg b/public/drawing-images/BLOCK8_upper-plan.svg new file mode 100644 index 0000000..65ccda8 --- /dev/null +++ b/public/drawing-images/BLOCK8_upper-plan.svg @@ -0,0 +1,4 @@ + +상부평면도 · 원본 DXF 벡터 캡처 +선형중심(BLOCK8)20.0991019.5005008.7501.0008.7505005008.7501.0008.75050019.500S=-2.000%S=-2.000%U-Type 구간(L=19.881m)1019.861신축이음STA. 0K+339.0001010STA. 0K+319.000신축이음상부평면도S=1:100fck = 24 MPa구체 콘크리트fck = 24 MPa구체 콘크리트(부제목)도면부명칭(타이틀)(BLOCK8) + \ No newline at end of file diff --git a/public/작업기록.txt b/public/작업기록.txt index 37998db..b2b9e8b 100644 --- a/public/작업기록.txt +++ b/public/작업기록.txt @@ -37,3 +37,10 @@ - 단일 중심선 기준 3D 모델 1개로 재생성 (154개 객체) - 35.000m는 도면 뷰 배치 좌표 차이로 기록하고 모델 간격에서 제외 - 분석 문서, 웹 뷰어, 모델 미리보기 갱신 + +7. 도면 뷰 이미지와 3D 모델 동시 보기 + - 원본 DXF에서 평면도·상부평면도·종단면도·단면 A-A/B-B 영역을 SVG 참고 이미지로 추출 + - 뷰어 현재 방향과 도면 이미지를 연결하고 도면 선택/표시/투명도 조절 추가 + - CAD 픽셀좌표를 모델 좌표로 변환해 A-A/B-B 끝 단면, 종단 측면, 평면 기준면으로 투영 + - 평면도·상부평면도는 35m 도면 배치 차이를 보정해 단일 구조물에 중첩 + - 단독 HTML과 전달용 소스 묶음에 추출 이미지를 포함 diff --git a/scripts/build_standalone_html.py b/scripts/build_standalone_html.py index 8d18f5c..aea0583 100644 --- a/scripts/build_standalone_html.py +++ b/scripts/build_standalone_html.py @@ -2,6 +2,8 @@ """Vite 빌드 결과를 독립 실행 가능한 BLOCK8 HTML로 묶는다.""" from html.parser import HTMLParser +import base64 +import json from pathlib import Path import re @@ -33,6 +35,10 @@ def main(): js = (DIST / "assets" / parser.script).read_text(encoding="utf-8") css = (DIST / "assets" / parser.stylesheet).read_text(encoding="utf-8") + image_map = {} + for name in ("plan", "upper-plan", "longitudinal", "section-a", "section-b"): + image = ROOT / "public/drawing-images" / f"BLOCK8_{name}.svg" + image_map[name] = "data:image/svg+xml;base64," + base64.b64encode(image.read_bytes()).decode("ascii") # public 폴더 안의 자료 링크가 file:// 환경에서도 열리도록 상대 경로로 바꾼다. for path in ("analysis/", "drawings/", "BLOCK8_", "작업기록.txt"): js = js.replace(f"/{path}", f"./{path}") @@ -51,6 +57,7 @@ def main():
+ diff --git a/scripts/package_handoff.py b/scripts/package_handoff.py index bb38d69..41f9e83 100644 --- a/scripts/package_handoff.py +++ b/scripts/package_handoff.py @@ -25,19 +25,20 @@ GUIDE = """# 광터지하차도 BLOCK8 전달 자료 안내 - `scripts/`: DXF 모델 추출, SVG 미리보기 생성, 단독 HTML 생성, 전달 ZIP 생성 코드 - `public/`: 원본 DXF, 분석·작업·커밋 기록, 단독 HTML 결과물 - `docs/`: 상세 분석과 모델 미리보기 +- `public/drawing-images/`: 도면 SVG 오버레이와 픽셀-CAD 연결 정보 ## 포함하지 않은 항목 `node_modules/`, `dist/`, `.git/`은 포함하지 않았습니다. 의존성은 `npm install`로 설치하고, 빌드 결과는 `npm run build`로 다시 만들 수 있습니다. Git 커밋 목록은 `public/BLOCK8_커밋기록.md`에서 확인하세요. -현재 기준 커밋: `89065ab` (단독 HTML file 실행 호환성 개선) +현재 압축본에는 DXF에서 생성한 평면·상부평면·종단·A-A/B-B 오버레이 이미지가 포함되어 있습니다. 3D 기준면 배치는 참고 시각화이며, 도면 요소의 최종 치수 검증은 원본 CAD에서 수행하세요. """ def main(): files = [ROOT / "AGENTS.md", ROOT / "README.md", ROOT / "index.html", ROOT / "package.json", ROOT / "package-lock.json", ROOT / "vite.config.js"] for folder in ("src", "scripts", "docs", "public"): - files.extend(path for path in (ROOT / folder).rglob("*") if path.is_file() and path.name not in EXCLUDED) + files.extend(path for path in (ROOT / folder).rglob("*") if path.is_file() and path.name not in EXCLUDED and "__pycache__" not in path.parts and path.suffix != ".pyc") files = sorted(set(files)) OUTPUT.parent.mkdir(parents=True, exist_ok=True) diff --git a/scripts/render_block8_drawing_views.py b/scripts/render_block8_drawing_views.py new file mode 100644 index 0000000..15b7d10 --- /dev/null +++ b/scripts/render_block8_drawing_views.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python3 +"""BLOCK8 DXF에서 평면/종단/단면 영역을 벡터 SVG 참조 이미지로 추출한다.""" + +from collections import defaultdict +from html import escape +import json +import math +from pathlib import Path +import re +import sys + +ROOT = Path(__file__).resolve().parents[1] +sys.dont_write_bytecode = True +sys.path.insert(0, str(ROOT / "scripts")) +import extract_block8_model as dxf + +OUTPUT = ROOT / "public/drawing-images" +WIDTH = 1400 +VIEWS = { + "plan": {"title": "평면도", "bounds": (1_195_000, 1_230_000, -90_000, -61_000)}, + "upper-plan": {"title": "상부평면도", "bounds": (1_230_000, 1_267_000, -90_000, -61_000)}, + "longitudinal": {"title": "종단면도", "bounds": (1_213_000, 1_247_000, -108_000, -90_000)}, + "section-a": {"title": "단면 A-A · STA. 0K+319.000", "bounds": (1_280_000, 1_312_000, -83_000, -64_000)}, + "section-b": {"title": "단면 B-B · STA. 0K+339.000", "bounds": (1_280_000, 1_312_000, -102_000, -83_000)}, +} +ACI = { + 1: "#d25245", 2: "#b58b32", 3: "#43845c", 4: "#438b9e", + 5: "#5273a6", 6: "#995d96", 7: "#26332b", 8: "#777f78", 9: "#a1aaa2", +} +FALLBACK = { + "CS-CONC-MAJR": "#26332b", "CS-CONC-MINR": "#3d817e", + "CS-CNTL": "#c05045", "CS-DIML": "#ad584c", "CS-DIMT": "#43845c", + "CS-NOTE": "#43845c", "CS-TEXT": "#43845c", "CZ-TEX1": "#995d96", + "CZ-TEX2": "#43845c", "CS-SYMB": "#43845c", "CS-CUTL": "#5273a6", +} + + +def compose(a, b): + return ( + a[0]*b[0] + a[2]*b[1], a[1]*b[0] + a[3]*b[1], + a[0]*b[2] + a[2]*b[3], a[1]*b[2] + a[3]*b[3], + a[0]*b[4] + a[2]*b[5] + a[4], a[1]*b[4] + a[3]*b[5] + a[5], + ) + + +def transform(matrix, point): + x, y = point + return matrix[0]*x + matrix[2]*y + matrix[4], matrix[1]*x + matrix[3]*y + matrix[5] + + +def make_insert_matrix(entity, block): + p = dxf.props(entity) + ix, iy = float(dxf.first(p, 10, "0")), float(dxf.first(p, 20, "0")) + sx, sy = float(dxf.first(p, 41, "1")), float(dxf.first(p, 42, "1")) + angle = math.radians(float(dxf.first(p, 50, "0"))) + bx, by = block["base"][:2] + co, si = math.cos(angle), math.sin(angle) + a, c = co*sx, -si*sy + b, e = si*sx, co*sy + return a, b, c, e, ix-a*bx-c*by, iy-b*bx-e*by + + +def entity_layer(entity, inherited=None): + name = dxf.layer(entity) + return inherited if name == "0" and inherited else name + + +def parse_primitives(entity, blocks, matrix, inherited=None, depth=0, visited=()): + if depth > 5: + return [] + kind = entity["type"] + layer = entity_layer(entity, inherited) + p = dxf.props(entity) + if kind == "INSERT": + name = dxf.first(p, 2, "") + block = blocks.get(name) + if not block or name in visited: + return [] + next_matrix = compose(matrix, make_insert_matrix(entity, block)) + result = [] + for child in block["entities"]: + result.extend(parse_primitives(child, blocks, next_matrix, layer, depth+1, visited+(name,))) + return result + if kind in ("LINE", "LWPOLYLINE", "ARC", "CIRCLE", "SOLID", "TRACE"): + points = [] + if kind == "LINE": + points = [(float(dxf.first(p, 10)), float(dxf.first(p, 20))), (float(dxf.first(p, 11)), float(dxf.first(p, 21)))] + elif kind == "LWPOLYLINE": + raw_x, raw_y = [float(v) for v in p.get(10, [])], [float(v) for v in p.get(20, [])] + points = list(zip(raw_x, raw_y)) + if int(dxf.first(p, 70, "0")) & 1 and points: + points.append(points[0]) + elif kind == "ARC": + points = dxf.arc_points(entity, 48) + elif kind == "CIRCLE": + cx, cy, r = float(dxf.first(p, 10)), float(dxf.first(p, 20)), float(dxf.first(p, 40)) + points = [(cx+r*math.cos(2*math.pi*i/64), cy+r*math.sin(2*math.pi*i/64)) for i in range(65)] + else: + points = [(float(dxf.first(p, x)), float(dxf.first(p, y))) for x, y in ((10,20),(11,21),(12,22),(13,23)) if x in p and y in p] + if points: + points.append(points[0]) + return [("path", [transform(matrix, point) for point in points], layer)] if len(points) > 1 else [] + if kind in ("TEXT", "MTEXT", "ATTRIB", "ATTDEF"): + x, y = float(dxf.first(p, 10, "0")), float(dxf.first(p, 20, "0")) + pos = transform(matrix, (x, y)) + text = "".join(p.get(1, []) + p.get(3, [])) + text = text.replace("\\P", " ").replace("%%d", "°").replace("%%p", "±").replace("%%c", "Ø") + text = re.sub(r"\\[A-Za-z][^;]*;", "", text) + size = float(dxf.first(p, 40, "250")) + # Text heights are in drawing units; image uses the same uniform drawing scale. + angle = float(dxf.first(p, 50, "0")) + align = int(dxf.first(p, 72, "0")) + anchor = {0: "start", 1: "middle", 2: "end"}.get(align, "start") + return [("text", [pos, text, size, angle, anchor], layer)] if text.strip() else [] + return [] + + +def get_colors(pairs): + begin, end = dxf.parse_sections(pairs, "TABLES") + colors = {} + for record in dxf.records(pairs, begin+2, end): + if record["type"] != "LAYER": + continue + p = dxf.props(record) + name = dxf.first(p, 2, "") + try: + colors[name] = ACI.get(abs(int(dxf.first(p, 62, "7"))), FALLBACK.get(name, "#374239")) + except ValueError: + colors[name] = FALLBACK.get(name, "#374239") + return colors + + +def render_view(name, spec, entities, blocks, colors): + x0, x1, y0, y1 = spec["bounds"] + HEIGHT = round(WIDTH * (y1-y0) / (x1-x0)) + scale = WIDTH / (x1-x0) + def screen(point): + x, y = point + return (x-x0)*scale, HEIGHT-(y-y0)*scale + + primitives = [] + for entity in entities: + primitives.extend(parse_primitives(entity, blocks, (1,0,0,1,0,0))) + elements = [] + for kind, data, layer in primitives: + color = colors.get(layer, FALLBACK.get(layer, "#667267")) + if kind == "path": + px = [point[0] for point in data] + py = [point[1] for point in data] + if max(px) < x0 or min(px) > x1 or max(py) < y0 or min(py) > y1: + continue + # Canvas crop clips geometry outside the requested drawing region. + points = [screen(point) for point in data] + path = "M" + " L".join(f"{x:.2f},{y:.2f}" for x,y in points) + width = 1.25 if layer == "CS-CONC-MAJR" else 0.8 + elements.append(f'') + else: + (x,y), text, height, angle, anchor = data + if not (x0-1000 <= x <= x1+1000 and y0-1000 <= y <= y1+1000): + continue + sx, sy = screen((x,y)) + size = max(4, min(26, height*scale)) + escaped = escape(text, quote=False) + # Negative angle compensates for the SVG screen's downward-positive y axis. + elements.append(f'{escaped}') + + svg = [ + f'', + f'{escape(spec["title"])} · 원본 DXF 벡터 캡처', + f'{"".join(elements)}', + '', + ] + path = OUTPUT / f"BLOCK8_{name}.svg" + path.write_text("\n".join(svg), encoding="utf-8") + print(f"{path.relative_to(ROOT)}: {len(elements)}개 도면 요소") + return { + "title": spec["title"], + "pixelSize": [WIDTH, HEIGHT], + "cadBounds": { + "xMin": x0, + "xMax": x1, + "yMin": y0, + "yMax": y1, + }, + "placement": None, + } + + +def main(): + pairs = dxf.read_pairs(dxf.SOURCE) + entities = dxf.parse_modelspace(pairs) + blocks = dxf.parse_blocks(pairs) + colors = get_colors(pairs) + OUTPUT.mkdir(parents=True, exist_ok=True) + metadata = {name: render_view(name, spec, entities, blocks, colors) for name, spec in VIEWS.items()} + metadata["plan"]["placement"] = {"kind": "plan", "xOffset": 0, "displayEL": 108.8} + metadata["upper-plan"]["placement"] = {"kind": "plan", "xOffset": -35_000, "displayEL": 108.8} + metadata["longitudinal"]["placement"] = { + "kind": "longitudinal", + "stationCad": [1_218_301.059683612, 1_241_698.059683612], + "elevationOffset": 205.2898, + "lateralOffset": 15, + } + metadata["section-a"]["placement"] = { + "kind": "section", "stationT": -0.0005005005, + "cadXCenter": 1_296_487.109248054, + "cadYBase": -78_059.37855593952, "baseEL": 101.777, + } + metadata["section-b"]["placement"] = { + "kind": "section", "stationT": 1.0005005005, + "cadXCenter": 1_296_487.109248054, + "cadYBase": -97_286.37855593952, "baseEL": 101.292, + } + model_metadata = ROOT / "src/model/drawingViews.json" + model_metadata.write_text(json.dumps(metadata, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + print(f"{model_metadata.relative_to(ROOT)}: 도면/모델 배치 기준 기록") + + +if __name__ == "__main__": + main() diff --git a/src/App.jsx b/src/App.jsx index caa4b49..c787d36 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,6 +8,14 @@ const categoryLabels = { insert: '블록 내부 콘크리트 윤곽', } const viewNames = ['전체', '평면', '정면', '측면', 'A-A', 'B-B'] +const drawingNames = { + plan: '평면도', + 'upper-plan': '상부평면도', + longitudinal: '종단면도', + 'section-a': '단면 A-A', + 'section-b': '단면 B-B', +} +const drawingForView = { 전체: 'plan', 평면: 'plan', 정면: 'section-a', 측면: 'longitudinal', 'A-A': 'section-a', 'B-B': 'section-b' } function pointRange(parts, key, coordinate) { const values = parts.flatMap(part => [...part.a, ...part.b].map(point => point[coordinate])) @@ -17,6 +25,9 @@ function pointRange(parts, key, coordinate) { export default function App() { const [view, setView] = useState('전체') const [renderMode, setRenderMode] = useState(false) + const [drawingVisible, setDrawingVisible] = useState(false) + const [drawingMode, setDrawingMode] = useState('auto') + const [drawingOpacity, setDrawingOpacity] = useState(0.68) const [hidden, setHidden] = useState(new Set()) const [selected, setSelected] = useState(null) const [tab, setTab] = useState('부재') @@ -35,6 +46,7 @@ export default function App() { minor: allParts.filter(part => part.group === 'minor').length, insert: allParts.filter(part => part.group === 'insert').length, } + const activeDrawing = drawingMode === 'auto' ? drawingForView[view] : drawingMode const togglePart = id => setHidden(current => { const next = new Set(current) @@ -90,16 +102,31 @@ export default function App() {
도면 구조선 기반 · 열린 표면 모델

BLOCK8 3D 구조 보기

-
+
+
+ +
{viewNames.map(name => )}
{visibleCount} / {allParts.length} 객체 표시
-
+ {drawingVisible &&
+ + + A-A/B-B는 해당 끝 측점 단면에 놓이며, 평면·종단 이미지는 CAD 좌표와 측점·EL 주석 기준으로 모델과 함께 투영됩니다. 평면 이미지는 화면 표시용 높이에 놓인 참고면입니다. +
}
끌기: 회전 · 휠: 확대/축소 · Shift+끌기 또는 오른쪽 끌기: 이동
{selectedPart && selectedUnit ? <> diff --git a/src/ModelViewer.jsx b/src/ModelViewer.jsx index b939183..fa1aea3 100644 --- a/src/ModelViewer.jsx +++ b/src/ModelViewer.jsx @@ -1,4 +1,5 @@ import { useEffect, useRef } from 'react' +import drawingViews from './model/drawingViews.json' with { type: 'json' } const DEFAULT_CAMERA = { yaw: -0.66, pitch: 0.43, zoom: 1, panX: 0, panY: 0 } const COLORS = { major: '#78917c', minor: '#d0aa69', insert: '#9a9074' } @@ -18,6 +19,34 @@ function worldPoint(unit, pointA, pointB, pointIndex, t) { return [cx + lateral * normalX, elevation, cz + lateral * normalZ] } +function centerlinePoint(unit, t, lateral, elevation) { + const angle = (unit.startAngle + (unit.endAngle - unit.startAngle) * t) * Math.PI / 180 + const cx = unit.center[0] + unit.radius * Math.cos(angle) + const cz = unit.center[1] + unit.radius * Math.sin(angle) + return [cx - lateral * Math.cos(angle), elevation, cz - lateral * Math.sin(angle)] +} + +function drawingPoint(unit, drawingId, pixelX, pixelY) { + const drawing = drawingViews[drawingId] + const [pixelWidth, pixelHeight] = drawing.pixelSize + const bounds = drawing.cadBounds + const cadX = bounds.xMin + (pixelX / pixelWidth) * (bounds.xMax - bounds.xMin) + const cadY = bounds.yMax - (pixelY / pixelHeight) * (bounds.yMax - bounds.yMin) + const placement = drawing.placement + if (placement.kind === 'plan') { + return [(cadX + placement.xOffset - unit.planOrigin[0]) / 1000, placement.displayEL, (cadY - unit.planOrigin[1]) / 1000] + } + if (placement.kind === 'section') { + const lateral = (cadX - placement.cadXCenter) / 1000 + const elevation = placement.baseEL + (cadY - placement.cadYBase) / 1000 + return centerlinePoint(unit, placement.stationT, lateral, elevation) + } + const [stationStart, stationEnd] = placement.stationCad + const t = (cadX - stationStart) / (stationEnd - stationStart) + const elevation = cadY / 1000 + placement.elevationOffset + return centerlinePoint(unit, t, placement.lateralOffset, elevation) +} + function hexRgb(hex) { return [1, 3, 5].map(index => parseInt(hex.slice(index, index + 2), 16)) } @@ -37,16 +66,28 @@ function inPolygon(point, polygon) { return inside } -export default function ModelViewer({ units, hidden, selected, onSelect, view, renderMode, resetToken }) { +export default function ModelViewer({ units, hidden, selected, onSelect, view, renderMode, resetToken, drawingVisible, drawing, drawingOpacity }) { const canvasRef = useRef(null) const cameraRef = useRef({ ...DEFAULT_CAMERA }) - const sceneRef = useRef({ units, hidden, selected, view, renderMode, onSelect }) + const drawingImagesRef = useRef({}) + const sceneRef = useRef({ units, hidden, selected, view, renderMode, onSelect, drawingVisible, drawing, drawingOpacity }) const drawRef = useRef(() => {}) useEffect(() => { - sceneRef.current = { units, hidden, selected, view, renderMode, onSelect } + sceneRef.current = { units, hidden, selected, view, renderMode, onSelect, drawingVisible, drawing, drawingOpacity } drawRef.current() - }, [units, hidden, selected, view, renderMode, onSelect]) + }, [units, hidden, selected, view, renderMode, onSelect, drawingVisible, drawing, drawingOpacity]) + + useEffect(() => { + const images = {} + for (const id of Object.keys(drawingViews)) { + const image = new Image() + image.onload = () => drawRef.current() + image.src = window.BLOCK8_DRAWING_IMAGES?.[id] || `/drawing-images/BLOCK8_${id}.svg` + images[id] = image + } + drawingImagesRef.current = images + }, []) useEffect(() => { const canvas = canvasRef.current @@ -74,7 +115,7 @@ export default function ModelViewer({ units, hidden, selected, onSelect, view, r canvas.width = Math.round(width * dpr); canvas.height = Math.round(height * dpr) } ctx.setTransform(dpr, 0, 0, dpr, 0, 0) - const { units, hidden, selected, renderMode } = sceneRef.current + const { units, hidden, selected, renderMode, drawingVisible, drawing, drawingOpacity } = sceneRef.current const background = ctx.createLinearGradient(0, 0, 0, height) background.addColorStop(0, renderMode ? '#e8efea' : '#f8faf8') background.addColorStop(1, renderMode ? '#cbd8cf' : '#e9efea') @@ -125,6 +166,27 @@ export default function ModelViewer({ units, hidden, selected, onSelect, view, r hitFaces.push(face) } + if (drawingVisible && drawing && units.length) { + const image = drawingImagesRef.current[drawing] + if (image?.complete && image.naturalWidth) { + const unit = units[0] + const [imageWidth, imageHeight] = drawingViews[drawing].pixelSize + const p00 = project(drawingPoint(unit, drawing, 0, 0), width, height) + const p10 = project(drawingPoint(unit, drawing, imageWidth, 0), width, height) + const p01 = project(drawingPoint(unit, drawing, 0, imageHeight), width, height) + ctx.save() + ctx.globalAlpha = drawingOpacity + ctx.globalCompositeOperation = 'source-over' + ctx.transform( + (p10[0]-p00[0])/imageWidth, (p10[1]-p00[1])/imageWidth, + (p01[0]-p00[0])/imageHeight, (p01[1]-p00[1])/imageHeight, + p00[0], p00[1], + ) + ctx.drawImage(image, 0, 0, imageWidth, imageHeight) + ctx.restore() + } + } + ctx.font = '11px sans-serif' ctx.textAlign = 'left' ctx.fillStyle = '#68806d' diff --git a/src/index.css b/src/index.css index 3a07c71..90ecba4 100644 --- a/src/index.css +++ b/src/index.css @@ -34,6 +34,9 @@ h1 em { margin-left:7px; color:#738b79; font-size:.8em; font-style:normal; font- .workspace { display:grid; grid-template-columns:minmax(0,1fr) 322px; gap:16px; align-items:start; } .viewer-card,.side-card,.info-card { min-width:0; overflow:hidden; border:1px solid #dbe4d7; border-radius:11px; background:#fafcf8; } .viewer-head { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:17px 19px 13px; } +.viewer-actions { display:flex; align-items:center; gap:8px; } +.drawing-toggle { padding:7px 10px; border:1px solid #d4dfd2; border-radius:6px; color:#5c765f; font-size:9px; white-space:nowrap; } +.drawing-toggle.active { border-color:#8aa48c; background:#e9f0e7; color:#385f42; } h2 { margin:5px 0 0; font-size:16px; letter-spacing:-.04em; } .segmented { display:flex; padding:3px; border-radius:7px; background:#eaf0e7; } .segmented button { padding:6px 9px; border-radius:5px; color:#7f8d7b; font-size:9px; white-space:nowrap; } @@ -44,6 +47,11 @@ h2 { margin:5px 0 0; font-size:16px; letter-spacing:-.04em; } .views button.active { border-color:#ccdac9; background:#eef3ea; color:#426a50; } .viewbar>span { color:#8b9687; font-size:9px; white-space:nowrap; } .canvas-wrap { position:relative; overflow:hidden; border-top:1px solid #dfe8da; border-bottom:1px solid #dfe8da; background:#f4f7f3; } +.drawing-controls { display:flex; align-items:center; gap:14px; padding:9px 15px; border-bottom:1px solid #e2e9dd; background:#f7faf5; } +.drawing-controls label { display:flex; align-items:center; gap:7px; color:#647568; font-size:9px; white-space:nowrap; } +.drawing-controls select { max-width:180px; padding:5px 7px; border:1px solid #d6e0d4; border-radius:5px; background:#fff; color:#526657; font-size:9px; } +.drawing-controls input { width:95px; accent-color:#59785e; } +.drawing-controls>span { color:#879287; font-size:8px; line-height:1.5; } .model-canvas { display:block; width:100%; height:485px; touch-action:none; cursor:grab; } .model-canvas:active { cursor:grabbing; } .model-canvas:focus-visible { outline:2px solid #7d9a83; outline-offset:-2px; } @@ -128,6 +136,8 @@ footer { padding-top:15px; color:#89958a; font-size:8px; } .notice { gap:8px; } .workspace { grid-template-columns:1fr; } .model-canvas { height:380px; } + .drawing-controls { flex-wrap:wrap; gap:8px 12px; } + .drawing-controls>span { flex-basis:100%; } .side-card { order:2; } .part-list { max-height:330px; } .bottom-grid { grid-template-columns:1fr; gap:9px; } @@ -138,6 +148,7 @@ footer { padding-top:15px; color:#89958a; font-size:8px; } .views { width:100%; flex-wrap:wrap; } .views button { padding:6px 8px; } .model-canvas { height:300px; } + .viewer-actions { flex-wrap:wrap; } .viewer-foot { align-items:flex-start; } .metrics strong { font-size:20px; } .metrics strong.el { font-size:16px; } diff --git a/src/model/drawingViews.json b/src/model/drawingViews.json new file mode 100644 index 0000000..f7bcd81 --- /dev/null +++ b/src/model/drawingViews.json @@ -0,0 +1,100 @@ +{ + "plan": { + "title": "평면도", + "pixelSize": [ + 1400, + 1160 + ], + "cadBounds": { + "xMin": 1195000, + "xMax": 1230000, + "yMin": -90000, + "yMax": -61000 + }, + "placement": { + "kind": "plan", + "xOffset": 0, + "displayEL": 108.8 + } + }, + "upper-plan": { + "title": "상부평면도", + "pixelSize": [ + 1400, + 1097 + ], + "cadBounds": { + "xMin": 1230000, + "xMax": 1267000, + "yMin": -90000, + "yMax": -61000 + }, + "placement": { + "kind": "plan", + "xOffset": -35000, + "displayEL": 108.8 + } + }, + "longitudinal": { + "title": "종단면도", + "pixelSize": [ + 1400, + 741 + ], + "cadBounds": { + "xMin": 1213000, + "xMax": 1247000, + "yMin": -108000, + "yMax": -90000 + }, + "placement": { + "kind": "longitudinal", + "stationCad": [ + 1218301.059683612, + 1241698.059683612 + ], + "elevationOffset": 205.2898, + "lateralOffset": 15 + } + }, + "section-a": { + "title": "단면 A-A · STA. 0K+319.000", + "pixelSize": [ + 1400, + 831 + ], + "cadBounds": { + "xMin": 1280000, + "xMax": 1312000, + "yMin": -83000, + "yMax": -64000 + }, + "placement": { + "kind": "section", + "stationT": -0.0005005005, + "cadXCenter": 1296487.109248054, + "cadYBase": -78059.37855593952, + "baseEL": 101.777 + } + }, + "section-b": { + "title": "단면 B-B · STA. 0K+339.000", + "pixelSize": [ + 1400, + 831 + ], + "cadBounds": { + "xMin": 1280000, + "xMax": 1312000, + "yMin": -102000, + "yMax": -83000 + }, + "placement": { + "kind": "section", + "stationT": 1.0005005005, + "cadXCenter": 1296487.109248054, + "cadYBase": -97286.37855593952, + "baseEL": 101.292 + } + } +}