{"id":8,"date":"2026-01-21T02:17:24","date_gmt":"2026-01-21T02:17:24","guid":{"rendered":"https:\/\/conpop.ai.kr\/?page_id=8"},"modified":"2026-04-21T02:15:23","modified_gmt":"2026-04-21T02:15:23","slug":"ai-%ec%84%b1%ec%9a%b0-%eb%85%b9%ec%9d%8c%ed%95%98%ea%b8%b0","status":"publish","type":"page","link":"https:\/\/conpop.ai.kr\/?page_id=8","title":{"rendered":"AI \uc74c\uc131 \uc0dd\uc131\uae30"},"content":{"rendered":"\n<div style=\"max-width:1100px; margin:0 auto; font-family:'Pretendard', sans-serif;\">\n    \n    <h2 style=\"text-align:center; margin-bottom:30px; font-weight:900; color:#222; letter-spacing:-0.5px; font-size:32px;\">CONPOP AI \ubcf4\uc774\uc2a4<\/h2>\n\n    <div style=\"background:#fff; padding:25px; border-radius:16px; border:1px solid #e1e1e1; margin-bottom:25px; box-shadow:0 10px 20px rgba(0,0,0,0.03);\">\n        <h3 style=\"margin-top:0; color:#444; font-size:18px; display:flex; align-items:center; gap:8px;\">\n            \u2699\ufe0f \uc131\uc6b0 \ubc0f \uc18d\ub3c4 \uc124\uc815 <span style=\"font-size:13px; color:#888; font-weight:normal;\">(\ubaa8\ub4e0 \uc791\uc5c5\uc5d0 \uacf5\ud1b5 \uc801\uc6a9)<\/span>\n        <\/h3>\n        \n        <div style=\"display:flex; gap:12px; flex-wrap:wrap; margin-top:15px;\">\n            <select id=\"lang-select\" style=\"flex:1; min-width:150px; padding:12px; border:1px solid #ccc; border-radius:8px; font-size:15px;\" onchange=\"updateVoiceList()\">\n                <option value=\"kr\">\ud83c\uddf0\ud83c\uddf7 \ud55c\uad6d\uc5b4 (Korean)<\/option>\n                <option value=\"en\">\ud83c\uddfa\ud83c\uddf8\/\ud83c\uddec\ud83c\udde7 \uc601\uc5b4 (English)<\/option>\n            <\/select>\n\n            <select id=\"voice-select\" style=\"flex:3; min-width:250px; padding:12px; border:1px solid #ccc; border-radius:8px; font-size:15px;\" onchange=\"checkSpeedCapability()\">\n                <\/select>\n\n            <div style=\"flex:1; min-width:180px; display:flex; align-items:center; gap:8px; background:#f9f9f9; padding:0 15px; border-radius:8px; border:1px solid #eee;\">\n                <span style=\"font-size:14px; font-weight:bold; white-space:nowrap; color:#555;\">\u26a1 \uc18d\ub3c4:<\/span>\n                <input type=\"number\" id=\"speed-input\" value=\"1.0\" step=\"0.1\" min=\"0.5\" max=\"2.0\" style=\"width:100%; padding:8px; border:1px solid #ccc; border-radius:6px; text-align:center;\">\n            <\/div>\n        <\/div>\n        <p id=\"chirp-notice\" style=\"font-size:12px; color:#e11d48; margin-top:10px; display:none;\">\n            \u203b <b>\u2728Chirp 3(\uc0dd\uc131\ud615 AI)<\/b> \ubaa8\ub378\uc740 \uc18d\ub3c4 \uc870\uc808\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. (1.0 \uace0\uc815)\n        <\/p>\n    <\/div>\n\n    <div style=\"display:flex; gap:25px; flex-wrap:wrap; margin-bottom:30px;\">\n        \n        <div style=\"flex:1; min-width:300px; border:1px solid #e0e7ff; padding:25px; border-radius:16px; background:#f0f4ff;\">\n            <h3 style=\"color:#3b82f6; margin-top:0; font-size:20px;\">1\ufe0f\u20e3 \ud55c \ubb38\uc7a5 \ub179\uc74c<\/h3>\n            <p style=\"font-size:14px; color:#666; margin-bottom:15px;\">\uc9e7\uc740 \ubb38\uc7a5\uc744 \ub179\uc74c\ud558\uace0 \ubc14\ub85c \ud655\uc778\ud558\uc138\uc694.<\/p>\n            \n            <textarea id=\"single-text\" rows=\"5\" style=\"width:100%; padding:15px; box-sizing: border-box; border:1px solid #cbd5e1; border-radius:8px; font-size:15px; resize:vertical;\" placeholder=\"\ub179\uc74c\ud560 \uba58\ud2b8\ub97c \uc785\ub825\ud558\uc138\uc694...\" oninput=\"updateCharCount()\"><\/textarea>\n            \n            <div style=\"text-align:right; font-size:13px; color:#666; margin-top:5px; font-weight:bold;\">\n                <span id=\"char-current\" style=\"color:#3b82f6;\">0<\/span> \/ <span id=\"char-limit\">1,600<\/span>\uc790\n            <\/div>\n            \n            <button onclick=\"generateSingle()\" id=\"single-btn\" style=\"width:100%; margin-top:15px; padding:14px; background:#3b82f6; color:white; border:none; border-radius:8px; cursor:pointer; font-weight:bold; font-size:16px; box-shadow:0 4px 6px rgba(59, 130, 246, 0.2); transition:0.2s;\">\ud83c\udf99\ufe0f \ub179\uc74c \uc0dd\uc131\ud558\uae30<\/button>\n            \n            <div id=\"single-result-area\" style=\"display:none; margin-top:20px; animation: fadeIn 0.5s;\">\n                <p id=\"single-status-msg\" style=\"text-align:center; color:#15803d; font-weight:bold; margin-bottom:10px;\">\u2705 \uc0dd\uc131 \uc644\ub8cc!<\/p>\n                <audio id=\"single-player\" controls style=\"width:100%; margin-bottom:10px;\"><\/audio>\n                <a id=\"single-download-link\" href=\"#\" download=\"voice.mp3\" style=\"display:block; text-align:center; background:white; border:1px solid #3b82f6; color:#3b82f6; padding:10px; border-radius:6px; text-decoration:none; font-weight:bold;\">\u2b07\ufe0f MP3 \ub2e4\uc6b4\ub85c\ub4dc<\/a>\n            <\/div>\n        <\/div>\n\n        <div style=\"flex:1; min-width:300px; border:1px solid #bbf7d0; padding:25px; border-radius:16px; background:#f0fdf4;\">\n            <h3 style=\"color:#15803d; margin-top:0; font-size:20px;\">2\ufe0f\u20e3 \uc5d1\uc140 \ub300\ub7c9 \ubcc0\ud658<\/h3>\n            <p style=\"font-size:14px; color:#666; margin-bottom:15px;\">\uc5c5\ub85c\ub4dc\ud55c <b>\ud30c\uc77c\uba85 \uadf8\ub300\ub85c<\/b> \ubc88\ud638\ub97c \ubd99\uc5ec \uc800\uc7a5\ud569\ub2c8\ub2e4.<\/p>\n            \n            <div id=\"drop-zone\" style=\"background:white; padding:30px 15px; border-radius:12px; border:2px dashed #86efac; text-align:center; cursor:pointer; transition:0.3s;\" onclick=\"document.getElementById('excel-file').click();\">\n                <p style=\"margin:0; font-size:24px;\">\ud83d\udcc2<\/p>\n                <p style=\"margin:5px 0 0 0; font-size:14px; color:#15803d; font-weight:bold;\">\ud074\ub9ad\ud558\uac70\ub098 \ud30c\uc77c\uc744 \uc5ec\uae30\ub85c \ub4dc\ub798\uadf8\ud558\uc138\uc694<\/p>\n                <p id=\"file-name-display\" style=\"margin:5px 0 0 0; font-size:12px; color:#888;\">(.xlsx, .xls, .csv)<\/p>\n                <input type=\"file\" id=\"excel-file\" accept=\".xlsx, .xls, .csv\" style=\"display:none;\" onchange=\"handleFileSelect(this)\">\n            <\/div>\n            \n            <p id=\"excel-limit-msg\" style=\"text-align:center; font-size:12px; color:#ef4444; margin-top:10px;\">\n                \u203b \ud55c \uc140\ub2f9 \ucd5c\ub300 1,600\uc790(\ud55c\uae00) \uc81c\ud55c\n            <\/p>\n            \n            <div id=\"batch-progress-container\" style=\"display:none; margin-top:20px;\">\n                <div style=\"background:#e5e7eb; height:24px; border-radius:12px; overflow:hidden;\">\n                    <div id=\"progress-bar\" style=\"width:0%; height:100%; background:#22c55e; transition:width 0.3s;\"><\/div>\n                <\/div>\n                <p id=\"progress-text\" style=\"text-align:center; font-size:13px; margin-top:8px; color:#555; font-weight:bold;\">\ub300\uae30 \uc911&#8230;<\/p>\n            <\/div>\n\n            <button onclick=\"processBatch()\" id=\"batch-btn\" style=\"width:100%; margin-top:15px; padding:14px; background:#22c55e; color:white; border:none; border-radius:8px; cursor:pointer; font-weight:bold; font-size:16px; box-shadow:0 4px 6px rgba(34, 197, 94, 0.2); transition:0.2s;\">\ud83d\udce6 \uc77c\uad04 \uc0dd\uc131 &#038; \ub2e4\uc6b4\ub85c\ub4dc<\/button>\n        <\/div>\n\n    <\/div>\n\n    <div style=\"display:flex; gap:20px; flex-wrap:wrap;\">\n        <div style=\"flex:1; min-width:300px; background:#fffbf0; padding:20px; border-radius:12px; border:1px solid #faeacc;\">\n            <h4 style=\"margin-top:0; color:#b7791f; display:flex; align-items:center; gap:5px;\">\n                \ud83c\udf6f \uc790\uc5f0\uc2a4\ub7ec\uc6b4 \uc5f0\uae30 \uafc0\ud301\n            <\/h4>\n            <ul style=\"margin:0; padding-left:0; list-style:none; font-size:13px; color:#555; line-height:1.8;\">\n                <li><span style=\"background:white; border:1px solid #ddd; padding:2px 6px; border-radius:4px; font-weight:bold; color:#d97706;\">,<\/span> <strong>\uc27c\ud45c:<\/strong> \ubc18 \ubc15\uc790 \uc27c<\/li>\n                <li><span style=\"background:white; border:1px solid #ddd; padding:2px 6px; border-radius:4px; font-weight:bold; color:#d97706;\">.<\/span> <strong>\ub9c8\uce68\ud45c:<\/strong> \ud55c \ubc15\uc790 \uc27c<\/li>\n                <li><span style=\"background:white; border:1px solid #ddd; padding:2px 6px; border-radius:4px; font-weight:bold; color:#d97706;\">&#8230;<\/span> <strong>\ub9d0\uc904\uc784\ud45c:<\/strong> \uae34 \ud638\ud761\/\uc5ec\uc6b4<\/li>\n            <\/ul>\n        <\/div>\n\n        <div style=\"flex:1; min-width:300px; background:#f8f9fa; padding:20px; border-radius:12px; border:1px solid #e9ecef;\">\n            <h4 style=\"margin-top:0; color:#333; display:flex; align-items:center; gap:5px;\">\n                \ud83d\udcc4 \uc5d1\uc140 \ud30c\uc77c \uc791\uc131\ubc95\n            <\/h4>\n            <div style=\"display:flex; gap:15px; align-items:flex-start;\">\n                <div style=\"background:white; border:1px solid #ccc; padding:0; border-radius:4px; box-shadow:0 2px 4px rgba(0,0,0,0.1); overflow:hidden; min-width:180px;\">\n                    <table style=\"border-collapse: collapse; font-size:12px; text-align:center; width:100%;\">\n                        <tr style=\"background:#f1f3f4; color:#555;\">\n                            <td style=\"border-bottom:1px solid #ccc; border-right:1px solid #ccc; padding:4px 5px; width:20px;\"><\/td>\n                            <td style=\"border-bottom:1px solid #ccc; border-right:1px solid #ccc; padding:4px 10px; font-weight:bold; color:#188038;\">A (\ub0b4\uc6a9)<\/td>\n                            <td style=\"border-bottom:1px solid #ccc; padding:4px 10px; color:#555; background:#fffbcc;\">\ud83d\udc49 \uacb0\uacfc<\/td>\n                        <\/tr>\n                        <tr>\n                            <td style=\"background:#f1f3f4; border-right:1px solid #ccc; border-bottom:1px solid #eee; padding:4px;\">1<\/td>\n                            <td style=\"border-right:1px solid #eee; border-bottom:1px solid #eee; padding:6px; text-align:left;\">\uccab \ubb38\uc7a5<\/td>\n                            <td style=\"border-bottom:1px solid #eee; color:#d97706; font-weight:bold;\">\ud30c\uc77c_001.mp3<\/td>\n                        <\/tr>\n                        <tr>\n                            <td style=\"background:#f1f3f4; border-right:1px solid #ccc; border-bottom:1px solid #eee; padding:4px;\">2<\/td>\n                            <td style=\"border-right:1px solid #eee; border-bottom:1px solid #eee; padding:6px; text-align:left;\">\ub450 \ubc88\uc9f8<\/td>\n                            <td style=\"border-bottom:1px solid #eee; color:#d97706; font-weight:bold;\">\ud30c\uc77c_002.mp3<\/td>\n                        <\/tr>\n                        <tr>\n                            <td style=\"background:#f1f3f4; border-right:1px solid #ccc; padding:4px;\">3<\/td>\n                            <td style=\"border-right:1px solid #eee; padding:6px; text-align:left;\">\uc138 \ubc88\uc9f8<\/td>\n                            <td style=\"color:#d97706; font-weight:bold;\">\ud30c\uc77c_003.mp3<\/td>\n                        <\/tr>\n                    <\/table>\n                <\/div>\n                <ul style=\"margin:0; padding-left:10px; font-size:13px; color:#666; line-height:1.6; list-style:none;\">\n                    <li style=\"margin-bottom:5px;\">\u2705 <strong>A\uc5f4 1\ubc88 \uc904<\/strong>\ubd80\ud130 \ub0b4\uc6a9\uc744 \ucb49 \uc801\uc5b4\uc8fc\uc138\uc694.<\/li>\n                    <li>\u2705 \ud30c\uc77c\uba85\uc740 \uc5c5\ub85c\ub4dc\ud55c \ud30c\uc77c \uc774\ub984\uc744 \ub530\ub77c\uac11\ub2c8\ub2e4.<\/li>\n                    <li id=\"excel-guide-limit\" style=\"font-weight:bold; color:#e11d48; margin-top:8px;\">\u2705 \ud55c\uae00 1,600\uc790 \/ \uc601\uc5b4 5,000\uc790 \uc81c\ud55c<\/li>\n                <\/ul>\n            <\/div>\n        <\/div>\n\n    <\/div>\n\n<\/div>\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/xlsx\/0.18.5\/xlsx.full.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jszip\/3.10.1\/jszip.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/FileSaver.js\/2.0.5\/FileSaver.min.js\"><\/script>\n\n<script>\n\/\/ \uc560\ub2c8\uba54\uc774\uc158\nconst style = document.createElement('style');\nstyle.innerHTML = `@keyframes fadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }`;\ndocument.head.appendChild(style);\n\n\/\/ \ub4dc\ub798\uadf8 \uc564 \ub4dc\ub86d\nconst dropZone = document.getElementById('drop-zone');\nconst fileInput = document.getElementById('excel-file');\nconst fileNameDisplay = document.getElementById('file-name-display');\n\ndropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.style.backgroundColor = '#ecfdf5'; dropZone.style.borderColor = '#22c55e'; });\ndropZone.addEventListener('dragleave', (e) => { e.preventDefault(); dropZone.style.backgroundColor = 'white'; dropZone.style.borderColor = '#86efac'; });\ndropZone.addEventListener('drop', (e) => {\n    e.preventDefault();\n    dropZone.style.backgroundColor = 'white';\n    dropZone.style.borderColor = '#86efac';\n    if (e.dataTransfer.files.length) { fileInput.files = e.dataTransfer.files; handleFileSelect(fileInput); }\n});\nfunction handleFileSelect(input) {\n    if (input.files && input.files[0]) {\n        fileNameDisplay.innerText = \"\u2705 \uc120\ud0dd\ub428: \" + input.files[0].name;\n        fileNameDisplay.style.color = \"#15803d\";\n        fileNameDisplay.style.fontWeight = \"bold\";\n    }\n}\n\n\/\/ \u2605 \uc131\uc6b0 \ub370\uc774\ud130 (\uc601\uc5b4 \uc124\uba85 \ucd94\uac00) \u2605\nconst voices = {\n    'kr': [\n        \/\/ Chirp 3 (8\uba85)\n        {val:'ko-KR-Chirp3-HD-Fenrir', name:'\u2728 [Chirp3] \ub0a8\uc131 (Fenrir) - \uc790\uc5f0\uc2a4\ub7ec\uc6c0'},\n        {val:'ko-KR-Chirp3-HD-Puck', name:'\u2728 [Chirp3] \ub0a8\uc131 (Puck) - \ubd80\ub4dc\ub7ec\uc6c0'},\n        {val:'ko-KR-Chirp3-HD-Kore', name:'\u2728 [Chirp3] \uc5ec\uc131 (Kore) - \ucc28\ubd84\ud568'},\n        {val:'ko-KR-Chirp3-HD-Aoede', name:'\u2728 [Chirp3] \uc5ec\uc131 (Aoede) - \ubc1d\uc74c'},\n        {val:'ko-KR-Chirp3-HD-Leda', name:'\u2728 [Chirp3] \uc5ec\uc131 (Leda) - \ub610\ub837\ud568'},\n        {val:'ko-KR-Chirp3-HD-Zephyr', name:'\u2728 [Chirp3] \uc5ec\uc131 (Zephyr) - \ubd80\ub4dc\ub7ec\uc6c0'},\n        {val:'ko-KR-Chirp3-HD-Orus', name:'\u2728 [Chirp3] \ub0a8\uc131 (Orus) - \uc911\ud6c4\ud568'},\n        {val:'ko-KR-Chirp3-HD-Rasalgethi', name:'\u2728 [Chirp3] \ub0a8\uc131 (Rasalgethi) - \ub2f4\ubc31\ud568'},\n\n        \/\/ Neural2 & Standard\n        {val:'ko-KR-Neural2-A', name:'[Neural2] \uc5ec\uc131 A (\uc815\ud655\ud55c \uc544\ub098\uc6b4\uc11c)'},\n        {val:'ko-KR-Neural2-B', name:'[Neural2] \uc5ec\uc131 B (\ubd80\ub4dc\ub7ec\uc6b4 \ud1a4)'},\n        {val:'ko-KR-Neural2-C', name:'[Neural2] \ub0a8\uc131 C (\uad75\uace0 \uc2e0\ub8b0\uac10)'},\n        {val:'ko-KR-Wavenet-A', name:'[Standard] \uc5ec\uc131 A (\ub9d1\uace0 \uae68\ub057\ud568)'},\n        {val:'ko-KR-Wavenet-D', name:'[Standard] \ub0a8\uc131 D (\uc911\uc800\uc74c)'}\n    ],\n    'en': [\n        \/\/ Chirp 3 (8\uba85) - \uc124\uba85 \ucd94\uac00\ub428 (Deep & Strong, Natural \ub4f1)\n        {val:'en-US-Chirp3-HD-Fenrir', name:'\u2728 [Chirp3] US Male (Fenrir) - Deep & Strong'},\n        {val:'en-US-Chirp3-HD-Puck', name:'\u2728 [Chirp3] US Male (Puck) - Natural & Casual'},\n        {val:'en-US-Chirp3-HD-Kore', name:'\u2728 [Chirp3] US Female (Kore) - Calm & Soothing'},\n        {val:'en-US-Chirp3-HD-Aoede', name:'\u2728 [Chirp3] US Female (Aoede) - Bright & Energetic'},\n        {val:'en-US-Chirp3-HD-Leda', name:'\u2728 [Chirp3] US Female (Leda) - Clear & Articulate'},\n        {val:'en-US-Chirp3-HD-Zephyr', name:'\u2728 [Chirp3] US Female (Zephyr) - Soft & Gentle'},\n        {val:'en-US-Chirp3-HD-Orus', name:'\u2728 [Chirp3] US Male (Orus) - Deep & Authoritative'},\n        {val:'en-US-Chirp3-HD-Rasalgethi', name:'\u2728 [Chirp3] US Male (Rasalgethi) - Neutral & Clean'},\n\n        \/\/ Neural2 & Studio - \uc124\uba85 \ubcf4\uac15\n        {val:'en-US-Studio-M', name:'\ud83c\uddfa\ud83c\uddf8 US Studio Male M (Deep Voice)'},\n        {val:'en-US-Journey-D', name:'\ud83c\uddfa\ud83c\uddf8 US Journey Male D (Podcast Style)'},\n        {val:'en-US-Studio-O', name:'\ud83c\uddfa\ud83c\uddf8 US Studio Female O (Calm & Professional)'},\n        {val:'en-GB-Studio-C', name:'\ud83c\uddec\ud83c\udde7 UK Studio Female C (Posh & Clear)'}\n    ]\n};\n\ndocument.addEventListener('DOMContentLoaded', function() { updateVoiceList(); });\n\n\/\/ \uc5b8\uc5b4\ubcc4 \uc81c\ud55c \uae00\uc790\uc218 \ubc18\ud658 (kr:1600 \/ en:5000)\nfunction getCurrentLimit() {\n    const lang = document.getElementById('lang-select').value;\n    return (lang === 'kr') ? 1600 : 5000;\n}\n\nfunction updateVoiceList() {\n    const lang = document.getElementById('lang-select').value;\n    const voiceSelect = document.getElementById('voice-select');\n    voiceSelect.innerHTML = '';\n    \n    \/\/ \uc131\uc6b0 \ubaa9\ub85d \uc5c5\ub370\uc774\ud2b8\n    const list = voices[lang];\n    list.forEach(v => {\n        const option = document.createElement('option');\n        option.value = v.val;\n        option.innerText = v.name;\n        voiceSelect.appendChild(option);\n    });\n    \n    \/\/ UI \uc5c5\ub370\uc774\ud2b8: \uae00\uc790\uc218 \uc81c\ud55c \ud45c\uc2dc \ubcc0\uacbd\n    const limit = getCurrentLimit();\n    const limitText = limit.toLocaleString();\n    const langName = (lang === 'kr') ? '\ud55c\uae00' : '\uc601\uc5b4';\n    \n    document.getElementById('char-limit').innerText = limitText;\n    document.getElementById('excel-limit-msg').innerText = `\u203b \ud55c \uc140\ub2f9 \ucd5c\ub300 ${limitText}\uc790(${langName}) \uc81c\ud55c`;\n    document.getElementById('excel-guide-limit').innerText = `\u2705 \ud55c\uae00 1,600\uc790 \/ \uc601\uc5b4 5,000\uc790 \uc81c\ud55c`;\n    \n    \/\/ \uc785\ub825\ub41c \ud14d\uc2a4\ud2b8 \uc7ac\uac80\uc0ac & \uc18d\ub3c4 \uc870\uc808 \uccb4\ud06c\n    updateCharCount();\n    checkSpeedCapability();\n}\n\nfunction checkSpeedCapability() {\n    const voice = document.getElementById('voice-select').value;\n    const speedInput = document.getElementById('speed-input');\n    const notice = document.getElementById('chirp-notice');\n\n    if (voice.includes(\"Chirp3\")) {\n        speedInput.value = 1.0;\n        speedInput.disabled = true;\n        speedInput.style.backgroundColor = '#e5e7eb';\n        speedInput.style.color = '#9ca3af';\n        notice.style.display = 'block';\n    } else {\n        speedInput.disabled = false;\n        speedInput.style.backgroundColor = 'white';\n        speedInput.style.color = 'black';\n        notice.style.display = 'none';\n    }\n}\n\n\/\/ \uc2e4\uc2dc\uac04 \uae00\uc790\uc218 \ud655\uc778 \ubc0f \uacbd\uace0 \uc2a4\ud0c0\uc77c\nfunction updateCharCount() {\n    const textarea = document.getElementById('single-text');\n    const counter = document.getElementById('char-current');\n    const max = getCurrentLimit();\n    const len = textarea.value.length;\n    \n    counter.innerText = len.toLocaleString();\n    \n    if (len > max) {\n        counter.style.color = \"red\";\n        counter.style.fontWeight = \"900\";\n        textarea.style.borderColor = \"red\";\n        textarea.style.backgroundColor = \"#fff0f0\";\n    } else {\n        counter.style.color = \"#3b82f6\";\n        counter.style.fontWeight = \"bold\";\n        textarea.style.borderColor = \"#cbd5e1\";\n        textarea.style.backgroundColor = \"white\";\n    }\n}\n\n\/\/ 1. \ub2e8\uac74 \ub179\uc74c (\uae38\uc774 \uc81c\ud55c \uccb4\ud06c \ucd94\uac00)\nasync function generateSingle() {\n    const text = document.getElementById('single-text').value;\n    const max = getCurrentLimit();\n\n    if(!text) return alert(\"\ub0b4\uc6a9\uc744 \uc785\ub825\ud574\uc8fc\uc138\uc694.\");\n    \n    \/\/ \uc81c\ud55c \ucd08\uacfc \uc2dc \ucc28\ub2e8\n    if(text.length > max) {\n        return alert(`[\uae38\uc774 \ucd08\uacfc]\\n\ud604\uc7ac \uc5b8\uc5b4 \uc81c\ud55c: ${max.toLocaleString()}\uc790\\n\uc785\ub825\ub41c \uae00\uc790: ${text.length.toLocaleString()}\uc790\\n\\n\ub0b4\uc6a9\uc744 \uc904\uc5ec\uc8fc\uc138\uc694.`);\n    }\n    \n    const btn = document.getElementById('single-btn');\n    const resultArea = document.getElementById('single-result-area');\n    const audio = document.getElementById('single-player');\n    const downloadLink = document.getElementById('single-download-link');\n\n    btn.innerText = \"\u23f3 \uc0dd\uc131 \uc911...\";\n    btn.disabled = true;\n    resultArea.style.display = 'none';\n\n    try {\n        await callApi(text, (audioData) => {\n            const audioUrl = \"data:audio\/mp3;base64,\" + audioData;\n            audio.src = audioUrl;\n            const date = new Date();\n            const timeStr = date.getHours() + \"\" + date.getMinutes() + \"\" + date.getSeconds();\n            downloadLink.href = audioUrl;\n            downloadLink.download = `voice_${timeStr}.mp3`;\n            resultArea.style.display = 'block';\n            audio.play(); \n        });\n    } catch(e) { alert(\"\uc624\ub958: \" + e); } \n    finally { btn.innerText = \"\ud83c\udf99\ufe0f \ub179\uc74c \uc0dd\uc131\ud558\uae30\"; btn.disabled = false; }\n}\n\n\/\/ 2. \uc5d1\uc140 \uc77c\uad04 (\uae38\uc774 \uc81c\ud55c \uccb4\ud06c \ucd94\uac00)\nasync function processBatch() {\n    const fileInput = document.getElementById('excel-file');\n    if(fileInput.files.length === 0) return alert(\"\uc5d1\uc140 \ud30c\uc77c\uc744 \uc120\ud0dd\ud558\uac70\ub098 \ub4dc\ub798\uadf8\ud574\uc8fc\uc138\uc694.\");\n\n    const file = fileInput.files[0];\n    let baseName = file.name;\n    if(baseName.lastIndexOf('.') !== -1) baseName = baseName.substring(0, baseName.lastIndexOf('.'));\n\n    const reader = new FileReader();\n    reader.onload = async function(e) {\n        try {\n            const data = new Uint8Array(e.target.result);\n            const workbook = XLSX.read(data, {type: 'array'});\n            const rows = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]], {header:1});\n            const cleanRows = rows.map(r => r[0]).filter(t => t && String(t).trim() !== \"\");\n            \n            if(cleanRows.length === 0) return alert(\"A\uc5f4\uc5d0 \ub0b4\uc6a9\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.\");\n            \n            \/\/ [\uac80\uc0ac] \uc5d1\uc140 \ub0b4\uc6a9 \uae38\uc774 \uac80\uc0ac\n            const max = getCurrentLimit();\n            for(let i=0; i<cleanRows.length; i++) {\n                if(String(cleanRows[i]).length > max) {\n                    return alert(`[\uc624\ub958] ${i+1}\ubc88\uc9f8 \uc904\uc758 \ub0b4\uc6a9\uc774 \uc81c\ud55c(${max.toLocaleString()}\uc790)\uc744 \ub118\uc5c8\uc2b5\ub2c8\ub2e4.\\n\ud604\uc7ac: ${String(cleanRows[i]).length.toLocaleString()}\uc790\\n\\n\uc904\uc5ec\uc11c \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694.`);\n                }\n            }\n\n            if(!confirm(`\ucd1d ${cleanRows.length}\uac1c \ubb38\uc7a5\uc744 \ubcc0\ud658\ud569\ub2c8\ub2e4.`)) return;\n\n            const zip = new JSZip();\n            const progressContainer = document.getElementById('batch-progress-container');\n            const progressBar = document.getElementById('progress-bar');\n            const progressText = document.getElementById('progress-text');\n            const btn = document.getElementById('batch-btn');\n\n            progressContainer.style.display = 'block';\n            btn.disabled = true;\n\n            for(let i=0; i<cleanRows.length; i++) {\n                const text = cleanRows[i];\n                const fileName = `${baseName}_${String(i+1).padStart(3, '0')}.mp3`;\n                progressBar.style.width = Math.round(((i)\/cleanRows.length)*100) + \"%\";\n                progressText.innerText = `(${i+1}\/${cleanRows.length}) \uc0dd\uc131 \uc911: ${fileName}`;\n                try { await callApi(text, (b64) => zip.file(fileName, b64, {base64:true})); } \n                catch(err) { zip.file(`error_${i+1}.txt`, `\uc2e4\ud328: ${text}`); }\n                await new Promise(r => setTimeout(r, 200));\n            }\n\n            progressBar.style.width = \"100%\";\n            progressText.innerText = \"\uc555\ucd95 \uc911...\";\n            zip.generateAsync({type:\"blob\"}).then(c => {\n                saveAs(c, `${baseName}_audio.zip`);\n                progressText.innerText = \"\u2705 \uc644\ub8cc!\";\n                alert(\"\ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc2dc\uc791\ub429\ub2c8\ub2e4.\");\n                btn.disabled = false;\n            });\n        } catch(e) { alert(\"\ud30c\uc77c \uc77d\uae30 \uc624\ub958: \" + e); }\n    };\n    reader.readAsArrayBuffer(file);\n}\n\n\/\/ API \ud638\ucd9c\nasync function callApi(text, callback) {\n    const voice = document.getElementById('voice-select').value;\n    const speed = parseFloat(document.getElementById('speed-input').value);\n    const response = await fetch('https:\/\/tts-generator-1060238498564.asia-northeast3.run.app', { \n        method: 'POST', headers: {'Content-Type': 'application\/json'},\n        body: JSON.stringify({ text, voice, speed }) \n    });\n    const data = await response.json();\n    if (data.audioContent) callback(data.audioContent);\n    else throw new Error(data.error || \"Server Error\");\n}\n<\/script>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>CONPOP AI \ubcf4\uc774\uc2a4 \u2699\ufe0f \uc131\uc6b0 \ubc0f \uc18d\ub3c4 \uc124\uc815 (\ubaa8\ub4e0 \uc791\uc5c5\uc5d0 \uacf5\ud1b5 \uc801\uc6a9) \ud83c\uddf0\ud83c\uddf7 \ud55c\uad6d\uc5b4 (Korean)\ud83c\uddfa\ud83c\uddf8\/\ud83c\uddec\ud83c\udde7 \uc601\uc5b4 (English) \u26a1 \uc18d\ub3c4: \u203b \u2728Chirp 3(\uc0dd\uc131\ud615 AI) \ubaa8\ub378\uc740 \uc18d\ub3c4 \uc870\uc808\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. (1.0 \uace0\uc815) 1\ufe0f\u20e3 \ud55c \ubb38\uc7a5 \ub179\uc74c \uc9e7\uc740 \ubb38\uc7a5\uc744 \ub179\uc74c\ud558\uace0 \ubc14\ub85c \ud655\uc778\ud558\uc138\uc694. 0 \/ 1,600\uc790 \ud83c\udf99\ufe0f \ub179\uc74c \uc0dd\uc131\ud558\uae30 \u2705 \uc0dd\uc131 \uc644\ub8cc! \u2b07\ufe0f MP3 \ub2e4\uc6b4\ub85c\ub4dc 2\ufe0f\u20e3 \uc5d1\uc140 \ub300\ub7c9 \ubcc0\ud658 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-8","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=\/wp\/v2\/pages\/8","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8"}],"version-history":[{"count":58,"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=\/wp\/v2\/pages\/8\/revisions"}],"predecessor-version":[{"id":67,"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=\/wp\/v2\/pages\/8\/revisions\/67"}],"wp:attachment":[{"href":"https:\/\/conpop.ai.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}