1(function () { 2 var scripts = document.getElementsByTagName('script'); 3 var currentScript = scripts[scripts.length - 1]; 4 var storeId = currentScript.getAttribute('data-store'); 5 var localStore = currentScript.getAttribute('data-store-local'); 6 var host = location.hostname; 7 // ë¡ì»¬Â·ì¤í ì´ì§ DBìë timeplex ì¬ë¡¯ì´ ìì. ê°ë° í¸ì¤í¸ë§ ëì²´ 매ì¥ì¼ë¡ ì°ë¤. 8 if (localStore && (host === 'localhost' || host === '127.0.0.1' || host === 'dev-chat.timeplex.ai')) { 9 storeId = localStore; 10 } 11 var scriptSrc = currentScript.src || ''; 12 var apiBase = scriptSrc.replace(/\/widget\.js(?:\?.*)?$/i, '') || 'https://chat.timeplex.ai'; 13 14 if (!storeId) return; 15 16 var chatIcon = '<svg width="26" height="26" viewBox="0 0 24 24" fill="white" aria-hidden="true">' + 17 '<path d="M20 2H4C2.9 2 2 2.9 2 4V22L6 18H20C21.1 18 22 17.1 22 16V4C22 2.9 21.1 2 20 2Z"/>' + 18 '</svg><span id="tpx-badge"></span>'; 19 var closeIcon = '<svg width="22" height="22" viewBox="0 0 24 24" fill="white" aria-hidden="true">' + 20 '<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>' + 21 '</svg>'; 22 23 var styleEl = document.createElement('style'); 24 styleEl.textContent = [ 25 '#tpx-btn{position:fixed;bottom:24px;right:24px;width:56px;height:56px;', 26 'background:#1e5b43;border:0;border-radius:50%;display:flex;align-items:center;', 27 'justify-content:center;cursor:pointer;z-index:99999;padding:0;', 28 'box-shadow:0 8px 24px rgba(30,91,67,.32);', 29 'transition:background .18s ease,box-shadow .18s ease;}', 30 '#tpx-btn:hover:not(.is-pop){transform:scale(1.06);background:#14432e;', 31 'box-shadow:0 10px 28px rgba(20,67,46,.4);', 32 'transition:transform .18s ease,background .18s ease,box-shadow .18s ease;}', 33 '#tpx-btn:focus-visible{outline:2px solid #d4ad3a;outline-offset:3px;}', 34 '#tpx-btn.is-pop{animation:tpx-btn-pop .36s ease-in-out;}', 35 '@keyframes tpx-btn-pop{0%{transform:scale(1);box-shadow:0 8px 24px rgba(30,91,67,.32)}', 36 '42%{transform:scale(.88);box-shadow:0 4px 14px rgba(30,91,67,.2)}', 37 '100%{transform:scale(1);box-shadow:0 8px 24px rgba(30,91,67,.32)}}', 38 '@media(prefers-reduced-motion:reduce){#tpx-btn.is-pop{animation:none;}', 39 '#tpx-btn:hover:not(.is-pop){transition:none;}}', 40 '#tpx-badge{position:absolute;top:-4px;right:-4px;background:#c23c3c;', 41 'color:#fff;border-radius:10px;padding:2px 6px;font-size:11px;', 42 'font-weight:700;display:none;', 43 'font-family:Pretendard,-apple-system,BlinkMacSystemFont,system-ui,sans-serif;}', 44 '#tpx-frame{position:fixed;bottom:92px;right:24px;width:380px;', 45 'height:min(640px,calc(100vh - 128px));border:1px solid #e6efe9;', 46 'border-radius:20px;z-index:99998;background:#fff;overflow:hidden;', 47 'box-shadow:0 18px 48px rgba(15,31,23,.16);', 48 'opacity:0;visibility:hidden;pointer-events:none;', 49 'transform:translateY(12px) scale(.98);transform-origin:bottom right;', 50 'transition:opacity .22s ease,transform .22s ease,visibility .22s;}', 51 '#tpx-frame.is-open{opacity:1;visibility:visible;pointer-events:auto;transform:none;}', 52 '@media(max-width:480px){', 53 '#tpx-btn{bottom:20px;right:16px;}', 54 '#tpx-frame{width:100vw;height:100%;height:100dvh;bottom:0;right:0;', 55 'border:0;border-radius:0;transform:translateY(16px);}', 56 '#tpx-frame.is-open{transform:none;}}' 57 ].join(''); 58 document.head.appendChild(styleEl); 59 60 var btn = document.createElement('button'); 61 btn.id = 'tpx-btn'; 62 btn.type = 'button'; 63 btn.setAttribute('aria-label', 'ìë´ ìì'); 64 btn.setAttribute('aria-expanded', 'false'); 65 btn.innerHTML = chatIcon; 66 document.body.appendChild(btn); 67 68 var frame = document.createElement('iframe'); 69 frame.id = 'tpx-frame'; 70 frame.title = 'Timeplex ìë´'; 71 frame.src = apiBase + '/store/' + storeId; 72 document.body.appendChild(frame); 73 74 var isOpen = false; 75 function setOpen(next) { 76 isOpen = next; 77 if (isOpen) frame.classList.add('is-open'); 78 else frame.classList.remove('is-open'); 79 btn.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); 80 btn.setAttribute('aria-label', isOpen ? 'ìë´ ë«ê¸°' : 'ìë´ ìì'); 81 btn.innerHTML = isOpen ? closeIcon : chatIcon; 82 var badge = document.getElementById('tpx-badge'); 83 if (badge) badge.style.display = 'none'; 84 } 85 86 function popBtn() { 87 btn.classList.remove('is-pop'); 88 void btn.offsetWidth; 89 btn.classList.add('is-pop'); 90 } 91 btn.addEventListener('animationend', function (e) { 92 if (e.animationName === 'tpx-btn-pop') btn.classList.remove('is-pop'); 93 }); 94 btn.addEventListener('click', function () { 95 popBtn(); 96 setOpen(!isOpen); 97 }); 98 99 window.addEventListener('message', function (e) { 100 if (!e.data) return; 101 if (e.data.type === 'timeplex_close') setOpen(false); 102 if (e.data.type === 'timeplex_unread' && !isOpen) { 103 var badge = document.getElementById('tpx-badge'); 104 if (badge && e.data.count > 0) { 105 badge.style.display = 'block'; 106 badge.textContent = e.data.count; 107 } 108 } 109 }); 110})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.