Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Update app.py
Browse files
app.py
CHANGED
@@ -1569,7 +1569,7 @@ HTML = """
|
|
1569 |
</div>
|
1570 |
</section>
|
1571 |
|
1572 |
-
|
1573 |
let projects=[], fb=null;
|
1574 |
const grid=document.getElementById('grid'), viewer=document.getElementById('viewer');
|
1575 |
pdfjsLib.GlobalWorkerOptions.workerSrc='/static/pdf.worker.js';
|
@@ -1584,115 +1584,114 @@ HTML = """
|
|
1584 |
// νμ¬ μ΄λ¦° PDFμ ID
|
1585 |
let currentPdfId = null;
|
1586 |
|
1587 |
-
// μ€λμ€ μ»¨ν
μ€νΈμ μ΄κΈ°ν μν κ΄λ¦¬
|
1588 |
-
let audioInitialized = false;
|
1589 |
-
let audioContext = null;
|
1590 |
|
1591 |
-
// μ€λμ€ μ΄κΈ°ν ν¨μ
|
1592 |
-
function initializeAudio() {
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
|
1611 |
-
|
1612 |
-
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
// μ¬μ©μ μνΈμμ©μ΄ νμν κ²½μ°, μ΄λ²€νΈ 리μ€λ μΆκ°
|
1619 |
-
const initOnUserAction = function() {
|
1620 |
-
const tempAudio = new Audio('/static/turnPage2.mp3');
|
1621 |
-
tempAudio.volume = 0.01;
|
1622 |
-
tempAudio.play()
|
1623 |
-
.then(() => {
|
1624 |
-
tempAudio.pause();
|
1625 |
-
audioInitialized = true;
|
1626 |
-
console.log('μ¬μ©μ μνΈμμ©μΌλ‘ μ€λμ€ μ΄κΈ°ν μ±κ³΅');
|
1627 |
-
resolve();
|
1628 |
-
|
1629 |
-
// μ΄λ²€νΈ 리μ€λ μ κ±°
|
1630 |
-
['click', 'touchstart', 'keydown'].forEach(event => {
|
1631 |
-
document.removeEventListener(event, initOnUserAction, { capture: true });
|
1632 |
-
});
|
1633 |
-
})
|
1634 |
-
.catch(e => console.error('μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
1635 |
-
};
|
1636 |
-
|
1637 |
-
// μ¬μ©μ μνΈμμ© μ΄λ²€νΈμ 리μ€λ μΆκ°
|
1638 |
-
['click', 'touchstart', 'keydown'].forEach(event => {
|
1639 |
-
document.addEventListener(event, initOnUserAction, { once: true, capture: true });
|
1640 |
-
});
|
1641 |
-
|
1642 |
-
// νμ΄μ§ λ‘λ μ§ν μ¬μ©μμκ² μ€λμ€ νμ±ν μμ²
|
1643 |
-
if (window.location.pathname.startsWith('/view/')) {
|
1644 |
-
// μ€λμ€ νμ±ν μλ΄ λ©μμ§ νμ (λ°λ‘κ°κΈ° λ§ν¬λ‘ μ μν κ²½μ°)
|
1645 |
-
setTimeout(() => {
|
1646 |
-
const audioPrompt = document.createElement('div');
|
1647 |
-
audioPrompt.style.position = 'fixed';
|
1648 |
-
audioPrompt.style.bottom = '80px';
|
1649 |
-
audioPrompt.style.left = '50%';
|
1650 |
-
audioPrompt.style.transform = 'translateX(-50%)';
|
1651 |
-
audioPrompt.style.backgroundColor = 'rgba(0,0,0,0.7)';
|
1652 |
-
audioPrompt.style.color = 'white';
|
1653 |
-
audioPrompt.style.padding = '10px 20px';
|
1654 |
-
audioPrompt.style.borderRadius = '20px';
|
1655 |
-
audioPrompt.style.zIndex = '10000';
|
1656 |
-
audioPrompt.style.cursor = 'pointer';
|
1657 |
-
audioPrompt.innerHTML = 'νμ΄μ§ μ΄λλ ν΄λ¦νμ¬ μ리 ν¨κ³Ό νμ±ν <i class="fas fa-volume-up"></i>';
|
1658 |
-
audioPrompt.id = 'audioPrompt';
|
1659 |
|
1660 |
-
//
|
1661 |
-
|
1662 |
-
|
1663 |
-
|
1664 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1665 |
|
1666 |
-
|
|
|
|
|
|
|
1667 |
|
1668 |
-
//
|
1669 |
-
|
1670 |
-
|
1671 |
-
|
1672 |
-
|
1673 |
-
|
1674 |
-
|
1675 |
-
|
1676 |
-
|
1677 |
-
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1681 |
}
|
1682 |
-
});
|
1683 |
-
}
|
1684 |
-
|
1685 |
-
// νμ΄μ§ λ‘λ μ μ€λμ€ μ΄κΈ°ν μλ
|
1686 |
-
document.addEventListener('DOMContentLoaded', initializeAudio);
|
1687 |
|
1688 |
/* ββ μ νΈ ββ */
|
1689 |
function $id(id){return document.getElementById(id)}
|
1690 |
|
1691 |
-
//
|
1692 |
-
|
1693 |
-
document.addEventListener('DOMContentLoaded', initializeAudio);
|
1694 |
console.log("DOM λ‘λ μλ£, μ΄λ²€νΈ μ€μ μμ");
|
1695 |
|
|
|
|
|
|
|
1696 |
// PDF μ
λ‘λ λ²νΌ
|
1697 |
const pdfBtn = document.getElementById('pdfUploadBtn');
|
1698 |
const pdfInput = document.getElementById('pdfInput');
|
@@ -1727,6 +1726,28 @@ document.addEventListener('DOMContentLoaded', initializeAudio);
|
|
1727 |
|
1728 |
// κ΄λ¦¬μ λ²νΌ μ΄λ²€νΈ μ€μ
|
1729 |
setupAdminFunctions();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1730 |
});
|
1731 |
|
1732 |
// μλ²μ PDF μ
λ‘λ ν¨μ
|
@@ -1763,46 +1784,44 @@ document.addEventListener('DOMContentLoaded', initializeAudio);
|
|
1763 |
}
|
1764 |
}
|
1765 |
|
1766 |
-
function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
1767 |
-
|
1768 |
-
|
1769 |
-
|
1770 |
-
|
1771 |
-
|
1772 |
-
|
1773 |
-
|
1774 |
-
|
1775 |
-
|
1776 |
-
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
|
1784 |
-
|
1785 |
-
|
1786 |
-
|
1787 |
-
|
1788 |
-
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
1793 |
-
|
1794 |
-
|
1795 |
-
|
1796 |
-
|
1797 |
-
|
1798 |
-
|
1799 |
-
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
-
}
|
1804 |
-
|
1805 |
-
|
1806 |
|
1807 |
/* ββ νλ‘μ νΈ μ μ₯ ββ */
|
1808 |
function save(pages, title, isCached = false, pdfId = null) {
|
@@ -1963,6 +1982,9 @@ function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
|
1963 |
/* ββ PDF IDλ‘ PDF μ΄κΈ° ββ */
|
1964 |
async function openPdfById(pdfId, pdfPath, isCached = false) {
|
1965 |
try {
|
|
|
|
|
|
|
1966 |
// λ¨Όμ ν νλ©΄μμ μΉ΄λλ₯Ό μ°Ύμμ ν΄λ¦νλ λ°©λ² μλ
|
1967 |
let foundCard = false;
|
1968 |
const cards = document.querySelectorAll('.card');
|
@@ -2270,157 +2292,138 @@ function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
|
2270 |
}
|
2271 |
}
|
2272 |
|
2273 |
-
|
2274 |
-
|
2275 |
-
console.log('FlipBook μμ± μμ. νμ΄μ§ μ:', pages.length);
|
2276 |
-
|
2277 |
-
try {
|
2278 |
-
// νλ©΄ λΉμ¨ κ³μ°
|
2279 |
-
const calculateAspectRatio = () => {
|
2280 |
-
const windowWidth = window.innerWidth;
|
2281 |
-
const windowHeight = window.innerHeight;
|
2282 |
-
const aspectRatio = windowWidth / windowHeight;
|
2283 |
|
2284 |
-
// λλΉ λλ λμ΄ κΈ°μ€μΌλ‘ μ΅λ 90% μ ν
|
2285 |
-
let width, height;
|
2286 |
-
if (aspectRatio > 1) { // κ°λ‘ νλ©΄
|
2287 |
-
height = Math.min(windowHeight * 0.9, windowHeight - 40);
|
2288 |
-
width = height * aspectRatio * 0.8; // κ°λ‘ νλ©΄μμλ μ½κ° μ€μ
|
2289 |
-
if (width > windowWidth * 0.9) {
|
2290 |
-
width = windowWidth * 0.9;
|
2291 |
-
height = width / (aspectRatio * 0.8);
|
2292 |
-
}
|
2293 |
-
} else { // μΈλ‘ νλ©΄
|
2294 |
-
width = Math.min(windowWidth * 0.9, windowWidth - 40);
|
2295 |
-
height = width / aspectRatio * 0.9; // μΈλ‘ νλ©΄μμλ μ½κ° λλ¦Ό
|
2296 |
-
if (height > windowHeight * 0.9) {
|
2297 |
-
height = windowHeight * 0.9;
|
2298 |
-
width = height * aspectRatio * 0.9;
|
2299 |
-
}
|
2300 |
-
}
|
2301 |
-
|
2302 |
-
// μ΅μ μ¬μ΄μ¦ λ°ν
|
2303 |
-
return {
|
2304 |
-
width: Math.round(width),
|
2305 |
-
height: Math.round(height)
|
2306 |
-
};
|
2307 |
-
};
|
2308 |
-
|
2309 |
-
// μ΄κΈ° νλ©΄ λΉμ¨ κ³μ°
|
2310 |
-
const size = calculateAspectRatio();
|
2311 |
-
viewer.style.width = size.width + 'px';
|
2312 |
-
viewer.style.height = size.height + 'px';
|
2313 |
-
|
2314 |
-
// μ¬μ΄λ μ΄κΈ°ν μ¬λΆ νμΈ
|
2315 |
-
if (!audioInitialized) {
|
2316 |
-
initializeAudio()
|
2317 |
-
.then(() => console.log('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μλ£'))
|
2318 |
-
.catch(e => console.warn('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
2319 |
-
}
|
2320 |
-
|
2321 |
-
// νμ΄μ§ λ°μ΄ν° μ μ (λΉ νμ΄μ§ μ²λ¦¬)
|
2322 |
-
const validPages = pages.map(page => {
|
2323 |
-
// srcκ° μλ νμ΄μ§λ λ‘λ© μ€ μ΄λ―Έμ§λ‘ λ체
|
2324 |
-
if (!page || !page.src) {
|
2325 |
-
return {
|
2326 |
-
src: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZjVmNWY1Ii8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zZW0iIGZpbGw9IiM1NTUiPkxvYWRpbmcuLi48L3RleHQ+PC9zdmc+',
|
2327 |
-
thumb: page && page.thumb ? page.thumb : ''
|
2328 |
-
};
|
2329 |
-
}
|
2330 |
-
return page;
|
2331 |
-
});
|
2332 |
-
|
2333 |
-
fb = new FlipBook(viewer, {
|
2334 |
-
pages: validPages,
|
2335 |
-
viewMode: 'webgl',
|
2336 |
-
autoSize: true,
|
2337 |
-
flipDuration: 800,
|
2338 |
-
backgroundColor: '#fff',
|
2339 |
-
/* π λ΄μ₯ μ¬μ΄λ */
|
2340 |
-
sound: true,
|
2341 |
-
assets: {flipMp3: '/static/turnPage2.mp3', hardFlipMp3: '/static/turnPage2.mp3'}, // μ λ κ²½λ‘λ‘ μμ
|
2342 |
-
controlsProps: {
|
2343 |
-
enableFullscreen: true,
|
2344 |
-
enableToc: true,
|
2345 |
-
enableDownload: false,
|
2346 |
-
enablePrint: false,
|
2347 |
-
enableZoom: true,
|
2348 |
-
enableShare: true, // 곡μ λ²νΌ νμ±ν
|
2349 |
-
enableSearch: true,
|
2350 |
-
enableAutoPlay: true,
|
2351 |
-
enableAnnotation: false,
|
2352 |
-
enableSound: true,
|
2353 |
-
enableLightbox: false,
|
2354 |
-
layout: 10, // λ μ΄μμ μ΅μ
|
2355 |
-
skin: 'light', // μ€ν¨ μ€νμΌ
|
2356 |
-
autoNavigationTime: 3600, // μλ λκΉ μκ°(μ΄)
|
2357 |
-
hideControls: false, // 컨νΈλ‘€ μ¨κΉ λΉνμ±ν
|
2358 |
-
paddingTop: 10, // μλ¨ ν¨λ©
|
2359 |
-
paddingLeft: 10, // μ’μΈ‘ ν¨λ©
|
2360 |
-
paddingRight: 10, // μ°μΈ‘ ν¨λ©
|
2361 |
-
paddingBottom: 10, // νλ¨ ν¨λ©
|
2362 |
-
pageTextureSize: 1024, // νμ΄μ§ ν
μ€μ² ν¬κΈ°
|
2363 |
-
thumbnails: true, // μ¬λ€μΌ νμ±ν
|
2364 |
-
autoHideControls: false, // μλ μ¨κΉ λΉνμ±ν
|
2365 |
-
controlsTimeout: 8000, // 컨νΈλ‘€ νμ μκ° μ°μ₯
|
2366 |
-
shareHandler: copyPdfShareUrl // 곡μ νΈλ€λ¬ μ€μ
|
2367 |
-
}
|
2368 |
-
});
|
2369 |
-
|
2370 |
-
// νλ©΄ ν¬κΈ° λ³κ²½ μ FlipBook ν¬κΈ° μ‘°μ
|
2371 |
-
window.addEventListener('resize', () => {
|
2372 |
-
if (fb) {
|
2373 |
-
const newSize = calculateAspectRatio();
|
2374 |
-
viewer.style.width = newSize.width + 'px';
|
2375 |
-
viewer.style.height = newSize.height + 'px';
|
2376 |
-
fb.resize();
|
2377 |
-
}
|
2378 |
-
});
|
2379 |
-
|
2380 |
-
// FlipBook μμ± ν 컨νΈλ‘€λ° κ°μ νμ
|
2381 |
-
setTimeout(() => {
|
2382 |
try {
|
2383 |
-
//
|
2384 |
-
const
|
2385 |
-
|
2386 |
-
|
2387 |
-
|
2388 |
-
|
2389 |
-
|
2390 |
-
|
2391 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2392 |
}
|
2393 |
-
|
2394 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2395 |
}
|
2396 |
-
}
|
2397 |
-
|
2398 |
-
console.log('FlipBook μμ± μλ£');
|
2399 |
-
} catch (error) {
|
2400 |
-
console.error('FlipBook μμ± μ€ μ€λ₯ λ°μ:', error);
|
2401 |
-
showError("FlipBookμ μμ±νλ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
2402 |
-
}
|
2403 |
-
}
|
2404 |
|
2405 |
/* ββ λ€λΉκ²μ΄μ
ββ */
|
2406 |
-
$id('homeButton').onclick=()=>{
|
2407 |
-
if(fb) {
|
2408 |
-
fb.destroy();
|
2409 |
-
viewer.innerHTML = '';
|
2410 |
-
fb = null;
|
2411 |
-
}
|
2412 |
-
toggle(true);
|
2413 |
-
|
2414 |
-
// λ‘λ© μΈλμΌμ΄ν° μ 리
|
2415 |
-
if (pageLoadingInterval) {
|
2416 |
-
clearInterval(pageLoadingInterval);
|
2417 |
-
pageLoadingInterval = null;
|
2418 |
-
}
|
2419 |
-
$id('loadingPages').style.display = 'none';
|
2420 |
-
currentLoadingPdfPath = null;
|
2421 |
-
currentPdfId = null;
|
2422 |
-
};
|
2423 |
-
|
2424 |
function toggle(showHome){
|
2425 |
$id('home').style.display=showHome?'block':'none';
|
2426 |
$id('viewerPage').style.display=showHome?'none':'block';
|
@@ -2438,154 +2441,91 @@ function createFlipBook(pages) {
|
|
2438 |
/* -- κ΄λ¦¬μ κΈ°λ₯ -- */
|
2439 |
function setupAdminFunctions() {
|
2440 |
// κ΄λ¦¬μ λ²νΌ ν΄λ¦ - λͺ¨λ¬ νμ
|
2441 |
-
|
2442 |
-
|
2443 |
-
|
2444 |
-
|
2445 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2446 |
|
2447 |
// λͺ¨λ¬ λ«κΈ° λ²νΌ
|
2448 |
-
|
2449 |
-
|
2450 |
-
|
|
|
|
|
|
|
|
|
2451 |
|
2452 |
// μν° ν€λ‘ λ‘κ·ΈμΈ
|
2453 |
-
|
2454 |
-
|
2455 |
-
|
2456 |
-
|
2457 |
-
});
|
2458 |
-
|
2459 |
-
// λ‘κ·ΈμΈ λ²νΌ
|
2460 |
-
$id('adminLoginButton').addEventListener('click', async function() {
|
2461 |
-
const password = $id('adminPasswordInput').value;
|
2462 |
-
|
2463 |
-
try {
|
2464 |
-
showLoading("λ‘κ·ΈμΈ μ€...");
|
2465 |
-
|
2466 |
-
const formData = new FormData();
|
2467 |
-
formData.append('password', password);
|
2468 |
-
|
2469 |
-
const response = await fetch('/api/admin-login', {
|
2470 |
-
method: 'POST',
|
2471 |
-
body: formData
|
2472 |
-
});
|
2473 |
-
|
2474 |
-
const data = await response.json();
|
2475 |
-
|
2476 |
-
hideLoading();
|
2477 |
-
|
2478 |
-
if (data.success) {
|
2479 |
-
// λ‘κ·ΈμΈ μ±κ³΅ - κ΄λ¦¬μ νμ΄μ§ νμ
|
2480 |
-
$id('adminLoginModal').style.display = 'none';
|
2481 |
-
showAdminPage();
|
2482 |
-
} else {
|
2483 |
-
// λ‘κ·ΈμΈ μ€ν¨
|
2484 |
-
showError("κ΄λ¦¬μ μΈμ¦ μ€ν¨: λΉλ°λ²νΈκ° μΌμΉνμ§ μμ΅λλ€.");
|
2485 |
}
|
2486 |
-
}
|
2487 |
-
console.error("κ΄λ¦¬μ λ‘κ·ΈμΈ μ€λ₯:", error);
|
2488 |
-
hideLoading();
|
2489 |
-
showError("λ‘κ·ΈμΈ μ²λ¦¬ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
2490 |
-
}
|
2491 |
-
});
|
2492 |
-
|
2493 |
-
// κ΄λ¦¬μ νμ΄μ§ λ€λ‘κ°κΈ°
|
2494 |
-
$id('adminBackButton').addEventListener('click', function() {
|
2495 |
-
$id('adminPage').style.display = 'none';
|
2496 |
-
$id('home').style.display = 'block';
|
2497 |
-
});
|
2498 |
-
}
|
2499 |
-
|
2500 |
-
/* ββ μΉ΄λ β FlipBook ββ */
|
2501 |
-
async function open(i) {
|
2502 |
-
// κΈ°μ‘΄ open ν¨μ λ΄μ©...
|
2503 |
-
}
|
2504 |
-
|
2505 |
-
/* ββ PDF IDλ‘ PDF μ΄κΈ° ββ */
|
2506 |
-
async function openPdfById(pdfId, pdfPath, isCached = false) {
|
2507 |
-
try {
|
2508 |
-
// μ€λμ€ μ΄κΈ°ν μλ
|
2509 |
-
await initializeAudio().catch(e => console.warn('PDF μ΄κΈ° μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
2510 |
-
|
2511 |
-
// λ¨Όμ ν νλ©΄μμ μΉ΄λλ₯Ό μ°Ύμμ ν΄λ¦νλ λ°©λ² μλ
|
2512 |
-
let foundCard = false;
|
2513 |
-
const cards = document.querySelectorAll('.card');
|
2514 |
-
|
2515 |
-
for (let i = 0; i < cards.length; i++) {
|
2516 |
-
if (cards[i].dataset.pdfId === pdfId) {
|
2517 |
-
cards[i].click();
|
2518 |
-
foundCard = true;
|
2519 |
-
break;
|
2520 |
}
|
2521 |
-
}
|
2522 |
-
|
2523 |
-
// μΉ΄λλ₯Ό μ°Ύμ§ λͺ»ν κ²½μ° μ§μ μ€ν
|
2524 |
-
if (!foundCard) {
|
2525 |
-
toggle(false);
|
2526 |
-
showLoading("PDF μ€λΉ μ€...");
|
2527 |
-
|
2528 |
-
let pages = [];
|
2529 |
|
2530 |
-
//
|
2531 |
-
if (
|
2532 |
-
|
2533 |
-
|
2534 |
-
|
|
|
2535 |
|
2536 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2537 |
hideLoading();
|
2538 |
-
|
2539 |
-
// νμ¬ μ΄λ¦° PDFμ ID μ μ₯
|
2540 |
-
currentPdfId = pdfId;
|
2541 |
-
return;
|
2542 |
}
|
2543 |
-
}
|
2544 |
-
console.error("μΊμ λ°μ΄ν° λ‘λ μ€ν¨:", error);
|
2545 |
-
}
|
2546 |
-
}
|
2547 |
-
|
2548 |
-
// μΈλ€μΌ κ°μ Έμ€κΈ°
|
2549 |
-
try {
|
2550 |
-
const thumbResponse = await fetch(`/api/pdf-thumbnail?path=${encodeURIComponent(pdfPath)}`);
|
2551 |
-
const thumbData = await thumbResponse.json();
|
2552 |
-
|
2553 |
-
if (thumbData.thumbnail) {
|
2554 |
-
pages = [{
|
2555 |
-
src: thumbData.thumbnail,
|
2556 |
-
thumb: thumbData.thumbnail,
|
2557 |
-
path: pdfPath,
|
2558 |
-
cached: isCached
|
2559 |
-
}];
|
2560 |
-
}
|
2561 |
-
} catch (error) {
|
2562 |
-
console.error("μΈλ€μΌ λ‘λ μ€ν¨:", error);
|
2563 |
}
|
2564 |
|
2565 |
-
//
|
2566 |
-
if (
|
2567 |
-
|
2568 |
-
|
2569 |
-
|
2570 |
-
}
|
2571 |
}
|
2572 |
-
|
2573 |
-
// νλ‘μ νΈμ μΆκ°νκ³ λ·°μ΄ μ€ν
|
2574 |
-
const projectId = projects.push(pages) - 1;
|
2575 |
-
hideLoading();
|
2576 |
-
open(projectId);
|
2577 |
-
|
2578 |
-
// νμ¬ μ΄λ¦° PDFμ ID μ μ₯
|
2579 |
-
currentPdfId = pdfId;
|
2580 |
}
|
2581 |
-
} catch (error) {
|
2582 |
-
console.error("PDF IDλ‘ μ΄κΈ° μ€ν¨:", error);
|
2583 |
-
hideLoading();
|
2584 |
-
showError("PDFλ₯Ό μ΄ μ μμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.");
|
2585 |
-
}
|
2586 |
-
}
|
2587 |
-
|
2588 |
-
|
2589 |
|
2590 |
// κ΄λ¦¬μ νμ΄μ§ νμ
|
2591 |
async function showAdminPage() {
|
|
|
1569 |
</div>
|
1570 |
</section>
|
1571 |
|
1572 |
+
<script>
|
1573 |
let projects=[], fb=null;
|
1574 |
const grid=document.getElementById('grid'), viewer=document.getElementById('viewer');
|
1575 |
pdfjsLib.GlobalWorkerOptions.workerSrc='/static/pdf.worker.js';
|
|
|
1584 |
// νμ¬ μ΄λ¦° PDFμ ID
|
1585 |
let currentPdfId = null;
|
1586 |
|
1587 |
+
// μ€λμ€ μ»¨ν
μ€νΈμ μ΄κΈ°ν μν κ΄λ¦¬
|
1588 |
+
let audioInitialized = false;
|
1589 |
+
let audioContext = null;
|
1590 |
|
1591 |
+
// μ€λμ€ μ΄κΈ°ν ν¨μ
|
1592 |
+
function initializeAudio() {
|
1593 |
+
if (audioInitialized) return Promise.resolve();
|
1594 |
+
|
1595 |
+
return new Promise((resolve) => {
|
1596 |
+
// μ€λμ€ μ»¨ν
μ€νΈ μμ± (μ¬μ©μ μνΈμμ©μ΄ νμ μλ μ΄κΈ°ν)
|
1597 |
+
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
1598 |
+
|
1599 |
+
// MP3 λ‘λ λ° μ΄κΈ°ν
|
1600 |
+
const audio = new Audio('/static/turnPage2.mp3');
|
1601 |
+
audio.volume = 0.01; // μ΅μ λ³Όλ₯¨μΌλ‘ μ€μ
|
1602 |
+
|
1603 |
+
// λ‘λλ μ€λμ€ μ¬μ μλ (μ¬μ©μ μνΈμμ© μꡬλ μ μμ)
|
1604 |
+
const playPromise = audio.play();
|
1605 |
+
|
1606 |
+
if (playPromise !== undefined) {
|
1607 |
+
playPromise
|
1608 |
+
.then(() => {
|
1609 |
+
// μ±κ³΅μ μΌλ‘ μ¬μλ¨ - μ¦μ μΌμμ μ§
|
1610 |
+
audio.pause();
|
1611 |
+
audioInitialized = true;
|
1612 |
+
console.log('μ€λμ€ μ΄κΈ°ν μ±κ³΅');
|
1613 |
+
resolve();
|
1614 |
+
})
|
1615 |
+
.catch((error) => {
|
1616 |
+
console.log('μλ μ€λμ€ μ΄κΈ°ν μ€ν¨, μ¬μ©μ μνΈμμ© νμ:', error);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1617 |
|
1618 |
+
// μ¬μ©μ μνΈμμ©μ΄ νμν κ²½μ°, μ΄λ²€νΈ 리μ€λ μΆκ°
|
1619 |
+
const initOnUserAction = function() {
|
1620 |
+
const tempAudio = new Audio('/static/turnPage2.mp3');
|
1621 |
+
tempAudio.volume = 0.01;
|
1622 |
+
tempAudio.play()
|
1623 |
+
.then(() => {
|
1624 |
+
tempAudio.pause();
|
1625 |
+
audioInitialized = true;
|
1626 |
+
console.log('μ¬μ©μ μνΈμμ©μΌλ‘ μ€λμ€ μ΄κΈ°ν μ±κ³΅');
|
1627 |
+
resolve();
|
1628 |
+
|
1629 |
+
// μ΄λ²€νΈ 리μ€λ μ κ±°
|
1630 |
+
['click', 'touchstart', 'keydown'].forEach(event => {
|
1631 |
+
document.removeEventListener(event, initOnUserAction, { capture: true });
|
1632 |
+
});
|
1633 |
+
})
|
1634 |
+
.catch(e => console.error('μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
1635 |
+
};
|
1636 |
|
1637 |
+
// μ¬μ©μ μνΈμμ© μ΄λ²€νΈμ 리μ€λ μΆκ°
|
1638 |
+
['click', 'touchstart', 'keydown'].forEach(event => {
|
1639 |
+
document.addEventListener(event, initOnUserAction, { once: true, capture: true });
|
1640 |
+
});
|
1641 |
|
1642 |
+
// νμ΄μ§ λ‘λ μ§ν μ¬μ©μμκ² μ€λμ€ νμ±ν μμ²
|
1643 |
+
if (window.location.pathname.startsWith('/view/')) {
|
1644 |
+
// μ€λμ€ νμ±ν μλ΄ λ©μμ§ νμ (λ°λ‘κ°κΈ° λ§ν¬λ‘ μ μν κ²½μ°)
|
1645 |
+
setTimeout(() => {
|
1646 |
+
const audioPrompt = document.createElement('div');
|
1647 |
+
audioPrompt.style.position = 'fixed';
|
1648 |
+
audioPrompt.style.bottom = '80px';
|
1649 |
+
audioPrompt.style.left = '50%';
|
1650 |
+
audioPrompt.style.transform = 'translateX(-50%)';
|
1651 |
+
audioPrompt.style.backgroundColor = 'rgba(0,0,0,0.7)';
|
1652 |
+
audioPrompt.style.color = 'white';
|
1653 |
+
audioPrompt.style.padding = '10px 20px';
|
1654 |
+
audioPrompt.style.borderRadius = '20px';
|
1655 |
+
audioPrompt.style.zIndex = '10000';
|
1656 |
+
audioPrompt.style.cursor = 'pointer';
|
1657 |
+
audioPrompt.innerHTML = 'νμ΄μ§ μ΄λλ ν΄λ¦νμ¬ μ리 ν¨κ³Ό νμ±ν <i class="fas fa-volume-up"></i>';
|
1658 |
+
audioPrompt.id = 'audioPrompt';
|
1659 |
+
|
1660 |
+
// ν΄λ¦ μ μ리 νμ±ν λ° λ©μμ§ μ κ±°
|
1661 |
+
audioPrompt.addEventListener('click', function() {
|
1662 |
+
initOnUserAction();
|
1663 |
+
audioPrompt.remove();
|
1664 |
+
});
|
1665 |
+
|
1666 |
+
document.body.appendChild(audioPrompt);
|
1667 |
+
|
1668 |
+
// 10μ΄ ν μλμΌλ‘ μ¨κΉ
|
1669 |
+
setTimeout(() => {
|
1670 |
+
if (document.getElementById('audioPrompt')) {
|
1671 |
+
document.getElementById('audioPrompt').remove();
|
1672 |
+
}
|
1673 |
+
}, 10000);
|
1674 |
+
}, 2000);
|
1675 |
+
}
|
1676 |
+
});
|
1677 |
+
} else {
|
1678 |
+
// λΈλΌμ°μ κ° Promise κΈ°λ° μ¬μμ μ§μνμ§ μλ κ²½μ°
|
1679 |
+
audioInitialized = true;
|
1680 |
+
resolve();
|
1681 |
+
}
|
1682 |
+
});
|
1683 |
}
|
|
|
|
|
|
|
|
|
|
|
1684 |
|
1685 |
/* ββ μ νΈ ββ */
|
1686 |
function $id(id){return document.getElementById(id)}
|
1687 |
|
1688 |
+
// DOMμ΄ λ‘λλλ©΄ μ€ν
|
1689 |
+
document.addEventListener('DOMContentLoaded', function() {
|
|
|
1690 |
console.log("DOM λ‘λ μλ£, μ΄λ²€νΈ μ€μ μμ");
|
1691 |
|
1692 |
+
// μ€λμ€ μ΄κΈ°ν μλ
|
1693 |
+
initializeAudio().catch(e => console.warn('μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
1694 |
+
|
1695 |
// PDF μ
λ‘λ λ²νΌ
|
1696 |
const pdfBtn = document.getElementById('pdfUploadBtn');
|
1697 |
const pdfInput = document.getElementById('pdfInput');
|
|
|
1726 |
|
1727 |
// κ΄λ¦¬μ λ²νΌ μ΄λ²€νΈ μ€μ
|
1728 |
setupAdminFunctions();
|
1729 |
+
|
1730 |
+
// ν λ²νΌ μ΄λ²€νΈ μ€μ
|
1731 |
+
const homeButton = document.getElementById('homeButton');
|
1732 |
+
if (homeButton) {
|
1733 |
+
homeButton.addEventListener('click', function() {
|
1734 |
+
if(fb) {
|
1735 |
+
fb.destroy();
|
1736 |
+
viewer.innerHTML = '';
|
1737 |
+
fb = null;
|
1738 |
+
}
|
1739 |
+
toggle(true);
|
1740 |
+
|
1741 |
+
// λ‘λ© μΈλμΌμ΄ν° μ 리
|
1742 |
+
if (pageLoadingInterval) {
|
1743 |
+
clearInterval(pageLoadingInterval);
|
1744 |
+
pageLoadingInterval = null;
|
1745 |
+
}
|
1746 |
+
$id('loadingPages').style.display = 'none';
|
1747 |
+
currentLoadingPdfPath = null;
|
1748 |
+
currentPdfId = null;
|
1749 |
+
});
|
1750 |
+
}
|
1751 |
});
|
1752 |
|
1753 |
// μλ²μ PDF μ
λ‘λ ν¨μ
|
|
|
1784 |
}
|
1785 |
}
|
1786 |
|
1787 |
+
function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
1788 |
+
const d = document.createElement('div');
|
1789 |
+
d.className = 'card fade-in';
|
1790 |
+
d.onclick = () => open(i);
|
1791 |
+
|
1792 |
+
// PDF IDκ° μμΌλ©΄ λ°μ΄ν° μμ±μΌλ‘ μ μ₯
|
1793 |
+
if (pdfId) {
|
1794 |
+
d.dataset.pdfId = pdfId;
|
1795 |
+
}
|
1796 |
+
|
1797 |
+
// μ λͺ© μ²λ¦¬
|
1798 |
+
const displayTitle = title ?
|
1799 |
+
(title.length > 15 ? title.substring(0, 15) + '...' : title) :
|
1800 |
+
'νλ‘μ νΈ ' + (i+1);
|
1801 |
+
|
1802 |
+
// μΊμ μν λ±μ§ μΆκ°
|
1803 |
+
const cachedBadge = isCached ?
|
1804 |
+
'<div class="cached-status">μΊμλ¨</div>' : '';
|
1805 |
+
|
1806 |
+
// λ°λ‘κ°κΈ° λ§ν¬ μΆκ° (PDF IDκ° μλ κ²½μ°μλ§)
|
1807 |
+
const linkHtml = pdfId ?
|
1808 |
+
`<div style="position: absolute; bottom: 55px; left: 50%; transform: translateX(-50%); z-index:5;">
|
1809 |
+
<a href="/view/${pdfId}" target="_blank" style="color:#4a6ee0; font-size:11px;">Share Link</a>
|
1810 |
+
</div>` : '';
|
1811 |
+
|
1812 |
+
d.innerHTML = `
|
1813 |
+
<div class="card-inner">
|
1814 |
+
${cachedBadge}
|
1815 |
+
<img src="${thumb}" alt="${displayTitle}" loading="lazy">
|
1816 |
+
${linkHtml}
|
1817 |
+
<p title="${title || 'νλ‘μ νΈ ' + (i+1)}">${displayTitle}</p>
|
1818 |
+
</div>
|
1819 |
+
`;
|
1820 |
+
grid.appendChild(d);
|
1821 |
+
|
1822 |
+
// νλ‘μ νΈκ° μμΌλ©΄ 'νλ‘μ νΈ μμ' λ©μμ§ μ¨κΈ°κΈ°
|
1823 |
+
$id('noProjects').style.display = 'none';
|
1824 |
+
}
|
|
|
|
|
1825 |
|
1826 |
/* ββ νλ‘μ νΈ μ μ₯ ββ */
|
1827 |
function save(pages, title, isCached = false, pdfId = null) {
|
|
|
1982 |
/* ββ PDF IDλ‘ PDF μ΄κΈ° ββ */
|
1983 |
async function openPdfById(pdfId, pdfPath, isCached = false) {
|
1984 |
try {
|
1985 |
+
// μ€λμ€ μ΄κΈ°ν μλ
|
1986 |
+
await initializeAudio().catch(e => console.warn('PDF μ΄κΈ° μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
1987 |
+
|
1988 |
// λ¨Όμ ν νλ©΄μμ μΉ΄λλ₯Ό μ°Ύμμ ν΄λ¦νλ λ°©λ² μλ
|
1989 |
let foundCard = false;
|
1990 |
const cards = document.querySelectorAll('.card');
|
|
|
2292 |
}
|
2293 |
}
|
2294 |
|
2295 |
+
function createFlipBook(pages) {
|
2296 |
+
console.log('FlipBook μμ± μμ. νμ΄μ§ μ:', pages.length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2297 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2298 |
try {
|
2299 |
+
// νλ©΄ λΉμ¨ κ³μ°
|
2300 |
+
const calculateAspectRatio = () => {
|
2301 |
+
const windowWidth = window.innerWidth;
|
2302 |
+
const windowHeight = window.innerHeight;
|
2303 |
+
const aspectRatio = windowWidth / windowHeight;
|
2304 |
+
|
2305 |
+
// λλΉ λλ λμ΄ κΈ°μ€μΌλ‘ μ΅λ 90% μ ν
|
2306 |
+
let width, height;
|
2307 |
+
if (aspectRatio > 1) { // κ°λ‘ νλ©΄
|
2308 |
+
height = Math.min(windowHeight * 0.9, windowHeight - 40);
|
2309 |
+
width = height * aspectRatio * 0.8; // κ°λ‘ νλ©΄μμλ μ½κ° μ€μ
|
2310 |
+
if (width > windowWidth * 0.9) {
|
2311 |
+
width = windowWidth * 0.9;
|
2312 |
+
height = width / (aspectRatio * 0.8);
|
2313 |
+
}
|
2314 |
+
} else { // μΈλ‘ νλ©΄
|
2315 |
+
width = Math.min(windowWidth * 0.9, windowWidth - 40);
|
2316 |
+
height = width / aspectRatio * 0.9; // μΈλ‘ νλ©΄μμλ μ½κ° λλ¦Ό
|
2317 |
+
if (height > windowHeight * 0.9) {
|
2318 |
+
height = windowHeight * 0.9;
|
2319 |
+
width = height * aspectRatio * 0.9;
|
2320 |
+
}
|
2321 |
+
}
|
2322 |
+
|
2323 |
+
// μ΅μ μ¬μ΄μ¦ λ°ν
|
2324 |
+
return {
|
2325 |
+
width: Math.round(width),
|
2326 |
+
height: Math.round(height)
|
2327 |
+
};
|
2328 |
+
};
|
2329 |
+
|
2330 |
+
// μ΄κΈ° νλ©΄ λΉμ¨ κ³μ°
|
2331 |
+
const size = calculateAspectRatio();
|
2332 |
+
viewer.style.width = size.width + 'px';
|
2333 |
+
viewer.style.height = size.height + 'px';
|
2334 |
+
|
2335 |
+
// μ¬μ΄λ μ΄κΈ°ν μ¬λΆ νμΈ
|
2336 |
+
if (!audioInitialized) {
|
2337 |
+
initializeAudio()
|
2338 |
+
.then(() => console.log('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μλ£'))
|
2339 |
+
.catch(e => console.warn('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
2340 |
}
|
2341 |
+
|
2342 |
+
// νμ΄μ§ λ°μ΄ν° μ μ (λΉ νμ΄μ§ μ²λ¦¬)
|
2343 |
+
const validPages = pages.map(page => {
|
2344 |
+
// srcκ° μλ νμ΄μ§λ λ‘λ© μ€ μ΄λ―Έμ§λ‘ λ체
|
2345 |
+
if (!page || !page.src) {
|
2346 |
+
return {
|
2347 |
+
src: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZjVmNWY1Ii8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zZW0iIGZpbGw9IiM1NTUiPkxvYWRpbmcuLi48L3RleHQ+PC9zdmc+',
|
2348 |
+
thumb: page && page.thumb ? page.thumb : ''
|
2349 |
+
};
|
2350 |
+
}
|
2351 |
+
return page;
|
2352 |
+
});
|
2353 |
+
|
2354 |
+
fb = new FlipBook(viewer, {
|
2355 |
+
pages: validPages,
|
2356 |
+
viewMode: 'webgl',
|
2357 |
+
autoSize: true,
|
2358 |
+
flipDuration: 800,
|
2359 |
+
backgroundColor: '#fff',
|
2360 |
+
/* π λ΄μ₯ μ¬μ΄λ */
|
2361 |
+
sound: true,
|
2362 |
+
assets: {flipMp3: '/static/turnPage2.mp3', hardFlipMp3: '/static/turnPage2.mp3'}, // μ λ κ²½λ‘λ‘ μμ
|
2363 |
+
controlsProps: {
|
2364 |
+
enableFullscreen: true,
|
2365 |
+
enableToc: true,
|
2366 |
+
enableDownload: false,
|
2367 |
+
enablePrint: false,
|
2368 |
+
enableZoom: true,
|
2369 |
+
enableShare: true, // 곡μ λ²νΌ νμ±ν
|
2370 |
+
enableSearch: true,
|
2371 |
+
enableAutoPlay: true,
|
2372 |
+
enableAnnotation: false,
|
2373 |
+
enableSound: true,
|
2374 |
+
enableLightbox: false,
|
2375 |
+
layout: 10, // λ μ΄μμ μ΅μ
|
2376 |
+
skin: 'light', // μ€ν¨ μ€νμΌ
|
2377 |
+
autoNavigationTime: 3600, // μλ λκΉ μκ°(μ΄)
|
2378 |
+
hideControls: false, // 컨νΈλ‘€ μ¨κΉ λΉνμ±ν
|
2379 |
+
paddingTop: 10, // μλ¨ ν¨λ©
|
2380 |
+
paddingLeft: 10, // μ’μΈ‘ ν¨λ©
|
2381 |
+
paddingRight: 10, // μ°μΈ‘ ν¨λ©
|
2382 |
+
paddingBottom: 10, // νλ¨ ν¨λ©
|
2383 |
+
pageTextureSize: 1024, // νμ΄μ§ ν
μ€μ² ν¬κΈ°
|
2384 |
+
thumbnails: true, // μ¬λ€μΌ νμ±ν
|
2385 |
+
autoHideControls: false, // μλ μ¨κΉ λΉνμ±ν
|
2386 |
+
controlsTimeout: 8000, // 컨νΈλ‘€ νμ μκ° μ°μ₯
|
2387 |
+
shareHandler: copyPdfShareUrl // 곡μ νΈλ€λ¬ μ€μ
|
2388 |
+
}
|
2389 |
+
});
|
2390 |
+
|
2391 |
+
// νλ©΄ ν¬κΈ° λ³κ²½ μ FlipBook ν¬κΈ° μ‘°μ
|
2392 |
+
window.addEventListener('resize', () => {
|
2393 |
+
if (fb) {
|
2394 |
+
const newSize = calculateAspectRatio();
|
2395 |
+
viewer.style.width = newSize.width + 'px';
|
2396 |
+
viewer.style.height = newSize.height + 'px';
|
2397 |
+
fb.resize();
|
2398 |
+
}
|
2399 |
+
});
|
2400 |
+
|
2401 |
+
// FlipBook μμ± ν 컨νΈλ‘€λ° κ°μ νμ
|
2402 |
+
setTimeout(() => {
|
2403 |
+
try {
|
2404 |
+
// 컨νΈλ‘€λ° κ΄λ ¨ μμ μ°ΎκΈ° λ° μ€νμΌ μ μ©
|
2405 |
+
const menuBars = document.querySelectorAll('.flipbook-container .fb3d-menu-bar');
|
2406 |
+
if (menuBars && menuBars.length > 0) {
|
2407 |
+
menuBars.forEach(menuBar => {
|
2408 |
+
menuBar.style.display = 'block';
|
2409 |
+
menuBar.style.opacity = '1';
|
2410 |
+
menuBar.style.visibility = 'visible';
|
2411 |
+
menuBar.style.zIndex = '9999';
|
2412 |
+
});
|
2413 |
+
}
|
2414 |
+
} catch (e) {
|
2415 |
+
console.warn('컨νΈλ‘€λ° μ€νμΌ μ μ© μ€ μ€λ₯:', e);
|
2416 |
+
}
|
2417 |
+
}, 1000);
|
2418 |
+
|
2419 |
+
console.log('FlipBook μμ± μλ£');
|
2420 |
+
} catch (error) {
|
2421 |
+
console.error('FlipBook μμ± μ€ μ€λ₯ λ°μ:', error);
|
2422 |
+
showError("FlipBookμ μμ±νλ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
2423 |
}
|
2424 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2425 |
|
2426 |
/* ββ λ€λΉκ²μ΄μ
ββ */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2427 |
function toggle(showHome){
|
2428 |
$id('home').style.display=showHome?'block':'none';
|
2429 |
$id('viewerPage').style.display=showHome?'none':'block';
|
|
|
2441 |
/* -- κ΄λ¦¬μ κΈ°λ₯ -- */
|
2442 |
function setupAdminFunctions() {
|
2443 |
// κ΄λ¦¬μ λ²νΌ ν΄λ¦ - λͺ¨λ¬ νμ
|
2444 |
+
const adminButton = document.getElementById('adminButton');
|
2445 |
+
const adminLoginModal = document.getElementById('adminLoginModal');
|
2446 |
+
const adminLoginClose = document.getElementById('adminLoginClose');
|
2447 |
+
const adminLoginButton = document.getElementById('adminLoginButton');
|
2448 |
+
const adminPasswordInput = document.getElementById('adminPasswordInput');
|
2449 |
+
const adminBackButton = document.getElementById('adminBackButton');
|
2450 |
+
|
2451 |
+
if (adminButton) {
|
2452 |
+
adminButton.addEventListener('click', function() {
|
2453 |
+
if (adminLoginModal) {
|
2454 |
+
adminLoginModal.style.display = 'flex';
|
2455 |
+
if (adminPasswordInput) {
|
2456 |
+
adminPasswordInput.value = '';
|
2457 |
+
adminPasswordInput.focus();
|
2458 |
+
}
|
2459 |
+
}
|
2460 |
+
});
|
2461 |
+
}
|
2462 |
|
2463 |
// λͺ¨λ¬ λ«κΈ° λ²νΌ
|
2464 |
+
if (adminLoginClose) {
|
2465 |
+
adminLoginClose.addEventListener('click', function() {
|
2466 |
+
if (adminLoginModal) {
|
2467 |
+
adminLoginModal.style.display = 'none';
|
2468 |
+
}
|
2469 |
+
});
|
2470 |
+
}
|
2471 |
|
2472 |
// μν° ν€λ‘ λ‘κ·ΈμΈ
|
2473 |
+
if (adminPasswordInput) {
|
2474 |
+
adminPasswordInput.addEventListener('keyup', function(e) {
|
2475 |
+
if (e.key === 'Enter' && adminLoginButton) {
|
2476 |
+
adminLoginButton.click();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2477 |
}
|
2478 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2479 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2480 |
|
2481 |
+
// λ‘κ·ΈμΈ λ²νΌ
|
2482 |
+
if (adminLoginButton) {
|
2483 |
+
adminLoginButton.addEventListener('click', async function() {
|
2484 |
+
if (!adminPasswordInput) return;
|
2485 |
+
|
2486 |
+
const password = adminPasswordInput.value;
|
2487 |
|
2488 |
+
try {
|
2489 |
+
showLoading("λ‘κ·ΈμΈ μ€...");
|
2490 |
+
|
2491 |
+
const formData = new FormData();
|
2492 |
+
formData.append('password', password);
|
2493 |
+
|
2494 |
+
const response = await fetch('/api/admin-login', {
|
2495 |
+
method: 'POST',
|
2496 |
+
body: formData
|
2497 |
+
});
|
2498 |
+
|
2499 |
+
const data = await response.json();
|
2500 |
+
|
2501 |
+
hideLoading();
|
2502 |
+
|
2503 |
+
if (data.success) {
|
2504 |
+
// λ‘κ·ΈμΈ μ±κ³΅ - κ΄λ¦¬μ νμ΄μ§ νμ
|
2505 |
+
if (adminLoginModal) {
|
2506 |
+
adminLoginModal.style.display = 'none';
|
2507 |
+
}
|
2508 |
+
showAdminPage();
|
2509 |
+
} else {
|
2510 |
+
// λ‘κ·ΈμΈ μ€ν¨
|
2511 |
+
showError("κ΄λ¦¬μ μΈμ¦ μ€ν¨: λΉλ°λ²νΈκ° μΌμΉνμ§ μμ΅λλ€.");
|
2512 |
+
}
|
2513 |
+
} catch (error) {
|
2514 |
+
console.error("κ΄λ¦¬μ λ‘κ·ΈμΈ μ€λ₯:", error);
|
2515 |
hideLoading();
|
2516 |
+
showError("λ‘κ·ΈμΈ μ²λ¦¬ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
|
|
|
|
|
|
2517 |
}
|
2518 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2519 |
}
|
2520 |
|
2521 |
+
// κ΄λ¦¬μ νμ΄μ§ λ€λ‘κ°κΈ°
|
2522 |
+
if (adminBackButton) {
|
2523 |
+
adminBackButton.addEventListener('click', function() {
|
2524 |
+
document.getElementById('adminPage').style.display = 'none';
|
2525 |
+
document.getElementById('home').style.display = 'block';
|
2526 |
+
});
|
2527 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2528 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2529 |
|
2530 |
// κ΄λ¦¬μ νμ΄μ§ νμ
|
2531 |
async function showAdminPage() {
|