<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>SmartRee</title>
    <link>https://smartree.tistory.com/</link>
    <description>인생에 정답이 있나 선택이 있지!
선택을 하면 후회가 없어야 한다!</description>
    <language>ko</language>
    <pubDate>Tue, 9 Jun 2026 09:20:01 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>SmartRee</managingEditor>
    <image>
      <title>SmartRee</title>
      <url>https://t1.daumcdn.net/cfile/tistory/18013441515FA84D07</url>
      <link>https://smartree.tistory.com</link>
    </image>
    <item>
      <title>e학습터 서비스 종료</title>
      <link>https://smartree.tistory.com/161</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;코로나 상황 속에서 그나마 교육 현장을 버티게 만들어준 서비스가 오늘 공문을 보니&amp;nbsp;종료한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추억 속에 하나의 서비스가 또 종료되는구나.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경기도야 하이러닝을 밀고 있긴 하지만 다른 지역은 뭐가 있을라나.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 원격수업으로 전환되는 일은 없어야 하는데.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말이지 코로나때 버텨낸 것이 참 다행이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;서비스 종료 안내.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1040&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cB547T/btsQoPNG30X/GjY4k0FDmPgV11xT4ek2ak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cB547T/btsQoPNG30X/GjY4k0FDmPgV11xT4ek2ak/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cB547T/btsQoPNG30X/GjY4k0FDmPgV11xT4ek2ak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcB547T%2FbtsQoPNG30X%2FGjY4k0FDmPgV11xT4ek2ak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;1040&quot; data-filename=&quot;서비스 종료 안내.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;1040&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>SmartRee/세상 사는 이야기</category>
      <category>e학습터종료</category>
      <category>코로나</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/161</guid>
      <comments>https://smartree.tistory.com/161#entry161comment</comments>
      <pubDate>Mon, 8 Sep 2025 17:01:01 +0900</pubDate>
    </item>
    <item>
      <title>60갑자 계산기</title>
      <link>https://smartree.tistory.com/159</link>
      <description>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;60갑자 계산기&lt;/title&gt;
    &lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&amp;display=swap');
        body {
            font-family: 'Noto Sans KR', sans-serif;
        }
        .animal-icon {
            font-size: 3rem;
            animation: bounce 2s infinite;
        }
        @media (min-width: 640px) {
            .animal-icon {
                font-size: 4rem;
            }
        }
        @media (min-width: 1024px) {
            .animal-icon {
                font-size: 5rem;
            }
        }
        @keyframes bounce {
            0%, 20%, 50%, 80%, 100% {
                transform: translateY(0);
            }
            40% {
                transform: translateY(-10px);
            }
            60% {
                transform: translateY(-5px);
            }
        }
        .result-card {
            border-radius: 20px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            transition: all 0.8s ease;
        }
        
        /* 천간별 배경 색상 */
        .blue-bg {
            background: linear-gradient(135deg, #74b9ff 0%, #0984e3 100%);
        }
        .red-bg {
            background: linear-gradient(135deg, #ff6b6b 0%, #feca57 100%);
        }
        .yellow-bg {
            background: linear-gradient(135deg, #ffeaa7 0%, #fab1a0 100%);
        }
        .white-bg {
            background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
        }
        .black-bg {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .input-field {
            background: white;
            border: 2px solid #e5e7eb;
            transition: all 0.3s ease;
        }
        .input-field:focus {
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }
        .calculate-btn {
            background: linear-gradient(45deg, #ff6b6b, #feca57);
            transition: all 0.3s ease;
        }
        .calculate-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 25px rgba(255, 107, 107, 0.3);
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body class=&quot;min-h-screen bg-white p-2 sm:p-4 lg:p-6&quot;&gt;
    &lt;div class=&quot;max-w-[800px] mx-auto px-4 sm:px-6&quot;&gt;
        &lt;!-- 헤더 --&gt;
        &lt;div class=&quot;text-center mb-6 sm:mb-8&quot;&gt;
            &lt;h1 class=&quot;text-2xl sm:text-3xl lg:text-4xl font-bold text-gray-800 mb-2&quot;&gt;  60갑자 계산기  &lt;/h1&gt;
            &lt;p class=&quot;text-gray-600 text-sm sm:text-base lg:text-lg&quot;&gt;연도를 입력하면 갑자와 띠를 알려드려요!&lt;/p&gt;
        &lt;/div&gt;

        &lt;!-- 입력 섹션 --&gt;
        &lt;div class=&quot;bg-gray-200 border border-gray-300 rounded-2xl p-4 sm:p-6 mb-4 sm:mb-6 shadow-lg&quot;&gt;
            &lt;div class=&quot;flex flex-col gap-3 sm:gap-4&quot;&gt;
                &lt;input 
                    type=&quot;number&quot; 
                    id=&quot;yearInput&quot; 
                    placeholder=&quot;연도를 입력하세요 (예: 2025)&quot;
                    class=&quot;input-field w-full px-4 py-3 sm:py-4 rounded-xl text-base sm:text-lg font-medium text-gray-800 outline-none&quot;
                    min=&quot;1&quot;
                    max=&quot;9999&quot;
                &gt;
                &lt;button 
                    onclick=&quot;calculateGapja()&quot; 
                    class=&quot;calculate-btn w-full px-6 py-3 sm:py-4 rounded-xl text-white font-bold text-base sm:text-lg shadow-lg&quot;
                &gt;
                    계산하기 ✨
                &lt;/button&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;!-- 결과 섹션 --&gt;
        &lt;div id=&quot;result&quot; class=&quot;hidden result-card p-4 sm:p-6 lg:p-8 text-center&quot;&gt;
            &lt;div id=&quot;animalIcon&quot; class=&quot;animal-icon mb-3 sm:mb-4&quot;&gt;&lt;/div&gt;
            &lt;div id=&quot;resultText&quot; class=&quot;text-base sm:text-lg lg:text-xl font-medium leading-relaxed&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;!-- 설명 섹션 --&gt;
        &lt;div class=&quot;bg-gray-200 border border-gray-300 rounded-2xl p-4 sm:p-6 mt-4 sm:mt-6 shadow-xl&quot;&gt;
            &lt;h3 class=&quot;text-gray-800 font-bold text-base sm:text-lg mb-3 sm:mb-4&quot;&gt;  60갑자란?&lt;/h3&gt;
            
            &lt;div class=&quot;space-y-3 sm:space-y-4 text-gray-700 text-sm sm:text-base leading-relaxed&quot;&gt;
                &lt;p&gt;
                    &lt;strong class=&quot;text-gray-900&quot;&gt;60갑자&lt;/strong&gt;는 우리 조상들이 만든 시간을 세는 방법이에요. 
                    마치 달력처럼 60년마다 같은 이름이 반복되는 순환 체계입니다.
                &lt;/p&gt;
                
                &lt;div class=&quot;grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4 mt-4&quot;&gt;
                    &lt;div class=&quot;bg-white rounded-xl p-4 sm:p-5 shadow-lg border border-gray-300&quot;&gt;
                        &lt;h4 class=&quot;text-gray-800 font-bold mb-3 text-sm sm:text-base&quot;&gt;  천간 (10개)&lt;/h4&gt;
                        &lt;div class=&quot;text-sm sm:text-base space-y-2 font-medium&quot;&gt;
                            &lt;p&gt;&lt;span class=&quot;text-white bg-blue-600 px-3 py-1 rounded-md font-semibold&quot;&gt;갑(甲), 을(乙)&lt;/span&gt; - 푸른색 (동쪽)&lt;/p&gt;
                            &lt;p&gt;&lt;span class=&quot;text-white bg-red-600 px-3 py-1 rounded-md font-semibold&quot;&gt;병(丙), 정(丁)&lt;/span&gt; - 붉은색 (남쪽)&lt;/p&gt;
                            &lt;p&gt;&lt;span class=&quot;text-gray-800 bg-yellow-400 px-3 py-1 rounded-md font-semibold&quot;&gt;무(戊), 기(己)&lt;/span&gt; - 노란색 (중앙)&lt;/p&gt;
                            &lt;p&gt;&lt;span class=&quot;text-gray-800 bg-gray-300 px-3 py-1 rounded-md font-semibold&quot;&gt;경(庚), 신(辛)&lt;/span&gt; - 흰색 (서쪽)&lt;/p&gt;
                            &lt;p&gt;&lt;span class=&quot;text-white bg-purple-600 px-3 py-1 rounded-md font-semibold&quot;&gt;임(壬), 계(癸)&lt;/span&gt; - 검은색 (북쪽)&lt;/p&gt;
                        &lt;/div&gt;
                        &lt;p class=&quot;text-sm mt-3 text-gray-600&quot;&gt;오행과 방위를 나타내요&lt;/p&gt;
                    &lt;/div&gt;
                    
                    &lt;div class=&quot;bg-white rounded-xl p-4 sm:p-5 shadow-lg border border-gray-300&quot;&gt;
                        &lt;h4 class=&quot;text-gray-800 font-bold mb-3 text-sm sm:text-base&quot;&gt;  지지 (12개)&lt;/h4&gt;
                        &lt;div class=&quot;text-sm sm:text-base space-y-2 font-medium&quot;&gt;
                            &lt;p class=&quot;bg-gray-100 px-3 py-2 rounded-md text-gray-800 font-semibold border border-gray-200&quot;&gt;자(子)  축(丑)  인(寅)  묘(卯) &lt;/p&gt;
                            &lt;p class=&quot;bg-gray-100 px-3 py-2 rounded-md text-gray-800 font-semibold border border-gray-200&quot;&gt;진(辰)  사(巳)  오(午)  미(未) &lt;/p&gt;
                            &lt;p class=&quot;bg-gray-100 px-3 py-2 rounded-md text-gray-800 font-semibold border border-gray-200&quot;&gt;신(申)  유(酉)  술(戌)  해(亥) &lt;/p&gt;
                        &lt;/div&gt;
                        &lt;p class=&quot;text-sm mt-3 text-gray-600&quot;&gt;12띠 동물과 시간을 나타내요&lt;/p&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                
                &lt;p class=&quot;mt-4&quot;&gt;
                    &lt;strong class=&quot;text-gray-900&quot;&gt;10 × 12 = 60&lt;/strong&gt;개의 조합이 만들어져서 
                    60년마다 같은 갑자가 돌아와요. 예를 들어 1984년과 2044년은 모두 '갑자년'이랍니다!  
                &lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // 천간 (10개)
        const heavenlyStems = [
            { korean: '갑', hanja: '甲', color: '푸른', bgClass: 'blue-bg' },
            { korean: '을', hanja: '乙', color: '푸른', bgClass: 'blue-bg' },
            { korean: '병', hanja: '丙', color: '붉은', bgClass: 'red-bg' },
            { korean: '정', hanja: '丁', color: '붉은', bgClass: 'red-bg' },
            { korean: '무', hanja: '戊', color: '노란', bgClass: 'yellow-bg' },
            { korean: '기', hanja: '己', color: '노란', bgClass: 'yellow-bg' },
            { korean: '경', hanja: '庚', color: '흰', bgClass: 'white-bg' },
            { korean: '신', hanja: '辛', color: '흰', bgClass: 'white-bg' },
            { korean: '임', hanja: '壬', color: '검은', bgClass: 'black-bg' },
            { korean: '계', hanja: '癸', color: '검은', bgClass: 'black-bg' }
        ];

        // 지지 (12개)
        const earthlyBranches = [
            { korean: '자', hanja: '子', animal: '쥐', icon: ' ' },
            { korean: '축', hanja: '丑', animal: '소', icon: ' ' },
            { korean: '인', hanja: '寅', animal: '호랑이', icon: ' ' },
            { korean: '묘', hanja: '卯', animal: '토끼', icon: ' ' },
            { korean: '진', hanja: '辰', animal: '용', icon: ' ' },
            { korean: '사', hanja: '巳', animal: '뱀', icon: ' ' },
            { korean: '오', hanja: '午', animal: '말', icon: ' ' },
            { korean: '미', hanja: '未', animal: '양', icon: ' ' },
            { korean: '신', hanja: '申', animal: '원숭이', icon: ' ' },
            { korean: '유', hanja: '酉', animal: '닭', icon: ' ' },
            { korean: '술', hanja: '戌', animal: '개', icon: ' ' },
            { korean: '해', hanja: '亥', animal: '돼지', icon: ' ' }
        ];

        function calculateGapja() {
            const yearInput = document.getElementById('yearInput');
            const year = parseInt(yearInput.value);
            
            if (!year || year &lt; 1 || year &gt; 9999) {
                alert('올바른 연도를 입력해주세요! (1-9999)');
                return;
            }

            // 갑자 계산 (기준년도: 1984년 = 갑자년)
            const baseYear = 1984;
            const yearDiff = year - baseYear;
            
            // 천간 계산 (10년 주기)
            const stemIndex = ((yearDiff % 10) + 10) % 10;
            const stem = heavenlyStems[stemIndex];
            
            // 지지 계산 (12년 주기)
            const branchIndex = ((yearDiff % 12) + 12) % 12;
            const branch = earthlyBranches[branchIndex];
            
            // 결과 표시
            displayResult(year, stem, branch);
        }

        function displayResult(year, stem, branch) {
            const resultDiv = document.getElementById('result');
            const animalIcon = document.getElementById('animalIcon');
            const resultText = document.getElementById('resultText');
            
            // 기존 배경 클래스 제거
            resultDiv.className = resultDiv.className.replace(/\b(blue|red|yellow|white|black)-bg\b/g, '');
            
            // 천간에 따른 배경색 적용
            resultDiv.classList.add(stem.bgClass);
            
            animalIcon.textContent = branch.icon;
            
            // 배경별 최적화된 텍스트 색상 설정
            let textColor, accentColor, animalColor;
            
            switch(stem.bgClass) {
                case 'blue-bg':
                    textColor = 'text-white';
                    accentColor = 'text-yellow-100';
                    animalColor = 'text-yellow-200';
                    break;
                case 'red-bg':
                    textColor = 'text-white';
                    accentColor = 'text-yellow-100';
                    animalColor = 'text-white';
                    break;
                case 'yellow-bg':
                    textColor = 'text-gray-800';
                    accentColor = 'text-purple-800';
                    animalColor = 'text-red-700';
                    break;
                case 'white-bg':
                    textColor = 'text-gray-900';
                    accentColor = 'text-blue-800';
                    animalColor = 'text-red-700';
                    break;
                case 'black-bg':
                    textColor = 'text-white';
                    accentColor = 'text-yellow-300';
                    animalColor = 'text-cyan-300';
                    break;
                default:
                    textColor = 'text-white';
                    accentColor = 'text-yellow-300';
                    animalColor = 'text-green-300';
            }
            
            resultText.innerHTML = `
                &lt;div class=&quot;mb-3 sm:mb-4&quot;&gt;
                    &lt;span class=&quot;text-lg sm:text-xl lg:text-2xl font-bold ${textColor}&quot;&gt;서기 ${year}년&lt;/span&gt;&lt;span class=&quot;${textColor}&quot;&gt;은&lt;/span&gt;
                &lt;/div&gt;
                &lt;div class=&quot;mb-3 sm:mb-4&quot;&gt;
                    &lt;span class=&quot;text-xl sm:text-2xl lg:text-3xl font-bold ${accentColor}&quot;&gt;${stem.korean}${branch.korean}(${stem.hanja}${branch.hanja})년&lt;/span&gt; &lt;span class=&quot;${textColor}&quot;&gt;이며,&lt;/span&gt;
                &lt;/div&gt;
                &lt;div class=&quot;text-lg sm:text-xl lg:text-2xl ${textColor}&quot;&gt;
                    &lt;span class=&quot;font-bold ${animalColor}&quot;&gt;${stem.color} ${branch.animal}&lt;/span&gt;의 해입니다.
                &lt;/div&gt;
            `;
            
            resultDiv.classList.remove('hidden');
            resultDiv.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }

        // 엔터키로 계산하기
        document.getElementById('yearInput').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                calculateGapja();
            }
        });

        // 페이지 로드시 현재 연도로 예시 보여주기
        window.addEventListener('load', function() {
            const currentYear = new Date().getFullYear();
            document.getElementById('yearInput').value = currentYear;
            calculateGapja();
        });
    &lt;/script&gt;
&lt;script&gt;(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML=&quot;window.__CF$cv$params={r:'96beb8d0c764ea8d',t:'MTc1NDY1MzA0OC4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);&quot;;b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&amp;&amp;(document.onreadystatechange=e,c())}}}})();&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</description>
      <category>수업자료</category>
      <category>60갑자</category>
      <category>불펌금지</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/159</guid>
      <comments>https://smartree.tistory.com/159#entry159comment</comments>
      <pubDate>Fri, 8 Aug 2025 20:20:55 +0900</pubDate>
    </item>
    <item>
      <title>이모지를 활용한 낱말 글씨 쓰기 학습지 생성기</title>
      <link>https://smartree.tistory.com/158</link>
      <description>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;낱말 학습지 생성기&lt;/title&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        /* 학교안심받아쓰기체 */
        @font-face {
            font-family: 'HakgyoansimBareunbatangR';
            src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/2408-5@1.0/HakgyoansimBadasseugiTTF-L.woff2') format('woff2');
            font-weight: normal;
            font-style: normal;
            font-display: swap;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 10px;
        }
        
        @media (max-width: 768px) {
            body {
                padding: 8px;
            }
        }
        
        @media (max-width: 480px) {
            body {
                padding: 5px;
            }
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            display: grid;
            grid-template-columns: 420px 600px;
            gap: 20px;
            height: calc(100vh - 20px);
        }
        
        @media (max-width: 1200px) {
            .container {
                grid-template-columns: 360px 500px;
                gap: 15px;
            }
        }
        
        @media (max-width: 1024px) {
            .container {
                grid-template-columns: 320px 450px;
                gap: 12px;
            }
        }
        
        @media (max-width: 768px) {
            .container {
                grid-template-columns: 1fr;
                height: auto;
                gap: 20px;
            }
        }
        
        .input-panel {
            background: white;
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 8px 25px rgba(0,0,0,0.15);
            display: flex;
            flex-direction: column;
        }
        
        @media (max-width: 768px) {
            .input-panel {
                padding: 15px;
                border-radius: 8px;
            }
        }
        
        @media (max-width: 480px) {
            .input-panel {
                padding: 12px;
                margin: 0 5px;
            }
        }
        
        .preview-panel {
            background: white;
            border-radius: 12px;
            padding: 15px;
            box-shadow: 0 8px 25px rgba(0,0,0,0.15);
            display: flex;
            flex-direction: column;
        }
        
        @media (max-width: 768px) {
            .preview-panel {
                padding: 12px;
                border-radius: 8px;
            }
        }
        
        @media (max-width: 480px) {
            .preview-panel {
                padding: 10px;
                margin: 0 5px;
            }
        }
        
        h1 {
            color: #4a5568;
            margin-bottom: 20px;
            font-size: 24px;
            text-align: center;
        }
        
        .input-area {
            flex: 1;
            display: flex;
            flex-direction: column;
        }
        
        textarea {
            height: 480px;
            border: 2px solid #e2e8f0;
            border-radius: 10px;
            padding: 15px;
            font-size: 20px;
            line-height: 1.8;
            resize: none;
            outline: none;
            transition: border-color 0.3s;
        }
        
        @media (max-width: 768px) {
            textarea {
                height: 300px;
                font-size: 18px;
                padding: 12px;
            }
        }
        
        @media (max-width: 480px) {
            textarea {
                height: 250px;
                font-size: 16px;
                padding: 10px;
            }
        }
        
        textarea:focus {
            border-color: #667eea;
        }
        
        .title-input-section {
            margin-bottom: 20px;
        }
        
        .title-input-section label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #4a5568;
        }
        
        .title-input-section input {
            width: 100%;
            padding: 12px;
            border: 2px solid #e2e8f0;
            border-radius: 8px;
            font-size: 20px;
            outline: none;
            transition: border-color 0.3s;
        }
        
        .title-input-section input:focus {
            border-color: #667eea;
        }
        
        .school-info-section {
            margin-bottom: 20px;
        }
        
        .school-info-section label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #4a5568;
        }
        
        .school-info-grid {
            display: grid;
            grid-template-columns: 1fr 1fr 1fr;
            gap: 10px;
        }
        
        @media (max-width: 480px) {
            .school-info-grid {
                grid-template-columns: 1fr;
                gap: 8px;
            }
        }
        
        .info-item {
            display: flex;
            flex-direction: column;
        }
        
        .info-item label {
            font-size: 14px;
            margin-bottom: 4px;
        }
        
        .info-item input {
            padding: 8px;
            border: 2px solid #e2e8f0;
            border-radius: 6px;
            font-size: 16px;
            outline: none;
            transition: border-color 0.3s;
        }
        
        .info-item input:focus {
            border-color: #667eea;
        }
        
        .color-selection {
            margin-bottom: 20px;
        }
        
        .color-selection label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #4a5568;
        }
        
        .color-options {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
        }
        
        @media (max-width: 480px) {
            .color-options {
                gap: 8px;
            }
        }
        
        .color-option {
            display: flex;
            align-items: center;
            gap: 5px;
            padding: 8px 12px;
            border: 2px solid #e2e8f0;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        .color-option:hover {
            background: #f7fafc;
        }
        
        .color-option.active {
            border-color: #667eea;
            background: #edf2f7;
        }
        
        .color-option input[type=&quot;radio&quot;] {
            margin: 0;
        }
        
        .color-option span {
            font-size: 14px;
            font-weight: 500;
        }
        
        .follow-mode-section {
            margin-bottom: 20px;
        }
        
        .checkbox-container {
            display: flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            font-weight: 500;
            color: #4a5568;
        }
        
        .checkbox-container input[type=&quot;checkbox&quot;] {
            width: 18px;
            height: 18px;
            cursor: pointer;
        }
        
        .instructions {
            background: #f7fafc;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 15px;
            font-size: 14px;
            color: #4a5568;
        }
        
        .preview-area {
            flex: 1;
            display: flex;
            flex-direction: column;
        }
        
        .preview-content {
            flex: 1;
            overflow-y: auto;
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100%;
            max-width: 210mm;
            margin: 0 auto;
        }
        
        .worksheet {
            width: 210mm;
            height: 297mm;
            max-width: 100%;
            margin: 0 auto;
            background: white;
            padding: 15px 5px;
            position: relative;
            box-shadow: 0 4px 8px rgba(0,0,0,0.1), 0 6px 20px rgba(0,0,0,0.1);
            border-radius: 2px;
            transform: scale(0.95);
            transform-origin: top center;
        }
        
        @media (max-width: 1024px) {
            .worksheet {
                transform: scale(0.85);
            }
        }
        
        @media (max-width: 768px) {
            .worksheet {
                transform: scale(0.75);
                width: 100%;
                max-width: 210mm;
            }
        }
        
        @media (max-width: 480px) {
            .worksheet {
                transform: scale(0.55);
                margin: -40px auto;
            }
        }
        
        @media (max-width: 360px) {
            .worksheet {
                transform: scale(0.5);
                margin: -50px auto;
            }
        }
        

        
        .worksheet-header {
            margin-bottom: 30px;
            margin-top: 21px;
            padding: 0 25px;
        }
        
        .title-row {
            width: 100%;
            padding: 15px 0;
            border-top: 3px solid #2d3748;
            border-bottom: 4px double #2d3748;
            text-align: center;
            margin-bottom: 15px;
        }
        
        .info-row {
            display: flex;
            justify-content: flex-end;
            align-items: flex-start;
            padding: 0 10px;
        }
        
        .info-section {
            text-align: right;
        }
        
        .worksheet-title {
            font-size: 36px;
            font-weight: bold;
            color: #2d3748;
            text-align: center;
            margin: 0;
            line-height: 1.2;
        }
        
        .worksheet-title.long {
            font-size: 32px;
        }
        
        .worksheet-title.very-long {
            font-size: 28px;
        }
        
        .school-info {
            font-size: 16px;
            color: #4a5568;
            line-height: 1.4;
            text-align: right;
            margin-bottom: 8px;
        }
        
        .name-line {
            font-size: 16px;
            color: #4a5568;
            text-align: right;
        }
        
        .name-underline {
            display: inline-block;
            border-bottom: 2px solid #2d3748;
            width: 120px;
            height: 20px;
            margin-left: 10px;
        }
        
        .words-container {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 10px;
            margin-top: 10px;
            padding: 0 20px;
        }
        
        @media (max-width: 768px) {
            .words-container {
                padding: 0 15px;
                gap: 8px;
            }
        }
        
        @media (max-width: 480px) {
            .words-container {
                grid-template-columns: repeat(2, 1fr);
                padding: 0 10px;
                gap: 6px;
            }
        }
        
        .word-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 12px;
            border: 1px solid #e2e8f0;
            border-radius: 6px;
            background: #f9f9f9;
            text-align: center;
        }
        
        .word-image {
            width: 120px;
            height: 120px;
            margin-bottom: 12px;
            border: 2px solid #e2e8f0;
            border-radius: 6px;
            display: flex;
            align-items: center;
            justify-content: center;
            background: white;
            font-size: 60px;
        }
        
        .word-text {
            width: 100%;
        }
        

        
        .word-grid {
            display: flex;
            justify-content: center;
            gap: 0;
            width: 100%;
            margin: 0 auto;
        }
        
        .letter-box {
            width: 28px;
            height: 32px;
            border: 2px solid #2d3748;
            border-right: none;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
            font-weight: bold;
            background: white;
            color: #2d3748;
            font-family: 'HakgyoansimBareunbatangR', 'Nanum Pen Script', cursive;
            text-align: center;
            position: relative;
        }
        
        .letter-box:last-child {
            border-right: 2px solid #2d3748;
        }
        
        .letter-box.blue-line::before,
        .letter-box.blue-line::after {
            content: '';
            position: absolute;
            border: 1px dotted #3182ce;
        }
        
        .letter-box.blue-line::before {
            top: 2px;
            bottom: 2px;
            left: 50%;
            transform: translateX(-50%);
            border-left: 1px dotted #3182ce;
            border-right: none;
            border-top: none;
            border-bottom: none;
        }
        
        .letter-box.blue-line::after {
            left: 2px;
            right: 2px;
            top: 50%;
            transform: translateY(-50%);
            border-top: 1px dotted #3182ce;
            border-bottom: none;
            border-left: none;
            border-right: none;
        }
        
        .letter-box.red-line::before,
        .letter-box.red-line::after {
            content: '';
            position: absolute;
            border: 1px dotted #e53e3e;
        }
        
        .letter-box.red-line::before {
            top: 2px;
            bottom: 2px;
            left: 50%;
            transform: translateX(-50%);
            border-left: 1px dotted #e53e3e;
            border-right: none;
            border-top: none;
            border-bottom: none;
        }
        
        .letter-box.red-line::after {
            left: 2px;
            right: 2px;
            top: 50%;
            transform: translateY(-50%);
            border-top: 1px dotted #e53e3e;
            border-bottom: none;
            border-left: none;
            border-right: none;
        }
        
        .letter-box.gray-line::before,
        .letter-box.gray-line::after {
            content: '';
            position: absolute;
            border: 1px dotted #718096;
        }
        
        .letter-box.gray-line::before {
            top: 2px;
            bottom: 2px;
            left: 50%;
            transform: translateX(-50%);
            border-left: 1px dotted #718096;
            border-right: none;
            border-top: none;
            border-bottom: none;
        }
        
        .letter-box.gray-line::after {
            left: 2px;
            right: 2px;
            top: 50%;
            transform: translateY(-50%);
            border-top: 1px dotted #718096;
            border-bottom: none;
            border-left: none;
            border-right: none;
        }
        
        .practice-box {
            width: 50px;
            height: 55px;
            border: 2px solid #2d3748;
            border-right: none;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 32px;
            font-weight: bold;
            background: white;
            color: #a0aec0;
            font-family: 'HakgyoansimBareunbatangR', 'Nanum Pen Script', cursive;
            text-align: center;
            position: relative;
        }
        
        .practice-box:last-child {
            border-right: 2px solid #2d3748;
        }
        
        .practice-box.blue-line::before,
        .practice-box.blue-line::after {
            content: '';
            position: absolute;
            border: 1px dotted #3182ce;
        }
        
        .practice-box.blue-line::before {
            top: 2px;
            bottom: 2px;
            left: 50%;
            transform: translateX(-50%);
            border-left: 1px dotted #3182ce;
            border-right: none;
            border-top: none;
            border-bottom: none;
        }
        
        .practice-box.blue-line::after {
            left: 2px;
            right: 2px;
            top: 50%;
            transform: translateY(-50%);
            border-top: 1px dotted #3182ce;
            border-bottom: none;
            border-left: none;
            border-right: none;
        }
        
        .practice-box.red-line::before,
        .practice-box.red-line::after {
            content: '';
            position: absolute;
            border: 1px dotted #e53e3e;
        }
        
        .practice-box.red-line::before {
            top: 2px;
            bottom: 2px;
            left: 50%;
            transform: translateX(-50%);
            border-left: 1px dotted #e53e3e;
            border-right: none;
            border-top: none;
            border-bottom: none;
        }
        
        .practice-box.red-line::after {
            left: 2px;
            right: 2px;
            top: 50%;
            transform: translateY(-50%);
            border-top: 1px dotted #e53e3e;
            border-bottom: none;
            border-left: none;
            border-right: none;
        }
        
        .practice-box.gray-line::before,
        .practice-box.gray-line::after {
            content: '';
            position: absolute;
            border: 1px dotted #718096;
        }
        
        .practice-box.gray-line::before {
            top: 2px;
            bottom: 2px;
            left: 50%;
            transform: translateX(-50%);
            border-left: 1px dotted #718096;
            border-right: none;
            border-top: none;
            border-bottom: none;
        }
        
        .practice-box.gray-line::after {
            left: 2px;
            right: 2px;
            top: 50%;
            transform: translateY(-50%);
            border-top: 1px dotted #718096;
            border-bottom: none;
            border-left: none;
            border-right: none;
        }
        
        .controls {
            display: flex;
            gap: 8px;
            margin-top: 20px;
            flex-wrap: wrap;
        }
        
        .btn {
            padding: 12px 16px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.3s;
            font-weight: 600;
            flex: 1;
            min-width: 140px;
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center;
            line-height: 1;
            white-space: nowrap;
        }
        
        @media (max-width: 768px) {
            .controls {
                gap: 8px;
                margin-top: 15px;
            }
            
            .btn {
                padding: 10px 20px;
                font-size: 18px;
                min-width: 100px;
            }
        }
        
        @media (max-width: 480px) {
            .controls {
                flex-direction: column;
                gap: 10px;
            }
            
            .btn {
                padding: 12px 16px;
                font-size: 16px;
                min-width: auto;
                width: 100%;
            }
        }
        
        .btn-primary {
            background: #667eea;
            color: white;
        }
        
        .btn-primary:hover {
            background: #5a67d8;
            transform: translateY(-2px);
        }
        
        .btn-secondary {
            background: #48bb78;
            color: white;
        }
        
        .btn-secondary:hover {
            background: #38a169;
            transform: translateY(-2px);
        }
        
        .empty-state {
            text-align: center;
            color: #a0aec0;
            font-style: italic;
            padding: 40px;
        }
        

    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
        &lt;div class=&quot;input-panel&quot;&gt;
            &lt;h1&gt;  낱말 글씨 쓰기 학습지&lt;/h1&gt;
            &lt;p style=&quot;text-align: center; font-size: 12px; color: #718096; margin-top: -10px; margin-bottom: 20px;&quot;&gt;- Made by SmartRee with Canva -&lt;/p&gt;
            &lt;div class=&quot;title-input-section&quot;&gt;
                &lt;label for=&quot;worksheetTitle&quot;&gt;학습지 제목:&lt;/label&gt;
                &lt;input 
                    type=&quot;text&quot; 
                    id=&quot;worksheetTitle&quot; 
                    placeholder=&quot;학습지 이름을 입력하세요 (비워두면 '낱말 글씨 쓰기 학습지'로 표시)&quot;
                    maxlength=&quot;50&quot;
                /&gt;
            &lt;/div&gt;
            &lt;div class=&quot;school-info-section&quot;&gt;
                &lt;label&gt;학교 정보:&lt;/label&gt;
                &lt;div class=&quot;school-info-grid&quot;&gt;
                    &lt;div class=&quot;info-item&quot;&gt;
                        &lt;label for=&quot;schoolName&quot;&gt;학교: (예) 한국초&lt;/label&gt;
                        &lt;input type=&quot;text&quot; id=&quot;schoolName&quot; placeholder=&quot;○○초&quot; maxlength=&quot;20&quot;&gt;
                    &lt;/div&gt;
                    &lt;div class=&quot;info-item&quot;&gt;
                        &lt;label for=&quot;grade&quot;&gt;학년:&lt;/label&gt;
                        &lt;input type=&quot;number&quot; id=&quot;grade&quot; placeholder=&quot;1&quot; min=&quot;1&quot; max=&quot;6&quot;&gt;
                    &lt;/div&gt;
                    &lt;div class=&quot;info-item&quot;&gt;
                        &lt;label for=&quot;classNum&quot;&gt;반:&lt;/label&gt;
                        &lt;input type=&quot;number&quot; id=&quot;classNum&quot; placeholder=&quot;1&quot; min=&quot;1&quot; max=&quot;20&quot;&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;color-selection&quot;&gt;
                &lt;label&gt;점선 색상:&lt;/label&gt;
                &lt;div class=&quot;color-options&quot;&gt;
                    &lt;label class=&quot;color-option active&quot;&gt;
                        &lt;input type=&quot;radio&quot; name=&quot;lineColor&quot; value=&quot;blue&quot; checked&gt;
                        &lt;span style=&quot;color: #3182ce;&quot;&gt;● 파란색&lt;/span&gt;
                    &lt;/label&gt;
                    &lt;label class=&quot;color-option&quot;&gt;
                        &lt;input type=&quot;radio&quot; name=&quot;lineColor&quot; value=&quot;red&quot;&gt;
                        &lt;span style=&quot;color: #e53e3e;&quot;&gt;● 빨간색&lt;/span&gt;
                    &lt;/label&gt;
                    &lt;label class=&quot;color-option&quot;&gt;
                        &lt;input type=&quot;radio&quot; name=&quot;lineColor&quot; value=&quot;gray&quot;&gt;
                        &lt;span style=&quot;color: #718096;&quot;&gt;● 회색&lt;/span&gt;
                    &lt;/label&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;follow-mode-section&quot;&gt;
                &lt;label class=&quot;checkbox-container&quot;&gt;
                    &lt;input type=&quot;checkbox&quot; id=&quot;followMode&quot;&gt;
                    &lt;span class=&quot;checkmark&quot;&gt;&lt;/span&gt;
                    따라쓰기 모드 (연습칸에 회색 글자 표시)
                &lt;/label&gt;
            &lt;/div&gt;
            &lt;div class=&quot;follow-mode-section&quot;&gt;
                &lt;label class=&quot;checkbox-container&quot;&gt;
                    &lt;input type=&quot;checkbox&quot; id=&quot;drawingMode&quot;&gt;
                    &lt;span class=&quot;checkmark&quot;&gt;&lt;/span&gt;
                    그리기 모드 (그림 없이 빈 칸으로 표시)
                &lt;/label&gt;
            &lt;/div&gt;
            &lt;div class=&quot;instructions&quot;&gt;
                  각 줄에 하나씩 낱말을 입력하세요 (최대 12개). 엔터키로 다음 줄로 이동합니다.
            &lt;/div&gt;
            &lt;div class=&quot;input-area&quot;&gt;
                &lt;textarea 
                    id=&quot;wordInput&quot; 
                    placeholder=&quot;예시:&amp;#10;사과&amp;#10;바나나&amp;#10;고양이&amp;#10;강아지&amp;#10;자동차&amp;#10;비행기&quot;
                    maxlength=&quot;500&quot;
                &gt;&lt;/textarea&gt;
                &lt;div class=&quot;controls&quot; style=&quot;margin-top: 15px;&quot;&gt;
                    &lt;button class=&quot;btn btn-primary&quot; onclick=&quot;generatePreview()&quot;&gt;  미리보기 생성&lt;/button&gt;
                    &lt;button class=&quot;btn btn-secondary&quot; onclick=&quot;clearInput()&quot;&gt; ️ 초기화&lt;/button&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;preview-panel&quot;&gt;
            &lt;div class=&quot;preview-area&quot;&gt;
                &lt;div class=&quot;preview-content&quot; id=&quot;previewContent&quot;&gt;
                    &lt;div class=&quot;worksheet&quot;&gt;
                        &lt;div class=&quot;worksheet-title&quot;&gt;낱말 학습지&lt;/div&gt;
                        &lt;div class=&quot;empty-state&quot;&gt;
                            왼쪽에 낱말을 입력하고 '미리보기 생성' 버튼을 클릭하세요
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class=&quot;controls&quot; style=&quot;margin-top: 5px; text-align: center;&quot;&gt;
                    &lt;button class=&quot;btn btn-secondary&quot; onclick=&quot;downloadPDF()&quot;&gt;  PDF 다운로드&lt;/button&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // 초등학생 필수 어휘 체계적 이모지 매핑 (중복 제거)
        const clipartMap = {
            // 1. 감정과 기분 (Emotions &amp; Feelings)
            '기쁨': ' ', '기쁘다': ' ',
            '슬픔': ' ', '슬프다': ' ',
            '화남': ' ', '화나다': ' ', '화': ' ',
            '놀람': ' ', '놀라다': ' ',
            '무서움': ' ', '무섭다': ' ', '두려움': ' ',
            '사랑': '❤️', '좋아하다': '❤️',
            '웃음': ' ', '웃다': ' ',
            '울음': ' ', '울다': ' ',
            '피곤': ' ', '피곤하다': ' ',
            '졸림': ' ', '졸리다': ' ', '잠': ' ',
            '행복': ' ', '행복하다': ' ',
            '당황': ' ', '당황하다': ' ',
            '자랑': ' ', '자랑하다': ' ',
            '부끄러움': ' ', '부끄럽다': ' ',
            '걱정': ' ', '걱정하다': ' ',
            '실망': ' ', '실망하다': ' ',
            '짜증': ' ', '짜증나다': ' ',
            '감사': ' ', '고맙다': ' ',
            '용기': ' ', '용감하다': ' ',
            '친절': ' ', '친절하다': ' ',
            '미안': ' ', '미안하다': ' ',
            '신나다': ' ',
            '심심하다': ' ',
            '부럽다': ' ',

            // 2. 가족과 사람 (Family &amp; People)
            '아빠': ' ', '아버지': ' ',
            '엄마': ' ', '어머니': ' ',
            '할아버지': ' ',
            '할머니': ' ',
            '형': ' ',
            '누나': ' ',
            '오빠': ' ',
            '언니': ' ‍♀️',
            '동생': ' ',
            '친구': ' ',
            '선생님': ' ‍ ',
            '아기': ' ',
            '사람': ' ‍ ‍ ',
            '남자': ' ‍ ',
            '여자': ' ‍ ',
            '어른': ' ‍ ',
            '아이': ' ',

            // 3. 학교와 교육 (School &amp; Education)
            '학교': ' ',
            '교실': ' ',
            '책상': ' ',
            '의자': ' ',
            '칠판': '⬛',
            '분필': ' ️',
            '책': ' ',
            '공책': ' ',
            '연필': '✏️',
            '지우개': ' ',
            '자': ' ',
            '필통': ' ',
            '가방': ' ',
            '시험': ' ',
            '숙제': ' ',
            '공부': ' ',
            '수업': ' ‍ ',
            '도서관': ' ',
            '운동장': ' ️',
            '급식': ' ️',
            '방학': ' ️',
            '졸업': ' ',

            // 4. 신체와 건강 (Body &amp; Health)
            '머리': ' ',
            '얼굴': ' ',
            '눈': ' ',
            '코': ' ',
            '입': ' ',
            '귀': ' ',
            '손': ' ️',
            '발': ' ',
            '다리': ' ',
            '팔': ' ',
            '이': ' ',
            '목': ' ️',
            '배': ' ',
            '등': ' ',
            '양치': ' ',
            '목욕': ' ',
            '약': ' ',
            '병원': ' ',
            '마스크': ' ',
            '운동': ' ',
            '상처': ' ',
            '건강': ' ',
            '아프다': ' ',

            // 5. 집과 일상생활 (Home &amp; Daily Life)
            '집': ' ',
            '방': ' ️',
            '거실': ' ️',
            '부엌': ' ',
            '욕실': ' ',
            '화장실': ' ',
            '문': ' ',
            '창문': ' ',
            '침대': ' ',
            '식탁': ' ️',
            '옷장': ' ',
            '전화기': '☎️',
            '냉장고': ' ',
            '세탁기': ' ',
            '청소': ' ',
            '커튼': ' ',
            '텔레비전': ' ',
            '컴퓨터': ' ',
            '우산': '☂️',
            '컵': ' ',
            '그릇': ' ',
            '접시': ' ️',
            '수건': ' ',

            // 6. 음식과 식사 (Food &amp; Meals)
            '밥': ' ',
            '국': ' ',
            '빵': ' ',
            '라면': ' ',
            '김밥': ' ',
            '떡': ' ',
            '사과': ' ',
            '바나나': ' ',
            '포도': ' ',
            '귤': ' ',
            '딸기': ' ',
            '수박': ' ',
            '감자': ' ',
            '당근': ' ',
            '계란': ' ',
            '치킨': ' ',
            '우유': ' ',
            '주스': ' ',
            '물': ' ',
            '과자': ' ',
            '아이스크림': ' ',
            '케이크': ' ',
            '피자': ' ',
            '햄버거': ' ',
            '포크': ' ',
            '젓가락': ' ',
            '숟가락': ' ',
            '김치': ' ',
            '생선': ' ',
            '고기': ' ',
            '야채': ' ',
            '과일': ' ',

            // 7. 동물 (Animals)
            '강아지': ' ',
            '고양이': ' ',
            '토끼': ' ',
            '말': ' ',
            '소': ' ',
            '돼지': ' ',
            '양': ' ',
            '닭': ' ',
            '오리': ' ',
            '사자': ' ',
            '호랑이': ' ',
            '코끼리': ' ',
            '원숭이': ' ',
            '거북이': ' ',
            '물고기': ' ',
            '펭귄': ' ',
            '개구리': ' ',
            '쥐': ' ',
            '여우': ' ',
            '곰': ' ',
            '나비': ' ',
            '사슴': ' ',
            '고래': ' ',
            '벌': ' ',
            '새': ' ',
            '뱀': ' ',
            '거미': ' ️',
            '개미': ' ',
            '물개': ' ',
            '악어': ' ',

            // 8. 식물과 자연 (Plants &amp; Nature)
            '꽃': ' ',
            '나무': ' ',
            '풀': ' ',
            '잎': ' ',
            '씨앗': ' ',
            '해바라기': ' ',
            '선인장': ' ',
            '버섯': ' ',
            '덩굴': ' ',
            '장미': ' ',
            '튤립': ' ',
            '민들레': ' ',
            '소나무': ' ',
            '대나무': ' ',

            // 9. 계절과 날씨 (Seasons &amp; Weather)
            '봄': ' ',
            '여름': '☀️',
            '가을': ' ',
            '겨울': '❄️',
            '해': ' ',
            '달': ' ',
            '별': '⭐',
            '비': ' ️',
            '눈': ' ️',
            '구름': '☁️',
            '안개': ' ️',
            '번개': '⚡',
            '바람': ' ',
            '무지개': ' ',
            '태풍': ' ',
            '천둥': '⛈️',

            // 10. 장소 (Places)
            '공원': ' ️',
            '마트': ' ',
            '시장': ' ',
            '놀이터': ' ',
            '은행': ' ',
            '영화관': ' ',
            '동물원': ' ',
            '박물관': ' ️',
            '서점': ' ',
            '카페': '☕',
            '우체국': ' ',
            '소방서': ' ',
            '경찰서': ' ',
            '주차장': ' ️',
            '바다': ' ',
            '산': '⛰️',
            '강': ' ️',
            '호수': ' ️',
            '해변': ' ️',
            '섬': ' ️',

            // 11. 교통수단 (Transportation)
            '자동차': ' ',
            '버스': ' ',
            '기차': ' ',
            '자전거': ' ',
            '오토바이': ' ️',
            '트럭': ' ',
            '지하철': ' ',
            '비행기': '✈️',
            '배': '⛴️',
            '스쿨버스': ' ',
            '택시': ' ',
            '구급차': ' ',
            '헬리콥터': ' ',
            '로켓': ' ',

            // 12. 숫자와 시간 (Numbers &amp; Time)
            '하나': '1️⃣', '일': '1️⃣',
            '둘': '2️⃣', '이': '2️⃣',
            '셋': '3️⃣', '삼': '3️⃣',
            '넷': '4️⃣', '사': '4️⃣',
            '다섯': '5️⃣', '오': '5️⃣',
            '여섯': '6️⃣', '육': '6️⃣',
            '일곱': '7️⃣', '칠': '7️⃣',
            '여덟': '8️⃣', '팔': '8️⃣',
            '아홉': '9️⃣', '구': '9️⃣',
            '열': ' ', '십': ' ',
            '백': ' ',
            '천': ' ',
            '수학': '➗',
            '계산': '➕',
            '더하기': '➕',
            '빼기': '➖',
            '곱하기': '✖️',
            '나누기': '➗',
            '요일': ' ',
            '월요일': ' ',
            '화요일': ' ',
            '수요일': ' ',
            '목요일': ' ',
            '금요일': ' ',
            '토요일': ' ',
            '일요일': ' ',
            '아침': ' ',
            '점심': ' ',
            '저녁': ' ',
            '밤': ' ',
            '어제': '⏪',
            '오늘': ' ',
            '내일': '⏩',
            '시계': '⏰',
            '달력': ' ',
            '시간': '⏱️',
            '분': '⏲️',
            '초': '⏳',

            // 13. 색깔과 모양 (Colors &amp; Shapes)
            '빨강': ' ', '빨간색': ' ',
            '파랑': ' ', '파란색': ' ',
            '노랑': ' ', '노란색': ' ',
            '초록': ' ', '초록색': ' ',
            '주황': ' ', '주황색': ' ',
            '보라': ' ', '보라색': ' ',
            '분홍': ' ', '분홍색': ' ',
            '검정': '⚫', '검은색': '⚫',
            '하양': '⚪', '하얀색': '⚪',
            '회색': ' ',
            '갈색': ' ',
            '동그라미': '⭕',
            '네모': '⬜',
            '세모': ' ',
            '별': '⭐',
            '하트': ' ',
            '다이아몬드': ' ',

            // 14. 동작과 행동 (Actions &amp; Behaviors)
            '걷다': ' ',
            '달리다': ' ',
            '뛰다': ' ‍♂️',
            '자다': ' ',
            '앉다': ' ',
            '서다': ' ',
            '먹다': ' ️',
            '마시다': ' ',
            '읽다': ' ',
            '쓰다': '✍️',
            '말하다': ' ️',
            '듣다': ' ',
            '보다': ' ',
            '그리다': ' ',
            '춤추다': ' ',
            '노래하다': ' ',
            '공부하다': ' ',
            '청소하다': ' ',
            '게임하다': ' ',
            '전화하다': '☎️',
            '만들다': ' ️',
            '배우다': ' ‍ ',
            '도와주다': ' ',
            '놀다': ' ',
            '기다리다': '⏳',
            '포기하다': ' ',
            '기억하다': ' ',
            '생각하다': ' ',
            '일어나다': '⏰',
            '씻다': ' ',
            '입다': ' ',
            '벗다': ' ',

            // 15. 직업 (Jobs &amp; Occupations)
            '경찰관': ' ',
            '소방관': ' ‍ ',
            '의사': ' ‍⚕️',
            '간호사': ' ‍⚕️',
            '운전사': ' ‍✈️',
            '요리사': ' ‍ ',
            '농부': ' ‍ ',
            '가수': ' ',
            '화가': ' ‍ ',
            '배우': ' ',
            '과학자': ' ‍ ',
            '기술자': ' ‍ ',
            '운동선수': ' ',
            '회사원': ' ',
            '우체국직원': ' ',
            '판매원': ' ',
            '기자': ' ',
            '변호사': '⚖️',

            // 16. 명절과 행사 (Holidays &amp; Events)
            '설날': ' ',
            '추석': ' ',
            '생일': ' ',
            '크리스마스': ' ',
            '어린이날': ' ',
            '할로윈': ' ',
            '발렌타인데이': ' ',
            '소풍': ' ',
            '체육대회': ' ',
            '졸업식': ' ',
            '입학식': ' ',
            '운동회': ' ‍♀️',

            // 17. 문화와 예술 (Culture &amp; Arts)
            '노래': ' ',
            '그림': ' ️',
            '춤': ' ',
            '영화': ' ',
            '만화': ' ',
            '연필화': '✏️',
            '서예': ' ️',
            '피아노': ' ',
            '기타': ' ',
            '바이올린': ' ',
            '드럼': ' ',
            '연극': ' ',
            '사진': ' ',
            '전시회': ' ',
            '콘서트': ' ',

            // 18. 스포츠와 놀이 (Sports &amp; Games)
            '축구': '⚽',
            '야구': '⚾',
            '농구': ' ',
            '배구': ' ',
            '테니스': ' ',
            '탁구': ' ',
            '수영': ' ',
            '태권도': ' ',
            '줄넘기': ' ',
            '그네': ' ',
            '미끄럼틀': ' ',
            '시소': '⚖️',
            '블록': ' ',
            '퍼즐': ' ',
            '인형': ' ',

            // 19. 도구와 물건 (Tools &amp; Objects)
            '가위': '✂️',
            '풀': ' ',
            '테이프': ' ',
            '못': ' ',
            '망치': ' ',
            '드라이버': ' ',
            '열쇠': ' ',
            '자물쇠': ' ',
            '거울': ' ',
            '빗': ' ',
            '칫솔': ' ',
            '비누': ' ',
            '휴지': ' ',
            '쓰레기통': ' ️',

            // 20. 의복 (Clothing)
            '옷': ' ',
            '바지': ' ',
            '치마': ' ',
            '신발': ' ',
            '양말': ' ',
            '모자': ' ',
            '장갑': ' ',
            '목도리': ' ',
            '코트': ' ',
            '잠옷': ' ',
            '속옷': ' ',
            '안경': ' ',

            // 기본값
            'default': ' '
        };

        function getClipart(word) {
            // 정확한 매칭 먼저 시도
            if (clipartMap[word]) {
                return clipartMap[word];
            }
            
            // 부분 매칭 시도
            for (let key in clipartMap) {
                if (word.includes(key) || key.includes(word)) {
                    return clipartMap[key];
                }
            }
            
            return clipartMap['default'];
        }

        function createLetterBoxes(word, lineColor = 'blue') {
            return word.split('').map(letter =&gt; 
                `&lt;div class=&quot;letter-box ${lineColor}-line&quot;&gt;${letter}&lt;/div&gt;`
            ).join('');
        }
        
        function createPracticeBoxes(word, lineColor = 'blue', showLetters = false) {
            return word.split('').map(letter =&gt; 
                `&lt;div class=&quot;practice-box ${lineColor}-line&quot;&gt;${showLetters ? letter : ''}&lt;/div&gt;`
            ).join('');
        }

        function generatePreview() {
            const input = document.getElementById('wordInput').value.trim();
            const words = input.split('\n')
                .map(word =&gt; word.trim())
                .filter(word =&gt; word.length &gt; 0)
                .slice(0, 12); // 최대 12개로 제한

            const previewContent = document.getElementById('previewContent');
            
            if (words.length === 0) {
                previewContent.innerHTML = `
                    &lt;div class=&quot;worksheet&quot;&gt;
                        &lt;div class=&quot;worksheet-header&quot;&gt;
                            &lt;div class=&quot;title-row&quot;&gt;
                                &lt;div class=&quot;worksheet-title&quot;&gt;낱말 글씨 쓰기 학습지&lt;/div&gt;
                            &lt;/div&gt;
                            &lt;div class=&quot;info-row&quot;&gt;
                                &lt;div class=&quot;info-section&quot;&gt;
                                    &lt;div class=&quot;school-info&quot;&gt;00초 0학년 0반 (　　)번&lt;/div&gt;
                                    &lt;div class=&quot;name-line&quot;&gt;이름: &lt;span class=&quot;name-underline&quot;&gt;&lt;/span&gt;&lt;/div&gt;
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                        &lt;div class=&quot;empty-state&quot;&gt;
                            왼쪽에 낱말을 입력하고 '미리보기 생성' 버튼을 클릭하세요
                        &lt;/div&gt;
                    &lt;/div&gt;
                `;
                return;
            }

            const selectedColor = document.querySelector('input[name=&quot;lineColor&quot;]:checked').value;
            const followMode = document.getElementById('followMode').checked;
            const drawingMode = document.getElementById('drawingMode').checked;
            
            const wordItems = words.map(word =&gt; `
                &lt;div class=&quot;word-item&quot;&gt;
                    &lt;div class=&quot;word-image&quot;&gt;${drawingMode ? '' : getClipart(word)}&lt;/div&gt;
                    &lt;div class=&quot;word-text&quot;&gt;
                        &lt;div class=&quot;word-grid&quot;&gt;
                            ${createPracticeBoxes(word, selectedColor, followMode || drawingMode)}
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            `).join('');

            const worksheetTitle = document.getElementById('worksheetTitle').value.trim() || '낱말 글씨 쓰기 학습지';
            
            const schoolName = document.getElementById('schoolName').value.trim();
            const grade = document.getElementById('grade').value.trim();
            const classNum = document.getElementById('classNum').value.trim();
            
            let schoolInfoText = '';
            const displaySchool = schoolName || '00초';
            const displayGrade = grade || '0';
            const displayClass = classNum || '0';
            schoolInfoText = `${displaySchool} ${displayGrade}학년 ${displayClass}반 (　　)번`;
            
            // 제목 길이에 따른 클래스 결정
            let titleClass = 'worksheet-title';
            if (worksheetTitle.length &gt; 15) {
                titleClass += ' very-long';
            } else if (worksheetTitle.length &gt; 10) {
                titleClass += ' long';
            }
            
            previewContent.innerHTML = `
                &lt;div class=&quot;worksheet&quot; id=&quot;worksheet&quot;&gt;
                    &lt;div class=&quot;worksheet-header&quot;&gt;
                        &lt;div class=&quot;title-row&quot;&gt;
                            &lt;div class=&quot;${titleClass}&quot;&gt;${worksheetTitle}&lt;/div&gt;
                        &lt;/div&gt;
                        &lt;div class=&quot;info-row&quot;&gt;
                            &lt;div class=&quot;info-section&quot;&gt;
                                &lt;div class=&quot;school-info&quot;&gt;${schoolInfoText}&lt;/div&gt;
                                &lt;div class=&quot;name-line&quot;&gt;이름: &lt;span class=&quot;name-underline&quot;&gt;&lt;/span&gt;&lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                    &lt;div class=&quot;words-container&quot;&gt;
                        ${wordItems}
                    &lt;/div&gt;
                &lt;/div&gt;
            `;
        }

        function clearInput() {
            document.getElementById('wordInput').value = '';
            generatePreview();
        }

        function downloadPDF() {
            const worksheet = document.getElementById('worksheet');
            if (!worksheet) {
                alert('먼저 미리보기를 생성해주세요!');
                return;
            }

            // PDF 생성을 위해 임시로 스케일 제거
            worksheet.style.transform = 'scale(1)';
            worksheet.style.transformOrigin = 'top left';
            
            const opt = {
                margin: [10, 10, 10, 10],
                filename: '낱말학습지.pdf',
                image: { type: 'jpeg', quality: 0.98 },
                html2canvas: { 
                    scale: 1.5,
                    useCORS: true,
                    letterRendering: true,
                    width: 794,
                    height: 1123,
                    scrollX: 0,
                    scrollY: 0
                },
                jsPDF: { 
                    unit: 'pt', 
                    format: 'a4', 
                    orientation: 'portrait' 
                },
                pagebreak: { mode: 'avoid-all' }
            };

            html2pdf().set(opt).from(worksheet).save().then(() =&gt; {
                // PDF 생성 후 원래 스케일로 복원
                worksheet.style.transform = 'scale(0.95)';
                worksheet.style.transformOrigin = 'top center';
            });


        }

        // 입력창에서 엔터키 처리
        document.getElementById('wordInput').addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                const lines = this.value.split('\n');
                if (lines.length &gt;= 12) {
                    e.preventDefault();
                    alert('최대 12개의 낱말까지 입력할 수 있습니다.');
                }
            }
        });

        // 실시간 미리보기 업데이트
        document.getElementById('wordInput').addEventListener('input', function() {
            generatePreview();
        });
        
        // 제목 입력 실시간 업데이트
        document.getElementById('worksheetTitle').addEventListener('input', function() {
            generatePreview();
        });
        
        // 학교 정보 실시간 업데이트
        ['schoolName', 'grade', 'classNum'].forEach(id =&gt; {
            document.getElementById(id).addEventListener('input', function() {
                generatePreview();
            });
        });
        
        // 색상 선택 이벤트 리스너
        document.querySelectorAll('input[name=&quot;lineColor&quot;]').forEach(radio =&gt; {
            radio.addEventListener('change', function() {
                // 활성 상태 업데이트
                document.querySelectorAll('.color-option').forEach(option =&gt; {
                    option.classList.remove('active');
                });
                this.closest('.color-option').classList.add('active');
                
                // 미리보기 업데이트
                generatePreview();
            });
        });
        
        // 따라쓰기 모드 이벤트 리스너
        document.getElementById('followMode').addEventListener('change', function() {
            generatePreview();
        });
        
        // 그리기 모드 이벤트 리스너
        document.getElementById('drawingMode').addEventListener('change', function() {
            generatePreview();
        });

        // 초기 미리보기 생성
        generatePreview();
    &lt;/script&gt;
&lt;script&gt;(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML=&quot;window.__CF$cv$params={r:'968a3ac9c50ad1d6',t:'MTc1NDEwMjYyNy4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);&quot;;b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&amp;&amp;(document.onreadystatechange=e,c())}}}})();&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</description>
      <category>수업자료</category>
      <category>불펌금지</category>
      <category>이모지</category>
      <category>이모지 활용 글씨 쓰기 학습지</category>
      <category>자동생성</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/158</guid>
      <comments>https://smartree.tistory.com/158#entry158comment</comments>
      <pubDate>Wed, 30 Jul 2025 22:23:46 +0900</pubDate>
    </item>
    <item>
      <title>렌즈 빛 굴절 시뮬레이션</title>
      <link>https://smartree.tistory.com/157</link>
      <description>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;렌즈 빛 굴절 시뮬레이션&lt;/title&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        body {
            margin: 0;
            padding: 20px;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #1e3c72, #2a5298);
            color: white;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
        }
        
        .header {
            text-align: center;
            margin-bottom: 20px;
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        
        .control-group {
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
            backdrop-filter: blur(10px);
        }
        
        .control-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
        }
        
        .lens-selector {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
        }
        
        .lens-btn {
            padding: 8px 16px;
            border: none;
            border-radius: 5px;
            background: rgba(255, 255, 255, 0.2);
            color: white;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        .lens-btn.active {
            background: #4CAF50;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
        }
        
        .lens-btn:hover {
            background: rgba(255, 255, 255, 0.3);
        }
        
        .slider {
            width: 200px;
            margin: 10px 0;
        }
        

        
        .warning {
            display: none;
        }
        
        @keyframes pulse {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.05); }
        }
        
        .canvas-container {
            display: flex;
            justify-content: center;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 15px;
            padding: 20px;
            backdrop-filter: blur(10px);
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
        &lt;div class=&quot;header&quot;&gt;
            &lt;h1&gt;  렌즈 빛 굴절 시뮬레이션&lt;/h1&gt;
            &lt;p&gt;볼록렌즈와 오목렌즈의 빛 굴절 원리를 학습해보세요&lt;/p&gt;
            &lt;p style=&quot;font-size: 12px; color: rgba(255, 255, 255, 0.7); margin-top: 5px;&quot;&gt;- Made by SmartRee with Canva -&lt;/p&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;controls&quot;&gt;
            &lt;div class=&quot;control-group&quot;&gt;
                &lt;label&gt;렌즈 종류 선택&lt;/label&gt;
                &lt;div class=&quot;lens-selector&quot;&gt;
                    &lt;button class=&quot;lens-btn active&quot; onclick=&quot;selectLens('convex')&quot;&gt;볼록렌즈&lt;/button&gt;
                    &lt;button class=&quot;lens-btn&quot; onclick=&quot;selectLens('concave')&quot;&gt;오목렌즈&lt;/button&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            
            &lt;div class=&quot;control-group&quot;&gt;
                &lt;label&gt;렌즈 거리: &lt;span id=&quot;distanceValue&quot;&gt;300&lt;/span&gt;px&lt;/label&gt;
                &lt;input type=&quot;range&quot; class=&quot;slider&quot; id=&quot;lensDistance&quot; min=&quot;200&quot; max=&quot;500&quot; value=&quot;300&quot; oninput=&quot;updateDistance()&quot;&gt;
            &lt;/div&gt;
            

        &lt;/div&gt;
        
        &lt;div class=&quot;canvas-container&quot; id=&quot;canvasContainer&quot;&gt;
            &lt;!-- p5.js 캔버스가 여기에 생성됩니다 --&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&quot;warning&quot; id=&quot;fireWarning&quot;&gt;
        &lt;h2&gt;  화재 위험 경고!  &lt;/h2&gt;
        &lt;p&gt;볼록렌즈가 빛을 한 점으로 집중시켜&lt;br&gt;종이가 타기 시작합니다!&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;실제 실험 시 주의하세요!&lt;/strong&gt;&lt;/p&gt;
    &lt;/div&gt;

    &lt;script&gt;
        let lightSource, lens, screen;
        let lightRays = [];
        let lensType = 'convex'; // 'convex' or 'concave'
        let lensDistance = 300;
        let screenDistance = 700;
        let focalLength = 150;
        let showFireWarning = false;
        let fireParticles = [];
        let smokeParticles = [];
        let fireWarningTimer = 0;
        let fireWarningActive = false;
        let fireStarted = false;
        
        function setup() {
            let canvas = createCanvas(1000, 401);
            canvas.parent('canvasContainer');
            
            // 광원 위치 (왼쪽)
            lightSource = { x: 47, y: height/2 - 50 };
            
            // 스크린 위치 (오른쪽)
            screen = { x: screenDistance, y: height/2 - 50 };
            
            // 렌즈 위치 (가운데)
            lens = { x: lensDistance, y: height/2 - 50 };
            
            // 5개의 광선 생성
            createLightRays();
        }
        
        function draw() {
            background(20, 25, 40);
            
            // 격자 배경
            drawGrid();
            
            // 광원 그리기 (손전등)
            drawLightSource();
            
            // 렌즈 그리기
            drawLens();
            
            // 스크린 그리기
            drawScreen();
            
            // 광선 그리기
            drawLightRays();
            
            // 화재 효과
            if (showFireWarning) {
                drawFireEffect();
            }
            
            // 화재 경고 카운터 표시
            if (fireWarningActive &amp;&amp; !fireStarted) {
                drawFireWarningCounter();
            }
            
            // 빨간색 화재 경고 박스 표시
            if (showFireWarning) {
                drawFireWarningBox();
            }
            
            // 정보 표시
            drawInfo();
        }
        
        function createLightRays() {
            lightRays = [];
            for (let i = 0; i &lt; 5; i++) {
                let angle = map(i, 0, 4, -0.3, 0.3);
                lightRays.push({
                    startX: lightSource.x + 49.5, // 한 격자 반(49.5px) 오른쪽에서 시작
                    startY: lightSource.y + i * 30 - 60,
                    angle: angle,
                    color: color(255, 255, 100 + i * 30)
                });
            }
        }
        
        function drawGrid() {
            stroke(40, 50, 70);
            strokeWeight(1);
            
            for (let x = 0; x &lt; width; x += 33) {
                line(x, 0, x, height);
            }
            for (let y = 0; y &lt; height; y += 33) {
                line(0, y, width, y);
            }
        }
        
        function drawLightSource() {
            // 태양 모양의 광원
            // 태양 본체
            fill(255, 255, 100);
            stroke(255, 200, 0);
            strokeWeight(3);
            ellipse(lightSource.x, lightSource.y, 40, 40);
            
            // 태양 광선들
            stroke(255, 255, 150);
            strokeWeight(4);
            for (let i = 0; i &lt; 8; i++) {
                let angle = (TWO_PI / 8) * i;
                let x1 = lightSource.x + cos(angle) * 25;
                let y1 = lightSource.y + sin(angle) * 25;
                let x2 = lightSource.x + cos(angle) * 35;
                let y2 = lightSource.y + sin(angle) * 35;
                line(x1, y1, x2, y2);
            }
            
            // 태양 얼굴
            fill(255, 200, 0);
            noStroke();
            ellipse(lightSource.x - 8, lightSource.y - 5, 4, 4); // 왼쪽 눈
            ellipse(lightSource.x + 8, lightSource.y - 5, 4, 4); // 오른쪽 눈
            arc(lightSource.x, lightSource.y + 5, 15, 10, 0, PI); // 미소
            
            // 텍스트
            fill(255);
            textAlign(CENTER);
            textSize(12);
            text('태양 (광원)', lightSource.x, lightSource.y + 80);
        }
        
        function drawLens() {
            // 렌즈 홀더 (금속 테두리) - 렌즈 크기에 맞게 조정
            fill(80, 80, 100);
            noStroke();
            if (lensType === 'convex') {
                rect(lens.x - 45, lens.y - 78, 90, 10, 5);
                rect(lens.x - 45, lens.y + 68, 90, 10, 5);
            } else {
                rect(lens.x - 45, lens.y - 78, 90, 10, 5);
                rect(lens.x - 45, lens.y + 68, 90, 10, 5);
            }
            
            if (lensType === 'convex') {
                // 볼록렌즈 - 간결한 디자인 (30% 크게)
                fill(180, 220, 255, 150);
                stroke(60, 100, 180);
                strokeWeight(3);
                
                // 볼록렌즈 - 타원형으로 간단하게
                ellipse(lens.x, lens.y, 78, 130);
                
                // 볼록한 효과를 위한 그라데이션
                fill(200, 230, 255, 100);
                noStroke();
                ellipse(lens.x, lens.y, 52, 104);
                
            } else {
                // 오목렌즈 - 양쪽이 안쪽으로 곡선을 그리는 실제 오목렌즈 형태
                fill(180, 220, 255, 150);
                stroke(60, 100, 180);
                strokeWeight(3);
                
                // 오목렌즈 전체 형태
                beginShape();
                // 위쪽 가장자리
                vertex(lens.x - 39, lens.y - 65);
                vertex(lens.x + 39, lens.y - 65);
                
                // 오른쪽 오목한 곡선 (바깥쪽에서 안쪽으로)
                bezierVertex(lens.x + 35, lens.y - 45, lens.x + 25, lens.y - 25, lens.x + 20, lens.y);
                bezierVertex(lens.x + 25, lens.y + 25, lens.x + 35, lens.y + 45, lens.x + 39, lens.y + 65);
                
                // 아래쪽 가장자리
                vertex(lens.x - 39, lens.y + 65);
                
                // 왼쪽 오목한 곡선 (바깥쪽에서 안쪽으로)
                bezierVertex(lens.x - 35, lens.y + 45, lens.x - 25, lens.y + 25, lens.x - 20, lens.y);
                bezierVertex(lens.x - 25, lens.y - 25, lens.x - 35, lens.y - 45, lens.x - 39, lens.y - 65);
                
                endShape(CLOSE);
                
                // 오목한 효과를 위한 내부 그라데이션
                fill(200, 230, 255, 80);
                noStroke();
                beginShape();
                // 내부 오목한 영역
                vertex(lens.x - 20, lens.y - 52);
                bezierVertex(lens.x - 15, lens.y - 35, lens.x - 10, lens.y - 15, lens.x - 5, lens.y);
                bezierVertex(lens.x - 10, lens.y + 15, lens.x - 15, lens.y + 35, lens.x - 20, lens.y + 52);
                vertex(lens.x + 20, lens.y + 52);
                bezierVertex(lens.x + 15, lens.y + 35, lens.x + 10, lens.y + 15, lens.x + 5, lens.y);
                bezierVertex(lens.x + 10, lens.y - 15, lens.x + 15, lens.y - 35, lens.x + 20, lens.y - 52);
                endShape(CLOSE);
            }
            
            // 렌즈 중심축 - 렌즈 크기에 맞게 조정
            stroke(100, 150, 255, 100);
            strokeWeight(1);
            line(lens.x, lens.y - 72, lens.x, lens.y + 72);
            
            // 볼록렌즈에만 반사광 효과 추가
            if (lensType === 'convex') {
                fill(255, 255, 255, 200);
                noStroke();
                ellipse(lens.x - 8, lens.y - 20, 4, 10);
                ellipse(lens.x + 5, lens.y - 15, 2, 6);
            }
            
            // 텍스트 제거됨
        }
        
        function drawScreen() {
            // 스크린 (종이벽) - 두께를 한 격자 크기로, 위치를 세 격자 왼쪽으로
            fill(showFireWarning ? color(255, 100, 100) : color(240, 240, 240));
            noStroke();
            rect(screen.x - 99, screen.y - 160 + 16.5, 33, 320, 5);
            
            // 스크린 텍스트 - 더 잘 보이도록 수정
            fill(showFireWarning ? color(255, 255, 255) : color(50));
            textAlign(CENTER);
            textSize(14);
            push();
            translate(screen.x - 83, screen.y + 16.5);
            rotate(PI/2);
            text('종이벽', 0, 0);
            pop();
        }
        
        function drawLightRays() {
            let convergencePoint = null;
            let allRaysConverge = true;
            
            for (let ray of lightRays) {
                stroke(ray.color);
                strokeWeight(3);
                
                // 광원에서 렌즈까지
                line(ray.startX, ray.startY, lens.x, ray.startY);
                
                // 렌즈에서의 굴절 계산
                let refractedAngle = calculateRefraction(ray.startY, ray.angle);
                
                // 굴절된 광선
                let endX = screen.x - 99;
                let endY = ray.startY + (endX - lens.x) * tan(refractedAngle);
                
                // 수렴점 계산 (볼록렌즈의 경우)
                if (lensType === 'convex') {
                    let convergenceX = lens.x + focalLength;
                    let convergenceY = ray.startY + (convergenceX - lens.x) * tan(refractedAngle);
                    
                    if (convergencePoint === null) {
                        convergencePoint = { x: convergenceX, y: convergenceY };
                    } else {
                        if (abs(convergencePoint.y - convergenceY) &gt; 10) {
                            allRaysConverge = false;
                        }
                    }
                }
                
                line(lens.x, ray.startY, endX, endY);
                
                // 광선 끝점에 작은 원
                fill(ray.color);
                noStroke();
                ellipse(endX, endY, 6, 6);
            }
            
            // 볼록렌즈에서 광선 수렴 확인 및 화재 경고
            if (lensType === 'convex') {
                // 모든 광선이 스크린 근처에서 수렴하는지 확인
                let rayEndPoints = [];
                for (let ray of lightRays) {
                    let refractedAngle = calculateRefraction(ray.startY, ray.angle);
                    let endY = ray.startY + ((screen.x - 99) - lens.x) * tan(refractedAngle);
                    rayEndPoints.push(endY);
                }
                
                // 광선들이 좁은 범위에 모이는지 확인
                let minY = Math.min(...rayEndPoints);
                let maxY = Math.max(...rayEndPoints);
                let convergenceRange = maxY - minY;
                
                let convergenceThreshold = 30;
                if (convergenceRange &lt; convergenceThreshold) { // 화재 위험
                    if (!fireWarningActive) {
                        // 경고 시작
                        fireWarningActive = true;
                        fireWarningTimer = 0;
                        fireStarted = false;
                    }
                    
                    // 타이머 증가
                    fireWarningTimer++;
                    
                    // 5초(300프레임) 후 화재 발생
                    if (fireWarningTimer &gt;= 300 &amp;&amp; !fireStarted) {
                        fireStarted = true;
                        showFireWarning = true;
                    }
                    
                    // 화재가 시작된 후 파티클 생성
                    if (fireStarted &amp;&amp; frameCount % 3 === 0) {
                        let centerY = (minY + maxY) / 2;
                        fireParticles.push({
                            x: (screen.x - 99) + random(-15, 5),
                            y: centerY + random(-10, 10),
                            vx: random(-1, 3),
                            vy: random(-8, -2),
                            life: random(40, 80),
                            size: random(4, 12)
                        });
                        
                        smokeParticles.push({
                            x: (screen.x - 99) + random(-20, 10),
                            y: centerY + random(-15, 15),
                            vx: random(-0.5, 2),
                            vy: random(-4, -1),
                            life: random(80, 150),
                            size: random(6, 20)
                        });
                    }
                } else {
                    // 수렴하지 않으면 모든 경고 리셋
                    fireWarningActive = false;
                    fireWarningTimer = 0;
                    fireStarted = false;
                    showFireWarning = false;
                    fireParticles = [];
                    smokeParticles = [];
                }
            } else {
                // 오목렌즈일 때는 모든 경고 리셋
                fireWarningActive = false;
                fireWarningTimer = 0;
                fireStarted = false;
                showFireWarning = false;
                fireParticles = [];
                smokeParticles = [];
            }
        }
        
        function calculateRefraction(rayY, initialAngle) {
            let distanceFromCenter = rayY - lens.y;
            let refractionStrength = map(abs(distanceFromCenter), 0, 78, 0, 0.65); // 렌즈 크기에 맞게 조정
            
            if (lensType === 'convex') {
                // 볼록렌즈: 중심으로 굽힘
                return distanceFromCenter &gt; 0 ? -refractionStrength : refractionStrength;
            } else {
                // 오목렌즈: 중심에서 멀어지게 굽힘
                return distanceFromCenter &gt; 0 ? refractionStrength : -refractionStrength;
            }
        }
        
        function drawFireEffect() {
            // 화재 파티클
            for (let i = fireParticles.length - 1; i &gt;= 0; i--) {
                let p = fireParticles[i];
                
                // 화염 색상 그라데이션 (빨강 -&gt; 주황 -&gt; 노랑)
                let lifeRatio = p.life / 80;
                if (lifeRatio &gt; 0.7) {
                    fill(255, 50, 0, map(p.life, 0, 80, 0, 255));
                } else if (lifeRatio &gt; 0.3) {
                    fill(255, 150, 0, map(p.life, 0, 80, 0, 255));
                } else {
                    fill(255, 255, 0, map(p.life, 0, 80, 0, 200));
                }
                
                noStroke();
                ellipse(p.x, p.y, p.size * lifeRatio);
                
                p.x += p.vx;
                p.y += p.vy;
                p.vy -= 0.1; // 중력 반대 (위로 올라감)
                p.vx *= 0.99;
                p.life--;
                
                if (p.life &lt;= 0) {
                    fireParticles.splice(i, 1);
                }
            }
            
            // 연기 파티클
            for (let i = smokeParticles.length - 1; i &gt;= 0; i--) {
                let p = smokeParticles[i];
                
                let lifeRatio = p.life / 150;
                fill(80, 80, 80, map(p.life, 0, 150, 0, 120));
                noStroke();
                ellipse(p.x, p.y, p.size * (1 - lifeRatio * 0.5));
                
                p.x += p.vx;
                p.y += p.vy;
                p.vx *= 0.995;
                p.vy *= 0.995;
                p.vy -= 0.05; // 연기도 위로 올라감
                p.life--;
                
                if (p.life &lt;= 0) {
                    smokeParticles.splice(i, 1);
                }
            }
        }
        
        function drawFireWarningCounter() {
            // 경고 박스 배경 - 왼쪽으로 2격자(66px), 위로 5격자(165px) 이동
            fill(255, 150, 0, 200);
            stroke(255, 100, 0);
            strokeWeight(3);
            rect(651, 20, 250, 80, 10);
            
            // 경고 텍스트
            fill(255, 255, 255);
            textAlign(LEFT);
            textSize(16);
            text('⚠️ 화재 위험 경고!', 661, 45);
            
            textSize(14);
            text('볼록렌즈가 빛을 집중시키고 있습니다', 661, 65);
            
            let remainingTime = Math.ceil((300 - fireWarningTimer) / 60);
            fill(255, 255, 0);
            textSize(18);
            text(`화재 발생까지: ${remainingTime}초`, 661, 85);
        }
        
        function drawFireWarningBox() {
            // 빨간색 화재 경고 박스 - 주황색 박스와 같은 위치
            fill(255, 68, 68, 220);
            stroke(255, 0, 0);
            strokeWeight(3);
            rect(651, 20, 250, 120, 10);
            
            // 깜빡이는 효과
            let alpha = map(sin(frameCount * 0.2), -1, 1, 180, 255);
            fill(255, 255, 255, alpha);
            textAlign(CENTER);
            textSize(18);
            text('  화재 위험 경고!  ', 776, 50);
            
            fill(255, 255, 255);
            textSize(14);
            text('볼록렌즈가 빛을 한 점으로 집중시켜', 776, 75);
            text('종이가 타기 시작합니다!', 776, 95);
            
            textSize(16);
            fill(255, 255, 0);
            text('실제 실험 시 주의하세요!', 776, 120);
        }
        
        function drawInfo() {
            fill(255, 255, 255, 200);
            textAlign(LEFT);
            textSize(14);
            
            text(`렌즈 종류: ${lensType === 'convex' ? '볼록렌즈' : '오목렌즈'}`, 20, 30);
            text(`렌즈 거리: ${lensDistance}px`, 20, 50);
            
            if (lensType === 'convex') {
                text('볼록렌즈: 빛을 한 점으로 모음', 20, height - 40 - 66);
            } else {
                text('오목렌즈: 빛을 퍼뜨림', 20, height - 40 - 66);
            }
        }
        
        // 컨트롤 함수들
        function selectLens(type) {
            lensType = type;
            
            // 버튼 활성화 상태 변경
            document.querySelectorAll('.lens-btn').forEach(btn =&gt; {
                btn.classList.remove('active');
            });
            event.target.classList.add('active');
            
            // 렌즈 변경 시 화재 경고 리셋
            fireWarningActive = false;
            fireWarningTimer = 0;
            fireStarted = false;
            showFireWarning = false;
            fireParticles = [];
            smokeParticles = [];
            
            createLightRays();
        }
        
        function updateDistance() {
            let sliderValue = parseInt(document.getElementById('lensDistance').value);
            
            lensDistance = sliderValue;
            lens.x = sliderValue;
            
            document.getElementById('distanceValue').textContent = Math.round(lensDistance);
        }
        

    &lt;/script&gt;
&lt;script&gt;(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML=&quot;window.__CF$cv$params={r:'958e52bc3096c43a',t:'MTc1MTQ2MTE5Ni4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);&quot;;b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&amp;&amp;(document.onreadystatechange=e,c())}}}})();&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</description>
      <category>수업자료</category>
      <category>가상실험</category>
      <category>볼록렌즈</category>
      <category>불펌금지</category>
      <category>오목렌즈</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/157</guid>
      <comments>https://smartree.tistory.com/157#entry157comment</comments>
      <pubDate>Wed, 2 Jul 2025 21:04:02 +0900</pubDate>
    </item>
    <item>
      <title>바른 글씨 쓰기 학습지 생성기</title>
      <link>https://smartree.tistory.com/156</link>
      <description>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;일일 학습지 생성기&lt;/title&gt;
    &lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        /* 기본 폰트 */
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&amp;display=swap');
        @import url('https://fonts.googleapis.com/css2?family=Nanum+Gothic:wght@400;700&amp;display=swap');
        @import url('https://fonts.googleapis.com/css2?family=Nanum+Myeongjo:wght@400;700&amp;display=swap');
        @import url('https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&amp;display=swap');
        
        /* 강원교육모두체L */
        @font-face {
            font-family: 'GangwonEduAll';
            src: url('https://cdn.jsdelivr.net/gh/fonts-archive/GangwonEduModu/GangwonEduModu-Light.woff2') format('woff2');
            font-weight: normal;
            font-style: normal;
            font-display: swap;
        }
        
        /* 강원교육모두체B */
        @font-face {
            font-family: 'GangwonEduAllBold';
            src: url('https://cdn.jsdelivr.net/gh/fonts-archive/GangwonEduModu/GangwonEduModu-Bold.woff2') format('woff2');
            font-weight: normal;
            font-style: normal;
            font-display: swap;
        }
        
        /* 강원교육모둠체 */
        @font-face {
            font-family: 'GangwonEduGroup';
            src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_2201-2@1.0/GangwonEduGroup.woff') format('woff');
            font-weight: normal;
            font-style: normal;
            font-display: swap;
        }
        
        /* 학교안심받아쓰기체 */
        @font-face {
            font-family: 'HakgyoansimBareunbatangR';
            src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/2408-5@1.0/HakgyoansimBadasseugiTTF-L.woff2') format('woff2');
            font-weight: normal;
            font-style: normal;
            font-display: swap;
        }
        
        @font-face {
            font-family: 'HakgyoansimWoojuR';
            src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_2307-2@1.0/HakgyoansimWoojuR.woff2') format('woff2');
            font-weight: normal;
            font-style: normal;
            font-display: swap;
        }
        
        body {
            font-family: 'Noto Sans KR', sans-serif;
        }
        
        /* A4 크기 정확한 환산: 1mm = 3.7795275591px (96 DPI 기준) */
        :root {
            --mm-to-px: 3.7795275591;
            --a4-width-px: 793.7007874px; /* 210mm */
            --a4-height-px: 1122.5196850px; /* 297mm */
            --padding-top-px: 37.795275591px; /* 10mm */
            --padding-right-px: 56.6929133858px; /* 15mm */
            --padding-bottom-px: 15.1181102362px; /* 4mm */
            --padding-left-px: 56.6929133858px; /* 15mm */
        }
        
        @media print {
            body {
                width: 210mm;
                height: 297mm;
                margin: 0;
                padding: 0;
                background: white !important;
            }
            
            .no-print {
                display: none !important;
            }
            
            .print-only {
                display: block !important;
            }
            
            .worksheet {
                border: 1px solid #000;
                width: 210mm !important;
                height: 297mm !important;
                max-width: none !important;
                aspect-ratio: auto !important;
                padding: 10mm 15mm 4mm 15mm;
                box-sizing: border-box;
                margin: 0 !important;
                transform: none !important;
                position: relative !important;
            }
            
            .character {
                font-size: 2.8rem !important;
            }
            
            @page {
                size: A4;
                margin: 0;
            }
        }
        
        .worksheet {
            width: var(--a4-width-px);
            height: var(--a4-height-px);
            max-width: none;
            max-height: none;
            border: 1px solid #000;
            outline: none;
            margin: 0 auto;
            padding: var(--padding-top-px) var(--padding-right-px) var(--padding-bottom-px) var(--padding-left-px);
            box-sizing: border-box;
            background-color: white;
            position: relative;
            overflow: hidden;
            box-shadow: none;
            border-radius: 0;
            opacity: 1;
            page-break-after: avoid;
            page-break-inside: avoid;
            page-break-before: avoid;
        }
        
        @media (max-width: 1023px) {
            .worksheet {
                width: 100%;
                max-width: 210mm;
                height: auto;
                min-height: 297mm;
                padding: 8mm 12mm 4mm 12mm;
            }
            
            /* 모바일에서는 기본 스크롤 유지 */
            .no-print {
                height: auto !important;
                overflow: visible !important;
            }
        }
        
        .print-only {
            display: none;
        }
        
        .student-number {
            display: inline-block;
            width: 40px;
            border-bottom: 2px solid black;
            text-align: center;
            margin: 0 2px;
        }
        
        .writing-grid {
            display: grid;
            grid-template-columns: repeat(10, 1fr);
            gap: 0;
            margin-top: 4px;
            height: auto;
            max-height: none;
            overflow: visible;
            page-break-inside: avoid !important;
            page-break-after: avoid !important;
            break-inside: avoid !important;
            border: 3px solid #000;
        }
        
        @media (min-width: 1024px) {
            .writing-grid {
                height: auto;
                max-height: none;
                overflow: visible;
            }
        }
        
        .writing-cell {
            aspect-ratio: 1/1;
            border: 1px solid #000;
            border-top: none;
            border-left: none;
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            page-break-inside: avoid !important;
            break-inside: avoid !important;
        }
        
        .writing-cell:nth-child(10n) {
            border-right: none;
        }
        
        .writing-cell:nth-child(n+131) {
            border-bottom: none;
        }
        
        .writing-cell::before {
            content: &quot;&quot;;
            position: absolute;
            top: 0;
            left: 50%;
            height: 100%;
            width: 2px;
            border-left: 2px dotted #0000ff;
            z-index: 0;
        }
        
        .writing-cell::after {
            content: &quot;&quot;;
            position: absolute;
            top: 50%;
            left: 0;
            width: 100%;
            height: 2px;
            border-top: 2px dotted #0000ff;
            z-index: 0;
        }
        
        .character {
            position: relative;
            font-size: clamp(1.5rem, 4vw, 2.8rem);
            z-index: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            width: 100%;
            height: 100%;
            line-height: 1;
            text-align: center;
            transform: translateY(0px);
        }
        
        @media (min-width: 1024px) {
            .character {
                font-size: 2.8rem;
            }
        }
        
        @media print {
            .character {
                transform: translateY(0px) !important;
                display: flex !important;
                align-items: center !important;
                justify-content: center !important;
            }
        }
        
        .header-section {
            padding-bottom: 8px;
            margin-bottom: 8px;
        }
        
        /* 폰트 클래스 */
        .font-gangwon-all { font-family: 'GangwonEduAll', 'Noto Sans KR', sans-serif; }
        .font-gangwon-all-bold { font-family: 'GangwonEduAllBold', 'Noto Sans KR', sans-serif; }
        .font-gangwon-group { font-family: 'GangwonEduGroup', 'Noto Sans KR', sans-serif; }
        .font-hakgyo-ansim { font-family: 'HakgyoansimBareunbatangR', 'Noto Sans KR', serif; }
        .font-hakgyo-wooju { font-family: 'HakgyoansimWoojuR', 'Noto Sans KR', serif; }
        .font-nanum-gothic { font-family: 'Nanum Gothic', 'Noto Sans KR', sans-serif; }
        .font-nanum-myeongjo { font-family: 'Nanum Myeongjo', 'Noto Sans KR', serif; }
        .font-nanum-pen { font-family: 'Nanum Pen Script', 'Noto Sans KR', cursive; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body class=&quot;bg-gray-100&quot;&gt;
    &lt;!-- 메인 컨테이너 --&gt;
    &lt;div class=&quot;no-print flex flex-col lg:flex-row lg:h-screen lg:overflow-hidden&quot;&gt;
        &lt;!-- 입력 폼 --&gt;
        &lt;div class=&quot;lg:w-1/3 lg:flex-shrink-0 lg:h-full lg:overflow-y-auto lg:p-4&quot;&gt;
            &lt;div class=&quot;max-w-md mx-auto lg:mx-0 my-8 lg:my-0 p-6 bg-white rounded-lg shadow-md&quot;&gt;
            &lt;h1 class=&quot;text-2xl font-bold text-center mb-2 text-blue-600&quot;&gt;바른 글씨 쓰기 학습지&lt;/h1&gt;
            &lt;p class=&quot;text-xs text-center mb-6 text-gray-500&quot;&gt;- Made by SmartRee with Canva -&lt;/p&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;title&quot;&gt;
                학습지명(예-하루에 한장씩, 예쁜 글씨쓰기 등)
            &lt;/label&gt;
            &lt;input class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot; id=&quot;title&quot; type=&quot;text&quot;&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;school&quot;&gt;
                초등학교명(예-한국초 등)
            &lt;/label&gt;
            &lt;input class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot; id=&quot;school&quot; type=&quot;text&quot;&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;flex mb-4&quot;&gt;
            &lt;div class=&quot;w-1/2 pr-2&quot;&gt;
                &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;grade&quot;&gt;
                    학년
                &lt;/label&gt;
                &lt;input class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot; id=&quot;grade&quot; type=&quot;number&quot; min=&quot;1&quot; max=&quot;6&quot;&gt;
            &lt;/div&gt;
            &lt;div class=&quot;w-1/2 pl-2&quot;&gt;
                &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;class&quot;&gt;
                    반
                &lt;/label&gt;
                &lt;input class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot; id=&quot;class&quot; type=&quot;number&quot; min=&quot;1&quot;&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;practice-text&quot;&gt;
                낱말 또는 문장 (최대 70자)
            &lt;/label&gt;
            &lt;textarea class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot; id=&quot;practice-text&quot; rows=&quot;3&quot; maxlength=&quot;70&quot;&gt;&lt;/textarea&gt;
            &lt;div class=&quot;text-right text-xs text-gray-500 mt-1&quot;&gt;
                &lt;span id=&quot;char-count&quot;&gt;0&lt;/span&gt;/70자
            &lt;/div&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;font-select&quot;&gt;
                글씨체 선택
            &lt;/label&gt;
            &lt;select id=&quot;font-select&quot; class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot;&gt;
                &lt;option value=&quot;font-gangwon-all&quot;&gt;강원교육모두체L&lt;/option&gt;
                &lt;option value=&quot;font-gangwon-all-bold&quot; selected&gt;강원교육모두체B&lt;/option&gt;
                &lt;option value=&quot;font-gangwon-group&quot;&gt;강원교육모둠체&lt;/option&gt;
                &lt;option value=&quot;font-hakgyo-ansim&quot;&gt;학교안심받아쓰기체&lt;/option&gt;
                &lt;option value=&quot;font-hakgyo-wooju&quot;&gt;학교안심우주체&lt;/option&gt;
                &lt;option value=&quot;font-nanum-gothic&quot;&gt;나눔고딕&lt;/option&gt;
                &lt;option value=&quot;font-nanum-myeongjo&quot;&gt;나눔명조&lt;/option&gt;
                &lt;option value=&quot;font-nanum-pen&quot;&gt;나눔펜&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;text-color&quot;&gt;
                글씨 색상 선택
            &lt;/label&gt;
            &lt;select id=&quot;text-color&quot; class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot;&gt;
                &lt;option value=&quot;#000000&quot; selected&gt;검정색&lt;/option&gt;
                &lt;option value=&quot;#999999&quot;&gt;회색&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot; for=&quot;dotline-color&quot;&gt;
                점선 색상 선택
            &lt;/label&gt;
            &lt;select id=&quot;dotline-color&quot; class=&quot;shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline&quot;&gt;
                &lt;option value=&quot;#0000ff&quot; selected&gt;파란색&lt;/option&gt;
                &lt;option value=&quot;#aaaaaa&quot;&gt;회색&lt;/option&gt;
                &lt;option value=&quot;#ff0000&quot;&gt;빨간색&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot;&gt;
                따라쓰기 모드
            &lt;/label&gt;
            &lt;div class=&quot;flex items-center mb-3&quot;&gt;
                &lt;input type=&quot;checkbox&quot; id=&quot;copy-mode&quot; class=&quot;mr-2&quot;&gt;
                &lt;label for=&quot;copy-mode&quot; class=&quot;text-sm text-gray-700&quot;&gt;
                    따라쓰기 글자 표시
                &lt;/label&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        
        &lt;div class=&quot;mb-4&quot;&gt;
            &lt;label class=&quot;block text-gray-700 text-sm font-bold mb-2&quot;&gt;
                한글 색상 구분
            &lt;/label&gt;
            &lt;div class=&quot;flex items-center mb-3&quot;&gt;
                &lt;input type=&quot;checkbox&quot; id=&quot;korean-color&quot; class=&quot;mr-2&quot;&gt;
                &lt;label for=&quot;korean-color&quot; class=&quot;text-sm text-gray-700&quot;&gt;
                    자음, 모음, 받침을 색상으로 구분
                &lt;/label&gt;
            &lt;/div&gt;
            &lt;div class=&quot;flex items-center mb-3&quot;&gt;
                &lt;input type=&quot;checkbox&quot; id=&quot;korean-color-copy&quot; class=&quot;mr-2&quot;&gt;
                &lt;label for=&quot;korean-color-copy&quot; class=&quot;text-sm text-gray-700&quot;&gt;
                    따라쓰기 모드
                &lt;/label&gt;
            &lt;/div&gt;
            
            &lt;div id=&quot;color-options&quot; class=&quot;text-sm&quot; style=&quot;display: none;&quot;&gt;
                &lt;!-- 색상 선택 --&gt;
                &lt;div class=&quot;grid grid-cols-3 gap-3 mb-4&quot;&gt;
                    &lt;div&gt;
                        &lt;label class=&quot;block text-gray-600 mb-1&quot;&gt;자음 색상&lt;/label&gt;
                        &lt;select id=&quot;chosung-color&quot; class=&quot;w-full border rounded px-2 py-1 text-xs&quot;&gt;
                            &lt;option value=&quot;#ff0000&quot; selected&gt;빨간색&lt;/option&gt;
                            &lt;option value=&quot;#ff8800&quot;&gt;주황색&lt;/option&gt;
                            &lt;option value=&quot;#0000ff&quot;&gt;파란색&lt;/option&gt;
                            &lt;option value=&quot;#00ff00&quot;&gt;초록색&lt;/option&gt;
                            &lt;option value=&quot;#000000&quot;&gt;검정색&lt;/option&gt;
                            &lt;option value=&quot;transparent&quot;&gt;투명&lt;/option&gt;
                        &lt;/select&gt;
                    &lt;/div&gt;
                    &lt;div&gt;
                        &lt;label class=&quot;block text-gray-600 mb-1&quot;&gt;모음 색상&lt;/label&gt;
                        &lt;select id=&quot;jungsung-color&quot; class=&quot;w-full border rounded px-2 py-1 text-xs&quot;&gt;
                            &lt;option value=&quot;#ff0000&quot;&gt;빨간색&lt;/option&gt;
                            &lt;option value=&quot;#ff8800&quot; selected&gt;주황색&lt;/option&gt;
                            &lt;option value=&quot;#0000ff&quot;&gt;파란색&lt;/option&gt;
                            &lt;option value=&quot;#00ff00&quot;&gt;초록색&lt;/option&gt;
                            &lt;option value=&quot;#000000&quot;&gt;검정색&lt;/option&gt;
                            &lt;option value=&quot;transparent&quot;&gt;투명&lt;/option&gt;
                        &lt;/select&gt;
                    &lt;/div&gt;
                    &lt;div&gt;
                        &lt;label class=&quot;block text-gray-600 mb-1&quot;&gt;받침 색상&lt;/label&gt;
                        &lt;select id=&quot;jongsung-color&quot; class=&quot;w-full border rounded px-2 py-1 text-xs&quot;&gt;
                            &lt;option value=&quot;#ff0000&quot;&gt;빨간색&lt;/option&gt;
                            &lt;option value=&quot;#ff8800&quot;&gt;주황색&lt;/option&gt;
                            &lt;option value=&quot;#0000ff&quot; selected&gt;파란색&lt;/option&gt;
                            &lt;option value=&quot;#00ff00&quot;&gt;초록색&lt;/option&gt;
                            &lt;option value=&quot;#000000&quot;&gt;검정색&lt;/option&gt;
                            &lt;option value=&quot;transparent&quot;&gt;투명&lt;/option&gt;
                        &lt;/select&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                
                &lt;!-- 위치 조절 컨트롤 --&gt;
                &lt;div class=&quot;border-t pt-3&quot;&gt;
                    &lt;div class=&quot;flex items-center mb-3&quot;&gt;
                        &lt;input type=&quot;checkbox&quot; id=&quot;position-control&quot; class=&quot;mr-2&quot;&gt;
                        &lt;label for=&quot;position-control&quot; class=&quot;text-sm text-gray-700 font-semibold&quot;&gt;
                            위치 조절
                        &lt;/label&gt;
                    &lt;/div&gt;
                    
                    &lt;div id=&quot;position-controls&quot; style=&quot;display: none;&quot;&gt;
                    
                    &lt;!-- 초성 위치 조절 --&gt;
                    &lt;div class=&quot;mb-4 p-3 bg-red-50 rounded&quot;&gt;
                        &lt;h5 class=&quot;text-red-700 font-medium mb-2&quot;&gt;초성 (자음) 위치&lt;/h5&gt;
                        &lt;div class=&quot;grid grid-cols-2 gap-2&quot;&gt;
                            &lt;div&gt;
                                &lt;label class=&quot;block text-xs text-gray-600 mb-1&quot;&gt;가로 위치&lt;/label&gt;
                                &lt;input type=&quot;range&quot; id=&quot;chosung-x&quot; min=&quot;-20&quot; max=&quot;20&quot; value=&quot;0&quot; class=&quot;w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer&quot;&gt;
                                &lt;div class=&quot;text-xs text-center text-gray-500 mt-1&quot;&gt;
                                    &lt;span id=&quot;chosung-x-value&quot;&gt;0&lt;/span&gt;px
                                &lt;/div&gt;
                            &lt;/div&gt;
                            &lt;div&gt;
                                &lt;label class=&quot;block text-xs text-gray-600 mb-1&quot;&gt;세로 위치&lt;/label&gt;
                                &lt;input type=&quot;range&quot; id=&quot;chosung-y&quot; min=&quot;-20&quot; max=&quot;20&quot; value=&quot;0&quot; class=&quot;w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer&quot;&gt;
                                &lt;div class=&quot;text-xs text-center text-gray-500 mt-1&quot;&gt;
                                    &lt;span id=&quot;chosung-y-value&quot;&gt;0&lt;/span&gt;px
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                    
                    &lt;!-- 중성 위치 조절 --&gt;
                    &lt;div class=&quot;mb-4 p-3 bg-orange-50 rounded&quot;&gt;
                        &lt;h5 class=&quot;text-orange-700 font-medium mb-2&quot;&gt;중성 (모음) 위치&lt;/h5&gt;
                        &lt;div class=&quot;grid grid-cols-2 gap-2&quot;&gt;
                            &lt;div&gt;
                                &lt;label class=&quot;block text-xs text-gray-600 mb-1&quot;&gt;가로 위치&lt;/label&gt;
                                &lt;input type=&quot;range&quot; id=&quot;jungsung-x&quot; min=&quot;-20&quot; max=&quot;20&quot; value=&quot;0&quot; class=&quot;w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer&quot;&gt;
                                &lt;div class=&quot;text-xs text-center text-gray-500 mt-1&quot;&gt;
                                    &lt;span id=&quot;jungsung-x-value&quot;&gt;0&lt;/span&gt;px
                                &lt;/div&gt;
                            &lt;/div&gt;
                            &lt;div&gt;
                                &lt;label class=&quot;block text-xs text-gray-600 mb-1&quot;&gt;세로 위치&lt;/label&gt;
                                &lt;input type=&quot;range&quot; id=&quot;jungsung-y&quot; min=&quot;-20&quot; max=&quot;20&quot; value=&quot;0&quot; class=&quot;w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer&quot;&gt;
                                &lt;div class=&quot;text-xs text-center text-gray-500 mt-1&quot;&gt;
                                    &lt;span id=&quot;jungsung-y-value&quot;&gt;0&lt;/span&gt;px
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                    
                    &lt;!-- 종성 위치 조절 --&gt;
                    &lt;div class=&quot;mb-4 p-3 bg-blue-50 rounded&quot;&gt;
                        &lt;h5 class=&quot;text-blue-700 font-medium mb-2&quot;&gt;종성 (받침) 위치&lt;/h5&gt;
                        &lt;div class=&quot;grid grid-cols-2 gap-2&quot;&gt;
                            &lt;div&gt;
                                &lt;label class=&quot;block text-xs text-gray-600 mb-1&quot;&gt;가로 위치&lt;/label&gt;
                                &lt;input type=&quot;range&quot; id=&quot;jongsung-x&quot; min=&quot;-20&quot; max=&quot;20&quot; value=&quot;0&quot; class=&quot;w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer&quot;&gt;
                                &lt;div class=&quot;text-xs text-center text-gray-500 mt-1&quot;&gt;
                                    &lt;span id=&quot;jongsung-x-value&quot;&gt;0&lt;/span&gt;px
                                &lt;/div&gt;
                            &lt;/div&gt;
                            &lt;div&gt;
                                &lt;label class=&quot;block text-xs text-gray-600 mb-1&quot;&gt;세로 위치&lt;/label&gt;
                                &lt;input type=&quot;range&quot; id=&quot;jongsung-y&quot; min=&quot;-20&quot; max=&quot;20&quot; value=&quot;5&quot; class=&quot;w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer&quot;&gt;
                                &lt;div class=&quot;text-xs text-center text-gray-500 mt-1&quot;&gt;
                                    &lt;span id=&quot;jongsung-y-value&quot;&gt;5&lt;/span&gt;px
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                    
                        &lt;!-- 리셋 버튼 --&gt;
                        &lt;div class=&quot;text-center&quot;&gt;
                            &lt;button id=&quot;reset-positions&quot; class=&quot;bg-gray-500 hover:bg-gray-600 text-white text-xs px-3 py-1 rounded&quot;&gt;
                                위치 초기화
                            &lt;/button&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        
            &lt;div class=&quot;mt-4 flex justify-center&quot;&gt;
                &lt;button onclick=&quot;savePDF()&quot; class=&quot;bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline&quot; type=&quot;button&quot;&gt;
                    PDF 저장
                &lt;/button&gt;
            &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        
        &lt;!-- 학습지 미리보기 --&gt;
        &lt;div id=&quot;worksheetContainer&quot; class=&quot;lg:w-2/3 lg:flex-grow lg:h-full lg:overflow-y-auto lg:p-4 mb-8 max-w-4xl mx-auto lg:mx-0&quot;&gt;
            &lt;div id=&quot;worksheet&quot; class=&quot;worksheet lg:mx-auto&quot;&gt;
                &lt;!-- 상단 부분 --&gt;
                &lt;div class=&quot;flex border-b-2 border-black header-section&quot;&gt;
                    &lt;!-- 제목 부분 (유연한 크기) --&gt;
                    &lt;div class=&quot;flex-1 border-r-2 border-black pr-4 flex items-center justify-center min-w-0&quot;&gt;
                        &lt;h1 id=&quot;worksheetTitle&quot; class=&quot;text-2xl sm:text-3xl lg:text-5xl font-bold text-center break-words&quot;&gt;&lt;/h1&gt;
                    &lt;/div&gt;
                    
                    &lt;!-- 학생 정보 부분 (고정 크기) --&gt;
                    &lt;div class=&quot;flex-shrink-0 pl-4&quot; style=&quot;min-width: 200px;&quot;&gt;
                        &lt;div class=&quot;mb-2 whitespace-nowrap&quot;&gt;
                            &lt;span id=&quot;studentClass&quot; class=&quot;text-sm sm:text-base lg:text-lg&quot;&gt;&lt;/span&gt;
                            &lt;span class=&quot;student-number&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;text-sm sm:text-base lg:text-lg&quot;&gt;번&lt;/span&gt;
                        &lt;/div&gt;
                        &lt;div class=&quot;whitespace-nowrap&quot;&gt;
                            &lt;span class=&quot;text-sm sm:text-base lg:text-lg&quot;&gt;이름: &lt;/span&gt;
                            &lt;span class=&quot;inline-block w-20 sm:w-24 lg:w-32&quot;&gt;&lt;/span&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                
                &lt;!-- 학습지 내용 부분 --&gt;
                &lt;div class=&quot;mt-2&quot;&gt;
                    &lt;div id=&quot;practice-content&quot; class=&quot;writing-grid&quot;&gt;
                        &lt;!-- 여기에 글씨 쓰기 칸이 동적으로 생성됩니다 --&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    
    &lt;script&gt;
        // 페이지 로드 시 즉시 실행되는 초기화 함수
        function initializeWorksheet() {
            console.log('학습지 초기화 시작...');
            
            // 기본값 설정
            const titleInput = document.getElementById('title');
            const schoolInput = document.getElementById('school');
            const gradeInput = document.getElementById('grade');
            const classInput = document.getElementById('class');
            const practiceTextInput = document.getElementById('practice-text');
            const charCountSpan = document.getElementById('char-count');
            
            // 글자 수 업데이트
            if (charCountSpan) {
                charCountSpan.textContent = practiceTextInput.value.length;
            }
            
            // 학습지 생성
            generateWorksheet();
            
            console.log('학습지 초기화 완료!');
        }
        
        // 한글 분해 함수
        function decomposeKorean(char) {
            const code = char.charCodeAt(0);
            
            // 한글이 아닌 경우
            if (code &lt; 0xAC00 || code &gt; 0xD7A3) {
                return null;
            }
            
            const base = code - 0xAC00;
            const chosung = Math.floor(base / 588); // 초성
            const jungsung = Math.floor((base % 588) / 28); // 중성
            const jongsung = base % 28; // 종성
            
            const chosungList = ['ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'];
            const jungsungList = ['ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'];
            const jongsungList = ['', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'];
            
            return {
                chosung: chosungList[chosung],
                jungsung: jungsungList[jungsung],
                jongsung: jongsungList[jongsung]
            };
        }
        
        // 한글 색상 적용 함수
        function applyKoreanColors(char, fontClass, isGrayMode = false) {
            const decomposed = decomposeKorean(char);
            
            if (!decomposed) {
                // 한글이 아닌 경우 기본 색상
                const charElement = document.createElement('div');
                charElement.className = `character ${fontClass}`;
                charElement.textContent = char;
                
                // 따라쓰기 모드일 때는 회색으로 표시
                if (isGrayMode) {
                    charElement.style.color = '#999999';
                }
                
                // 마침표와 쉼표만 특별 위치 조정
                if (char === '.' || char === ',') {
                    charElement.style.position = 'relative';
                    charElement.style.left = '-27px';
                    charElement.style.top = '12px';
                }
                
                return charElement;
            }
            
            // 선택된 색상 가져오기
            let chosungColor = document.getElementById('chosung-color').value;
            let jungsungColor = document.getElementById('jungsung-color').value;
            let jongsungColor = document.getElementById('jongsung-color').value;
            
            // 따라쓰기 모드일 때 색상 처리
            if (isGrayMode) {
                // 투명이 아닌 경우에만 회색으로 변경
                if (chosungColor !== 'transparent') chosungColor = '#999999';
                if (jungsungColor !== 'transparent') jungsungColor = '#999999';
                if (jongsungColor !== 'transparent') jongsungColor = '#999999';
            }
            
            // 위치 조절 값 가져오기
            const chosungXOffset = parseInt(document.getElementById('chosung-x').value) || 0;
            const chosungYOffset = parseInt(document.getElementById('chosung-y').value) || 0;
            const jungsungXOffset = parseInt(document.getElementById('jungsung-x').value) || 0;
            const jungsungYOffset = parseInt(document.getElementById('jungsung-y').value) || 0;
            const jongsungXOffset = parseInt(document.getElementById('jongsung-x').value) || 0;
            const jongsungYOffset = parseInt(document.getElementById('jongsung-y').value) || 5;
            
            const charElement = document.createElement('div');
            charElement.className = `character ${fontClass}`;
            charElement.style.position = 'relative';
            charElement.style.display = 'flex';
            charElement.style.alignItems = 'center';
            charElement.style.justifyContent = 'center';
            
            // 모음 타입 분류
            const verticalVowels = ['ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅣ'];
            const horizontalVowels = ['ㅗ', 'ㅛ', 'ㅜ', 'ㅠ', 'ㅡ'];
            const complexVowels = ['ㅘ', 'ㅙ', 'ㅚ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅢ'];
            
            const hasJongsung = decomposed.jongsung !== '';
            const vowelType = verticalVowels.includes(decomposed.jungsung) ? 'vertical' :
                            horizontalVowels.includes(decomposed.jungsung) ? 'horizontal' : 'complex';
            
            // 초성 (자음) 위치 설정
            const chosungSpan = document.createElement('span');
            chosungSpan.textContent = decomposed.chosung;
            chosungSpan.style.color = chosungColor;
            chosungSpan.style.position = 'absolute';
            chosungSpan.style.fontSize = '0.85em';
            chosungSpan.style.fontWeight = 'bold';
            
            // 중성 (모음) 위치 설정
            const jungsungSpan = document.createElement('span');
            jungsungSpan.textContent = decomposed.jungsung;
            jungsungSpan.style.color = jungsungColor;
            jungsungSpan.style.position = 'absolute';
            jungsungSpan.style.fontSize = '0.85em';
            jungsungSpan.style.fontWeight = 'bold';
            
            // ㅗ, ㅛ, ㅡ의 경우 2px 아래로 이동
            const needsLowerPosition = ['ㅗ', 'ㅛ', 'ㅡ'].includes(decomposed.jungsung);
            
            // 받침 유무와 모음 타입에 따른 기본 위치 조정
            if (vowelType === 'vertical') {
                // 세로 모음 (ㅏㅑㅓㅕㅣ)
                if (hasJongsung) {
                    chosungSpan.style.left = `calc(30% + ${chosungXOffset}px)`;
                    chosungSpan.style.top = `calc(25% + ${chosungYOffset}px)`;
                    chosungSpan.style.transform = 'translate(-50%, -50%)';
                    jungsungSpan.style.right = `calc(30% - ${jungsungXOffset}px)`;
                    jungsungSpan.style.top = `calc(25% + ${jungsungYOffset}px)`;
                    jungsungSpan.style.transform = 'translate(50%, -50%)';
                } else {
                    // 받침이 없는 세로 모음: 자음은 오른쪽으로 2px, 위로 2px, 모음은 왼쪽으로 6px, 위로 2px
                    chosungSpan.style.left = `calc(30% + ${chosungXOffset + 2}px)`;
                    chosungSpan.style.top = `calc(50% + ${chosungYOffset - 2}px)`;
                    chosungSpan.style.transform = 'translate(-50%, -50%)';
                    jungsungSpan.style.right = `calc(30% - ${jungsungXOffset - 6}px)`;
                    jungsungSpan.style.top = `calc(50% + ${jungsungYOffset - 2}px)`;
                    jungsungSpan.style.transform = 'translate(50%, -50%)';
                }
            } else if (vowelType === 'horizontal') {
                // 가로 모음
                if (hasJongsung) {
                    // 받침이 있는 가로 모음별 특별 조정
                    let chosungExtraYOffset = 0;
                    let jungsungExtraYOffset = 0;
                    
                    if (['ㅗ', 'ㅛ'].includes(decomposed.jungsung)) {
                        // 받침이 있는 ㅗㅛ: 자음 위로 3px, 모음 아래로 1px
                        chosungExtraYOffset = -3;
                        jungsungExtraYOffset = 1;
                    } else if (['ㅜ', 'ㅠ'].includes(decomposed.jungsung)) {
                        // 받침이 있는 ㅜㅠ: 자음 위로 3px, 모음 아래로 4px
                        chosungExtraYOffset = -3;
                        jungsungExtraYOffset = 4;
                    }
                    
                    chosungSpan.style.left = `calc(50% + ${chosungXOffset}px)`;
                    chosungSpan.style.top = `calc(25% + ${chosungYOffset + chosungExtraYOffset}px)`;
                    chosungSpan.style.transform = 'translate(-50%, -50%)';
                    
                    // 받침이 있는 ㅡ 모음의 경우 아래로 3px 추가 이동
                    let baseTop = needsLowerPosition ? 42 : 40;
                    let extraYOffset = 0;
                    if (decomposed.jungsung === 'ㅡ') {
                        extraYOffset = 3;
                    }
                    
                    jungsungSpan.style.left = `calc(50% + ${jungsungXOffset}px)`;
                    jungsungSpan.style.top = `calc(${baseTop}% + ${jungsungYOffset + extraYOffset + jungsungExtraYOffset}px)`;
                    jungsungSpan.style.transform = 'translate(-50%, -50%)';
                } else {
                    chosungSpan.style.left = `calc(50% + ${chosungXOffset}px)`;
                    chosungSpan.style.top = `calc(35% + ${chosungYOffset}px)`;
                    chosungSpan.style.transform = 'translate(-50%, -50%)';
                    
                    // 받침이 없는 가로 모음별 특별 조정
                    let baseTop = needsLowerPosition ? 67 : 65;
                    let extraXOffset = 0;
                    let extraYOffset = 0;
                    
                    if (['ㅗ', 'ㅛ'].includes(decomposed.jungsung)) {
                        // ㅗㅛ: 왼쪽 1px, 위로 4px
                        extraXOffset = -1;
                        extraYOffset = -4;
                    } else if (['ㅜ', 'ㅠ'].includes(decomposed.jungsung)) {
                        // ㅜㅠ: 위로 2px
                        extraYOffset = -2;
                    }
                    
                    jungsungSpan.style.left = `calc(50% + ${jungsungXOffset + extraXOffset}px)`;
                    jungsungSpan.style.top = `calc(${baseTop}% + ${jungsungYOffset + extraYOffset}px)`;
                    jungsungSpan.style.transform = 'translate(-50%, -50%)';
                }
            } else {
                // 복합 모음
                let chosungExtraXOffset = 0;
                let chosungExtraYOffset = 0;
                
                // 복합 모음별 특별 조정
                if (decomposed.jungsung === 'ㅢ') {
                    // ㅢ: 자음 오른쪽으로 14px
                    chosungExtraXOffset = 14;
                } else if (decomposed.jungsung === 'ㅟ') {
                    // ㅟ: 자음 오른쪽으로 14px, 위로 4px
                    chosungExtraXOffset = 14;
                    chosungExtraYOffset = -4;
                } else if (decomposed.jungsung === 'ㅚ') {
                    // ㅚ: 자음 오른쪽으로 14px, 위로 4px
                    chosungExtraXOffset = 14;
                    chosungExtraYOffset = -4;
                } else if (decomposed.jungsung === 'ㅙ') {
                    // ㅙ: 자음 오른쪽으로 11px, 위로 4px
                    chosungExtraXOffset = 11;
                    chosungExtraYOffset = -4;
                } else if (decomposed.jungsung === 'ㅞ') {
                    // ㅞ: 자음 오른쪽으로 11px, 위로 6px
                    chosungExtraXOffset = 11;
                    chosungExtraYOffset = -6;
                }
                
                if (hasJongsung) {
                    chosungSpan.style.left = `calc(25% + ${chosungXOffset + chosungExtraXOffset}px)`;
                    chosungSpan.style.top = `calc(20% + ${chosungYOffset + chosungExtraYOffset}px)`;
                    chosungSpan.style.transform = 'translate(-50%, -50%)';
                    jungsungSpan.style.left = `calc(50% + ${jungsungXOffset}px)`;
                    jungsungSpan.style.top = `calc(25% + ${jungsungYOffset}px)`;
                    jungsungSpan.style.transform = 'translate(-50%, -50%)';
                } else {
                    chosungSpan.style.left = `calc(25% + ${chosungXOffset + chosungExtraXOffset}px)`;
                    chosungSpan.style.top = `calc(40% + ${chosungYOffset + chosungExtraYOffset}px)`;
                    chosungSpan.style.transform = 'translate(-50%, -50%)';
                    jungsungSpan.style.left = `calc(50% + ${jungsungXOffset}px)`;
                    jungsungSpan.style.top = `calc(45% + ${jungsungYOffset}px)`;
                    jungsungSpan.style.transform = 'translate(-50%, -50%)';
                }
            }
            
            // 종성 (받침) 위치 설정
            if (hasJongsung) {
                const jongsungSpan = document.createElement('span');
                jongsungSpan.textContent = decomposed.jongsung;
                jongsungSpan.style.color = jongsungColor;
                jongsungSpan.style.position = 'absolute';
                jongsungSpan.style.fontSize = '0.85em';
                jongsungSpan.style.fontWeight = 'bold';
                jongsungSpan.style.left = `calc(50% + ${jongsungXOffset}px)`;
                jongsungSpan.style.bottom = `calc(10% - ${jongsungYOffset}px)`;
                jongsungSpan.style.transform = 'translateX(-50%)';
                charElement.appendChild(jongsungSpan);
            }
            
            charElement.appendChild(chosungSpan);
            charElement.appendChild(jungsungSpan);
            
            return charElement;
        }
        
        function generateWorksheet() {
            console.log('generateWorksheet 함수 실행 중...');
            
            const title = document.getElementById('title').value || '일일 학습지';
            const school = document.getElementById('school').value || '00초';
            const grade = document.getElementById('grade').value || '0';
            const classNum = document.getElementById('class').value || '0';
            const practiceText = document.getElementById('practice-text').value || '';
            const selectedFont = document.getElementById('font-select').value;
            const dotlineColor = document.getElementById('dotline-color').value;
            const textColor = document.getElementById('text-color').value;
            
            // 제목과 학생 정보 업데이트
            const worksheetTitle = document.getElementById('worksheetTitle');
            const studentClass = document.getElementById('studentClass');
            
            if (worksheetTitle) {
                worksheetTitle.textContent = title;
            }
            
            if (studentClass) {
                studentClass.textContent = `${school}         ${grade}학년 ${classNum}반`;
            }
            
            // 점선 색상 적용
            updateDotlineColor(dotlineColor);
            
            // 글씨 쓰기 칸 생성
            generateWritingGrid(practiceText, selectedFont, textColor);
            
            console.log('generateWorksheet 함수 완료!');
        }
        
        function updateDotlineColor(color) {
            // 기존 스타일 제거
            const existingStyle = document.getElementById('dotline-style');
            if (existingStyle) {
                existingStyle.remove();
            }
            
            // 새로운 스타일 추가
            const style = document.createElement('style');
            style.id = 'dotline-style';
            style.textContent = `
                .writing-cell::before {
                    border-left: 2px dotted ${color} !important;
                }
                .writing-cell::after {
                    border-top: 2px dotted ${color} !important;
                }
            `;
            document.head.appendChild(style);
        }
        
        function generateWritingGrid(text, fontClass, textColor = '#000000') {
            console.log('generateWritingGrid 함수 실행 중...', text, fontClass, textColor);
            
            const practiceContent = document.getElementById('practice-content');
            if (!practiceContent) {
                console.error('practice-content 요소를 찾을 수 없습니다!');
                return;
            }
            
            practiceContent.innerHTML = '';
            
            const totalRows = 14; // 총 줄 수
            const charsPerRow = 10; // 한 줄에 들어갈 수 있는 글자 수
            const copyModeEnabled = document.getElementById('copy-mode').checked;
            const koreanColorEnabled = document.getElementById('korean-color').checked;
            const koreanColorCopyEnabled = document.getElementById('korean-color-copy').checked;
            
            // 텍스트를 줄바꿈으로 먼저 나누고, 각 줄을 10자씩 나누어 배열로 만들기
            const textChunks = [];
            if (text.trim() !== '') {
                const lines = text.split('\n');
                
                for (let line of lines) {
                    if (line.trim() === '') {
                        textChunks.push('');
                    } else {
                        for (let i = 0; i &lt; line.length; i += charsPerRow) {
                            textChunks.push(line.substr(i, charsPerRow));
                        }
                    }
                }
            }
            
            // 모든 줄 처리
            for (let row = 0; row &lt; totalRows; row++) {
                const isOddRow = row % 2 === 0;
                const chunkIndex = Math.floor(row / 2);
                
                let rowText = '';
                let isGrayText = false;
                
                if (isOddRow &amp;&amp; chunkIndex &lt; textChunks.length) {
                    rowText = textChunks[chunkIndex];
                    isGrayText = false;
                } else if (!isOddRow &amp;&amp; (copyModeEnabled || koreanColorCopyEnabled) &amp;&amp; chunkIndex &lt; textChunks.length) {
                    rowText = textChunks[chunkIndex];
                    isGrayText = true;
                }
                
                for (let col = 0; col &lt; charsPerRow; col++) {
                    const cell = document.createElement('div');
                    cell.className = 'writing-cell';
                    
                    if (col &lt; rowText.length) {
                        const displayColor = isGrayText ? '#999999' : textColor;
                        
                        if (koreanColorEnabled &amp;&amp; !isGrayText) {
                            const charElement = applyKoreanColors(rowText[col], fontClass);
                            cell.appendChild(charElement);
                        } else if (koreanColorCopyEnabled &amp;&amp; koreanColorEnabled &amp;&amp; isGrayText) {
                            const charElement = applyKoreanColors(rowText[col], fontClass, true);
                            cell.appendChild(charElement);
                        } else {
                            const char = document.createElement('div');
                            char.className = `character ${fontClass}`;
                            char.textContent = rowText[col];
                            char.style.color = displayColor;
                            
                            // 마침표와 쉼표만 특별 위치 조정
                            if (rowText[col] === '.' || rowText[col] === ',') {
                                char.style.position = 'relative';
                                char.style.left = '-27px';
                                char.style.top = '12px';
                            }
                            
                            cell.appendChild(char);
                        }
                    }
                    
                    practiceContent.appendChild(cell);
                }
            }
            
            console.log('generateWritingGrid 함수 완료!');
        }
        

        
        // 폰트 로딩 확인 함수
        async function waitForFontsToLoad() {
            const fontFamilies = [
                'GangwonEduAll',
                'GangwonEduAllBold', 
                'GangwonEduGroup',
                'HakgyoansimBareunbatangR',
                'HakgyoansimWoojuR',
                'Nanum Gothic',
                'Nanum Myeongjo',
                'Nanum Pen Script',
                'Noto Sans KR'
            ];
            
            const fontPromises = fontFamilies.map(family =&gt; {
                return document.fonts.load(`16px &quot;${family}&quot;`).catch(() =&gt; {
                    console.warn(`폰트 로딩 실패: ${family}`);
                });
            });
            
            await Promise.allSettled(fontPromises);
            
            // 추가 대기 시간으로 폰트 완전 로딩 보장
            await new Promise(resolve =&gt; setTimeout(resolve, 500));
        }
        
        // PDF 저장 함수 - html2pdf.js 사용으로 더 정확한 출력
        async function savePDF() {
            try {
                // 학습지 제목 가져오기 (파일명으로 사용)
                const title = document.getElementById('title').value || '일일_학습지';
                const fileName = `${title.replace(/[^가-힣a-zA-Z0-9]/g, '_')}.pdf`;
                
                // 학습지 요소 가져오기
                const element = document.getElementById('worksheet');
                
                if (!element) {
                    alert('학습지를 찾을 수 없습니다.');
                    return;
                }
                
                // PDF 생성 전 스타일 고정
                const originalStyle = element.style.cssText;
                const originalClassName = element.className;
                
                // A4 크기로 고정 (794px x 1123px는 A4의 픽셀 크기)
                element.style.width = '794px';
                element.style.height = '1123px';
                element.style.maxWidth = '794px';
                element.style.maxHeight = '1123px';
                element.style.minHeight = '1123px';
                element.style.minWidth = '794px';
                element.style.aspectRatio = 'auto';
                element.style.margin = '0';
                element.style.padding = '37.8px 56.7px'; // 10mm 15mm을 픽셀로 변환
                element.style.transform = 'none';
                element.style.position = 'relative';
                element.style.overflow = 'hidden';
                element.style.pageBreakAfter = 'avoid';
                element.style.pageBreakInside = 'avoid';
                element.style.pageBreakBefore = 'avoid';
                element.style.boxSizing = 'border-box';
                element.style.backgroundColor = '#ffffff';
                element.style.border = '1px solid #000000';
                element.className = originalClassName + ' no-break-inside';
                
                // 모든 character 요소의 폰트 크기 고정
                const characters = element.querySelectorAll('.character');
                const originalCharacterStyles = [];
                characters.forEach((char, index) =&gt; {
                    originalCharacterStyles[index] = char.style.cssText;
                    char.style.fontSize = '2.8rem';
                });
                
                // 폰트 로딩 대기
                await waitForFontsToLoad();
                
                // PDF 출력을 위한 최적화된 옵션 설정
                const options = {
                    margin: 0,
                    filename: fileName,
                    image: { 
                        type: 'jpeg', 
                        quality: 0.98 
                    },
                    html2canvas: { 
                        scale: 3, // 스케일을 3으로 증가하여 더 선명한 출력
                        useCORS: true,
                        allowTaint: true,
                        letterRendering: true,
                        logging: false,
                        width: 794, // A4 픽셀 크기 고정 (210mm * 3.78)
                        height: 1122, // A4 픽셀 크기 고정 (297mm * 3.78)
                        windowWidth: 794,
                        windowHeight: 1122,
                        x: 0,
                        y: 0,
                        scrollX: 0,
                        scrollY: 0,
                        backgroundColor: '#ffffff',
                        removeContainer: true,
                        foreignObjectRendering: false,
                        dpi: 300,
                        pixelRatio: 3
                    },
                    jsPDF: { 
                        unit: 'mm', 
                        format: [210, 297], // A4 크기 명시적 지정
                        orientation: 'portrait',
                        compress: false, // 압축 해제로 품질 향상
                        putOnlyUsedFonts: true,
                        floatPrecision: 2
                    },
                    pagebreak: { 
                        mode: 'avoid-all',
                        avoid: ['#worksheet', '.worksheet', '.no-break-inside']
                    }
                };
                
                // html2pdf를 사용하여 PDF 생성
                await html2pdf().set(options).from(element).save();
                
                // 원래 스타일 복원
                element.style.cssText = originalStyle;
                element.className = originalClassName;
                
                // character 요소들의 원래 스타일 복원
                characters.forEach((char, index) =&gt; {
                    char.style.cssText = originalCharacterStyles[index];
                });
                
            } catch (error) {
                console.error('PDF 생성 오류:', error);
                alert('PDF 생성 중 오류가 발생했습니다.');
                
                // 오류 발생 시에도 원래 스타일 복원
                const element = document.getElementById('worksheet');
                if (element &amp;&amp; originalStyle !== undefined) {
                    element.style.cssText = originalStyle;
                    element.className = originalClassName;
                }
            }
        }
        
        // 이벤트 리스너 등록
        function setupEventListeners() {
            // 글자 수 카운터 업데이트 및 실시간 학습지 업데이트
            document.getElementById('practice-text').addEventListener('input', function() {
                document.getElementById('char-count').textContent = this.value.length;
                generateWorksheet();
            });
            
            // 폰트 변경 시 미리보기 업데이트
            document.getElementById('font-select').addEventListener('change', generateWorksheet);
            
            // 점선 색상 변경 시 미리보기 업데이트
            document.getElementById('dotline-color').addEventListener('change', generateWorksheet);
            
            // 글씨 색상 변경 시 미리보기 업데이트
            document.getElementById('text-color').addEventListener('change', generateWorksheet);
            
            // 따라쓰기 모드 체크박스 변경 시 미리보기 업데이트
            document.getElementById('copy-mode').addEventListener('change', generateWorksheet);
            
            // 한글 색상 구분 체크박스 변경 시 미리보기 업데이트
            document.getElementById('korean-color').addEventListener('change', function() {
                const colorOptions = document.getElementById('color-options');
                const koreanColorCopy = document.getElementById('korean-color-copy');
                
                if (this.checked) {
                    colorOptions.style.display = 'grid';
                } else {
                    colorOptions.style.display = 'none';
                    // 메인 색상 구분이 해제되면 따라쓰기 색상 구분도 자동으로 해제
                    koreanColorCopy.checked = false;
                }
                generateWorksheet();
            });
            
            // 위치 조절 체크박스 변경 시 컨트롤 표시/숨김
            document.getElementById('position-control').addEventListener('change', function() {
                const positionControls = document.getElementById('position-controls');
                
                if (this.checked) {
                    positionControls.style.display = 'block';
                } else {
                    positionControls.style.display = 'none';
                }
            });
            
            // 따라쓰기 한글 색상 구분 체크박스 변경 시 미리보기 업데이트
            document.getElementById('korean-color-copy').addEventListener('change', function() {
                // 메인 한글 색상 구분이 체크되어 있지 않으면 따라쓰기 색상 구분도 해제
                if (this.checked &amp;&amp; !document.getElementById('korean-color').checked) {
                    this.checked = false;
                    alert('먼저 &quot;자음, 모음, 받침을 색상으로 구분&quot; 옵션을 체크해주세요.');
                    return;
                }
                generateWorksheet();
            });
            
            // 색상 선택 변경 시 미리보기 업데이트
            document.getElementById('chosung-color').addEventListener('change', generateWorksheet);
            document.getElementById('jungsung-color').addEventListener('change', generateWorksheet);
            document.getElementById('jongsung-color').addEventListener('change', generateWorksheet);
            
            // 위치 조절 슬라이더 이벤트 리스너
            const positionSliders = [
                'chosung-x', 'chosung-y', 'jungsung-x', 'jungsung-y', 'jongsung-x', 'jongsung-y'
            ];
            
            positionSliders.forEach(sliderId =&gt; {
                const slider = document.getElementById(sliderId);
                const valueSpan = document.getElementById(sliderId + '-value');
                
                slider.addEventListener('input', function() {
                    valueSpan.textContent = this.value;
                    generateWorksheet();
                });
            });
            
            // 위치 초기화 버튼
            document.getElementById('reset-positions').addEventListener('click', function() {
                document.getElementById('chosung-x').value = 0;
                document.getElementById('chosung-y').value = 0;
                document.getElementById('jungsung-x').value = 0;
                document.getElementById('jungsung-y').value = 0;
                document.getElementById('jongsung-x').value = 0;
                document.getElementById('jongsung-y').value = 5;
                
                // 값 표시 업데이트
                document.getElementById('chosung-x-value').textContent = '0';
                document.getElementById('chosung-y-value').textContent = '0';
                document.getElementById('jungsung-x-value').textContent = '0';
                document.getElementById('jungsung-y-value').textContent = '0';
                document.getElementById('jongsung-x-value').textContent = '0';
                document.getElementById('jongsung-y-value').textContent = '5';
                
                generateWorksheet();
            });
            
            // 모든 입력 필드에 실시간 업데이트 추가
            document.getElementById('title').addEventListener('input', generateWorksheet);
            document.getElementById('school').addEventListener('input', generateWorksheet);
            document.getElementById('grade').addEventListener('input', generateWorksheet);
            document.getElementById('class').addEventListener('input', generateWorksheet);
        }
        
        // DOM이 완전히 로드된 후 실행
        document.addEventListener('DOMContentLoaded', function() {
            console.log('DOM 로드 완료, 초기화 시작...');
            
            // 이벤트 리스너 설정
            setupEventListeners();
            
            // 학습지 초기화
            setTimeout(initializeWorksheet, 100); // 약간의 지연을 두어 확실히 초기화
        });
        
        // 추가 안전장치: window.onload도 함께 사용
        window.addEventListener('load', function() {
            console.log('Window 로드 완료, 추가 초기화...');
            
            // DOM이 준비되지 않았다면 다시 초기화
            const worksheet = document.getElementById('worksheet');
            const practiceContent = document.getElementById('practice-content');
            
            if (worksheet &amp;&amp; practiceContent &amp;&amp; practiceContent.children.length === 0) {
                console.log('학습지가 비어있음, 재초기화 실행...');
                initializeWorksheet();
            }
        });
    &lt;/script&gt;
&lt;script&gt;(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML=&quot;window.__CF$cv$params={r:'96ccf6831663ea33',t:'MTc1NDgwMjM3Ni4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);&quot;;b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&amp;&amp;(document.onreadystatechange=e,c())}}}})();&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</description>
      <category>수업자료</category>
      <category>바른 글씨 쓰기</category>
      <category>불펌금지</category>
      <category>학습지자동화</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/156</guid>
      <comments>https://smartree.tistory.com/156#entry156comment</comments>
      <pubDate>Mon, 30 Jun 2025 17:27:43 +0900</pubDate>
    </item>
    <item>
      <title>살다 보니 별일이 다 있네요.</title>
      <link>https://smartree.tistory.com/154</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;살다 보니 별일이 다 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저야 전문적인 프로그래머도 아니고 그냥 삘 받을 때 이렇게 하면 되지 않을까?&amp;nbsp;생각해 보고 고민하면서&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;만든 프로그램(교사 정년 계산)의 소스를 그대로 사용하는 사람이 있네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 저도 여기 저기 블로그 보면서 공부해 보고, 물론 소스 오픈해 놓고 참고해 놓으라는 사이트지만..서도..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 소스 공개도 해 놓지 않았고..(물론 소스 보기 하면 다 볼 수 있겠죠?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저에게 사용해도 되냐 물어보지도 않고, 연락 한적도 없었는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주석 조차 제가 만들어 놓은 그대로 복사해서 붙여 넣고 사용한 사람이 있네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더군다가 (중등) 교사인듯한데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전국구 강연다닌다고 하고 책도 내고, 음반도, 소설가에 영화제작까지..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;능력도 좋은 사람이 왜 그런지 모르겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더군다나 광고까지 덕지덕지..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 살다 보니 별일이 다 생기네요.&lt;/p&gt;</description>
      <category>SmartRee/세상 사는 이야기</category>
      <category>교사정년</category>
      <category>교사정년계산기</category>
      <category>교원정년</category>
      <category>만나이계산</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/154</guid>
      <comments>https://smartree.tistory.com/154#entry154comment</comments>
      <pubDate>Sun, 1 Oct 2023 12:16:04 +0900</pubDate>
    </item>
    <item>
      <title>구글 공유드라이브 용량 제한 해제 방법 및 안될 때 처리 방법</title>
      <link>https://smartree.tistory.com/151</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;구글 공유 드라이브 용량하는 부분이 생겼습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_blob&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5bzCh/btsbSfGysoL/NikiDUVUtQQLsmEFIHO9Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5bzCh/btsbSfGysoL/NikiDUVUtQQLsmEFIHO9Ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5bzCh/btsbSfGysoL/NikiDUVUtQQLsmEFIHO9Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5bzCh%2FbtsbSfGysoL%2FNikiDUVUtQQLsmEFIHO9Ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;397&quot; data-filename=&quot;edited_blob&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽 하단의 저장 용량을 클릭하시고&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;663&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/owfER/btsbTWzuB5C/QITbhDud5CpI3dveo4mWs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/owfER/btsbTWzuB5C/QITbhDud5CpI3dveo4mWs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/owfER/btsbTWzuB5C/QITbhDud5CpI3dveo4mWs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FowfER%2FbtsbTWzuB5C%2FQITbhDud5CpI3dveo4mWs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;856&quot; height=&quot;663&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;663&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가운데의 관리를 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1563&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnpsVR/btsbVfrMFqz/ETsBozrWUK0It79phKArN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnpsVR/btsbVfrMFqz/ETsBozrWUK0It79phKArN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnpsVR/btsbVfrMFqz/ETsBozrWUK0It79phKArN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnpsVR%2FbtsbVfrMFqz%2FETsBozrWUK0It79phKArN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1563&quot; height=&quot;723&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1563&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;곰돌이 근처를 눌러보시면 펜이 나옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;펜 모양을 누르시면 공유드라이브의 저장용량 한도를 조절할 수 있는데요&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조직 단위로 해서 저장용량을 조절할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 중요한 것이 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상하게 조정해도 24시간 이내에 조정해서 용량을 늘려준다고 하는데 계속 안되는 경우가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조직도 옮겨보고, 기다려도 보고, 설정 했다가 용량 늘렸다가 사용 중지도 했다가 별의 방법을 다 써 봤는데&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속 용량이 제한되었다고 경고창이 뜨고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글 드라이브 앱에서 오류가 나오는 경우가 있었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은!!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리자를 제외한 모든 공유드라이브 사람들을 삭제하시면 정상 작동됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이후 다시 공유 드라이브 사람들을 재 추가 하시면 문제 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 들 활용하시길 ~&lt;/p&gt;</description>
      <category>학습도구/Google Workspace for Education</category>
      <category>공유 드라이브 용량 제한 풀기</category>
      <category>공유드라이브</category>
      <category>공유드라이브 용량 제한 풀었는데 오류 대처법</category>
      <category>구글</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/151</guid>
      <comments>https://smartree.tistory.com/151#entry151comment</comments>
      <pubDate>Sun, 23 Apr 2023 14:10:26 +0900</pubDate>
    </item>
    <item>
      <title>한글 2020 멈춤 현상 해결법</title>
      <link>https://smartree.tistory.com/150</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;한동안 큰 문제가 없었는데&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘들어 이상하게 한글 2020의 멈춤 현상이 엄청 많아졌다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학교 교육과정을 작성하면서 날려버린게 너무 많아 화가 많아 났었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각종 사이트 검색해보니 다양한 해결방법 등이 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한컴 입력기 삭제, 레지스트리 삭제 등 다 해봤는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 멈춤 현상이 생겨서 .. 도저히 안되겠어서.. 한컴 기술지원팀에 연락해 봤다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엄청 연결이 안되었지만.. 인내심을 갖고 계속 도전..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 알아낸 사실은&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞춤법 도우미에서 충돌이 난다라는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 내용도 검색을 했었던 부분인데..&amp;nbsp;맞춤법 도우미도 많이 쓰긴 하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 기능에 문제가 있겠냐 하는 생각에 하지 않았던 부분이였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만.. 업체에서 한글 켜서 옵션에서 그 부분을 체크해제하라는 이야기를 들었을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 방법이 업체에서 내 놓은 최선의 해결책인가 하는 의구심이 들긴 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발부에서 패치를 하기 위해 노력한다고 하면서도&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022 버전도 역시나 동일하게 문제가 있다라고 안내하면서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 체크 해제하면 큰 문제가 없다고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐 바로 적용해보고 써 볼란다. 언젠간 패치가 되겠지!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;해결법&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한글 2020 실행 -&amp;gt; 상단 메뉴에서&lt;b&gt; 도구&lt;/b&gt; 클릭 -&amp;gt;&amp;nbsp; &lt;b&gt;환경 설정&lt;/b&gt; 클릭 하면 아래의 모습처럼 나오는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간 정도에서 &quot;&lt;b&gt;맞춤법 도우미 작동&lt;/b&gt;&quot; 을 &lt;b&gt;체크 해제&lt;/b&gt; 하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2023-03-08 144814.png&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CLOk7/btr2D0EnnFN/6caCY4rWkYUrKEY9kkDdK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CLOk7/btr2D0EnnFN/6caCY4rWkYUrKEY9kkDdK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CLOk7/btr2D0EnnFN/6caCY4rWkYUrKEY9kkDdK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCLOk7%2Fbtr2D0EnnFN%2F6caCY4rWkYUrKEY9kkDdK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;613&quot; data-filename=&quot;화면 캡처 2023-03-08 144814.png&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>알아두면 쓸데있는 IT 지식</category>
      <category>맞춤법 도우미 작동</category>
      <category>체크해제</category>
      <category>한글 멈춤</category>
      <category>한글2020 멈춤</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/150</guid>
      <comments>https://smartree.tistory.com/150#entry150comment</comments>
      <pubDate>Wed, 8 Mar 2023 14:55:40 +0900</pubDate>
    </item>
    <item>
      <title>알리익스프레스 노이즈 필터 구입 및 짧은 사용 후기</title>
      <link>https://smartree.tistory.com/146</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;학교에서는 아직도 PC 연결을 영상은 RGB로 연결하고 음성을 3.5mm 연결하는 곳이 많다.&lt;br /&gt;&lt;br /&gt;내가 일하는 곳도 당연히....&lt;br /&gt;물론 새로 들어오는 TV는 당연히 HDMI로 연결해주지만, 연식이 오래된 곳은 아직도 그렇다. &lt;br /&gt;그리고 싹 다 바꿔줄 정도로 예산을 내려 주지도 않는다. 이런 걸 바꿔주지 않느냐고 정치권에서는 그런걸~ 뚜드려패야지 열심히 사는 학교를 못잡아 먹어서 난리린지 모르겠다. 각설하고....&lt;br /&gt;&lt;br /&gt;알리에서 감사하게도 무료 쿠폰을 줘서....&lt;br /&gt;&lt;br /&gt;스피커 라인 3.5mm Aux 오디오 노이즈 필터 접지 루프 노이즈 아이솔레이터 제거 카 스테레오 오디오 시스템 홈 스테레오로 판매되는 걸 질러봤다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;3040&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UQ1Lo/btrQZipUrsC/0LsMElwX3uxOCYaOXHgyM0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UQ1Lo/btrQZipUrsC/0LsMElwX3uxOCYaOXHgyM0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UQ1Lo/btrQZipUrsC/0LsMElwX3uxOCYaOXHgyM0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUQ1Lo%2FbtrQZipUrsC%2F0LsMElwX3uxOCYaOXHgyM0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;3040&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;3040&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;가격은 천차만별&lt;br /&gt;1달러 안되는 가격도 많으니 참고하시고, &lt;br /&gt;난 무료 쿠폰이 있으니 최대한 무료 배송에 쿠폰쓸 수 있는 가격을 찾아서 191원에 구입&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KMTPS/btrQ0HI3F5u/v1ouGkLRrkdcRVC9f5Bf60/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KMTPS/btrQ0HI3F5u/v1ouGkLRrkdcRVC9f5Bf60/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KMTPS/btrQ0HI3F5u/v1ouGkLRrkdcRVC9f5Bf60/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKMTPS%2FbtrQ0HI3F5u%2Fv1ouGkLRrkdcRVC9f5Bf60%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;1223&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1223&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;10월 10일 구입, 11월 9일 도착. 뭐 배송이 그다지 빠르진 않았다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qLk8o/btrQZXZWpbQ/tSiW6JNpwhYMIekhYsPGu1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qLk8o/btrQZXZWpbQ/tSiW6JNpwhYMIekhYsPGu1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qLk8o/btrQZXZWpbQ/tSiW6JNpwhYMIekhYsPGu1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqLk8o%2FbtrQZXZWpbQ%2FtSiW6JNpwhYMIekhYsPGu1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;구성품은 단촐&lt;br /&gt;&lt;br /&gt;사용방법은 TV에 연결된 3.5mm단자 빼고 검정색 필터에 넣고 필터를 TV에 연결하면 끝.&lt;br /&gt;&lt;br /&gt;효과는 엄청 좋다.&lt;br /&gt;스피커에서 찌이잉찌이잉 거리는걸 확 줄여준다.&lt;br /&gt;물론 민감함 사람이야 줄어든 것도 난다고 할 수 있지만 거의 소음의 90%정도는 줄여준듯 느껴진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;볼륨 자체가 줄어든다는 이야기가 있으나, 딱히 그렇게 느껴지지도 않는다.&lt;br /&gt;&lt;br /&gt;매우 만족스러운 제품 중 하나이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(모바일로도 블로그를 쓰는 좋은 세상이다. 태어나서 첨으로 전철 타면서 써보네)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>알아두면 쓸데있는 리뷰</category>
      <category>노이즈필터</category>
      <category>매우만족</category>
      <category>알리익스프레스</category>
      <category>학교TV를 좀 좋은 걸로 교체해주세요</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/146</guid>
      <comments>https://smartree.tistory.com/146#entry146comment</comments>
      <pubDate>Sat, 12 Nov 2022 11:34:30 +0900</pubDate>
    </item>
    <item>
      <title>카톡 사태 이후&amp;hellip;</title>
      <link>https://smartree.tistory.com/145</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;방문자 유입이 현저하게 줄었네..&lt;br&gt;네이버 연관 검색 노출도 사라져 버렸고..&lt;br&gt;뭐 나야 광고가 없어서 큰 상관은 없지만..&lt;br&gt;유입경로가 떨어지니 아쉽긴 하다.&lt;/p&gt;</description>
      <category>SmartRee/세상 사는 이야기</category>
      <category>카톡 사태</category>
      <category>카톡 오류</category>
      <author>SmartRee</author>
      <guid isPermaLink="true">https://smartree.tistory.com/145</guid>
      <comments>https://smartree.tistory.com/145#entry145comment</comments>
      <pubDate>Sun, 23 Oct 2022 22:53:14 +0900</pubDate>
    </item>
  </channel>
</rss>