@nine-lab/nine-util 0.9.124 → 0.9.125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nine-util.js +1 -1
- package/dist/nine-util.umd.js +1 -1
- package/package.json +1 -1
package/dist/nine-util.js
CHANGED
|
@@ -1175,7 +1175,7 @@ class UxSplitter extends HTMLElement {
|
|
|
1175
1175
|
const htmlTmpl = document.createElement("template");
|
|
1176
1176
|
htmlTmpl.innerHTML = `
|
|
1177
1177
|
<style>
|
|
1178
|
-
@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@${"0.9.
|
|
1178
|
+
@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@${"0.9.125"}/dist/css/nine-util.css";
|
|
1179
1179
|
${this.cssPath ? `@import "${this.cssPath}";` : ""}
|
|
1180
1180
|
</style>
|
|
1181
1181
|
${gripTmpl}
|
package/dist/nine-util.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self)["nine-util"]={})}(this,function(t){"use strict";var n,e,o,i,s,a,r,l,c,d,h,p,g,u,m,f,v,w,b,x,y,k,E,L=Object.defineProperty,C=t=>{throw TypeError(t)},R=(t,n,e)=>((t,n,e)=>n in t?L(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e)(t,"symbol"!=typeof n?n+"":n,e),M=(t,n,e)=>n.has(t)||C("Cannot "+e),$=(t,n,e)=>(M(t,n,"read from private field"),e?e.call(t):n.get(t)),S=(t,n,e)=>n.has(t)?C("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(t):n.set(t,e),B=(t,n,e,o)=>(M(t,n,"write to private field"),o?o.call(t,e):n.set(t,e),e),z=(t,n,e)=>(M(t,n,"access private method"),e);const T=new Set,A={ux:{nativeOverride:!1,theme:"light"},board:{readOnly:!1},cssPath:"",debug:!1};"undefined"==typeof window||window.__NINE_GLOBAL_CONFIG__||(window.__NINE_GLOBAL_CONFIG__=A);const P="undefined"!=typeof window?window.__NINE_GLOBAL_CONFIG__:A,W=t=>(T.add(t),t("all",P),()=>T.delete(t)),_=new Proxy(P,{set:(t,n,e)=>(t[n]=e,T.forEach(e=>e(n,t)),!0),get:(t,n)=>t[n]}),N={config:_,get cssPath(){return this.config.cssPath||""},setup(t={}){Object.entries(t).forEach(([t,n])=>{"object"!=typeof n||null===n||Array.isArray(n)?this.config[t]=n:this.config[t]={...this.config[t],...n}}),"undefined"!=typeof window&&(window.nine=window.nine||this)}};class X extends HTMLElement{constructor(){super(),S(this,n),S(this,e),R(this,"showModal",()=>{$(this,e).showModal()}),R(this,"close",()=>{$(this,e).close(),this.remove()}),S(this,o,()=>{this.querySelector(".head"),this.querySelectorAll(".close, .close2, .cancel").forEach(t=>{t.onclick=()=>this.closeWithAnimation(null)}),this.querySelectorAll(".ok").forEach(t=>{})}),S(this,i,t=>{if(t.target.closest("buttons"))return;if(0!==t.button||t.altKey||t.ctrlKey||t.shiftKey)return;const o=$(this,e).getBoundingClientRect();B(this,n,{x:t.clientX-o.left,y:t.clientY-o.top});const i=t=>{$(this,e).style.position="fixed",$(this,e).style.margin="0",$(this,e).style.left=t.clientX-$(this,n).x+"px",$(this,e).style.top=t.clientY-$(this,n).y+"px"},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s)};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}),S(this,s,t=>{if(t.target.closest("buttons"))return;const o=$(this,e).getBoundingClientRect(),i=t.changedTouches[0];B(this,n,{x:i.pageX-o.left,y:i.pageY-o.top});const s=t=>{const o=t.changedTouches[0];$(this,e).style.position="fixed",$(this,e).style.margin="0",$(this,e).style.left=o.pageX-$(this,n).x+"px",$(this,e).style.top=o.pageY-$(this,n).y+"px"},a=()=>{document.removeEventListener("touchmove",s),document.removeEventListener("touchend",a)};document.addEventListener("touchmove",s),document.addEventListener("touchend",a)})}connectedCallback(){const t=this.innerHTML,n=this.getAttribute("title")||"Details";trace.log("111111111"),this.innerHTML=`\n\t\t\t<style>\n\tdialog::backdrop {\n\t\tbackground: rgba(0, 0, 0, 0.3);\n\t}\n\t\n\tdialog:modal {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tpadding: 0;\n\t\toverflow: hidden;\n\t\tborder: 1px solid darkgreen;\n\t\toutline: none;\n\t\tresize: both;\n\t\tbox-shadow: 0 0 4px 0 darkgreen;\n width: 500px;\n height: 150px;\n min-width: 330px;\n min-height: 60px;\n }\n \n \n \n \n\tdiv.head .rect1, div.head .rect2, div.head .rect3 {\n\t\tdisplay: none;\n\t\twidth: 50px;\n\t\theight: 100%;\n\t}\n\tdiv.head .rect1 {\n\t\tbackground-color: red;\n\t}\n\tdiv.head .rect2 {\n\t\tbackground-color: darkgreen;\n\t}\n\tdiv.head .rect3 {\n\t\tbackground-color: olive;\n\t}\n\t\n\tdiv.head {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\t--height: 30px;\n\t\tbackground-color: darkgreen;\n\t\tpadding: 4px;\n\t\tcursor: move;\n\t}\n\tdiv.head:hover {\n\t\tfilter: brightness(110%);\n\t}\n\t\n\tdiv.head span {\n\t\tfont-size: 12px;\n\t\tposition: relative;\n\t}\n\t\n\tdiv.head span.title {\n\t\tcolor: #ddd;\n\t\tmargin-left: 4px;\n\t\tfont-weight: bold;\n\t}\n\t\n\tdiv.head span.sub-title {\n\t\tcolor: #ccc;\n\t\tmargin-left: 8px;\n\t\tfont-style: italic;\n\t}\n\t\n\tdiv.head form {\n\t\tmargin: 0;\n\t}\n\tdiv.head button {\n\t\tmargin-right: 4px;\n\t\tbackground-color: transparent;\n\t\tborder: none;\n\t\tcolor: #ccc;\n\t\tfont-size: x-small;\n\t}\n\tdiv.head button:hover {\n\t\tcursor: pointer;\n\t}\n\t\n\tdiv.contents {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\toverflow: hidden;\n\t}\n\tdiv.left {\n\t\tposition: relative;\n\t\twidth: 16px;\n\t\theight: 100%;\n\t\tbackground-color: #ddd;\n\t\tdisplay: none;\n\t}\n\t\n\tdiv.left span {\n\t\twriting-mode: vertical-rl;\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t\tuser-select: none;\n\t\tcolor: #ccc;\n\t\tfont-weight: 700;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tmargin-left: 3px;\n\t\tmargin-top: 3px;\n\t}\n\tdiv.close2 {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\tright: 0;\n\t\ttop: 3px;\n\t\tcursor: pointer;\n\t\tcolor: #666;\n\t}\n\tdiv.close2 svg:hover {\n\t\tcolor: #999;\n\t}\n\t\n\tdiv.body {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: unset;\n\t\t--border: 3px solid #999;\n\t\t--border-top: none;\n\t\toverflow-x: hidden;\n\t\toverflow-y: auto;\n\t\tpadding: 10px;\n\t\tgap: 8px;\n\t\tflex-direction: column;\n\t}\n\t\n\t\n\t\n\t\n\tng-sphere.icon {\n\t\tmargin-left: 8px;\n\t}\n\t\n\t.buttons {\n\t\tdisplay: flex;\n\t\tposition: absolute;\n\t\tright: 4px;\n\t}\n\t\n\tng-sphere {\n\t\tposition: relative;\n\t\t--width: 16px;\n\t\t--height: 16px;\n\t\tcursor: pointer;\n\t\tmargin-right: 4px;\n\t\tdisplay: flex;\n\t}\n\tng-sphere:hover {\n\t\tfilter: brightness(90%);\n\t}\n\tng-sphere:active {\n\t\tfilter: brightness(80%);\n\t}\n\t\n\tng-sphere:hover::after {\n\t\tcontent: "";\n\t\tposition: absolute;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: center;\n\t}\n\tng-sphere.apply:hover::after {\n\t\tbackground-size: 14px 14px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><polyline points="2.5,7 6,10 11,3" style="fill:none;stroke:white;stroke-width:2px;" /></svg>');\n\t}\n\t\n\tng-sphere.reset:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true"><path d="M10 5h5V0"></path><path d="M15 8a6.957 6.957 0 0 1-7 7 6.957 6.957 0 0 1-7-7 6.957 6.957 0 0 1 7-7 6.87 6.87 0 0 1 6.3 4"></path></svg>');\n\t}\n\t\n\tng-sphere.close:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true" viewBox="0 0 16 16"><path d="M2 2l12 12M14 2L2 14"></path></svg>');\n\t}\n\t\n\t\n\tbutton {\n cursor: pointer;\n }\n \n .input-area {\n position: relative;\n height: 100%;\n --display: flex;\n textarea {\n width: 100%;\n height: 100%;\n min-height: 100px;\n padding: 8px;\n box-sizing: border-box;\n resize: none;\n border-radius: 2px;\n border-color: #ccc;\n }\n textarea:focus {\n border-color: green;\n outline: none; /* 브라우저 기본 파란색 테두리 제거 */\n }\n }\n \n .buttons-confirm {\n position: relative;\n display: flex;\n justify-content: flex-end;\n --bottom: 8px;\n --right: 8px;\n }\n \n \n .buttons-confirm button {\n height: 32px;\n margin-right: 8px;\n border: none;\n outline: none;\n width: 60px;\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n }\n .buttons-confirm button:hover {\n filter: brightness(90%);\n }\n .buttons-confirm button:active {\n color: #ccc;\n }\n \n button.ok {\n --display: none;\n background-color: darkgreen;\n color: white;\n }\n button.cancel {\n color: white;\n background-color: #6c757d;\n }\n \n \n \n div.msg {\n position: relative;\n height: 100%;\n font-size: 14px;\n color: #333;\n }\n \n .reset, .apply {\n display: none;\n }\n \n \n \n :host(.classic) dialog:modal {\n border: 1px solid #007bff;\n box-shadow: 0 0 4px 0 #007bff;\n }\n \n :host(.classic) div.head {\n background-color: #007bff;\n }\n :host(.classic) div.head:hover {\n filter: brightness(110%);\n }\n \n :host(.classic) div.head span {\n font-size: 12px;\n }\n \n :host(.classic) div.head span.title {\n color: #ddd;\n margin-left: 4px;\n font-weight: bold;\n }\n \n :host(.classic) div.head span.sub-title {\n color: #ccc;\n margin-left: 8px;\n font-style: italic;\n }\n :host(.classic) div.head button {\n margin-right: 4px;\n background-color: transparent;\n border: none;\n color: #ccc;\n font-size: x-small;\n }\n \n \n \n \n :host(.rgb) dialog:modal {\n border: none;\n box-shadow: unset;\n border-top: none;\n }\n \n :host(.rgb) div.left {\n display: block;\n background-color: #ddd;\n }\n :host(.rgb) div.left span {\n color: #ccc;\n }\n :host(.rgb) div.close2 {\n display: block;\n color: #666;\n }\n :host(.rgb) div.close2 svg:hover {\n color: #999;\n }\n :host(.rgb) div.head {\n height: 4px;\n background-color: #999;\n padding: 0;\n }\n :host(.rgb) div.contents {\n height: calc(100% - 4px);\n }\n \n :host(.rgb) div.head ng-sphere,\n :host(.rgb) div.head span,\n :host(.rgb) div.head .buttons {\n display: none;\n }\n \n :host(.rgb) div.head .rect1,\n :host(.rgb) div.head .rect2,\n :host(.rgb) div.head .rect3 {\n display: flex;\n }\n \n \n :host(.rgb) div.head:hover {\n filter: unset;\n }\n \n \n /* --- Animation Core --- */\n:host {\n --nx-duration: 0.4s;\n --nx-timing: cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n\n/* 🎯 수정: 애니메이션 클래스가 붙은 경우에만 초기 opacity를 0으로 설정 */\n:host(.fade) dialog,\n:host(.zoom) dialog,\n:host(.moveUp) dialog,\n:host(.moveDown) dialog,\n:host(.moveLeft) dialog,\n:host(.moveRight) dialog,\n:host(.roadRunner) dialog {\n opacity: 0;\n}\n\n/* shake는 애니메이션 내부에서 opacity를 다루므로 제외하거나 별도 처리 */\n:host(.shake) dialog { \n opacity: 1; \n}\n\n/* 1. Fade (서서히 나타남) */\n:host(.fade) dialog { animation: nx-fade-in var(--nx-duration) forwards; }\n@keyframes nx-fade-in { from { opacity: 0; } to { opacity: 1; } }\n\n/* 2. Zoom (커지며 나타남) */\n:host(.zoom) dialog { animation: nx-zoom-in var(--nx-duration) var(--nx-timing) forwards; }\n@keyframes nx-zoom-in { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } }\n\n/* 3. Slide (상하좌우) */\n:host(.moveUp) dialog { animation: nx-move-up var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveDown) dialog { animation: nx-move-down var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveLeft) dialog { animation: nx-move-left var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveRight) dialog { animation: nx-move-right var(--nx-duration) var(--nx-timing) forwards; }\n\n@keyframes nx-move-up { from { opacity: 0; transform: translateY(100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-down { from { opacity: 0; transform: translateY(-100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-left { from { opacity: 0; transform: translateX(100px); } to { opacity: 1; transform: translateX(0); } }\n@keyframes nx-move-right { from { opacity: 0; transform: translateX(-100px); } to { opacity: 1; transform: translateY(0); } }\n\n/* 4. Shake (상하좌우 격렬한 진동 - 에러 인지용) */\n:host(.shake) dialog { \n animation: nx-heavy-shake 0.5s cubic-bezier(.36,.07,.19,.97) both;\n opacity: 1; \n}\n\n@keyframes nx-heavy-shake {\n 10%, 90% { transform: translate3d(-1px, -2px, 0); }\n 20%, 80% { transform: translate3d(2px, 4px, 0); }\n 30%, 50%, 70% { transform: translate3d(-6px, -6px, 0); }\n 40%, 60% { transform: translate3d(6px, 6px, 0); }\n}\n\n/* 5. Road Runner (등장: 왼쪽에서 탄력 있게 / 퇴장: 움츠렸다가 광속 탈출) */\n:host(.roadRunner) dialog { \n animation: roadRunnerIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; \n}\n\n@keyframes roadRunnerIn {\n 0% { transform: translateX(-1500px) skewX(30deg); opacity: 1; }\n 70% { transform: translateX(30px) skewX(-10deg); opacity: 1; }\n 100% { transform: translateX(0) skewX(0deg); opacity: 1; }\n}\n\n/* --- Out Animations (닫힐 때) --- */\ndialog.out { pointer-events: none; }\n\n/* Road Runner 퇴장: 슥 움츠렸다가(Anticipation) 쌩~! */\n:host(.roadRunner) dialog.out { \n animation: roadRunnerOut 0.5s cubic-bezier(0.6, -0.28, 0.735, 0.045) forwards; \n}\n\n@keyframes roadRunnerOut {\n 0% { \n transform: translateX(0) scale(1) skewX(0deg); \n opacity: 1; \n }\n 30% { \n /* 예비 동작: 뒤로 살짝 갔다가 움츠러들기 */\n transform: translateX(50px) scaleX(1.2) scaleY(0.8) skewX(-20deg); \n opacity: 1; \n }\n 100% { \n /* 발사: 길게 늘어나며 광속 탈출 */\n transform: translateX(2000px) scaleX(4) scaleY(0.3) skewX(50deg); \n opacity: 0; \n filter: blur(10px); /* 👈 잔상 느낌 추가 */\n }\n}\n\n/* 일반 퇴장 (기본) */\ndialog.out { animation: nx-fade-out 0.3s forwards; }\n@keyframes nx-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.9); } }\n</style>\n\t\t\n\t\t\t<dialog>\n\t\t\t\t<div class="head">\n\t\t\t\t\t<div class="rect1"></div>\n\t\t\t\t\t<div class="rect2"></div>\n\t\t\t\t\t<div class="rect3"></div>\n\t\t\t\t\t<ng-sphere class="icon" end-fill="#666" size="8"></ng-sphere>\n\t\t\t\t\t<span class="title">${n}</span>\n\t\t\t\t\t<span class="sub-title"></span>\n\t\t\t\t\t<div class="buttons">\n\t\t\t\t\t\t<ng-sphere class="apply" start-fill="#cc6" end-fill="#660" size="16" title="apply"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="reset" start-fill="#99f" end-fill="#00f" size="16" title="reset"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="close" start-fill="#f99" end-fill="#f00" size="16" title="close"></ng-sphere>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="contents">\n\t\t\t\t\t<div class="left">\n\t\t\t\t\t\t<span>가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="body">\n\t\t\t\t\t\t${t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="close2">\n\t\t\t\t\t\t<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">\n\t\t\t\t\t\t\t<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</dialog>\n\t\t`,B(this,e,this.querySelector("dialog")),$(this,o).call(this)}closeWithAnimation(t){$(this,e).classList.add("out"),setTimeout(()=>{$(this,e).close(),this.dispatchEvent(new CustomEvent("closed",{detail:t})),this.remove()},300)}}n=new WeakMap,e=new WeakMap,o=new WeakMap,i=new WeakMap,s=new WeakMap;class O extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}static async open(t,n,e,o,i){var s,a,r;const l=t.tagName.toLowerCase(),c={"true-text":"확인","false-text":"취소",class:"classic",animation:"fade",...(null==(r=null==(a=null==(s=window.nine)?void 0:s.config)?void 0:a.ux)?void 0:r[l.replace("nine-","").replace("-popup","")])||{},...o};document.querySelectorAll(l).forEach(t=>t.remove());const d=document.createElement(l);c.class&&d.classList.add(c.class),c.animation&&d.classList.add(c.animation),document.body.appendChild(d),i(d,n,c);const h=d.shadowRoot.querySelector("nine-dialog");return e&&h.setAttribute("title",e),new Promise(t=>{h.addEventListener("closed",n=>t(n.detail)),d.setupEvents(t,h),h.showModal()})}}customElements.get("nine-dialog")||customElements.define("nine-dialog",X);const F=class extends O{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(!0)}};R(F,"tagName","nine-confirm-popup"),R(F,"confirm",(t,n,e)=>O.open(F,t,n,e,(t,n,e)=>t.render(n,e)));let I=F;const j=class extends O{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">확인</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){}};R(j,"tagName","nine-alert-popup"),R(j,"alert",(t,n,e)=>O.open(j,t,n,e,(t,n,e)=>t.render(n,e)));let H=j;customElements.get("nine-confirm-popup")||customElements.define("nine-confirm-popup",I),customElements.get("nine-alert-popup")||customElements.define("nine-alert-popup",H);const Y=class extends O{constructor(){super()}render(t,n){trace.log(this),trace.log(this.shadowRoot),this.shadowRoot.innerHTML=`\n\t\t\t<style>\n\t\t\t\tdialog {\n\t\t\t\t\theight: 300px !important;\n\t\t\t\t}\n\t\t\t\t.msg {\n\t\t\t\t\theight: unset !important;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="input-area">\n <textarea placeholder="내용을 입력하세요..."></textarea>\n </div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){const e=this.shadowRoot.querySelector("textarea");this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(e.value),requestAnimationFrame(()=>e.focus())}};R(Y,"tagName","nine-prompt-popup"),R(Y,"prompt",(t,n,e)=>O.open(Y,t,n,e,(t,n,e)=>t.render(n,e)));let q=Y;customElements.get("nine-prompt-popup")||customElements.define("nine-prompt-popup",q);class D{constructor(){S(this,a)}alert(t,n="Alert"){return z(this,a,r).call(this,"alert",t,n,"classic")}confirm(t,n="Confirm"){return z(this,a,r).call(this,"confirm",t,n,"classic")}prompt(t,n="Prompt"){return z(this,a,r).call(this,"prompt",t,n,"classic")}}a=new WeakSet,r=function(t,n,e,o){const i={class:o,animation:"fade"};let s=!1;const a={alert:H,confirm:I,prompt:q}[t],r={rgb:()=>(i.class="rgb",r),classic:()=>(i.class="classic",r),shake:()=>(i.animation="shake",r),run:()=>(i.animation="roadRunner",r),zoom:()=>(i.animation="zoom",r),then:(o,r)=>(s=!0,a[t](n,e,i).then(o,r))};return Promise.resolve().then(()=>{s||(s=!0,a[t](n,e,i))}),r},R(D,"cssPath","");class G{constructor(t=null,n="green"){S(this,h),S(this,l),S(this,c),S(this,d,!0),B(this,l,t),B(this,c,n),z(this,h,p).call(this)}initBAK(t,n="green"){B(this,l,t),B(this,c,n)}init(t,n="green"){return B(this,l,t),B(this,c,n),this}get log(){const t=`color: ${$(this,c)}; font-weight: bold;`;return $(this,l)?console.log.bind(console,`%c[${$(this,l)}]`,t):console.log.bind(console)}get warn(){return $(this,d)?$(this,l)?console.warn.bind(console,`%c[${$(this,l)}]`,"color: cyan; font-weight: bold;"):console.warn.bind(console):()=>{}}get error(){return $(this,l)?console.error.bind(console,`%c[${$(this,l)}]`,"color: red; font-weight: bold;"):console.error.bind(console)}enable(){B(this,d,!0)}disable(){B(this,d,!1)}}l=new WeakMap,c=new WeakMap,d=new WeakMap,h=new WeakSet,p=function(){if("undefined"==typeof window)return;"localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.startsWith("192.168.")?this.enable():(this.disable(),console.log(`%c[${$(this,l)||"Trace"}]%c 운영 모드: 로그 비활성화. %ctrace.enable()%c 로 활성화 가능`,"color: #4CAF50; font-weight: bold;","","background: #333; color: yellow; padding: 2px 5px;",""))};const K=new G;"undefined"!=typeof window&&(window.trace=K);g=new WeakMap,u=new WeakMap,m=new WeakMap,f=new WeakSet,v=function(){if(0===$(this,u).length)return;const t=$(this,u).splice(0,$(this,u).length),n=new Set;t.forEach(t=>{const e=`${t.func.name}_${JSON.stringify(t.args)}`;n.has(e)||(t.func(...t.args),n.add(e))}),B(this,g,null)};class U{static show(){let t=document.getElementById("global-loading-overlay");if(!t&&(t=document.createElement("div"),t.id="global-loading-overlay",t.style.cssText="\n position: fixed; inset: 0; z-index: 9999;\n background: rgba(0, 0, 0, 0.4); display: flex; \n justify-content: center; align-items: center;\n backdrop-filter: blur(2px);\n ",t.innerHTML='<div class="loading-spinner"></div>',document.body.appendChild(t),!document.getElementById("nine-util-style"))){const t=document.createElement("style");t.id="nine-util-style",t.innerHTML="\n .loading-spinner {\n width: 48px; height: 48px;\n border: 5px solid rgba(255, 255, 255, 0.3);\n border-top-color: white; border-radius: 50%;\n animation: nine-spin 1s linear infinite;\n }\n @keyframes nine-spin { to { transform: rotate(360deg); } }\n ",document.head.appendChild(t)}t.style.display="flex"}static hide(){const t=document.getElementById("global-loading-overlay");t&&(t.style.display="none")}}const J=class{};w=new WeakMap,R(J,"BASE_URL",window.__API_BASE_URL__||""),S(J,w,(t,n,e={},o=!0)=>{const i=n.startsWith("http")?n:`${J.BASE_URL}${n}`;o&&U.show();const s={};e instanceof FormData||(s["Content-Type"]="application/json");const a={method:t,headers:s};let r=i;return"GET"===t?r+=`?${new URLSearchParams(e)}`:a.body=e instanceof FormData?e:JSON.stringify(e),fetch(r,a).then(async t=>{if(!t.ok){const n=await t.text();throw new Error(`API 오류 (${t.status}): ${n}`)}return t.json()}).catch(n=>{throw K.error(`[IdeFetch.${t.toLowerCase()}] ${i} 실패:`,n),n}).finally(()=>{o&&U.hide()})}),R(J,"get",(t,n={},e=!0)=>{var o;return $(o=J,w).call(o,"GET",t,n,e)}),R(J,"post",(t,n={},e=!0)=>{var o;return $(o=J,w).call(o,"POST",t,n,e)}),R(J,"postMultipart",async(t,n=[],e={})=>{const{fileKey:o="fileContents",filePartName:i="files",jsonPartName:s="dataList",chunkSize:a=10}=e;U.show();let r=0,l=null;return(async()=>{for(let e=0;e<n.length;e+=a){const c=new FormData,d=n.slice(e,e+a),h=[];d.forEach(t=>{const{[o]:n,_fileObj:e,...s}=t;h.push(s),n instanceof File&&c.append(i,n)});const p=new Blob([JSON.stringify(h)],{type:"application/json"});if(c.append(s,p),l=await J.post(t,c,!1),!l||!l.success&&"OK"!==l.status)throw new Error(`청크 전송 실패: ${e}번째 섹션`);r+=d.length}return{...l,success:!0,totalCount:r}})().catch(t=>{throw K.error("[postChunk] Error:",t),t}).finally(()=>{U.hide()})});let V=J;const Z=V;class Q extends HTMLElement{constructor(){super(),S(this,b),S(this,x,t=>{const n=t.previousElementSibling,e=t.nextElementSibling;if(!n||!e)return void B(this,b,this.classList.contains("h")?"h":"v");const o=n.getBoundingClientRect(),i=e.getBoundingClientRect();this.classList.contains("h")?B(this,b,"h"):this.classList.contains("v")?B(this,b,"v"):B(this,b,Math.abs(o.top-i.top)<5?"h":"v")}),S(this,y,t=>{t.preventDefault(),t.stopPropagation();const n=this.getBoundingClientRect(),e="h"===$(this,b),o=e?t.clientX-n.left:t.clientY-n.top,i=document.createElement("div");i.className=`nx-splitter-drag-bar-${$(this,b)}`,Object.assign(i.style,{position:"absolute",zIndex:"999",background:"#666",opacity:"0.6",pointerEvents:"none"});const s=this.getRootNode({composed:!0}),a=s instanceof ShadowRoot?s.host:this.parentElement,r=this.previousElementSibling,l=this.nextElementSibling;if(!a||!r||!l)return void K.warn("Spliter's parent or siblings not found.");(a.shadowRoot||a).appendChild(i);const c=i.offsetParent.getBoundingClientRect(),d=r.getBoundingClientRect(),h=l.getBoundingClientRect(),p=(e?n.left-c.left:n.top-c.top)+o;e?(i.style.top="0",i.style.left=`${p}px`,i.style.width="2px",i.style.height="100%"):(i.style.left="0",i.style.top=`${p}px`,i.style.height="2px",i.style.width="100%"),i.style.mixBlendMode="difference",i.style.zIndex="99999";const g=e?d.left-c.left:d.top-c.top,u=e?h.right-c.left-n.width:h.bottom-c.top-n.height,m=t=>{const n=e?t.clientX:t.clientY,o=e?n-c.left:n-c.top,s=Math.max(g,Math.min(o,u));e?i.style.left=`${s}px`:i.style.top=`${s}px`},f=()=>{window.removeEventListener("mousemove",m),window.removeEventListener("mouseup",f),i.remove();const t=Array.from(a.children),n=t.filter(t=>"nx-splitter"!==t.tagName.toLowerCase()),o=window.getComputedStyle(a),s=e?o.getPropertyValue("column-gap"):o.getPropertyValue("row-gap"),c=parseFloat(s)||0,d=(t.length>1?t.length-1:0)*c,h=(e?parseFloat(i.style.left):parseFloat(i.style.top))-p,g=e?r.getBoundingClientRect().width:r.getBoundingClientRect().height,u=e?l.getBoundingClientRect().width:l.getBoundingClientRect().height;let v=g+h,w=u-h;v<0&&(w+=v,v=0),w<0&&(v+=w,w=0);const b=n.map(t=>e?t.getBoundingClientRect().width:t.getBoundingClientRect().height),x=t.reduce((t,n)=>"nx-splitter"===n.tagName.toLowerCase()?t+(e?n.getBoundingClientRect().width:n.getBoundingClientRect().height):t,0),y=(e?a.getBoundingClientRect().width:a.getBoundingClientRect().height)-x-d;let k=0;n.forEach((t,n)=>{let e;e=t===r?v:t===l?w:b[n];const o=e/y;K.log(t),t.classList.contains("sidebar")?t.style.flex=`0 0 ${e}px`:t.style.flex=`${o} ${o} 0`,k+=o}),K.log(`dragOffset: ${h}`),K.log(`Calculated FlexSum: ${k}`)};window.addEventListener("mousemove",m),window.addEventListener("mouseup",f)}),S(this,k,()=>{$(this,x).call(this,this),this.classList.add($(this,b));const t=this.innerHTML.trim(),n=""===t?'<div class="grip"></div>':`<div class="grip"></div><div class="inner-container">${t}</div><div class="grip"></div>`;this.innerHTML="";const e=document.createElement("template");e.innerHTML=`\n\t\t\t<style>\n\t\t\t\t@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@0.9.124/dist/css/nine-util.css";\n\t\t\t\t${this.cssPath?`@import "${this.cssPath}";`:""}\n\t\t\t</style>\n\t\t\t${n}\n `,this.shadowRoot.appendChild(e.content.cloneNode(!0)),this.shadowRoot.querySelectorAll(".grip").forEach(t=>{t.addEventListener("mousedown",t=>$(this,y).call(this,t))}),$(this,E).call(this),window.addEventListener("resize",()=>$(this,E).call(this))}),S(this,E,()=>{const t="h"===$(this,b),n=this.parentElement,e=Array.from(n.children).filter(t=>"nx-splitter"!==t.tagName.toLowerCase());if(e.length<2)return;const o=n.getBoundingClientRect(),i=e.reduce((n,e)=>n+(t?e.getBoundingClientRect().width:e.getBoundingClientRect().height),0),s=t?o.width:o.height;e.forEach(n=>{const e=t?n.getBoundingClientRect().width:n.getBoundingClientRect().height,o=s*(e/i)/s;n.style.flex=`${o} ${o} 0`})}),this.attachShadow({mode:"open"})}connectedCallback(){$(this,k).call(this)}get cssPath(){return this.getAttribute("css-path")||D.cssPath}}b=new WeakMap,x=new WeakMap,y=new WeakMap,k=new WeakMap,E=new WeakMap,customElements.get("nine-splitter")||customElements.define("nine-splitter",Q);const tt=new D;N.alert=tt.alert.bind(tt),N.confirm=tt.confirm.bind(tt),N.prompt=tt.prompt.bind(tt),N.api=Z,N.trace=K,N.subscribeConfig=W,N.config=_||{},"undefined"!=typeof window&&(window.nine=N),t.Fetch=V,t.NineUtil=D,t.TaskDebouncer=class{constructor(t=50){S(this,f),S(this,g,null),S(this,u,[]),S(this,m),B(this,m,t)}exec(t,...n){$(this,u).push({func:t,args:n}),$(this,g)&&clearTimeout($(this,g)),B(this,g,setTimeout(()=>z(this,f,v).call(this),$(this,m)))}execWithKey(t,n,...e){B(this,u,$(this,u).filter(n=>n.key!==t)),$(this,u).push({key:t,func:n,args:e}),$(this,g)&&clearTimeout($(this,g)),B(this,g,setTimeout(()=>z(this,f,v).call(this),$(this,m)))}},t.Trace=G,t.api=Z,t.config=_,t.loading=U,t.nine=N,t.nineAlertPopup=H,t.nineConfirmPopup=I,t.nineDialog=X,t.ninePromptPopup=q,t.subscribeConfig=W,t.trace=K,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self)["nine-util"]={})}(this,function(t){"use strict";var n,e,o,i,s,a,r,l,c,d,h,p,g,u,m,f,v,w,b,x,y,k,E,L=Object.defineProperty,C=t=>{throw TypeError(t)},R=(t,n,e)=>((t,n,e)=>n in t?L(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e)(t,"symbol"!=typeof n?n+"":n,e),M=(t,n,e)=>n.has(t)||C("Cannot "+e),$=(t,n,e)=>(M(t,n,"read from private field"),e?e.call(t):n.get(t)),S=(t,n,e)=>n.has(t)?C("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(t):n.set(t,e),B=(t,n,e,o)=>(M(t,n,"write to private field"),o?o.call(t,e):n.set(t,e),e),z=(t,n,e)=>(M(t,n,"access private method"),e);const T=new Set,A={ux:{nativeOverride:!1,theme:"light"},board:{readOnly:!1},cssPath:"",debug:!1};"undefined"==typeof window||window.__NINE_GLOBAL_CONFIG__||(window.__NINE_GLOBAL_CONFIG__=A);const P="undefined"!=typeof window?window.__NINE_GLOBAL_CONFIG__:A,W=t=>(T.add(t),t("all",P),()=>T.delete(t)),_=new Proxy(P,{set:(t,n,e)=>(t[n]=e,T.forEach(e=>e(n,t)),!0),get:(t,n)=>t[n]}),N={config:_,get cssPath(){return this.config.cssPath||""},setup(t={}){Object.entries(t).forEach(([t,n])=>{"object"!=typeof n||null===n||Array.isArray(n)?this.config[t]=n:this.config[t]={...this.config[t],...n}}),"undefined"!=typeof window&&(window.nine=window.nine||this)}};class X extends HTMLElement{constructor(){super(),S(this,n),S(this,e),R(this,"showModal",()=>{$(this,e).showModal()}),R(this,"close",()=>{$(this,e).close(),this.remove()}),S(this,o,()=>{this.querySelector(".head"),this.querySelectorAll(".close, .close2, .cancel").forEach(t=>{t.onclick=()=>this.closeWithAnimation(null)}),this.querySelectorAll(".ok").forEach(t=>{})}),S(this,i,t=>{if(t.target.closest("buttons"))return;if(0!==t.button||t.altKey||t.ctrlKey||t.shiftKey)return;const o=$(this,e).getBoundingClientRect();B(this,n,{x:t.clientX-o.left,y:t.clientY-o.top});const i=t=>{$(this,e).style.position="fixed",$(this,e).style.margin="0",$(this,e).style.left=t.clientX-$(this,n).x+"px",$(this,e).style.top=t.clientY-$(this,n).y+"px"},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s)};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}),S(this,s,t=>{if(t.target.closest("buttons"))return;const o=$(this,e).getBoundingClientRect(),i=t.changedTouches[0];B(this,n,{x:i.pageX-o.left,y:i.pageY-o.top});const s=t=>{const o=t.changedTouches[0];$(this,e).style.position="fixed",$(this,e).style.margin="0",$(this,e).style.left=o.pageX-$(this,n).x+"px",$(this,e).style.top=o.pageY-$(this,n).y+"px"},a=()=>{document.removeEventListener("touchmove",s),document.removeEventListener("touchend",a)};document.addEventListener("touchmove",s),document.addEventListener("touchend",a)})}connectedCallback(){const t=this.innerHTML,n=this.getAttribute("title")||"Details";trace.log("111111111"),this.innerHTML=`\n\t\t\t<style>\n\tdialog::backdrop {\n\t\tbackground: rgba(0, 0, 0, 0.3);\n\t}\n\t\n\tdialog:modal {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tpadding: 0;\n\t\toverflow: hidden;\n\t\tborder: 1px solid darkgreen;\n\t\toutline: none;\n\t\tresize: both;\n\t\tbox-shadow: 0 0 4px 0 darkgreen;\n width: 500px;\n height: 150px;\n min-width: 330px;\n min-height: 60px;\n }\n \n \n \n \n\tdiv.head .rect1, div.head .rect2, div.head .rect3 {\n\t\tdisplay: none;\n\t\twidth: 50px;\n\t\theight: 100%;\n\t}\n\tdiv.head .rect1 {\n\t\tbackground-color: red;\n\t}\n\tdiv.head .rect2 {\n\t\tbackground-color: darkgreen;\n\t}\n\tdiv.head .rect3 {\n\t\tbackground-color: olive;\n\t}\n\t\n\tdiv.head {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\t--height: 30px;\n\t\tbackground-color: darkgreen;\n\t\tpadding: 4px;\n\t\tcursor: move;\n\t}\n\tdiv.head:hover {\n\t\tfilter: brightness(110%);\n\t}\n\t\n\tdiv.head span {\n\t\tfont-size: 12px;\n\t\tposition: relative;\n\t}\n\t\n\tdiv.head span.title {\n\t\tcolor: #ddd;\n\t\tmargin-left: 4px;\n\t\tfont-weight: bold;\n\t}\n\t\n\tdiv.head span.sub-title {\n\t\tcolor: #ccc;\n\t\tmargin-left: 8px;\n\t\tfont-style: italic;\n\t}\n\t\n\tdiv.head form {\n\t\tmargin: 0;\n\t}\n\tdiv.head button {\n\t\tmargin-right: 4px;\n\t\tbackground-color: transparent;\n\t\tborder: none;\n\t\tcolor: #ccc;\n\t\tfont-size: x-small;\n\t}\n\tdiv.head button:hover {\n\t\tcursor: pointer;\n\t}\n\t\n\tdiv.contents {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\toverflow: hidden;\n\t}\n\tdiv.left {\n\t\tposition: relative;\n\t\twidth: 16px;\n\t\theight: 100%;\n\t\tbackground-color: #ddd;\n\t\tdisplay: none;\n\t}\n\t\n\tdiv.left span {\n\t\twriting-mode: vertical-rl;\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t\tuser-select: none;\n\t\tcolor: #ccc;\n\t\tfont-weight: 700;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tmargin-left: 3px;\n\t\tmargin-top: 3px;\n\t}\n\tdiv.close2 {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\tright: 0;\n\t\ttop: 3px;\n\t\tcursor: pointer;\n\t\tcolor: #666;\n\t}\n\tdiv.close2 svg:hover {\n\t\tcolor: #999;\n\t}\n\t\n\tdiv.body {\n\t\tdisplay: flex;\n\t\twidth: 100%;\n\t\theight: unset;\n\t\t--border: 3px solid #999;\n\t\t--border-top: none;\n\t\toverflow-x: hidden;\n\t\toverflow-y: auto;\n\t\tpadding: 10px;\n\t\tgap: 8px;\n\t\tflex-direction: column;\n\t}\n\t\n\t\n\t\n\t\n\tng-sphere.icon {\n\t\tmargin-left: 8px;\n\t}\n\t\n\t.buttons {\n\t\tdisplay: flex;\n\t\tposition: absolute;\n\t\tright: 4px;\n\t}\n\t\n\tng-sphere {\n\t\tposition: relative;\n\t\t--width: 16px;\n\t\t--height: 16px;\n\t\tcursor: pointer;\n\t\tmargin-right: 4px;\n\t\tdisplay: flex;\n\t}\n\tng-sphere:hover {\n\t\tfilter: brightness(90%);\n\t}\n\tng-sphere:active {\n\t\tfilter: brightness(80%);\n\t}\n\t\n\tng-sphere:hover::after {\n\t\tcontent: "";\n\t\tposition: absolute;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: center;\n\t}\n\tng-sphere.apply:hover::after {\n\t\tbackground-size: 14px 14px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><polyline points="2.5,7 6,10 11,3" style="fill:none;stroke:white;stroke-width:2px;" /></svg>');\n\t}\n\t\n\tng-sphere.reset:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true"><path d="M10 5h5V0"></path><path d="M15 8a6.957 6.957 0 0 1-7 7 6.957 6.957 0 0 1-7-7 6.957 6.957 0 0 1 7-7 6.87 6.87 0 0 1 6.3 4"></path></svg>');\n\t}\n\t\n\tng-sphere.close:hover::after {\n\t\tbackground-size: 12px 12px;\n\t\tbackground-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" style="fill:none;stroke:white;stroke-width:2px;" focusable="false" aria-hidden="true" viewBox="0 0 16 16"><path d="M2 2l12 12M14 2L2 14"></path></svg>');\n\t}\n\t\n\t\n\tbutton {\n cursor: pointer;\n }\n \n .input-area {\n position: relative;\n height: 100%;\n --display: flex;\n textarea {\n width: 100%;\n height: 100%;\n min-height: 100px;\n padding: 8px;\n box-sizing: border-box;\n resize: none;\n border-radius: 2px;\n border-color: #ccc;\n }\n textarea:focus {\n border-color: green;\n outline: none; /* 브라우저 기본 파란색 테두리 제거 */\n }\n }\n \n .buttons-confirm {\n position: relative;\n display: flex;\n justify-content: flex-end;\n --bottom: 8px;\n --right: 8px;\n }\n \n \n .buttons-confirm button {\n height: 32px;\n margin-right: 8px;\n border: none;\n outline: none;\n width: 60px;\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n }\n .buttons-confirm button:hover {\n filter: brightness(90%);\n }\n .buttons-confirm button:active {\n color: #ccc;\n }\n \n button.ok {\n --display: none;\n background-color: darkgreen;\n color: white;\n }\n button.cancel {\n color: white;\n background-color: #6c757d;\n }\n \n \n \n div.msg {\n position: relative;\n height: 100%;\n font-size: 14px;\n color: #333;\n }\n \n .reset, .apply {\n display: none;\n }\n \n \n \n :host(.classic) dialog:modal {\n border: 1px solid #007bff;\n box-shadow: 0 0 4px 0 #007bff;\n }\n \n :host(.classic) div.head {\n background-color: #007bff;\n }\n :host(.classic) div.head:hover {\n filter: brightness(110%);\n }\n \n :host(.classic) div.head span {\n font-size: 12px;\n }\n \n :host(.classic) div.head span.title {\n color: #ddd;\n margin-left: 4px;\n font-weight: bold;\n }\n \n :host(.classic) div.head span.sub-title {\n color: #ccc;\n margin-left: 8px;\n font-style: italic;\n }\n :host(.classic) div.head button {\n margin-right: 4px;\n background-color: transparent;\n border: none;\n color: #ccc;\n font-size: x-small;\n }\n \n \n \n \n :host(.rgb) dialog:modal {\n border: none;\n box-shadow: unset;\n border-top: none;\n }\n \n :host(.rgb) div.left {\n display: block;\n background-color: #ddd;\n }\n :host(.rgb) div.left span {\n color: #ccc;\n }\n :host(.rgb) div.close2 {\n display: block;\n color: #666;\n }\n :host(.rgb) div.close2 svg:hover {\n color: #999;\n }\n :host(.rgb) div.head {\n height: 4px;\n background-color: #999;\n padding: 0;\n }\n :host(.rgb) div.contents {\n height: calc(100% - 4px);\n }\n \n :host(.rgb) div.head ng-sphere,\n :host(.rgb) div.head span,\n :host(.rgb) div.head .buttons {\n display: none;\n }\n \n :host(.rgb) div.head .rect1,\n :host(.rgb) div.head .rect2,\n :host(.rgb) div.head .rect3 {\n display: flex;\n }\n \n \n :host(.rgb) div.head:hover {\n filter: unset;\n }\n \n \n /* --- Animation Core --- */\n:host {\n --nx-duration: 0.4s;\n --nx-timing: cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n\n/* 🎯 수정: 애니메이션 클래스가 붙은 경우에만 초기 opacity를 0으로 설정 */\n:host(.fade) dialog,\n:host(.zoom) dialog,\n:host(.moveUp) dialog,\n:host(.moveDown) dialog,\n:host(.moveLeft) dialog,\n:host(.moveRight) dialog,\n:host(.roadRunner) dialog {\n opacity: 0;\n}\n\n/* shake는 애니메이션 내부에서 opacity를 다루므로 제외하거나 별도 처리 */\n:host(.shake) dialog { \n opacity: 1; \n}\n\n/* 1. Fade (서서히 나타남) */\n:host(.fade) dialog { animation: nx-fade-in var(--nx-duration) forwards; }\n@keyframes nx-fade-in { from { opacity: 0; } to { opacity: 1; } }\n\n/* 2. Zoom (커지며 나타남) */\n:host(.zoom) dialog { animation: nx-zoom-in var(--nx-duration) var(--nx-timing) forwards; }\n@keyframes nx-zoom-in { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } }\n\n/* 3. Slide (상하좌우) */\n:host(.moveUp) dialog { animation: nx-move-up var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveDown) dialog { animation: nx-move-down var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveLeft) dialog { animation: nx-move-left var(--nx-duration) var(--nx-timing) forwards; }\n:host(.moveRight) dialog { animation: nx-move-right var(--nx-duration) var(--nx-timing) forwards; }\n\n@keyframes nx-move-up { from { opacity: 0; transform: translateY(100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-down { from { opacity: 0; transform: translateY(-100px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes nx-move-left { from { opacity: 0; transform: translateX(100px); } to { opacity: 1; transform: translateX(0); } }\n@keyframes nx-move-right { from { opacity: 0; transform: translateX(-100px); } to { opacity: 1; transform: translateY(0); } }\n\n/* 4. Shake (상하좌우 격렬한 진동 - 에러 인지용) */\n:host(.shake) dialog { \n animation: nx-heavy-shake 0.5s cubic-bezier(.36,.07,.19,.97) both;\n opacity: 1; \n}\n\n@keyframes nx-heavy-shake {\n 10%, 90% { transform: translate3d(-1px, -2px, 0); }\n 20%, 80% { transform: translate3d(2px, 4px, 0); }\n 30%, 50%, 70% { transform: translate3d(-6px, -6px, 0); }\n 40%, 60% { transform: translate3d(6px, 6px, 0); }\n}\n\n/* 5. Road Runner (등장: 왼쪽에서 탄력 있게 / 퇴장: 움츠렸다가 광속 탈출) */\n:host(.roadRunner) dialog { \n animation: roadRunnerIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; \n}\n\n@keyframes roadRunnerIn {\n 0% { transform: translateX(-1500px) skewX(30deg); opacity: 1; }\n 70% { transform: translateX(30px) skewX(-10deg); opacity: 1; }\n 100% { transform: translateX(0) skewX(0deg); opacity: 1; }\n}\n\n/* --- Out Animations (닫힐 때) --- */\ndialog.out { pointer-events: none; }\n\n/* Road Runner 퇴장: 슥 움츠렸다가(Anticipation) 쌩~! */\n:host(.roadRunner) dialog.out { \n animation: roadRunnerOut 0.5s cubic-bezier(0.6, -0.28, 0.735, 0.045) forwards; \n}\n\n@keyframes roadRunnerOut {\n 0% { \n transform: translateX(0) scale(1) skewX(0deg); \n opacity: 1; \n }\n 30% { \n /* 예비 동작: 뒤로 살짝 갔다가 움츠러들기 */\n transform: translateX(50px) scaleX(1.2) scaleY(0.8) skewX(-20deg); \n opacity: 1; \n }\n 100% { \n /* 발사: 길게 늘어나며 광속 탈출 */\n transform: translateX(2000px) scaleX(4) scaleY(0.3) skewX(50deg); \n opacity: 0; \n filter: blur(10px); /* 👈 잔상 느낌 추가 */\n }\n}\n\n/* 일반 퇴장 (기본) */\ndialog.out { animation: nx-fade-out 0.3s forwards; }\n@keyframes nx-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.9); } }\n</style>\n\t\t\n\t\t\t<dialog>\n\t\t\t\t<div class="head">\n\t\t\t\t\t<div class="rect1"></div>\n\t\t\t\t\t<div class="rect2"></div>\n\t\t\t\t\t<div class="rect3"></div>\n\t\t\t\t\t<ng-sphere class="icon" end-fill="#666" size="8"></ng-sphere>\n\t\t\t\t\t<span class="title">${n}</span>\n\t\t\t\t\t<span class="sub-title"></span>\n\t\t\t\t\t<div class="buttons">\n\t\t\t\t\t\t<ng-sphere class="apply" start-fill="#cc6" end-fill="#660" size="16" title="apply"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="reset" start-fill="#99f" end-fill="#00f" size="16" title="reset"></ng-sphere>\n\t\t\t\t\t\t<ng-sphere class="close" start-fill="#f99" end-fill="#f00" size="16" title="close"></ng-sphere>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="contents">\n\t\t\t\t\t<div class="left">\n\t\t\t\t\t\t<span>가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하가나다라마바사아자차카타파하</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="body">\n\t\t\t\t\t\t${t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class="close2">\n\t\t\t\t\t\t<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">\n\t\t\t\t\t\t\t<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</dialog>\n\t\t`,B(this,e,this.querySelector("dialog")),$(this,o).call(this)}closeWithAnimation(t){$(this,e).classList.add("out"),setTimeout(()=>{$(this,e).close(),this.dispatchEvent(new CustomEvent("closed",{detail:t})),this.remove()},300)}}n=new WeakMap,e=new WeakMap,o=new WeakMap,i=new WeakMap,s=new WeakMap;class O extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}static async open(t,n,e,o,i){var s,a,r;const l=t.tagName.toLowerCase(),c={"true-text":"확인","false-text":"취소",class:"classic",animation:"fade",...(null==(r=null==(a=null==(s=window.nine)?void 0:s.config)?void 0:a.ux)?void 0:r[l.replace("nine-","").replace("-popup","")])||{},...o};document.querySelectorAll(l).forEach(t=>t.remove());const d=document.createElement(l);c.class&&d.classList.add(c.class),c.animation&&d.classList.add(c.animation),document.body.appendChild(d),i(d,n,c);const h=d.shadowRoot.querySelector("nine-dialog");return e&&h.setAttribute("title",e),new Promise(t=>{h.addEventListener("closed",n=>t(n.detail)),d.setupEvents(t,h),h.showModal()})}}customElements.get("nine-dialog")||customElements.define("nine-dialog",X);const F=class extends O{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(!0)}};R(F,"tagName","nine-confirm-popup"),R(F,"confirm",(t,n,e)=>O.open(F,t,n,e,(t,n,e)=>t.render(n,e)));let I=F;const j=class extends O{constructor(){super()}render(t,n){this.shadowRoot.innerHTML=`\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="buttons-confirm">\n <button class="cancel">확인</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){}};R(j,"tagName","nine-alert-popup"),R(j,"alert",(t,n,e)=>O.open(j,t,n,e,(t,n,e)=>t.render(n,e)));let H=j;customElements.get("nine-confirm-popup")||customElements.define("nine-confirm-popup",I),customElements.get("nine-alert-popup")||customElements.define("nine-alert-popup",H);const Y=class extends O{constructor(){super()}render(t,n){trace.log(this),trace.log(this.shadowRoot),this.shadowRoot.innerHTML=`\n\t\t\t<style>\n\t\t\t\tdialog {\n\t\t\t\t\theight: 300px !important;\n\t\t\t\t}\n\t\t\t\t.msg {\n\t\t\t\t\theight: unset !important;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n <nine-dialog>\n <div class="msg">${t.replace(/\n/g,"<br/>")}</div>\n <div class="input-area">\n <textarea placeholder="내용을 입력하세요..."></textarea>\n </div>\n <div class="buttons-confirm">\n <button class="cancel">${n["false-text"]}</button>\n <button class="ok">${n["true-text"]}</button>\n </div>\n </nine-dialog>`}setupEvents(t,n){const e=this.shadowRoot.querySelector("textarea");this.shadowRoot.querySelector(".ok").onclick=()=>n.closeWithAnimation(e.value),requestAnimationFrame(()=>e.focus())}};R(Y,"tagName","nine-prompt-popup"),R(Y,"prompt",(t,n,e)=>O.open(Y,t,n,e,(t,n,e)=>t.render(n,e)));let q=Y;customElements.get("nine-prompt-popup")||customElements.define("nine-prompt-popup",q);class D{constructor(){S(this,a)}alert(t,n="Alert"){return z(this,a,r).call(this,"alert",t,n,"classic")}confirm(t,n="Confirm"){return z(this,a,r).call(this,"confirm",t,n,"classic")}prompt(t,n="Prompt"){return z(this,a,r).call(this,"prompt",t,n,"classic")}}a=new WeakSet,r=function(t,n,e,o){const i={class:o,animation:"fade"};let s=!1;const a={alert:H,confirm:I,prompt:q}[t],r={rgb:()=>(i.class="rgb",r),classic:()=>(i.class="classic",r),shake:()=>(i.animation="shake",r),run:()=>(i.animation="roadRunner",r),zoom:()=>(i.animation="zoom",r),then:(o,r)=>(s=!0,a[t](n,e,i).then(o,r))};return Promise.resolve().then(()=>{s||(s=!0,a[t](n,e,i))}),r},R(D,"cssPath","");class G{constructor(t=null,n="green"){S(this,h),S(this,l),S(this,c),S(this,d,!0),B(this,l,t),B(this,c,n),z(this,h,p).call(this)}initBAK(t,n="green"){B(this,l,t),B(this,c,n)}init(t,n="green"){return B(this,l,t),B(this,c,n),this}get log(){const t=`color: ${$(this,c)}; font-weight: bold;`;return $(this,l)?console.log.bind(console,`%c[${$(this,l)}]`,t):console.log.bind(console)}get warn(){return $(this,d)?$(this,l)?console.warn.bind(console,`%c[${$(this,l)}]`,"color: cyan; font-weight: bold;"):console.warn.bind(console):()=>{}}get error(){return $(this,l)?console.error.bind(console,`%c[${$(this,l)}]`,"color: red; font-weight: bold;"):console.error.bind(console)}enable(){B(this,d,!0)}disable(){B(this,d,!1)}}l=new WeakMap,c=new WeakMap,d=new WeakMap,h=new WeakSet,p=function(){if("undefined"==typeof window)return;"localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.startsWith("192.168.")?this.enable():(this.disable(),console.log(`%c[${$(this,l)||"Trace"}]%c 운영 모드: 로그 비활성화. %ctrace.enable()%c 로 활성화 가능`,"color: #4CAF50; font-weight: bold;","","background: #333; color: yellow; padding: 2px 5px;",""))};const K=new G;"undefined"!=typeof window&&(window.trace=K);g=new WeakMap,u=new WeakMap,m=new WeakMap,f=new WeakSet,v=function(){if(0===$(this,u).length)return;const t=$(this,u).splice(0,$(this,u).length),n=new Set;t.forEach(t=>{const e=`${t.func.name}_${JSON.stringify(t.args)}`;n.has(e)||(t.func(...t.args),n.add(e))}),B(this,g,null)};class U{static show(){let t=document.getElementById("global-loading-overlay");if(!t&&(t=document.createElement("div"),t.id="global-loading-overlay",t.style.cssText="\n position: fixed; inset: 0; z-index: 9999;\n background: rgba(0, 0, 0, 0.4); display: flex; \n justify-content: center; align-items: center;\n backdrop-filter: blur(2px);\n ",t.innerHTML='<div class="loading-spinner"></div>',document.body.appendChild(t),!document.getElementById("nine-util-style"))){const t=document.createElement("style");t.id="nine-util-style",t.innerHTML="\n .loading-spinner {\n width: 48px; height: 48px;\n border: 5px solid rgba(255, 255, 255, 0.3);\n border-top-color: white; border-radius: 50%;\n animation: nine-spin 1s linear infinite;\n }\n @keyframes nine-spin { to { transform: rotate(360deg); } }\n ",document.head.appendChild(t)}t.style.display="flex"}static hide(){const t=document.getElementById("global-loading-overlay");t&&(t.style.display="none")}}const J=class{};w=new WeakMap,R(J,"BASE_URL",window.__API_BASE_URL__||""),S(J,w,(t,n,e={},o=!0)=>{const i=n.startsWith("http")?n:`${J.BASE_URL}${n}`;o&&U.show();const s={};e instanceof FormData||(s["Content-Type"]="application/json");const a={method:t,headers:s};let r=i;return"GET"===t?r+=`?${new URLSearchParams(e)}`:a.body=e instanceof FormData?e:JSON.stringify(e),fetch(r,a).then(async t=>{if(!t.ok){const n=await t.text();throw new Error(`API 오류 (${t.status}): ${n}`)}return t.json()}).catch(n=>{throw K.error(`[IdeFetch.${t.toLowerCase()}] ${i} 실패:`,n),n}).finally(()=>{o&&U.hide()})}),R(J,"get",(t,n={},e=!0)=>{var o;return $(o=J,w).call(o,"GET",t,n,e)}),R(J,"post",(t,n={},e=!0)=>{var o;return $(o=J,w).call(o,"POST",t,n,e)}),R(J,"postMultipart",async(t,n=[],e={})=>{const{fileKey:o="fileContents",filePartName:i="files",jsonPartName:s="dataList",chunkSize:a=10}=e;U.show();let r=0,l=null;return(async()=>{for(let e=0;e<n.length;e+=a){const c=new FormData,d=n.slice(e,e+a),h=[];d.forEach(t=>{const{[o]:n,_fileObj:e,...s}=t;h.push(s),n instanceof File&&c.append(i,n)});const p=new Blob([JSON.stringify(h)],{type:"application/json"});if(c.append(s,p),l=await J.post(t,c,!1),!l||!l.success&&"OK"!==l.status)throw new Error(`청크 전송 실패: ${e}번째 섹션`);r+=d.length}return{...l,success:!0,totalCount:r}})().catch(t=>{throw K.error("[postChunk] Error:",t),t}).finally(()=>{U.hide()})});let V=J;const Z=V;class Q extends HTMLElement{constructor(){super(),S(this,b),S(this,x,t=>{const n=t.previousElementSibling,e=t.nextElementSibling;if(!n||!e)return void B(this,b,this.classList.contains("h")?"h":"v");const o=n.getBoundingClientRect(),i=e.getBoundingClientRect();this.classList.contains("h")?B(this,b,"h"):this.classList.contains("v")?B(this,b,"v"):B(this,b,Math.abs(o.top-i.top)<5?"h":"v")}),S(this,y,t=>{t.preventDefault(),t.stopPropagation();const n=this.getBoundingClientRect(),e="h"===$(this,b),o=e?t.clientX-n.left:t.clientY-n.top,i=document.createElement("div");i.className=`nx-splitter-drag-bar-${$(this,b)}`,Object.assign(i.style,{position:"absolute",zIndex:"999",background:"#666",opacity:"0.6",pointerEvents:"none"});const s=this.getRootNode({composed:!0}),a=s instanceof ShadowRoot?s.host:this.parentElement,r=this.previousElementSibling,l=this.nextElementSibling;if(!a||!r||!l)return void K.warn("Spliter's parent or siblings not found.");(a.shadowRoot||a).appendChild(i);const c=i.offsetParent.getBoundingClientRect(),d=r.getBoundingClientRect(),h=l.getBoundingClientRect(),p=(e?n.left-c.left:n.top-c.top)+o;e?(i.style.top="0",i.style.left=`${p}px`,i.style.width="2px",i.style.height="100%"):(i.style.left="0",i.style.top=`${p}px`,i.style.height="2px",i.style.width="100%"),i.style.mixBlendMode="difference",i.style.zIndex="99999";const g=e?d.left-c.left:d.top-c.top,u=e?h.right-c.left-n.width:h.bottom-c.top-n.height,m=t=>{const n=e?t.clientX:t.clientY,o=e?n-c.left:n-c.top,s=Math.max(g,Math.min(o,u));e?i.style.left=`${s}px`:i.style.top=`${s}px`},f=()=>{window.removeEventListener("mousemove",m),window.removeEventListener("mouseup",f),i.remove();const t=Array.from(a.children),n=t.filter(t=>"nx-splitter"!==t.tagName.toLowerCase()),o=window.getComputedStyle(a),s=e?o.getPropertyValue("column-gap"):o.getPropertyValue("row-gap"),c=parseFloat(s)||0,d=(t.length>1?t.length-1:0)*c,h=(e?parseFloat(i.style.left):parseFloat(i.style.top))-p,g=e?r.getBoundingClientRect().width:r.getBoundingClientRect().height,u=e?l.getBoundingClientRect().width:l.getBoundingClientRect().height;let v=g+h,w=u-h;v<0&&(w+=v,v=0),w<0&&(v+=w,w=0);const b=n.map(t=>e?t.getBoundingClientRect().width:t.getBoundingClientRect().height),x=t.reduce((t,n)=>"nx-splitter"===n.tagName.toLowerCase()?t+(e?n.getBoundingClientRect().width:n.getBoundingClientRect().height):t,0),y=(e?a.getBoundingClientRect().width:a.getBoundingClientRect().height)-x-d;let k=0;n.forEach((t,n)=>{let e;e=t===r?v:t===l?w:b[n];const o=e/y;K.log(t),t.classList.contains("sidebar")?t.style.flex=`0 0 ${e}px`:t.style.flex=`${o} ${o} 0`,k+=o}),K.log(`dragOffset: ${h}`),K.log(`Calculated FlexSum: ${k}`)};window.addEventListener("mousemove",m),window.addEventListener("mouseup",f)}),S(this,k,()=>{$(this,x).call(this,this),this.classList.add($(this,b));const t=this.innerHTML.trim(),n=""===t?'<div class="grip"></div>':`<div class="grip"></div><div class="inner-container">${t}</div><div class="grip"></div>`;this.innerHTML="";const e=document.createElement("template");e.innerHTML=`\n\t\t\t<style>\n\t\t\t\t@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-util@0.9.125/dist/css/nine-util.css";\n\t\t\t\t${this.cssPath?`@import "${this.cssPath}";`:""}\n\t\t\t</style>\n\t\t\t${n}\n `,this.shadowRoot.appendChild(e.content.cloneNode(!0)),this.shadowRoot.querySelectorAll(".grip").forEach(t=>{t.addEventListener("mousedown",t=>$(this,y).call(this,t))}),$(this,E).call(this),window.addEventListener("resize",()=>$(this,E).call(this))}),S(this,E,()=>{const t="h"===$(this,b),n=this.parentElement,e=Array.from(n.children).filter(t=>"nx-splitter"!==t.tagName.toLowerCase());if(e.length<2)return;const o=n.getBoundingClientRect(),i=e.reduce((n,e)=>n+(t?e.getBoundingClientRect().width:e.getBoundingClientRect().height),0),s=t?o.width:o.height;e.forEach(n=>{const e=t?n.getBoundingClientRect().width:n.getBoundingClientRect().height,o=s*(e/i)/s;n.style.flex=`${o} ${o} 0`})}),this.attachShadow({mode:"open"})}connectedCallback(){$(this,k).call(this)}get cssPath(){return this.getAttribute("css-path")||D.cssPath}}b=new WeakMap,x=new WeakMap,y=new WeakMap,k=new WeakMap,E=new WeakMap,customElements.get("nine-splitter")||customElements.define("nine-splitter",Q);const tt=new D;N.alert=tt.alert.bind(tt),N.confirm=tt.confirm.bind(tt),N.prompt=tt.prompt.bind(tt),N.api=Z,N.trace=K,N.subscribeConfig=W,N.config=_||{},"undefined"!=typeof window&&(window.nine=N),t.Fetch=V,t.NineUtil=D,t.TaskDebouncer=class{constructor(t=50){S(this,f),S(this,g,null),S(this,u,[]),S(this,m),B(this,m,t)}exec(t,...n){$(this,u).push({func:t,args:n}),$(this,g)&&clearTimeout($(this,g)),B(this,g,setTimeout(()=>z(this,f,v).call(this),$(this,m)))}execWithKey(t,n,...e){B(this,u,$(this,u).filter(n=>n.key!==t)),$(this,u).push({key:t,func:n,args:e}),$(this,g)&&clearTimeout($(this,g)),B(this,g,setTimeout(()=>z(this,f,v).call(this),$(this,m)))}},t.Trace=G,t.api=Z,t.config=_,t.loading=U,t.nine=N,t.nineAlertPopup=H,t.nineConfirmPopup=I,t.nineDialog=X,t.ninePromptPopup=q,t.subscribeConfig=W,t.trace=K,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
|
|
2
2
|
//# sourceMappingURL=nine-util.umd.js.map
|