<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>NasifyTech 納啟科技 - 免費線上服務平台</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&family=Exo+2:wght@500;700&display=swap" rel="stylesheet">
  <style>
    *, *::before, *::after {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    :root {
      --primary-color: #333;
      --secondary-color: #555;
      --accent-color: #ae7d2f;
      --background-color: #f9f9f9;
      --header-height: 70px;
      --transition-speed: 0.3s;
      --font-family-primary: 'Noto Serif TC', serif;
      --max-width: 1200px;
    }
    body {
      font-family: var(--font-family-primary);
      color: var(--primary-color);
      background-color: #fff;
      line-height: 1.6;
      overflow-x: hidden;
      padding-top: var(--header-height);
      scroll-behavior: smooth;
    }
    a {
      color: var(--primary-color);
      text-decoration: none;
      transition: color var(--transition-speed) ease;
    }
    a:hover {
      color: var(--secondary-color);
    }
    img {
      max-width: 100%;
      height: auto;
      display: block;
      margin: 0 auto;
    }
    .container {
      width: 90%;
      max-width: var(--max-width);
      margin: 0 auto;
    }
    header {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      background: rgba(255,255,255,0.95);
      padding: 15px 0;
      z-index: 1000;
      transition: background var(--transition-speed) ease, box-shadow var(--transition-speed) ease;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    header.scrolled {
      background: #fff;
      box-shadow: 0 2px 8px rgba(0,0,0,0.2);
    }
    header h1 {
      font-size: 1.8em;
      color: var(--primary-color);
      transition: color var(--transition-speed) ease;
      font-weight: 400;
    }
    nav {
      flex-grow: 1;
    }
    nav ul {
      list-style: none;
      display: flex;
      gap: 20px;
      align-items: center;
      justify-content: flex-end;
    }
    nav ul li a {
      font-size: 1em;
      font-weight: 400;
      position: relative;
      padding: 5px 0;
      display: flex;
      align-items: center;
      gap: 8px;
    }
    nav ul li a::after {
      content: '';
      position: absolute;
      width: 0%;
      height: 2px;
      background: var(--primary-color);
      left: 0;
      bottom: -2px;
      transition: width var(--transition-speed) ease;
    }
    nav ul li a:hover::after {
      width: 100%;
    }
    .header-inner {
      display: flex;
      align-items: center;
      justify-content: space-between;
      flex-wrap: wrap;
    }
    .menu-toggle {
      display: none;
      flex-direction: column;
      justify-content: space-between;
      width: 25px;
      height: 20px;
      cursor: pointer;
    }
    .menu-toggle div {
      width: 100%;
      height: 3px;
      background: var(--primary-color);
      border-radius: 1.5px;
      transition: all var(--transition-speed) ease;
    }
    .menu-toggle.active div:nth-child(1) {
      transform: rotate(45deg) translate(5px, 5px);
    }
    .menu-toggle.active div:nth-child(2) {
      opacity: 0;
    }
    .menu-toggle.active div:nth-child(3) {
      transform: rotate(-45deg) translate(5px, -5px);
    }
    @media (max-width:1024px) {
      .menu-toggle {
        display: flex;
      }
      nav ul {
        flex-direction: column;
        align-items: center;
        background: rgba(255,255,255,0.95);
        position: absolute;
        top: var(--header-height);
        right: 0;
        width: 220px;
        display: none;
        padding: 20px 0;
        border-radius: 0 0 8px 8px;
        box-shadow: 0 2px 8px rgba(0,0,0,0.1);
      }
      nav ul.active {
        display: flex;
      }
      nav ul li {
        margin: 15px 0;
      }
    }
    /* 首頁主視覺 */
    #home {
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      background: url('https://i.meee.com.tw/8FQeqHk.gif') no-repeat center center/cover;
      text-align: center;
      padding: 0; /* 取消預設 padding，讓背景能夠滿版 */
      margin: 0;
      width: 100%;
      color: #fff;
    }
    #home .content {
      width: 100%;
      padding: 20px;
    }
    #home .content h1 {
      font-size: 2.5em;
      margin-bottom: 20px;
    }
    #home .home-button {
      display: inline-block;
      padding: 10px 20px;
      background: var(--accent-color);
      color: #fff;
      border-radius: 5px;
      margin-top: 20px;
      transition: transform 0.3s ease;
    }
    #home .home-button:hover {
      transform: scale(1.05);
    }
    /* Tab 分頁樣式 */
    .tab-menu {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 10px;
      margin: 100px auto 20px;
    }
    .tab-menu button {
      background: var(--background-color);
      border: none;
      padding: 10px 20px;
      cursor: pointer;
      font-size: 1em;
      border-bottom: 2px solid transparent;
      transition: border-bottom 0.3s ease, color var(--transition-speed) ease;
    }
    .tab-menu button.active {
      color: var(--accent-color);
      border-bottom: 2px solid var(--accent-color);
    }
    /* 預設情況下，tab-menu 會自動換列（flex-wrap 已設定） */
    .tab-contents {
      margin-bottom: 50px;
    }
    .tab-content {
      display: none;
      animation: fadeIn 0.3s ease-in;
    }
    .tab-content.active {
      display: block;
    }
    /* 加入動畫 class 供 JS 控制 */
    .tab-content.animate {
      animation: fadeIn 0.3s ease-in;
    }
    @keyframes fadeIn {
      from { opacity: 0; }
      to { opacity: 1; }
    }
    /* 兩欄式工具排版（參照螢幕錄影版型），移除藍色背景 */
    .tool-section {
      display: flex;
      flex-wrap: wrap;
      gap: 40px;
      margin: 20px 0 50px;
      align-items: flex-start;
      border-radius: 8px;
      padding: 20px;
    }
    /* 為避免工具因螢幕縮小而變形，設定最小寬度與橫向捲動 */
    @media (max-width: 768px) {
      /* 手機版 container 直接滿版，僅左右留 10px */
      .container {
        width: 100%;
        padding: 0 10px;
      }
      .tab-menu {
        /* 取消水平滾動，改為換列，每列兩個 */
        flex-wrap: wrap;
      }
      .tab-menu button {
        flex: 1 1 48%;
        margin: 2px;
        padding: 8px 10px;
        font-size: 0.9em;
      }
      /* 主工具區塊縮小間距 */
      .tool-section {
        margin: 10px 0 30px;
        padding: 10px;
      }
      .tool-section .tool-left,
      .tool-section .tool-right {
        flex: 0 0 100%;
        min-width: 300px;
      }
    }
    .tool-section .tool-left,
    .tool-section .tool-right {
      flex: 1 1 45%;
    }
    .tool-section .tool-left h2 {
      font-size: 1.8em;
      margin-bottom: 20px;
    }
    .tool-section .tool-right h3 {
      font-size: 1.4em;
      margin-bottom: 20px;
      text-align: center;
      font-weight: 400;
    }
    @media (max-width: 768px) {
      .tool-section {
        flex-direction: column;
      }
      .tool-section .tool-left,
      .tool-section .tool-right {
        flex: 1 1 100%;
      }
    }
    /* 表單、按鈕、進度條與下載連結 */
    .btn {
      width: 100%;
      text-align: center;
      padding: 12px;
      font-size: 1em;
      background: var(--accent-color);
      color: #fff;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      transition: background var(--transition-speed) ease;
      margin-top: 10px;
    }
    .btn:hover {
      background: var(--secondary-color);
    }
    label {
      display: block;
      margin-bottom: 5px;
      font-size: 1em;
    }
    input[type="file"],
    input[type="password"],
    input[type="number"],
    textarea,
    select {
      width: 100%;
      padding: 10px;
      font-size: 0.95em;
      margin-bottom: 15px;
      border: 1px solid #ccc;
      border-radius: 6px;
      transition: background var(--transition-speed) ease;
    }
    .loading {
      display: none;
      margin-top: 20px;
      font-size: 1.1em;
      text-align: center;
    }
    .progress-container {
      display: none;
      width: 100%;
      background-color: #e0e0e0;
      border-radius: 5px;
      overflow: hidden;
      height: 20px;
      margin-top: 20px;
    }
    .progress-bar {
      height: 100%;
      width: 0%;
      background-color: var(--accent-color);
      transition: width 0.3s ease;
    }
    .result {
      margin-top: 10px;
      text-align: center;
    }
    .download-link {
      display: inline-block;
      margin: 10px;
      padding: 8px 15px;
      background: var(--accent-color);
      color: #fff;
      border-radius: 6px;
      transition: background var(--transition-speed) ease;
    }
    .download-link:hover {
      background: var(--secondary-color);
    }
    /* Footer */
    footer {
      background: #fff;
      padding: 40px 20px;
      text-align: center;
      color: #333;
      font-weight: 400;
      border-top: 1px solid #e0e0e0;
    }
    footer .container {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 15px;
    }
    footer p {
      margin-bottom: 10px;
      font-size: 1em;
    }
    footer .social-links {
      display: flex;
      gap: 15px;
    }
    footer .social-links a {
      color: #333;
      font-size: 1.5em;
      transition: color var(--transition-speed) ease, transform var(--transition-speed) ease;
    }
    footer .social-links a:hover {
      color: var(--accent-color);
      transform: scale(1.1);
    }
  </style>
  
  <!-- 外部 JavaScript 函式庫 -->
  <script src="https://www.gstatic.com/firebasejs/9.22.1/firebase-app-compat.js"></script>
  <script src="https://www.gstatic.com/firebasejs/9.22.1/firebase-database-compat.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf-lib/1.17.1/pdf-lib.min.js" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/ffmpeg/0.11.0/ffmpeg.min.js"></script>
  <script async src="https://www.googletagmanager.com/gtag/js?id=G-286HZQTWFH"></script>
  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'G-286HZQTWFH');
  </script>
</head>
<body>
  <!-- 頁首 -->
  <header>
    <div class="container header-inner">
      <h1>NasifyTech</h1>
      <nav>
        <ul id="nav-links">
          <li><a href="../index.html"><i class="fas fa-home" aria-hidden="true"></i> 官網</a></li>
          <li><a href="../member/index.html"><i class="fas fa-envelope" aria-hidden="true"></i> 線上服務</a></li>
          <li><a href="../about.html" target="_blank" rel="noopener noreferrer"><i class="fas fa-user" aria-hidden="true"></i> 關於創辦人</a></li>
        </ul>
      </nav>
      <div class="menu-toggle" id="mobile-menu" aria-label="導航選單切換" aria-expanded="false" role="button" tabindex="0">
        <div></div>
        <div></div>
        <div></div>
      </div>
    </div>
  </header>

  <!-- 首頁主視覺 -->
  <section id="home" aria-labelledby="home-title">
    <div class="content animate__animated animate__fadeInUp" data-aos="fade-up">
      <h1 id="home-title" class="animate__animated animate__bounceIn" data-aos="bounce-in">還在為線上壓縮、轉檔而煩惱嗎？</h1>
      <p class="animate__animated animate__fadeInUp" data-aos="fade-up" data-aos-delay="500">網路上限制大小、需要付費、好困擾！沒關係</p>
      <p class="animate__animated animate__fadeInUp" data-aos="fade-up" data-aos-delay="1000">試試我們納啟科技開發免費線上服務工具</p>
      <a href="#tools" class="home-button animate__animated animate__fadeInUp" data-aos="fade-up" data-aos-delay="700">點我使用納啟更多工具</a>
    </div>
  </section>

  <!-- 多工具 Tab 分頁區 -->
  <section id="tools">
    <div class="container">
      <!-- Tab 選單（依照新排序：螢幕錄影、檔案加密／解密、圖片壓縮、圖片轉檔、影片壓縮、PDF 壓縮、Apple 行事曆轉換）-->
      <div class="tab-menu">
        <button class="tab-btn active" data-target="screen-recording">螢幕錄影</button>
        <button class="tab-btn" data-target="file-tools">檔案加密／解密</button>
        <button class="tab-btn" data-target="image-compress">圖片壓縮</button>
        <button class="tab-btn" data-target="image-convert">圖片轉檔</button>
        <button class="tab-btn" data-target="video-compress">影片壓縮</button>
        <button class="tab-btn" data-target="pdf-compress">PDF 壓縮</button>
        <button class="tab-btn" data-target="apple-calendar-tools">Apple行事曆批次新增</button>
      </div>
      
      <!-- Tab 內容 -->
      <!-- 1. 螢幕錄影工具 -->
      <section id="screen-recording" class="tab-content active">
        <div class="tool-section">
          <div class="tool-left">
            <h2>螢幕錄影工具</h2>
            <p>用電腦再也不用擔心螢幕錄影問題，直接線上免安裝用到好。<br>錄製完成後，可以下載回 WebM 的影片檔案。</p>
          </div>
          <div class="tool-right">
            <label style="display: inline-flex; align-items: center; gap: 5px; margin-bottom: 15px;">
              <input type="checkbox" id="include-mic" />
              錄製麥克風音訊
            </label>
            <button id="start-record-btn" class="btn" style="margin-bottom: 15px;"><i class="fas fa-circle"></i> 開始錄影</button>
            <button id="stop-record-btn" class="btn" disabled style="margin-bottom: 20px;"><i class="fas fa-square"></i> 停止錄影</button>
            <div id="recording-status" class="loading">錄影中...</div>
            <div id="recording-result" class="result"></div>
          </div>
        </div>
      </section>
      
      <!-- 2. 檔案加密／解密工具 -->
      <section id="file-tools" class="tab-content">
        <div class="tool-section">
          <div class="tool-left">
            <h2>檔案加密／解密工具</h2>
            <p>這個工具，可以超快速加密檔案以確保資料安全，<br>
          </div>
          <div class="tool-right">
            <div class="toggle-buttons" style="display: flex; justify-content: center; gap: 20px; margin-bottom: 20px;">
              <button id="encrypt-toggle" class="active" style="flex: 1; padding: 10px 0; border: none; background: var(--background-color); border-bottom: 2px solid var(--accent-color);">檔案加密</button>
              <button id="decrypt-toggle" style="flex: 1; padding: 10px 0; border: none; background: var(--background-color); border-bottom: 2px solid transparent;">檔案解密</button>
            </div>
            <!-- 加密表單 -->
            <div id="encrypt-form">
              <form id="upload-file-form">
                <label for="files">選擇檔案：</label>
                <input type="file" name="files" id="files" multiple required />
                <label for="encryption-password">加密密碼：</label>
                <input type="password" name="encryption-password" id="encryption-password" placeholder="請輸入加密密碼" required />
                <button type="submit" class="btn"><i class="fas fa-lock"></i> 加密並下載</button>
              </form>
            </div>
            <!-- 解密表單 -->
            <div id="decrypt-form" style="display: none;">
              <form id="decrypt-file-form">
                <label for="encrypted-files">選擇加密檔案：</label>
                <input type="file" name="encrypted-files" id="encrypted-files" multiple accept=".enc" required />
                <label for="decryption-password">解密密碼：</label>
                <input type="password" name="decryption-password" id="decryption-password" placeholder="請輸入解密密碼" required />
                <button type="submit" class="btn"><i class="fas fa-unlock"></i> 解密並下載</button>
              </form>
            </div>
            <div id="loading-file" class="loading">處理中，請稍候...</div>
            <div id="progress-container-file" class="progress-container">
              <div id="progress-bar-file" class="progress-bar"></div>
            </div>
            <div id="result-file" class="result"></div>
          </div>
        </div>
      </section>
      
      <!-- 3. 圖片壓縮工具 -->
      <section id="image-compress" class="tab-content">
        <div class="tool-section">
          <div class="tool-left">
            <h2>圖片壓縮工具</h2>
            <p>可以很Easy壓縮圖片，減少大小。<br/>
                支援多張圖片上傳，滿足您的批次需求。</p>
          </div>
          <div class="tool-right">
            <form id="upload-image-compress-form">
              <label for="images-compress">選擇圖片：</label>
              <input type="file" name="images" id="images-compress" accept="image/*" multiple required />
              <label for="quality-compress">選擇壓縮品質：</label>
              <select name="quality" id="quality-compress" required>
                <option value="0.7">壓縮8～～</option>
                <option value="0.5">中等壓縮</option>
                <option value="0.3">高壓縮</option>
              </select>
              <button type="submit" class="btn"><i class="fas fa-upload"></i> 上傳並壓縮</button>
            </form>
            <div id="loading-compress" class="loading">正在壓縮，請稍候...</div>
            <div id="progress-container-compress" class="progress-container">
              <div id="progress-bar-compress" class="progress-bar"></div>
            </div>
            <div id="result-compress" class="result"></div>
          </div>
        </div>
      </section>
      
      <!-- 4. 圖片轉檔工具 -->
      <section id="image-convert" class="tab-content">
        <div class="tool-section">
          <div class="tool-left">
            <h2>圖片轉檔工具</h2>
            <p>上傳並轉換圖片，將圖片轉換為 JPG、PNG等多種格式。</p>
          </div>
          <div class="tool-right">
            <form id="upload-image-convert-form">
              <label for="images-convert">選擇圖片：</label>
              <input type="file" name="images" id="images-convert" accept=".jpg,.jpeg,.png,.gif,.bmp,.webp,.tiff" multiple required />
              <label for="target-format-convert">選擇目標格式：</label>
              <select name="target-format" id="target-format-convert" required>
                <option value="image/jpeg">JPG</option>
                <option value="image/png">PNG</option>
                <option value="image/gif">GIF</option>
                <option value="image/webp">WEBP</option>
              </select>
              <button type="submit" class="btn"><i class="fas fa-upload"></i> 上傳並轉檔</button>
            </form>
            <div id="loading-convert" class="loading">正在轉檔，請稍候...</div>
            <div id="progress-container-convert" class="progress-container">
              <div id="progress-bar-convert" class="progress-bar"></div>
            </div>
            <div id="result-convert" class="result"></div>
          </div>
        </div>
      </section>
      
      <!-- 5. 影片壓縮工具 -->
      <section id="video-compress" class="tab-content">
        <div class="tool-section">
          <div class="tool-left">
            <h2>影片壓縮工具</h2>
            <p>你可以很Easy壓縮影片大小。<br/>
                支援多種影片格式上傳，並提供多種解析度。</p>
          </div>
          <div class="tool-right">
            <form id="upload-video-form">
              <label for="videos">選擇影片：</label>
              <input type="file" name="videos" id="videos" accept=".mp4,.mov,.mpeg,.avi,.wmv,.flv,.mkv,.webm,.3gp,.ogg" multiple required />
              <label for="resolution">選擇壓縮解析度：</label>
              <select name="resolution" id="resolution" required>
                <option value="480">480p</option>
                <option value="720">720p</option>
                <option value="1080">1080p</option>
              </select>
              <button type="submit" class="btn"><i class="fas fa-upload"></i> 上傳並壓縮</button>
            </form>
            <div id="loading-video" class="loading">正在壓縮，請稍候...</div>
            <div id="progress-container-video" class="progress-container">
              <div id="progress-bar-video" class="progress-bar"></div>
            </div>
            <div id="result-video" class="result"></div>
          </div>
        </div>
      </section>
      
      <!-- 6. PDF 壓縮工具 -->
      <section id="pdf-compress" class="tab-content">
        <div class="tool-section">
          <div class="tool-left">
            <h2>PDF 壓縮工具</h2>
            <p> 可以很Easy壓縮PDF 檔案，減少檔案大小。<br/>
                要注意用途，有標準跟深度壓縮兩種唷～</p>
          </div>
          <div class="tool-right">
            <form id="upload-pdf-form">
              <label for="pdfs">選擇 PDF 檔案：</label>
              <input type="file" name="pdfs" id="pdfs" accept="application/pdf" multiple required />
              <label for="compression">選擇壓縮比例：</label>
              <select name="compression" id="compression" required>
                <option value="standard">標準壓縮</option>
                <option value="deep">深度壓縮（最大化壓縮）</option>
              </select>
              <button type="submit" class="btn"><i class="fas fa-upload"></i> 上傳並壓縮</button>
            </form>
            <div id="loading-pdf" class="loading">正在壓縮，請稍候...</div>
            <div id="progress-container-pdf" class="progress-container">
              <div id="progress-bar-pdf" class="progress-bar"></div>
            </div>
            <div id="result-pdf" class="result"></div>
          </div>
        </div>
      </section>
      
      <!-- 7. Apple 行事曆轉換工具 -->
      <section id="apple-calendar-tools" class="tab-content">
        <div class="tool-section">
          <div class="tool-left">
            <h2>Apple 行事曆轉換工具</h2>
            <p>輕鬆將您的行程活動批次加入到 Apple 行事曆裡，不用再手動一個一個加了。<br/>
                輸入年/月/日，就可以批次將行程批次新增進來！</p>
          </div>
          <div class="tool-right">
            <form id="generate-ics-form">
              <label for="year">選擇年份：</label>
              <input type="number" name="year" id="year" placeholder="例：2024" required />
              <label for="content">輸入活動內容：</label>
              <textarea name="content" id="content" rows="10" placeholder="每行一個活動，格式：YYYY/MM/DD 活動名稱" required></textarea>
              <button type="submit" class="btn"><i class="fas fa-download"></i> 處理行程中</button>
            </form>
            <div id="loading" class="loading">正在處理行程中，請稍候...</div>
            <div id="progress-container" class="progress-container">
              <div id="progress-bar" class="progress-bar"></div>
            </div>
            <div id="result" class="result"></div>
          </div>
        </div>
      </section>
    </div>
  </section>

  <!-- Footer -->
  <footer>
    <div class="container">
      <p>&copy; 2025 NasifyTech 納啟科技</p>
      <p>
        <a href="https://www.instagram.com/hayashiiii__" target="_blank" aria-label="Instagram">
          <i class="fab fa-instagram" aria-hidden="true"></i> Instagram
        </a> |
        <a href="https://www.facebook.com/profile.php?id=61571159491052" target="_blank" aria-label="LINE">
          <i class="fab fa-facebook" aria-hidden="true"></i> Facebook
        </a>
      </p>
    </div>
  </footer>

  <!-- JavaScript 程式碼 -->
  <script>
    // AOS 初始化
    AOS.init({
      duration: 800,
      easing: 'ease-in-out',
      once: true,
      mirror: false
    });
    
    // 手機選單切換
    const menuToggle = document.getElementById('mobile-menu');
    const navLinks = document.getElementById('nav-links');
    menuToggle.addEventListener('click', () => {
      menuToggle.classList.toggle('active');
      navLinks.classList.toggle('active');
      const isExpanded = menuToggle.classList.contains('active');
      menuToggle.setAttribute('aria-expanded', isExpanded);
    });
    navLinks.querySelectorAll('a').forEach(link => {
      link.addEventListener('click', () => {
        menuToggle.classList.remove('active');
        navLinks.classList.remove('active');
        menuToggle.setAttribute('aria-expanded', 'false');
      });
    });
    window.addEventListener('scroll', () => {
      const header = document.querySelector('header');
      header.classList.toggle('scrolled', window.scrollY > 50);
    });
    
    /**********************************
     * Tab 分頁切換功能（加入動畫效果）
     **********************************/
    document.querySelectorAll('.tab-btn').forEach(btn => {
      btn.addEventListener('click', function(){
        document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
        document.querySelectorAll('.tab-content').forEach(c => {
           c.classList.remove('active', 'animate');
        });
        this.classList.add('active');
        const target = document.getElementById(this.dataset.target);
        target.classList.add('active');
        // 加入動畫效果
        target.classList.add('animate');
        setTimeout(() => { target.classList.remove('animate'); }, 300);
      });
    });
    
    /**********************************
     * 首頁「點我使用納啟更多工具」平滑滾動效果
     **********************************/
    document.querySelector('.home-button').addEventListener('click', function(e) {
      e.preventDefault();
      document.querySelector('#tools').scrollIntoView({ behavior: 'smooth' });
    });
    
    /**********************************
     * 檔案加密／解密工具
     **********************************/
    const encryptToggle = document.getElementById('encrypt-toggle');
    const decryptToggle = document.getElementById('decrypt-toggle');
    const encryptForm = document.getElementById('encrypt-form');
    const decryptForm = document.getElementById('decrypt-form');
    const uploadFileForm = document.getElementById('upload-file-form');
    const fileInput = document.getElementById('files');
    const encryptionPasswordInput = document.getElementById('encryption-password');
    const decryptFileForm = document.getElementById('decrypt-file-form');
    const encryptedFileInput = document.getElementById('encrypted-files');
    const decryptionPasswordInput = document.getElementById('decryption-password');
    const loadingFile = document.getElementById('loading-file');
    const progressContainerFile = document.getElementById('progress-container-file');
    const progressBarFile = document.getElementById('progress-bar-file');
    const resultFile = document.getElementById('result-file');
    
    encryptToggle.addEventListener('click', () => {
      encryptToggle.classList.add('active');
      decryptToggle.classList.remove('active');
      encryptForm.style.display = 'block';
      decryptForm.style.display = 'none';
      resetFileUI();
    });
    
    decryptToggle.addEventListener('click', () => {
      decryptToggle.classList.add('active');
      encryptToggle.classList.remove('active');
      decryptForm.style.display = 'block';
      encryptForm.style.display = 'none';
      resetFileUI();
    });
    
    function resetFileUI() {
      loadingFile.style.display = 'none';
      progressContainerFile.style.display = 'none';
      progressBarFile.style.width = '0%';
      resultFile.innerHTML = '';
    }
    
    function isFileSelected(file) {
      return file.size > 0;
    }
    function generateSalt(length = 16) {
      return crypto.getRandomValues(new Uint8Array(length));
    }
    async function deriveKey(password, salt) {
      const encoder = new TextEncoder();
      const keyMaterial = await crypto.subtle.importKey(
        'raw',
        encoder.encode(password),
        { name: 'PBKDF2' },
        false,
        ['deriveKey']
      );
      return crypto.subtle.deriveKey(
        {
          name: 'PBKDF2',
          salt: salt,
          iterations: 100000,
          hash: 'SHA-256'
        },
        keyMaterial,
        { name: 'AES-GCM', length: 256 },
        false,
        ['encrypt', 'decrypt']
      );
    }
    async function encryptData(data, key) {
      const iv = crypto.getRandomValues(new Uint8Array(12));
      const ciphertext = await crypto.subtle.encrypt(
        { name: 'AES-GCM', iv: iv },
        key,
        data
      );
      return { iv, ciphertext };
    }
    async function decryptData(ciphertext, key, iv) {
      return await crypto.subtle.decrypt(
        { name: 'AES-GCM', iv: iv },
        key,
        ciphertext
      );
    }
    function concatenateBuffers(...buffers) {
      let totalLength = 0;
      buffers.forEach(buf => { totalLength += buf.byteLength; });
      let temp = new Uint8Array(totalLength);
      let offset = 0;
      buffers.forEach(buf => {
        temp.set(new Uint8Array(buf), offset);
        offset += buf.byteLength;
      });
      return temp.buffer;
    }
    
    uploadFileForm.addEventListener('submit', async function(e) {
      e.preventDefault();
      if (fileInput.files.length === 0) {
        Swal.fire({ title: '未選擇檔案', text: '請選擇要加密的檔案', icon: 'warning', confirmButtonText: '確定' });
        return;
      }
      const password = encryptionPasswordInput.value.trim();
      if (password.length === 0) {
        Swal.fire({ title: '未輸入密碼', text: '請輸入加密密碼', icon: 'warning', confirmButtonText: '確定' });
        return;
      }
      loadingFile.style.display = 'block';
      progressContainerFile.style.display = 'block';
      progressBarFile.style.width = '0%';
      resultFile.innerHTML = '';
      const files = Array.from(fileInput.files);
      const totalFiles = files.length;
      let processedCount = 0;
      const zipFile = new JSZip();
      let isMultiple = totalFiles > 1;
      try {
        for (const [index, file] of files.entries()) {
          try {
            if (!isFileSelected(file)) {
              throw new Error(`檔案為空或無效: ${file.name}`);
            }
            const arrayBuffer = await file.arrayBuffer();
            const salt = generateSalt();
            const key = await deriveKey(password, salt);
            const { iv, ciphertext } = await encryptData(arrayBuffer, key);
            const encryptedBuffer = concatenateBuffers(salt.buffer, iv.buffer, ciphertext);
            const encryptedBlob = new Blob([encryptedBuffer], { type: 'application/octet-stream' });
            const fileName = `${file.name}.enc`;
            if (isMultiple) {
              zipFile.file(fileName, encryptedBlob);
            } else {
              saveAs(encryptedBlob, fileName);
            }
            processedCount++;
            const progress = ((index + 1) / totalFiles) * 100;
            progressBarFile.style.width = `${Math.min(progress, 100)}%`;
          } catch (error) {
            console.error('加密失敗:', error);
            Swal.fire({ title: '加密錯誤', text: `無法加密檔案: ${file.name}\n錯誤訊息: ${error.message}`, icon: 'error', confirmButtonText: '確定' });
          }
        }
        if (processedCount > 0) {
          if (isMultiple) {
            const zipBlobFile = await zipFile.generateAsync({ type: 'blob' }, function(metadata) {
              progressBarFile.style.width = `${Math.round(metadata.percent)}%`;
            });
            const zipNameFile = `encrypted_files_${new Date().getTime()}.zip`;
            saveAs(zipBlobFile, zipNameFile);
            Swal.fire({ title: '加密完成！', text: `${processedCount} 個檔案已成功加密並打包成 ZIP 檔案。`, icon: 'success', confirmButtonText: '確定' });
          } else {
            Swal.fire({ title: '加密完成！', text: `${processedCount} 個檔案已成功加密。`, icon: 'success', confirmButtonText: '確定' });
          }
        }
      } catch (error) {
        console.error('處理錯誤:', error);
        Swal.fire({ title: '錯誤', text: `處理過程發生錯誤：${error.message}`, icon: 'error', confirmButtonText: '確定' });
      } finally {
        loadingFile.style.display = 'none';
        if (isMultiple) {
          progressBarFile.style.width = '100%';
        }
      }
    });
    
    decryptFileForm.addEventListener('submit', async function(e) {
      e.preventDefault();
      if (encryptedFileInput.files.length === 0) {
        Swal.fire({ title: '未選擇檔案', text: '請選擇要解密的檔案', icon: 'warning', confirmButtonText: '確定' });
        return;
      }
      const password = decryptionPasswordInput.value.trim();
      if (password.length === 0) {
        Swal.fire({ title: '未輸入密碼', text: '請輸入解密密碼', icon: 'warning', confirmButtonText: '確定' });
        return;
      }
      loadingFile.style.display = 'block';
      progressContainerFile.style.display = 'block';
      progressBarFile.style.width = '0%';
      resultFile.innerHTML = '';
      const files = Array.from(encryptedFileInput.files);
      const totalFiles = files.length;
      let processedCount = 0;
      const zipDecrypt = new JSZip();
      let isMultipleDecrypt = totalFiles > 1;
      try {
        for (const [index, file] of files.entries()) {
          try {
            if (!isFileSelected(file)) {
              throw new Error(`檔案為空或無效: ${file.name}`);
            }
            const arrayBuffer = await file.arrayBuffer();
            const encryptedData = new Uint8Array(arrayBuffer);
            if (encryptedData.byteLength < 28) {
              throw new Error(`檔案格式無效或損壞: ${file.name}`);
            }
            const salt = encryptedData.slice(0, 16);
            const iv = encryptedData.slice(16, 28);
            const ciphertext = encryptedData.slice(28);
            const key = await deriveKey(password, salt.buffer);
            const decryptedArrayBuffer = await decryptData(ciphertext, key, iv);
            const decryptedBlob = new Blob([decryptedArrayBuffer], { type: 'application/octet-stream' });
            let originalFileName = file.name;
            if (originalFileName.endsWith('.enc')) {
              originalFileName = originalFileName.slice(0, -4);
            } else {
              originalFileName = `decrypted_${originalFileName}`;
            }
            if (isMultipleDecrypt) {
              zipDecrypt.file(originalFileName, decryptedBlob);
            } else {
              saveAs(decryptedBlob, originalFileName);
            }
            processedCount++;
            const progress = ((index + 1) / totalFiles) * 100;
            progressBarFile.style.width = `${Math.min(progress, 100)}%`;
          } catch (error) {
            console.error('解密失敗:', error);
            Swal.fire({ title: '解密錯誤', text: `無法解密檔案: ${file.name}\n錯誤訊息: ${error.message}`, icon: 'error', confirmButtonText: '確定' });
          }
        }
        if (processedCount > 0) {
          if (isMultipleDecrypt) {
            const zipBlobDecrypt = await zipDecrypt.generateAsync({ type: 'blob' }, function(metadata) {
              progressBarFile.style.width = `${Math.round(metadata.percent)}%`;
            });
            const zipNameDecrypt = `decrypted_files_${new Date().getTime()}.zip`;
            saveAs(zipBlobDecrypt, zipNameDecrypt);
            Swal.fire({ title: '解密完成！', text: `${processedCount} 個檔案已成功解密並打包成 ZIP 檔案。`, icon: 'success', confirmButtonText: '確定' });
          } else {
            Swal.fire({ title: '解密完成！', text: `${processedCount} 個檔案已成功解密。`, icon: 'success', confirmButtonText: '確定' });
          }
        }
      } catch (error) {
        console.error('處理錯誤:', error);
        Swal.fire({ title: '錯誤', text: `處理過程發生錯誤：${error.message}`, icon: 'error', confirmButtonText: '確定' });
      } finally {
        loadingFile.style.display = 'none';
        if (isMultipleDecrypt) {
          progressBarFile.style.width = '100%';
        }
      }
    });
    
    /**********************************
     * Apple 行事曆轉換工具
     **********************************/
    document.addEventListener('DOMContentLoaded', () => {
      const generateForm = document.getElementById('generate-ics-form');
      const loadingIndicator = document.getElementById('loading');
      const progressContainer = document.getElementById('progress-container');
      const progressBar = document.getElementById('progress-bar');
      const resultDiv = document.getElementById('result');
      generateForm.addEventListener('submit', async (e) => {
        e.preventDefault();
        const year = document.getElementById('year').value;
        const content = document.getElementById('content').value.trim();
        if (!year || !content) {
          Swal.fire({ icon: 'warning', title: '輸入錯誤', text: '請填寫所有欄位。' });
          return;
        }
        loadingIndicator.style.display = 'block';
        progressContainer.style.display = 'block';
        progressBar.style.width = '0%';
        resultDiv.innerHTML = '';
        try {
          await simulateProgress();
          generateICS(year, content);
        } catch (error) {
          Swal.fire({ icon: 'error', title: '處理失敗', text: '在處理過程中發生錯誤。' });
        } finally {
          loadingIndicator.style.display = 'none';
          progressContainer.style.display = 'none';
        }
      });
      function simulateProgress() {
        return new Promise((resolve) => {
          let progress = 0;
          const interval = setInterval(() => {
            progress += 20;
            if (progress > 100) progress = 100;
            progressBar.style.width = `${progress}%`;
            if (progress === 100) {
              clearInterval(interval);
              resolve();
            }
          }, 200);
        });
      }
    });
    function downloadICS(filename, content) {
      const blob = new Blob([content], { type: 'text/calendar;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      setTimeout(() => {
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      }, 0);
    }
    function generateICS(year, content) {
      const events = content.split('\n').map((line, index) => {
        const trimmedLine = line.trim();
        if (trimmedLine === '') return null;
        const [date, ...descParts] = trimmedLine.split(' ');
        const description = descParts.join(' ');
        if (!date || !description) {
          Swal.fire({ icon: 'warning', title: '格式錯誤', text: `第 ${index + 1} 行格式不正確，應為 "YYYY/MM/DD 活動名稱"` });
          return null;
        }
        return { date, description };
      }).filter(event => event !== null);
      if (events.length === 0) {
        Swal.fire({ icon: 'error', title: '無效輸入', text: '沒有有效的活動內容可批次處理行程中。' });
        return;
      }
      let icsContent = `BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//NasifyTech 納啟科技//Apple Calendar Converter//EN\r\nCALSCALE:GREGORIAN\r\n`;
      events.forEach(event => {
        const [yearPart, month, day] = event.date.split('/');
        if (!yearPart || !month || !day) return;
        const eventDate = new Date(yearPart, month - 1, day);
        if (isNaN(eventDate)) return;
        const dtstamp = formatDate(new Date());
        const dtstart = formatDate(eventDate);
        icsContent += `BEGIN:VEVENT\r\nDTSTAMP:${dtstamp}T000000Z\r\nDTSTART;VALUE=DATE:${dtstart}\r\nSUMMARY:${escapeICS(event.description)}\r\nEND:VEVENT\r\n`;
      });
      icsContent += 'END:VCALENDAR\r\n';
      try {
        if (typeof saveAs === 'function') {
          const blob = new Blob([icsContent], { type: 'text/calendar;charset=utf-8' });
          saveAs(blob, `${year}_events.ics`);
        } else {
          downloadICS(`${year}_events.ics`, icsContent);
        }
      } catch (blobError) {
        Swal.fire({ icon: 'error', title: '檔案生成失敗', text: '無法批次處理行程中。' });
      }
    }
    function formatDate(date) {
      const yyyy = date.getFullYear().toString().padStart(4, '0');
      const mm = (date.getMonth() + 1).toString().padStart(2, '0');
      const dd = date.getDate().toString().padStart(2, '0');
      return `${yyyy}${mm}${dd}`;
    }
    function escapeICS(text) {
      return text.replace(/\\/g, '\\\\')
                 .replace(/;/g, '\\;')
                 .replace(/,/g, '\\,')
                 .replace(/\n/g, '\\n');
    }
    
    /**********************************
     * 螢幕錄影工具
     **********************************/
    const startRecordBtn = document.getElementById('start-record-btn');
    const stopRecordBtn = document.getElementById('stop-record-btn');
    const recordingStatus = document.getElementById('recording-status');
    const recordingResult = document.getElementById('recording-result');
    const includeMicCheckbox = document.getElementById('include-mic');
    let mediaRecorder;
    let recordedChunks = [];
    if(startRecordBtn && stopRecordBtn){
      startRecordBtn.addEventListener('click', startRecording);
      stopRecordBtn.addEventListener('click', stopRecording);
    }
    async function startRecording() {
      recordedChunks = [];
      try {
        const displayStream = await navigator.mediaDevices.getDisplayMedia({
          video: { displaySurface: "monitor", cursor: "always" },
          audio: { echoCancellation: true, noiseSuppression: true, sampleRate: 44100 }
        });
        let finalStream = new MediaStream();
        displayStream.getVideoTracks().forEach(track => finalStream.addTrack(track));
        displayStream.getAudioTracks().forEach(track => finalStream.addTrack(track));
        if (includeMicCheckbox.checked) {
          try {
            const micStream = await navigator.mediaDevices.getUserMedia({
              audio: { echoCancellation: true, noiseSuppression: true, sampleRate: 44100 }
            });
            micStream.getAudioTracks().forEach(track => finalStream.addTrack(track));
          } catch (micError) {
            Swal.fire({ title: '麥克風無法使用', text: '將繼續錄影，但不包含麥克風音訊', icon: 'warning', timer: 3000, showConfirmButton: false });
          }
        }
        let mimeType = 'video/webm;codecs=vp8,opus';
        if (!MediaRecorder.isTypeSupported(mimeType)) {
          mimeType = 'video/webm;codecs=vp9,opus';
          if (!MediaRecorder.isTypeSupported(mimeType)) {
            mimeType = 'video/webm';
          }
        }
        mediaRecorder = new MediaRecorder(finalStream, { mimeType: mimeType, videoBitsPerSecond: 2500000, audioBitsPerSecond: 128000 });
        mediaRecorder.ondataavailable = (event) => {
          if (event.data && event.data.size > 0) {
            recordedChunks.push(event.data);
          }
        };
        mediaRecorder.onstop = () => {
          const blob = new Blob(recordedChunks, { type: mimeType });
          const url = URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.href = url;
          a.download = `screen-recording-${new Date().toISOString()}.webm`;
          a.classList.add('download-link');
          a.innerHTML = '<i class="fas fa-download"></i> 下載錄影檔案';
          recordingResult.innerHTML = '';
          recordingResult.appendChild(a);
          finalStream.getTracks().forEach(track => track.stop());
          Swal.fire({ title: '錄影完成！', text: '您可以點擊下載按鈕來保存錄影檔案', icon: 'success', confirmButtonText: '確定' });
        };
        displayStream.getVideoTracks()[0].onended = () => {
          if (mediaRecorder && mediaRecorder.state !== 'inactive') {
            stopRecording();
          }
        };
        mediaRecorder.start(1000);
        recordingStatus.style.display = 'block';
        startRecordBtn.disabled = true;
        stopRecordBtn.disabled = false;
        Swal.fire({ title: '錄影開始', text: '螢幕錄影已開始', icon: 'success', timer: 2000, showConfirmButton: false });
      } catch (err) {
        startRecordBtn.disabled = false;
        stopRecordBtn.disabled = true;
        Swal.fire({ title: '錄影失敗', text: err.message || '請確認是否允許螢幕分享權限', icon: 'error', confirmButtonText: '確定' });
      }
    }
    async function stopRecording() {
      if (mediaRecorder && mediaRecorder.state !== 'inactive') {
        mediaRecorder.stop();
        recordingStatus.style.display = 'none';
        stopRecordBtn.disabled = true;
        startRecordBtn.disabled = false;
        Swal.fire({ title: '錄影已停止', text: '正在處理錄影檔案...', icon: 'info', timer: 2000, showConfirmButton: false });
      }
    }
    
    /**********************************
     * 圖片壓縮工具
     **********************************/
    document.getElementById('upload-image-compress-form').addEventListener('submit', function (e) {
      e.preventDefault();
      const fileInput = document.querySelector("#upload-image-compress-form input[name='images']");
      const quality = parseFloat(document.getElementById('quality-compress').value);
      const resultDiv = document.getElementById('result-compress');
      const loadingDiv = document.getElementById('loading-compress');
      const progressContainer = document.getElementById('progress-container-compress');
      const progressBar = document.getElementById('progress-bar-compress');
      if (fileInput.files.length > 0) {
        loadingDiv.style.display = 'block';
        resultDiv.innerHTML = '';
        const files = Array.from(fileInput.files);
        if (files.length === 1) {
          progressContainer.style.display = 'block';
          progressBar.style.width = '0%';
          const file = files[0];
          const reader = new FileReader();
          reader.onload = function (event) {
            const img = new Image();
            img.src = event.target.result;
            img.onload = function () {
              const canvas = document.createElement('canvas');
              const ctx = canvas.getContext('2d');
              canvas.width = img.width;
              canvas.height = img.height;
              ctx.drawImage(img, 0, 0);
              canvas.toBlob(function (blob) {
                const url = URL.createObjectURL(blob);
                const fileName = file.name.replace(/\.[^/.]+$/, '') + '_compressed.jpg';
                const link = document.createElement('a');
                link.href = url;
                link.download = fileName;
                link.classList.add('download-link');
                link.innerHTML = '<i class="fas fa-download"></i> 下載圖片';
                progressBar.style.width = '100%';
                resultDiv.appendChild(link);
                loadingDiv.style.display = 'none';
                progressContainer.style.display = 'none';
                Swal.fire({ title: '壓縮完成！', text: `圖片已成功壓縮。`, icon: 'success', confirmButtonText: '確定' });
              }, 'image/jpeg', quality);
            };
          };
          reader.onerror = function () {
            Swal.fire({ title: '錯誤', text: `無法讀取檔案: ${file.name}`, icon: 'error', confirmButtonText: '確定' });
            loadingDiv.style.display = 'none';
            progressContainer.style.display = 'none';
          };
          reader.readAsDataURL(file);
        } else {
          progressContainer.style.display = 'block';
          progressBar.style.width = '0%';
          const zip = new JSZip();
          let processedCount = 0;
          files.forEach((file) => {
            const reader = new FileReader();
            reader.onload = function (event) {
              const img = new Image();
              img.src = event.target.result;
              img.onload = function () {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.drawImage(img, 0, 0);
                canvas.toBlob(function (blob) {
                  const fileName = file.name.replace(/\.[^/.]+$/, '') + '_compressed.jpg';
                  zip.file(fileName, blob);
                  processedCount++;
                  const progressPercentage = Math.round((processedCount / files.length) * 100);
                  progressBar.style.width = progressPercentage + '%';
                  if (processedCount === files.length) {
                    zip.generateAsync({ type: 'blob' }).then(function (zipBlob) {
                      loadingDiv.style.display = 'none';
                      progressContainer.style.display = 'none';
                      const url = URL.createObjectURL(zipBlob);
                      const link = document.createElement('a');
                      link.href = url;
                      link.download = 'compressed_images.zip';
                      link.classList.add('download-link');
                      link.innerHTML = '<i class="fas fa-download"></i> 下載 ZIP 檔案';
                      resultDiv.appendChild(link);
                      Swal.fire({ title: '壓縮完成！', text: `${files.length} 張圖片已壓縮並打包成 ZIP 檔案。`, icon: 'success', confirmButtonText: '確定' });
                    });
                  }
                }, 'image/jpeg', quality);
              };
            };
            reader.onerror = function () {
              Swal.fire({ title: '錯誤', text: `無法讀取檔案: ${file.name}`, icon: 'error', confirmButtonText: '確定' });
              processedCount++;
              const progressPercentage = Math.round((processedCount / files.length) * 100);
              progressBar.style.width = progressPercentage + '%';
              if (processedCount === files.length) {
                loadingDiv.style.display = 'none';
                progressContainer.style.display = 'none';
              }
            };
            reader.readAsDataURL(file);
          });
        }
      } else {
        Swal.fire({ title: '未選擇圖片', text: '請選擇要上傳的圖片檔案', icon: 'warning', confirmButtonText: '確定' });
      }
    });
    
    /**********************************
     * 圖片轉檔工具
     **********************************/
    const uploadConvertForm = document.getElementById('upload-image-convert-form');
    uploadConvertForm.addEventListener('submit', async function (e) {
      e.preventDefault();
      const fileInput = uploadConvertForm.querySelector("input[name='images']");
      const targetFormat = document.getElementById('target-format-convert');
      const resultDiv = document.getElementById('result-convert');
      const loadingDiv = document.getElementById('loading-convert');
      const progressContainer = document.getElementById('progress-container-convert');
      const progressBar = document.getElementById('progress-bar-convert');
      const SUPPORTED_FORMATS = ['image/jpeg','image/png','image/gif','image/bmp','image/webp','image/tiff'];
      function isImageFormatSupported(file) {
        if (SUPPORTED_FORMATS.includes(file.type)) return true;
        const extension = file.name.split('.').pop().toLowerCase();
        return ['jpg','jpeg','png','gif','bmp','webp','tiff'].includes(extension);
      }
      async function convertImage(file, format) {
        return new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = function (event) {
            const img = new Image();
            img.onload = function () {
              const canvas = document.createElement('canvas');
              canvas.width = img.width;
              canvas.height = img.height;
              const ctx = canvas.getContext('2d');
              ctx.drawImage(img, 0, 0);
              let quality = (format === 'image/jpeg' || format === 'image/webp') ? 0.8 : 0.92;
              canvas.toBlob(function (blob) {
                blob ? resolve(blob) : reject(new Error('轉檔失敗'));
              }, format, quality);
            };
            img.onerror = () => reject(new Error('圖片加載失敗'));
            img.src = event.target.result;
          };
          reader.onerror = () => reject(new Error('檔案讀取失敗'));
          reader.readAsDataURL(file);
        });
      }
      if (fileInput.files.length === 0) {
        Swal.fire({ title: '未選擇圖片', text: '請選擇要上傳的圖片檔案', icon: 'warning', confirmButtonText: '確定' });
        return;
      }
      loadingDiv.style.display = 'block';
      progressContainer.style.display = 'block';
      progressBar.style.width = '0%';
      resultDiv.innerHTML = '';
      const files = Array.from(fileInput.files);
      const totalFiles = files.length;
      let processedCount = 0;
      const zip = new JSZip();
      const isMultiple = totalFiles > 1;
      try {
        for (const [index, file] of files.entries()) {
          try {
            if (!isImageFormatSupported(file)) {
              throw new Error(`不支援的圖片格式: ${file.name}`);
            }
            const convertedBlob = await convertImage(file, targetFormat.value);
            const newExtension = targetFormat.value.split('/')[1] === 'jpeg' ? 'jpg' : targetFormat.value.split('/')[1];
            const fileName = file.name.split('.').slice(0, -1).join('.') + `_converted.${newExtension}`;
            if (isMultiple) {
              zip.file(fileName, convertedBlob);
            } else {
              const url = URL.createObjectURL(convertedBlob);
              const link = document.createElement('a');
              link.href = url;
              link.download = fileName;
              link.classList.add('download-link');
              link.innerHTML = `<i class="fas fa-download"></i> 下載 ${newExtension.toUpperCase()}`;
              resultDiv.appendChild(link);
              link.addEventListener('click', () => setTimeout(() => URL.revokeObjectURL(url), 100));
            }
            processedCount++;
            const progress = ((index + 1) / totalFiles) * 100;
            progressBar.style.width = `${Math.min(progress, 100)}%`;
          } catch (error) {
            Swal.fire({ title: '轉檔錯誤', text: `無法轉檔檔案: ${file.name}\n錯誤訊息: ${error.message}`, icon: 'error', confirmButtonText: '確定' });
          }
        }
        if (processedCount > 0) {
          if (isMultiple) {
            const zipBlob = await zip.generateAsync({ type: 'blob' }, function (metadata) {
              progressBar.style.width = `${Math.round(metadata.percent)}%`;
            });
            const zipName = `converted_images_${new Date().getTime()}.zip`;
            const zipUrl = URL.createObjectURL(zipBlob);
            const zipLink = document.createElement('a');
            zipLink.href = zipUrl;
            zipLink.download = zipName;
            zipLink.classList.add('download-link');
            zipLink.innerHTML = '<i class="fas fa-download"></i> 下載所有圖片 (ZIP)';
            resultDiv.appendChild(zipLink);
            zipLink.addEventListener('click', () => setTimeout(() => URL.revokeObjectURL(zipUrl), 100));
            Swal.fire({ title: '轉檔完成！', text: `${processedCount} 張圖片已成功轉檔並打包成 ZIP 檔案。`, icon: 'success', confirmButtonText: '確定' });
          } else {
            Swal.fire({ title: '轉檔完成！', text: `${processedCount} 張圖片已成功轉檔。`, icon: 'success', confirmButtonText: '確定' });
          }
        }
      } catch (error) {
        Swal.fire({ title: '錯誤', text: `處理過程發生錯誤：${error.message}`, icon: 'error', confirmButtonText: '確定' });
      } finally {
        loadingDiv.style.display = 'none';
      }
    });
    
    /**********************************
     * 影片壓縮工具
     **********************************/
    document.getElementById('upload-video-form').addEventListener('submit', async function (e) {
      e.preventDefault();
      const fileInput = document.querySelector("input[name='videos']");
      const resolution = document.getElementById('resolution');
      const resultDiv = document.getElementById('result-video');
      const loadingDiv = document.getElementById('loading-video');
      const progressContainer = document.getElementById('progress-container-video');
      const progressBar = document.getElementById('progress-bar-video');
      const SUPPORTED_FORMATS = ['video/mp4','video/quicktime','video/webm','video/x-msvideo','video/x-ms-wmv','video/x-matroska','video/3gpp','video/ogg'];
      function isVideoFormatSupported(file) {
        if (SUPPORTED_FORMATS.includes(file.type)) return true;
        const extension = file.name.split('.').pop().toLowerCase();
        return ['mp4','mov','webm','avi','wmv','mkv','3gp','ogv','qt'].includes(extension);
      }
      async function convertToMp4(webmBlob) {
        return new Promise((resolve) => {
          const webmUrl = URL.createObjectURL(webmBlob);
          const video = document.createElement('video');
          video.src = webmUrl;
          video.muted = true;
          video.onloadedmetadata = () => {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;
            const stream = canvas.captureStream();
            const recorder = new MediaRecorder(stream, { mimeType: 'video/mp4; codecs="avc1.42E01E"' });
            const chunks = [];
            recorder.ondataavailable = (e) => chunks.push(e.data);
            recorder.onstop = () => {
              const mp4Blob = new Blob(chunks, { type: 'video/mp4' });
              URL.revokeObjectURL(webmUrl);
              resolve(mp4Blob);
            };
            video.play();
            recorder.start();
            const drawFrame = () => {
              if (video.ended) {
                recorder.stop();
                return;
              }
              ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
              requestAnimationFrame(drawFrame);
            };
            drawFrame();
          };
        });
      }
      async function compressVideo(file, quality) {
        return new Promise(async (resolve, reject) => {
          try {
            const videoElem = document.createElement('video');
            videoElem.style.display = 'none';
            videoElem.muted = true;
            document.body.appendChild(videoElem);
            const videoUrl = URL.createObjectURL(file);
            videoElem.src = videoUrl;
            await new Promise((resolve) => videoElem.addEventListener('loadedmetadata', resolve));
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            let targetHeight = parseInt(quality);
            let targetWidth = Math.floor(videoElem.videoWidth * (targetHeight / videoElem.videoHeight));
            canvas.width = targetWidth;
            canvas.height = targetHeight;
            const canvasStream = canvas.captureStream();
            const recorder = new MediaRecorder(canvasStream, { mimeType: 'video/webm;codecs=vp8', videoBitsPerSecond: 2500000 });
            const chunks = [];
            recorder.ondataavailable = (e) => chunks.push(e.data);
            recorder.onstop = async () => {
              videoElem.remove();
              URL.revokeObjectURL(videoUrl);
              const webmBlob = new Blob(chunks, { type: 'video/webm' });
              const mp4Blob = await convertToMp4(webmBlob);
              resolve(mp4Blob);
            };
            videoElem.addEventListener('play', () => {
              function drawFrame() {
                if (videoElem.ended || videoElem.paused) {
                  recorder.stop();
                  return;
                }
                ctx.drawImage(videoElem, 0, 0, targetWidth, targetHeight);
                requestAnimationFrame(drawFrame);
                const progress = (videoElem.currentTime / videoElem.duration) * 100;
                progressBar.style.width = `${Math.min(progress, 100)}%`;
              }
              recorder.start(1000);
              drawFrame();
            });
            videoElem.play();
          } catch (error) {
            reject(error);
          }
        });
      }
      if (fileInput.files.length === 0) {
        Swal.fire({ title: '未選擇影片', text: '請選擇要上傳的影片檔案', icon: 'warning', confirmButtonText: '確定' });
        return;
      }
      loadingDiv.style.display = 'block';
      progressContainer.style.display = 'block';
      progressBar.style.width = '0%';
      resultDiv.innerHTML = '';
      const files = Array.from(fileInput.files);
      let processedCount = 0;
      try {
        for (const file of files) {
          if (!isVideoFormatSupported(file)) {
            Swal.fire({ title: '錯誤', text: `不支援的影片格式: ${file.name}`, icon: 'error', confirmButtonText: '確定' });
            continue;
          }
          const compressedBlob = await compressVideo(file, resolution.value);
          const url = URL.createObjectURL(compressedBlob);
          const link = document.createElement('a');
          link.href = url;
          link.download = `${file.name.split('.')[0]}_compressed.mp4`;
          link.classList.add('download-link');
          link.innerHTML = '<i class="fas fa-download"></i> 下載壓縮後的影片';
          resultDiv.appendChild(link);
          link.addEventListener('click', () => setTimeout(() => URL.revokeObjectURL(url), 100));
          processedCount++;
        }
        if (processedCount > 0) {
          Swal.fire({ title: '壓縮完成！', text: `${processedCount} 個影片已成功壓縮。`, icon: 'success', confirmButtonText: '確定' });
        }
      } catch (error) {
        Swal.fire({ title: '錯誤', text: `處理過程發生錯誤：${error.message}`, icon: 'error', confirmButtonText: '確定' });
      } finally {
        loadingDiv.style.display = 'none';
      }
    });
    
    /**********************************
     * PDF 壓縮工具
     **********************************/
    document.getElementById('upload-pdf-form').addEventListener('submit', async function (e) {
      e.preventDefault();
      const fileInput = document.querySelector("input[name='pdfs']");
      const compression = document.getElementById('compression').value;
      const resultDiv = document.getElementById('result-pdf');
      const loadingDiv = document.getElementById('loading-pdf');
      const progressContainer = document.getElementById('progress-container-pdf');
      const progressBar = document.getElementById('progress-bar-pdf');
      if (fileInput.files.length > 0) {
        loadingDiv.style.display = 'block';
        resultDiv.innerHTML = '';
        const files = Array.from(fileInput.files);
        if (files.length === 1) {
          progressContainer.style.display = 'block';
          progressBar.style.width = '0%';
          const file = files[0];
          const reader = new FileReader();
          reader.onload = async function (event) {
            try {
              if (compression === 'standard') {
                const pdfDoc = await PDFLib.PDFDocument.load(event.target.result);
                const compressedPdfBytes = await pdfDoc.save({ useObjectStreams: false });
                const blob = new Blob([compressedPdfBytes], { type: 'application/pdf' });
                const url = URL.createObjectURL(blob);
                const fileName = file.name.replace(/\.[^/.]+$/, '') + '_compressed.pdf';
                const link = document.createElement('a');
                link.href = url;
                link.download = fileName;
                link.classList.add('download-link');
                link.innerHTML = '<i class="fas fa-download"></i> 下載 PDF';
                progressBar.style.width = '100%';
                resultDiv.appendChild(link);
                loadingDiv.style.display = 'none';
                progressContainer.style.display = 'none';
                Swal.fire({ title: '壓縮完成！', text: `PDF 已成功壓縮。`, icon: 'success', confirmButtonText: '確定' });
              } else if (compression === 'deep') {
                const pdf = await pdfjsLib.getDocument({ data: event.target.result }).promise;
                const pdfDoc = await PDFLib.PDFDocument.create();
                const scale = 2;
                const jpegQuality = 0.8;
                for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
                  const page = await pdf.getPage(pageNum);
                  const viewport = page.getViewport({ scale: scale });
                  const canvas = document.createElement('canvas');
                  const context = canvas.getContext('2d');
                  canvas.width = viewport.width;
                  canvas.height = viewport.height;
                  await page.render({ canvasContext: context, viewport: viewport }).promise;
                  const imgData = canvas.toDataURL('image/jpeg', jpegQuality);
                  const img = await pdfDoc.embedJpg(imgData);
                  const imgDims = img.scale(1);
                  const newPage = pdfDoc.addPage([imgDims.width, imgDims.height]);
                  newPage.drawImage(img, { x: 0, y: 0, width: imgDims.width, height: imgDims.height });
                  progressBar.style.width = Math.round((pageNum / pdf.numPages) * 100 / 2) + '%';
                }
                const compressedPdfBytes = await pdfDoc.save();
                const blob = new Blob([compressedPdfBytes], { type: 'application/pdf' });
                const url = URL.createObjectURL(blob);
                const fileName = file.name.replace(/\.[^/.]+$/, '') + '_compressed.pdf';
                const link = document.createElement('a');
                link.href = url;
                link.download = fileName;
                link.classList.add('download-link');
                link.innerHTML = '<i class="fas fa-download"></i> 下載 PDF';
                progressBar.style.width = '100%';
                resultDiv.appendChild(link);
                loadingDiv.style.display = 'none';
                progressContainer.style.display = 'none';
                Swal.fire({ title: '深度壓縮完成！', text: `PDF 已深度壓縮。`, icon: 'success', confirmButtonText: '確定' });
              }
            } catch (error) {
              Swal.fire({ title: '錯誤', text: `壓縮過程中發生錯誤: ${error.message}`, icon: 'error', confirmButtonText: '確定' });
              loadingDiv.style.display = 'none';
              progressContainer.style.display = 'none';
            }
          };
          reader.onerror = function () {
            Swal.fire({ title: '錯誤', text: `無法讀取檔案: ${file.name}`, icon: 'error', confirmButtonText: '確定' });
            loadingDiv.style.display = 'none';
            progressContainer.style.display = 'none';
          };
          reader.readAsArrayBuffer(file);
        } else {
          progressContainer.style.display = 'block';
          progressBar.style.width = '0%';
          const zip = new JSZip();
          let processedCount = 0;
          for (const file of files) {
            const reader = new FileReader();
            reader.onload = async function (event) {
              try {
                if (compression === 'standard') {
                  const pdfDoc = await PDFLib.PDFDocument.load(event.target.result);
                  const compressedPdfBytes = await pdfDoc.save({ useObjectStreams: false });
                  zip.file(file.name.replace(/\.[^/.]+$/, '') + '_compressed.pdf', compressedPdfBytes);
                } else if (compression === 'deep') {
                  const pdf = await pdfjsLib.getDocument({ data: event.target.result }).promise;
                  const pdfDoc = await PDFLib.PDFDocument.create();
                  const scale = 2;
                  const jpegQuality = 0.8;
                  for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
                    const page = await pdf.getPage(pageNum);
                    const viewport = page.getViewport({ scale: scale });
                    const canvas = document.createElement('canvas');
                    const context = canvas.getContext('2d');
                    canvas.width = viewport.width;
                    canvas.height = viewport.height;
                    await page.render({ canvasContext: context, viewport: viewport }).promise;
                    const imgData = canvas.toDataURL('image/jpeg', jpegQuality);
                    const img = await pdfDoc.embedJpg(imgData);
                    const imgDims = img.scale(1);
                    const newPage = pdfDoc.addPage([imgDims.width, imgDims.height]);
                    newPage.drawImage(img, { x: 0, y: 0, width: imgDims.width, height: imgDims.height });
                  }
                  const compressedPdfBytes = await pdfDoc.save();
                  zip.file(file.name.replace(/\.[^/.]+$/, '') + '_compressed.pdf', compressedPdfBytes);
                }
                processedCount++;
                progressBar.style.width = Math.round((processedCount / files.length) * 100) + '%';
                if (processedCount === files.length) {
                  const zipBlob = await zip.generateAsync({ type: 'blob' });
                  const url = URL.createObjectURL(zipBlob);
                  const link = document.createElement('a');
                  link.href = url;
                  link.download = 'compressed_pdfs.zip';
                  link.classList.add('download-link');
                  link.innerHTML = '<i class="fas fa-download"></i> 下載 ZIP 檔案';
                  resultDiv.appendChild(link);
                  loadingDiv.style.display = 'none';
                  progressContainer.style.display = 'none';
                  Swal.fire({ title: '壓縮完成！', text: `${files.length} 個 PDF 已壓縮並打包成 ZIP 檔案。`, icon: 'success', confirmButtonText: '確定' });
                }
              } catch (error) {
                Swal.fire({ title: '錯誤', text: `壓縮過程中發生錯誤: ${error.message}`, icon: 'error', confirmButtonText: '確定' });
                processedCount++;
                progressBar.style.width = Math.round((processedCount / files.length) * 100) + '%';
                if (processedCount === files.length) {
                  loadingDiv.style.display = 'none';
                  progressContainer.style.display = 'none';
                }
              }
            };
            reader.readAsArrayBuffer(file);
          }
        }
      } else {
        Swal.fire({ title: '未選擇 PDF 檔案', text: '請選擇要上傳的 PDF 檔案', icon: 'warning', confirmButtonText: '確定' });
      }
    });
    function detectDevTools() {
    const threshold = 160;
    const isMobile = /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);

    if (!isMobile) {
        const isDevToolsOpen = window.outerWidth - window.innerWidth > threshold || window.outerHeight - window.innerHeight > threshold;

        if (isDevToolsOpen) {
            window.location.href = 'about:blank';
        }
    }
}

document.addEventListener('keydown', (e) => {
    if (e.key === 'F12') {
        e.preventDefault();
        window.location.href = 'about:blank';
    }
});
document.addEventListener('keydown', (e) => {
    if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
    }
});

document.addEventListener('keydown', (e) => {
    if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === 'i') {
        e.preventDefault();
        window.location.href = 'about:blank';
    }
});

setInterval(detectDevTools, 50);
  </script>
</body>
</html>
