<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>SimpleGallery Android→HarmonyOS 功能覆盖追踪</title>

<style>

  :root {

    --primary: #007DFF;

    --primary-light: #E3F2FD;

    --success: #4CAF50;

    --success-light: #E8F5E9;

    --warning: #FF9800;

    --warning-light: #FFF3E0;

    --error: #E84026;

    --gray-100: #F5F5F5;

    --gray-200: #EEEEEE;

    --gray-300: #E0E0E0;

    --gray-500: #9E9E9E;

    --gray-700: #616161;

    --gray-900: #212121;

    --radius: 8px;

    --shadow: 0 2px 8px rgba(0,0,0,0.08);

  }

  * { margin: 0; padding: 0; box-sizing: border-box; }

  body {

    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;

    background: var(--gray-100);

    color: var(--gray-900);

    line-height: 1.6;

  }

  .header {

    background: linear-gradient(135deg, var(--primary), #0056b3);

    color: white;

    padding: 24px 32px;

    position: sticky;

    top: 0;

    z-index: 100;

    box-shadow: 0 4px 12px rgba(0,0,0,0.15);

  }

  .header h1 { font-size: 22px; font-weight: 600; }

  .header .subtitle { font-size: 13px; opacity: 0.85; margin-top: 4px; }

  .global-stats {

    display: flex;

    gap: 24px;

    margin-top: 16px;

    flex-wrap: wrap;

  }

  .stat-card {

    background: rgba(255,255,255,0.15);

    border-radius: var(--radius);

    padding: 12px 20px;

    min-width: 160px;

    backdrop-filter: blur(4px);

  }

  .stat-card.primary {

    background: rgba(255,255,255,0.25);

    border: 2px solid rgba(255,255,255,0.5);

    padding: 16px 28px;

    min-width: 200px;

  }

  .stat-card.primary .label { font-size: 13px; font-weight: 600; opacity: 0.95; }

  .stat-card.primary .value { font-size: 38px; }

  .stat-card.primary .detail { font-size: 12px; }

  .stat-card.secondary { opacity: 0.8; }

  .stat-card.secondary .value { font-size: 22px; }

  .stat-card .label { font-size: 12px; opacity: 0.8; }

  .stat-card .value { font-size: 28px; font-weight: 700; }

  .stat-card .detail { font-size: 11px; opacity: 0.7; margin-top: 2px; }



  .container { max-width: 1400px; margin: 0 auto; padding: 24px; }



  /* SPEC Checkboxes */

  .spec-section {

    background: white;

    border-radius: var(--radius);

    padding: 20px 24px;

    margin-bottom: 20px;

    box-shadow: var(--shadow);

  }

  .spec-section h2 {

    font-size: 16px;

    font-weight: 600;

    margin-bottom: 12px;

    color: var(--gray-700);

    display: flex;

    align-items: center;

    gap: 8px;

  }

  .spec-section h2::before { content: ''; display: inline-block; width: 4px; height: 18px; background: var(--primary); border-radius: 2px; }

  .spec-grid {

    display: grid;

    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));

    gap: 8px;

  }

  .spec-item {

    display: flex;

    align-items: center;

    gap: 10px;

    padding: 10px 14px;

    border-radius: 6px;

    cursor: pointer;

    transition: all 0.15s;

    border: 1px solid var(--gray-200);

    user-select: none;

  }

  .spec-item:hover { background: var(--primary-light); border-color: var(--primary); }

  .spec-item.checked { background: var(--success-light); border-color: var(--success); }

  .spec-item input[type="checkbox"] {

    width: 18px; height: 18px;

    accent-color: var(--success);

    cursor: pointer;

    flex-shrink: 0;

  }

  .spec-item .spec-id {

    font-size: 11px;

    font-weight: 700;

    color: var(--primary);

    background: var(--primary-light);

    padding: 2px 6px;

    border-radius: 3px;

    white-space: nowrap;

  }

  .spec-item.checked .spec-id { color: var(--success); background: var(--success-light); }

  .spec-item .spec-name { font-size: 13px; color: var(--gray-700); }

  .spec-actions {

    display: flex;

    gap: 8px;

    margin-top: 12px;

  }

  .spec-actions button {

    padding: 6px 16px;

    border-radius: 4px;

    border: 1px solid var(--gray-300);

    background: white;

    cursor: pointer;

    font-size: 12px;

    color: var(--gray-700);

    transition: all 0.15s;

  }

  .spec-actions button:hover { background: var(--gray-100); border-color: var(--primary); color: var(--primary); }

  .spec-actions button.export-btn { background: var(--primary); color: white; border-color: var(--primary); }

  .spec-actions button.export-btn:hover { background: #0056b3; }



  /* Activity Cards */

  .activity-section h2 {

    font-size: 16px;

    font-weight: 600;

    margin-bottom: 12px;

    color: var(--gray-700);

    display: flex;

    align-items: center;

    gap: 8px;

  }

  .activity-section h2::before { content: ''; display: inline-block; width: 4px; height: 18px; background: var(--warning); border-radius: 2px; }

  .activity-card {

    background: white;

    border-radius: var(--radius);

    margin-bottom: 8px;

    box-shadow: var(--shadow);

    overflow: hidden;

    transition: all 0.2s;

  }

  .activity-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.12); }

  .activity-header {

    display: flex;

    align-items: center;

    padding: 14px 20px;

    cursor: pointer;

    gap: 16px;

    transition: background 0.15s;

  }

  .activity-header:hover { background: var(--gray-100); }

  .activity-name {

    font-size: 15px;

    font-weight: 600;

    min-width: 220px;

    color: var(--gray-900);

  }

  .activity-progress-bar {

    flex: 1;

    height: 8px;

    background: var(--gray-200);

    border-radius: 4px;

    overflow: hidden;

    position: relative;

  }

  .activity-progress-fill {

    height: 100%;

    border-radius: 4px;

    transition: width 0.4s ease, background 0.3s;

    background: var(--primary);

  }

  .activity-progress-fill.full { background: var(--success); }

  .activity-progress-fill.partial { background: var(--primary); }

  .activity-progress-fill.none { background: var(--gray-300); width: 0!important; }

  .activity-stats {

    font-size: 13px;

    color: var(--gray-500);

    min-width: 100px;

    text-align: right;

    white-space: nowrap;

  }

  .activity-stats .pct {

    font-weight: 700;

    font-size: 15px;

  }

  .activity-stats .pct.full { color: var(--success); }

  .activity-stats .pct.partial { color: var(--primary); }

  .activity-stats .pct.none { color: var(--gray-500); }

  .chevron {

    width: 20px; height: 20px;

    transition: transform 0.2s;

    color: var(--gray-500);

    flex-shrink: 0;

  }

  .chevron.open { transform: rotate(90deg); }



  /* Component Table */

  .activity-body {

    max-height: 0;

    overflow: hidden;

    transition: max-height 0.3s ease;

  }

  .activity-body.open { max-height: 5000px; }

  .activity-desc {

    padding: 0 20px 12px;

    font-size: 13px;

    color: var(--gray-500);

    border-bottom: 1px solid var(--gray-200);

  }

  .component-table {

    width: 100%;

    border-collapse: collapse;

    font-size: 13px;

  }

  .component-table th {

    background: var(--gray-100);

    padding: 8px 16px;

    text-align: left;

    font-weight: 600;

    color: var(--gray-700);

    font-size: 12px;

    border-bottom: 1px solid var(--gray-300);

    position: sticky;

    top: 0;

  }

  .component-table td {

    padding: 8px 16px;

    border-bottom: 1px solid var(--gray-200);

    vertical-align: top;

  }

  .component-table tr.covered { background: var(--success-light); }

  .component-table tr.uncovered { background: white; }

  .component-table tr.no-spec { background: #FFF8E1; }

  .status-badge {

    display: inline-block;

    padding: 2px 8px;

    border-radius: 10px;

    font-size: 11px;

    font-weight: 600;

    white-space: nowrap;

  }

  .status-badge.covered { background: var(--success); color: white; }

  .status-badge.uncovered { background: var(--gray-300); color: var(--gray-700); }

  .status-badge.no-spec { background: #FFE082; color: #F57F17; }

  .spec-tags { display: flex; gap: 4px; flex-wrap: wrap; }

  .spec-tag {

    font-size: 10px;

    padding: 1px 6px;

    border-radius: 3px;

    background: var(--primary-light);

    color: var(--primary);

    font-weight: 600;

  }

  .spec-tag.active { background: var(--success); color: white; }



  /* Legend */

  .legend {

    display: flex;

    gap: 20px;

    margin-bottom: 16px;

    font-size: 12px;

    color: var(--gray-700);

    flex-wrap: wrap;

  }

  .legend-item { display: flex; align-items: center; gap: 6px; }

  .legend-dot {

    width: 12px; height: 12px;

    border-radius: 3px;

    flex-shrink: 0;

  }



  @media (max-width: 768px) {

    .spec-grid { grid-template-columns: 1fr; }

    .activity-name { min-width: 120px; font-size: 13px; }

    .container { padding: 12px; }

    .header { padding: 16px; }

    .global-stats { gap: 12px; }

    .stat-card { min-width: 120px; padding: 8px 12px; }

  }

</style>

</head>

<body>

<div class="header">

  <h1>SimpleGallery Android &rarr; HarmonyOS 功能覆盖追踪</h1>

  <div class="subtitle">基于 ui_navigation_analysis.md 与 SPEC-01~SPEC-20 plan 的功能点映射分析</div>

  <div class="global-stats">

    <div class="stat-card primary">

      <div class="label">总体功能点覆盖率</div>

      <div class="value" id="globalPct">0%</div>

      <div class="detail" id="globalDetail">0 / 0 功能点</div>

    </div>

    <div class="stat-card secondary">

      <div class="label">Spec 覆盖率</div>

      <div class="value" id="specPct">0%</div>

      <div class="detail" id="specDetail">0 / 20 Spec</div>

    </div>

    <div class="stat-card secondary">

      <div class="label">Activity 覆盖率</div>

      <div class="value" id="actPct">0%</div>

      <div class="detail" id="actDetail">0 / 18 Activity</div>

    </div>

  </div>

</div>



<div class="container">

  <div class="spec-section">

    <h2>Spec 开发进度 (勾选已完成的 Spec)</h2>

    <div class="spec-grid" id="specGrid"></div>

    <div class="spec-actions">

      <button onclick="selectAll()">全选</button>

      <button onclick="deselectAll()">全部取消</button>

      <button class="export-btn" onclick="exportMarkdown()">导出 Markdown</button>

    </div>

  </div>



  <div class="activity-section">

    <h2>Activity 功能覆盖详情</h2>

    <div class="legend">

      <div class="legend-item"><div class="legend-dot" style="background:var(--success)"></div> 已覆盖</div>

      <div class="legend-item"><div class="legend-dot" style="background:var(--gray-300)"></div> 未覆盖</div>

      <div class="legend-item"><div class="legend-dot" style="background:#FFE082"></div> 无对应Spec (外部/平台差异)</div>

    </div>

    <div id="activityList"></div>

  </div>

</div>



<script>

// ========== DATA ==========

const SPECS = [

  { id: "SPEC-01", name: "应用启动与初始化" },

  { id: "SPEC-02", name: "存储权限申请与管理" },

  { id: "SPEC-03", name: "媒体文件夹浏览" },

  { id: "SPEC-04", name: "媒体文件浏览" },

  { id: "SPEC-05", name: "图片全屏查看" },

  { id: "SPEC-06", name: "视频播放" },

  { id: "SPEC-07", name: "全景图片/视频查看" },

  { id: "SPEC-08", name: "媒体搜索" },

  { id: "SPEC-09", name: "媒体编辑" },

  { id: "SPEC-10", name: "媒体文件管理" },

  { id: "SPEC-11", name: "收藏夹管理" },

  { id: "SPEC-12", name: "回收站管理" },

  { id: "SPEC-13", name: "幻灯片播放" },

  { id: "SPEC-14", name: "壁纸设置" },

  { id: "SPEC-15", name: "第三方Want响应" },

  { id: "SPEC-16", name: "隐藏文件夹管理" },

  { id: "SPEC-17", name: "排除/包含文件夹管理" },

  { id: "SPEC-18", name: "桌面小部件" },

  { id: "SPEC-19", name: "设置与个性化" },

  { id: "SPEC-20", name: "后台媒体同步服务" }

];



const ACTIVITIES = [

  {

    name: "SplashActivity",

    desc: "应用启动入口,执行初始化和收藏迁移后跳转至 MainActivity。",

    components: [

      { id: "launchActivity()", ui: "程序化方法", desc: "初始化完成后启动 MainActivity 并 finish", target: "MainActivity", specs: ["SPEC-01"] }

    ]

  },

  {

    name: "MainActivity",

    desc: "主页,展示媒体文件夹网格/列表,支持 picker 模式、搜索、多选等。",

    components: [

      { id: "directories_grid (item click)", ui: "DirectoryAdapter item", desc: "点击文件夹进入媒体列表或子文件夹", target: "MediaActivity", specs: ["SPEC-03"] },

      { id: "open_camera", ui: "MenuItem", desc: "启动设备相机", target: "外部应用", specs: ["SPEC-03"] },

      { id: "show_all", ui: "MenuItem", desc: "显示所有媒体模式", target: "MediaActivity", specs: ["SPEC-03", "SPEC-04"] },

      { id: "sort", ui: "MenuItem", desc: "打开排序对话框", target: "MainActivity (self)", specs: ["SPEC-03"] },

      { id: "filter", ui: "MenuItem", desc: "打开媒体类型过滤器", target: "MainActivity (self)", specs: ["SPEC-03"] },

      { id: "change_view_type", ui: "MenuItem", desc: "网格/列表视图切换", target: "MainActivity (self)", specs: ["SPEC-03"] },

      { id: "temporarily_show_hidden", ui: "MenuItem", desc: "临时显示隐藏文件夹", target: "MainActivity (self)", specs: ["SPEC-16"] },

      { id: "stop_showing_hidden", ui: "MenuItem", desc: "恢复隐藏文件夹", target: "MainActivity (self)", specs: ["SPEC-16"] },

      { id: "temporarily_show_excluded", ui: "MenuItem", desc: "临时显示排除文件夹", target: "MainActivity (self)", specs: ["SPEC-17"] },

      { id: "stop_showing_excluded", ui: "MenuItem", desc: "恢复排除文件夹", target: "MainActivity (self)", specs: ["SPEC-17"] },

      { id: "create_new_folder", ui: "MenuItem", desc: "创建新文件夹", target: "MainActivity (self)", specs: ["SPEC-10"] },

      { id: "open_recycle_bin", ui: "MenuItem", desc: "打开回收站", target: "MediaActivity", specs: ["SPEC-12"] },

      { id: "column_count", ui: "MenuItem", desc: "设置网格列数", target: "MainActivity (self)", specs: ["SPEC-03"] },

      { id: "set_as_default_folder", ui: "MenuItem", desc: "清除默认文件夹设置", target: "MainActivity (self)", specs: ["SPEC-19"] },

      { id: "settings", ui: "MenuItem", desc: "打开设置页", target: "SettingsActivity", specs: ["SPEC-19"] },

      { id: "about", ui: "MenuItem", desc: "打开关于页面", target: "AboutActivity (commons)", specs: [] },

      { id: "more_apps_from_us", ui: "MenuItem", desc: "打开应用商店", target: "外部应用", specs: [] },

      { id: "directories_switch_searching", ui: "MyTextView", desc: "切换到全局文件搜索", target: "SearchActivity", specs: ["SPEC-08"] },

      { id: "directories_empty_placeholder_2", ui: "MyTextView", desc: "空态操作(添加文件夹/过滤器)", target: "MainActivity (self)", specs: ["SPEC-03"] },

      { id: "directories_refresh_layout", ui: "SwipeRefreshLayout", desc: "下拉刷新文件夹列表", target: "MainActivity (self)", specs: ["SPEC-03"] },

      { id: "search_open", ui: "MySearchMenu", desc: "搜索焦点时跳转搜索页", target: "SearchActivity", specs: ["SPEC-08"] }

    ]

  },

  {

    name: "MediaActivity",

    desc: "显示特定文件夹内的媒体网格/列表,支持 picker/壁纸模式、回收站视图。",

    components: [

      { id: "media_grid (item click, image)", ui: "RecyclerView item", desc: "点击图片进入全屏查看", target: "ViewPagerActivity", specs: ["SPEC-04"] },

      { id: "media_grid (item click, video)", ui: "RecyclerView item", desc: "点击视频使用外部播放器", target: "外部应用", specs: ["SPEC-04"] },

      { id: "media_grid (item click, pick)", ui: "RecyclerView item", desc: "Picker模式选择媒体返回URI", target: "返回调用方", specs: ["SPEC-15"] },

      { id: "media_grid (item click, wallpaper)", ui: "RecyclerView item", desc: "设置图片为壁纸", target: "返回调用方", specs: ["SPEC-14"] },

      { id: "slideshow", ui: "MenuItem", desc: "启动幻灯片播放", target: "ViewPagerActivity", specs: ["SPEC-13"] },

      { id: "folder_view", ui: "MenuItem (Show All)", desc: "切换到文件夹浏览视图", target: "MainActivity", specs: ["SPEC-04"] },

      { id: "open_camera", ui: "MenuItem (Show All)", desc: "启动设备相机", target: "外部应用", specs: [] },

      { id: "settings", ui: "MenuItem", desc: "打开设置页", target: "SettingsActivity", specs: ["SPEC-19"] },

      { id: "about", ui: "MenuItem (Show All)", desc: "打开关于页面", target: "AboutActivity (commons)", specs: [] },

      { id: "open_recycle_bin", ui: "MenuItem", desc: "打开回收站列表", target: "MediaActivity (self)", specs: ["SPEC-12"] },

      { id: "sort", ui: "MenuItem", desc: "打开排序对话框", target: "MediaActivity (self)", specs: ["SPEC-04"] },

      { id: "filter", ui: "MenuItem", desc: "打开媒体类型过滤器", target: "MediaActivity (self)", specs: ["SPEC-04"] },

      { id: "change_view_type", ui: "MenuItem", desc: "网格/列表视图切换", target: "MediaActivity (self)", specs: ["SPEC-04"] },

      { id: "group", ui: "MenuItem (grid)", desc: "打开分组设置", target: "MediaActivity (self)", specs: ["SPEC-04"] },

      { id: "toggle_filename", ui: "MenuItem (grid)", desc: "切换文件名显示", target: "MediaActivity (self)", specs: ["SPEC-04"] },

      { id: "column_count", ui: "MenuItem (grid)", desc: "设置网格列数", target: "MediaActivity (self)", specs: ["SPEC-04"] },

      { id: "empty_recycle_bin", ui: "MenuItem (Recycle Bin)", desc: "清空回收站", target: "返回", specs: ["SPEC-12"] },

      { id: "empty_disable_recycle_bin", ui: "MenuItem (Recycle Bin)", desc: "清空并禁用回收站", target: "返回", specs: ["SPEC-12"] },

      { id: "restore_all_files", ui: "MenuItem (Recycle Bin)", desc: "还原所有已删除文件", target: "返回", specs: ["SPEC-12"] },

      { id: "create_new_folder", ui: "MenuItem", desc: "创建子文件夹", target: "MediaActivity (self)", specs: ["SPEC-10"] },

      { id: "temporarily_show_hidden", ui: "MenuItem", desc: "临时显示隐藏文件", target: "MediaActivity (self)", specs: ["SPEC-16"] },

      { id: "stop_showing_hidden", ui: "MenuItem", desc: "恢复隐藏文件", target: "MediaActivity (self)", specs: ["SPEC-16"] },

      { id: "set_as_default_folder", ui: "MenuItem", desc: "设为默认启动文件夹", target: "MediaActivity (self)", specs: ["SPEC-19"] },

      { id: "unset_as_default_folder", ui: "MenuItem", desc: "取消默认文件夹", target: "MediaActivity (self)", specs: ["SPEC-19"] },

      { id: "media_empty_text_placeholder_2", ui: "TextView", desc: "空态打开过滤器", target: "MediaActivity (self)", specs: ["SPEC-04"] },

      { id: "media_refresh_layout", ui: "SwipeRefreshLayout", desc: "下拉刷新媒体列表", target: "MediaActivity (self)", specs: ["SPEC-04"] }

    ]

  },

  {

    name: "SearchActivity",

    desc: "全局全文搜索,实时过滤设备上所有媒体文件名。",

    components: [

      { id: "search_grid (item click, image)", ui: "RecyclerView item", desc: "点击图片进入全屏查看", target: "ViewPagerActivity", specs: ["SPEC-08"] },

      { id: "search_grid (item click, video)", ui: "RecyclerView item", desc: "使用系统播放器打开视频", target: "外部应用", specs: ["SPEC-08"] },

      { id: "search_menu (back, empty)", ui: "MySearchMenu back", desc: "关闭搜索页", target: "返回", specs: ["SPEC-08"] },

      { id: "search_menu (back, non-empty)", ui: "MySearchMenu back", desc: "清空搜索文字", target: "SearchActivity (self)", specs: ["SPEC-08"] },

      { id: "toggle_filename", ui: "MenuItem", desc: "切换文件名显示", target: "SearchActivity (self)", specs: ["SPEC-08"] },

      { id: "search_menu (text input)", ui: "MySearchMenu", desc: "输入关键词实时过滤", target: "SearchActivity (self)", specs: ["SPEC-08"] },

      { id: "(CAB actions)", ui: "MediaAdapter CAB", desc: "多选操作(同 MediaActivity)", target: "多种", specs: ["SPEC-08", "SPEC-10"] }

    ]

  },

  {

    name: "ViewPagerActivity",

    desc: "全屏媒体查看器,支持横滑浏览、幻灯片、文件操作、底部快捷栏。",

    components: [

      { id: "medium_viewer_toolbar (back)", ui: "Toolbar back", desc: "返回上一页", target: "返回", specs: ["SPEC-05"] },

      { id: "view_pager", ui: "MyViewPager", desc: "可滑动的图片/视频分页", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "fragment tap", ui: "PhotoFragment/VideoFragment", desc: "点击切换全屏模式", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "menu_set_as", ui: "MenuItem", desc: "设为壁纸/头像等", target: "外部应用", specs: ["SPEC-14"] },

      { id: "menu_slideshow", ui: "MenuItem", desc: "启动幻灯片播放", target: "ViewPagerActivity (self)", specs: ["SPEC-13"] },

      { id: "menu_copy_to", ui: "MenuItem", desc: "复制文件到目标目录", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_move_to", ui: "MenuItem", desc: "移动文件到目标目录", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_open_with", ui: "MenuItem", desc: "用其他应用打开", target: "外部应用", specs: ["SPEC-15"] },

      { id: "menu_hide", ui: "MenuItem", desc: "隐藏文件", target: "ViewPagerActivity (self)", specs: ["SPEC-16"] },

      { id: "menu_unhide", ui: "MenuItem", desc: "取消隐藏文件", target: "ViewPagerActivity (self)", specs: ["SPEC-16"] },

      { id: "menu_share", ui: "MenuItem", desc: "通过系统分享面板分享", target: "外部应用", specs: ["SPEC-15"] },

      { id: "menu_delete", ui: "MenuItem", desc: "删除文件", target: "ViewPagerActivity/返回", specs: ["SPEC-10"] },

      { id: "menu_rename", ui: "MenuItem", desc: "重命名文件", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_print", ui: "MenuItem", desc: "发送到打印服务", target: "外部应用", specs: [] },

      { id: "menu_edit", ui: "MenuItem", desc: "打开外部图片编辑器", target: "外部应用", specs: ["SPEC-09"] },

      { id: "menu_properties", ui: "MenuItem", desc: "显示文件属性对话框", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "menu_show_on_map", ui: "MenuItem", desc: "在地图上显示GPS位置", target: "外部应用", specs: [] },

      { id: "menu_rotate_right", ui: "Submenu MenuItem", desc: "顺时针旋转90\u00B0", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_rotate_left", ui: "Submenu MenuItem", desc: "逆时针旋转90\u00B0", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_rotate_one_eighty", ui: "Submenu MenuItem", desc: "旋转180\u00B0", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_add_to_favorites", ui: "MenuItem", desc: "添加到收藏", target: "ViewPagerActivity (self)", specs: ["SPEC-11"] },

      { id: "menu_remove_from_favorites", ui: "MenuItem", desc: "从收藏中移除", target: "ViewPagerActivity (self)", specs: ["SPEC-11"] },

      { id: "menu_restore_file", ui: "MenuItem", desc: "从回收站还原文件", target: "ViewPagerActivity (self)", specs: ["SPEC-12"] },

      { id: "menu_force_portrait", ui: "Submenu MenuItem", desc: "锁定竖屏方向", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "menu_force_landscape", ui: "Submenu MenuItem", desc: "锁定横屏方向", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "menu_default_orientation", ui: "Submenu MenuItem", desc: "解锁屏幕方向", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "menu_save_as", ui: "MenuItem", desc: "另存为", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_create_shortcut", ui: "MenuItem", desc: "创建桌面快捷方式", target: "ViewPagerActivity (via shortcut)", specs: [] },

      { id: "menu_resize", ui: "MenuItem", desc: "调整图片尺寸", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "menu_settings", ui: "MenuItem", desc: "打开设置", target: "SettingsActivity", specs: ["SPEC-19"] },

      { id: "bottom_favorite", ui: "ImageView", desc: "切换收藏状态", target: "ViewPagerActivity (self)", specs: ["SPEC-11"] },

      { id: "bottom_edit", ui: "ImageView", desc: "打开外部图片编辑器", target: "外部应用", specs: ["SPEC-09"] },

      { id: "bottom_share", ui: "ImageView", desc: "分享文件", target: "外部应用", specs: ["SPEC-15"] },

      { id: "bottom_delete", ui: "ImageView", desc: "删除当前文件", target: "ViewPagerActivity/返回", specs: ["SPEC-10"] },

      { id: "bottom_rotate", ui: "ImageView", desc: "旋转图片90\u00B0", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "bottom_properties", ui: "ImageView", desc: "显示文件属性", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "bottom_change_orientation", ui: "ImageView", desc: "循环切换屏幕方向", target: "ViewPagerActivity (self)", specs: ["SPEC-05"] },

      { id: "bottom_slideshow", ui: "ImageView", desc: "启动幻灯片播放", target: "ViewPagerActivity (self)", specs: ["SPEC-13"] },

      { id: "bottom_show_on_map", ui: "ImageView", desc: "在地图上显示位置", target: "外部应用", specs: [] },

      { id: "bottom_toggle_file_visibility", ui: "ImageView", desc: "切换文件可见性", target: "ViewPagerActivity (self)", specs: ["SPEC-16"] },

      { id: "bottom_rename", ui: "ImageView", desc: "重命名文件", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "bottom_set_as", ui: "ImageView", desc: "设为壁纸/头像", target: "外部应用", specs: ["SPEC-14"] },

      { id: "bottom_copy", ui: "ImageView", desc: "复制到目标目录", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "bottom_move", ui: "ImageView", desc: "移动到目标目录", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "bottom_resize", ui: "ImageView", desc: "调整图片尺寸", target: "ViewPagerActivity (self)", specs: ["SPEC-10"] },

      { id: "launchViewVideoIntent()", ui: "FragmentListener callback", desc: "启动外部视频播放器", target: "外部应用", specs: ["SPEC-06"] }

    ]

  },

  {

    name: "SettingsActivity",

    desc: "应用设置中心,包含颜色定制、显示、视频、缩略图、安全、回收站等设置分类。",

    components: [

      { id: "settings_toolbar", ui: "MaterialToolbar (Arrow)", desc: "返回导航", target: "返回", specs: ["SPEC-19"] },

      { id: "settings_color_customization_holder", ui: "ConstraintLayout", desc: "颜色/主题定制", target: "CustomizationActivity", specs: ["SPEC-19"] },

      { id: "settings_use_english_holder", ui: "RelativeLayout (checkbox)", desc: "切换英语,重启应用", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_language_holder", ui: "RelativeLayout", desc: "打开系统语言设置", target: "外部应用", specs: ["SPEC-19"] },

      { id: "settings_change_date_time_format_holder", ui: "RelativeLayout", desc: "日期/时间格式设置", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_file_loading_priority_holder", ui: "RelativeLayout", desc: "文件加载优先级设置", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_manage_included_folders_holder", ui: "RelativeLayout", desc: "导航到包含文件夹管理", target: "IncludedFoldersActivity", specs: ["SPEC-17"] },

      { id: "settings_manage_excluded_folders_holder", ui: "RelativeLayout", desc: "导航到排除文件夹管理", target: "ExcludedFoldersActivity", specs: ["SPEC-17"] },

      { id: "settings_manage_hidden_folders_holder", ui: "RelativeLayout", desc: "导航到隐藏文件夹管理", target: "HiddenFoldersActivity", specs: ["SPEC-16"] },

      { id: "settings_show_hidden_items_holder", ui: "RelativeLayout (checkbox)", desc: "切换隐藏媒体可见性", target: "SettingsActivity (self)", specs: ["SPEC-16"] },

      { id: "settings_search_all_files_holder", ui: "RelativeLayout (checkbox)", desc: "切换全文件搜索", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_autoplay_videos_holder", ui: "RelativeLayout (checkbox)", desc: "切换视频自动播放", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_remember_last_video_position_holder", ui: "RelativeLayout (checkbox)", desc: "记住视频播放位置", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_loop_videos_holder", ui: "RelativeLayout (checkbox)", desc: "切换视频循环", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_open_videos_on_separate_screen_holder", ui: "RelativeLayout (checkbox)", desc: "切换独立视频窗口", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_allow_video_gestures_holder", ui: "RelativeLayout (checkbox)", desc: "切换视频手势", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_crop_thumbnails_holder", ui: "RelativeLayout (checkbox)", desc: "切换缩略图裁剪", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_animate_gifs_holder", ui: "RelativeLayout (checkbox)", desc: "切换GIF缩略图动画", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_file_thumbnail_style_holder", ui: "RelativeLayout", desc: "文件缩略图样式", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_folder_thumbnail_style_holder", ui: "RelativeLayout", desc: "文件夹缩略图样式", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_scroll_horizontally_holder", ui: "RelativeLayout (checkbox)", desc: "切换水平滚动", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_enable_pull_to_refresh_holder", ui: "RelativeLayout (checkbox)", desc: "切换下拉刷新", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_max_brightness_holder", ui: "RelativeLayout (checkbox)", desc: "全屏最大亮度", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_black_background_holder", ui: "RelativeLayout (checkbox)", desc: "切换黑色背景", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_hide_system_ui_holder", ui: "RelativeLayout (checkbox)", desc: "切换系统UI隐藏", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_allow_instant_change_holder", ui: "RelativeLayout (checkbox)", desc: "切换即时媒体切换", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_allow_photo_gestures_holder", ui: "RelativeLayout (checkbox)", desc: "切换图片手势", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_allow_down_gesture_holder", ui: "RelativeLayout (checkbox)", desc: "切换下滑关闭", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_show_notch_holder", ui: "RelativeLayout (checkbox)", desc: "切换刘海屏渲染", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_screen_rotation_holder", ui: "RelativeLayout", desc: "屏幕旋转设置", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_allow_zooming_images_holder", ui: "RelativeLayout (checkbox)", desc: "切换深度缩放", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_allow_rotating_with_gestures_holder", ui: "RelativeLayout (checkbox)", desc: "切换手势旋转", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_show_highest_quality_holder", ui: "RelativeLayout (checkbox)", desc: "切换最高画质", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_allow_one_to_one_zoom_holder", ui: "RelativeLayout (checkbox)", desc: "切换1:1像素缩放", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_show_extended_details_holder", ui: "RelativeLayout (checkbox)", desc: "切换扩展详情覆盖层", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_hide_extended_details_holder", ui: "RelativeLayout (checkbox)", desc: "切换自动隐藏扩展详情", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_manage_extended_details_holder", ui: "RelativeLayout", desc: "管理扩展详情显示项", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_app_password_protection_holder", ui: "RelativeLayout (checkbox)", desc: "切换应用密码保护", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_hidden_item_password_protection_holder", ui: "RelativeLayout (checkbox)", desc: "切换隐藏内容密码", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_excluded_item_password_protection_holder", ui: "RelativeLayout (checkbox)", desc: "切换排除文件夹密码", target: "SettingsActivity (self)", specs: ["SPEC-17", "SPEC-19"] },

      { id: "settings_file_deletion_password_protection_holder", ui: "RelativeLayout (checkbox)", desc: "切换删除密码保护", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_delete_empty_folders_holder", ui: "RelativeLayout (checkbox)", desc: "切换自动删除空文件夹", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_keep_last_modified_holder", ui: "RelativeLayout (checkbox)", desc: "切换保留时间戳", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_skip_delete_confirmation_holder", ui: "RelativeLayout (checkbox)", desc: "切换跳过删除确认", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_bottom_actions_checkbox_holder", ui: "RelativeLayout (checkbox)", desc: "切换底部操作栏", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_manage_bottom_actions_holder", ui: "RelativeLayout", desc: "管理底部操作按钮", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_use_recycle_bin_holder", ui: "RelativeLayout (checkbox)", desc: "切换回收站使用", target: "SettingsActivity (self)", specs: ["SPEC-12"] },

      { id: "settings_show_recycle_bin_holder", ui: "RelativeLayout (checkbox)", desc: "切换回收站文件夹显示", target: "SettingsActivity (self)", specs: ["SPEC-12"] },

      { id: "settings_show_recycle_bin_last_holder", ui: "RelativeLayout (checkbox)", desc: "切换回收站排列最后", target: "SettingsActivity (self)", specs: ["SPEC-12"] },

      { id: "settings_empty_recycle_bin_holder", ui: "RelativeLayout", desc: "清空回收站", target: "SettingsActivity (self)", specs: ["SPEC-12"] },

      { id: "settings_clear_cache_holder", ui: "RelativeLayout", desc: "清除应用图片缓存", target: "SettingsActivity (self)", specs: ["SPEC-19"] },

      { id: "settings_export_favorites_holder", ui: "RelativeLayout", desc: "导出收藏到文件", target: "外部文件选择器", specs: ["SPEC-11"] },

      { id: "settings_import_favorites_holder", ui: "RelativeLayout", desc: "从文件导入收藏", target: "外部文件选择器", specs: ["SPEC-11"] },

      { id: "settings_export_holder", ui: "RelativeLayout", desc: "导出所有设置", target: "外部文件选择器", specs: ["SPEC-19"] },

      { id: "settings_import_holder", ui: "RelativeLayout", desc: "导入设置", target: "外部文件选择器", specs: ["SPEC-19"] }

    ]

  },

  {

    name: "IncludedFoldersActivity",

    desc: "管理显式包含在扫描中的文件夹列表。",

    components: [

      { id: "manage_folders_toolbar", ui: "MaterialToolbar (Arrow)", desc: "返回导航", target: "返回", specs: ["SPEC-17"] },

      { id: "add_folder", ui: "MenuItem", desc: "打开文件选择器添加文件夹", target: "IncludedFoldersActivity (self)", specs: ["SPEC-17"] },

      { id: "overflow_menu_icon (adapter)", ui: "ImageView (每行)", desc: "弹出菜单可移除", target: "IncludedFoldersActivity (self)", specs: ["SPEC-17"] },

      { id: "cab_remove", ui: "CAB MenuItem", desc: "移除选中的包含文件夹", target: "IncludedFoldersActivity (self)", specs: ["SPEC-17"] }

    ]

  },

  {

    name: "ExcludedFoldersActivity",

    desc: "管理从扫描中排除的文件夹列表。",

    components: [

      { id: "manage_folders_toolbar", ui: "MaterialToolbar (Arrow)", desc: "返回导航", target: "返回", specs: ["SPEC-17"] },

      { id: "add_folder", ui: "MenuItem", desc: "打开文件选择器添加文件夹", target: "ExcludedFoldersActivity (self)", specs: ["SPEC-17"] },

      { id: "overflow_menu_icon (adapter)", ui: "ImageView (每行)", desc: "弹出菜单可移除", target: "ExcludedFoldersActivity (self)", specs: ["SPEC-17"] },

      { id: "cab_remove", ui: "CAB MenuItem", desc: "移除选中的排除文件夹", target: "ExcludedFoldersActivity (self)", specs: ["SPEC-17"] }

    ]

  },

  {

    name: "HiddenFoldersActivity",

    desc: "管理通过 .nomedia 文件隐藏的文件夹。",

    components: [

      { id: "manage_folders_toolbar", ui: "MaterialToolbar (Arrow)", desc: "返回导航", target: "返回", specs: ["SPEC-16"] },

      { id: "add_folder", ui: "MenuItem", desc: "打开文件选择器隐藏文件夹", target: "HiddenFoldersActivity (self)", specs: ["SPEC-16"] },

      { id: "cab_unhide", ui: "CAB MenuItem", desc: "取消隐藏选中文件夹", target: "HiddenFoldersActivity (self)", specs: ["SPEC-16"] }

    ]

  },

  {

    name: "EditActivity",

    desc: "图片编辑器:滤镜、裁剪/旋转/缩放、涂鸦绘制。",

    components: [

      { id: "save_as", ui: "MenuItem", desc: "保存编辑后的图片", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "edit", ui: "MenuItem", desc: "用外部编辑器打开", target: "外部应用", specs: ["SPEC-09"] },

      { id: "share", ui: "MenuItem", desc: "分享编辑后的图片", target: "外部应用", specs: ["SPEC-09"] },

      { id: "bottom_primary_filter", ui: "ImageView", desc: "切换滤镜模式", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_primary_crop_rotate", ui: "ImageView", desc: "切换裁剪/旋转模式", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_primary_draw", ui: "ImageView", desc: "切换绘画模式", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_rotate", ui: "ImageView", desc: "旋转裁剪视图90\u00B0", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_resize", ui: "ImageView", desc: "打开尺寸调整对话框", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_aspect_ratio", ui: "ImageView", desc: "切换宽高比子栏", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_flip_horizontally", ui: "ImageView", desc: "水平翻转", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_flip_vertically", ui: "ImageView", desc: "垂直翻转", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_aspect_ratio_free", ui: "TextView", desc: "设置自由宽高比", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_aspect_ratio_one_one", ui: "TextView", desc: "设置1:1宽高比", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_aspect_ratio_four_three", ui: "TextView", desc: "设置4:3宽高比", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_aspect_ratio_sixteen_nine", ui: "TextView", desc: "设置16:9宽高比", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_aspect_ratio_other", ui: "TextView", desc: "自定义宽高比", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_draw_color_clickable", ui: "ImageView", desc: "打开画笔颜色选择器", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_draw_width", ui: "MySeekBar", desc: "调整画笔大小", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_draw_undo", ui: "ImageView", desc: "撤销上一笔", target: "EditActivity (self)", specs: ["SPEC-09"] },

      { id: "bottom_actions_filter_list", ui: "MyRecyclerView", desc: "滤镜缩略图列表", target: "EditActivity (self)", specs: ["SPEC-09"] }

    ]

  },

  {

    name: "SetWallpaperActivity",

    desc: "裁剪并设置图片为设备壁纸(主屏/锁屏/两者)。",

    components: [

      { id: "save", ui: "MenuItem", desc: "设置为壁纸(Nougat+可选主屏/锁屏)", target: "SetWallpaperActivity (self)", specs: ["SPEC-14"] },

      { id: "allow_changing_aspect_ratio", ui: "MenuItem", desc: "清除固定宽高比", target: "SetWallpaperActivity (self)", specs: ["SPEC-14"] },

      { id: "bottom_set_wallpaper_aspect_ratio", ui: "ImageView", desc: "循环切换宽高比", target: "SetWallpaperActivity (self)", specs: ["SPEC-14"] },

      { id: "bottom_set_wallpaper_rotate", ui: "ImageView", desc: "旋转裁剪视图90\u00B0", target: "SetWallpaperActivity (self)", specs: ["SPEC-14"] },

      { id: "(implicit redirect)", ui: "程序化", desc: "无图片数据时跳转选择", target: "MainActivity", specs: ["SPEC-14"] }

    ]

  },

  {

    name: "WidgetConfigureActivity",

    desc: "桌面小部件配置:选择文件夹、颜色、透明度。",

    components: [

      { id: "config_save", ui: "Button", desc: "保存小部件配置", target: "返回", specs: ["SPEC-18"] },

      { id: "config_bg_color", ui: "ImageView", desc: "背景颜色选择器", target: "WidgetConfigureActivity (self)", specs: ["SPEC-18"] },

      { id: "config_text_color", ui: "ImageView", desc: "文字颜色选择器", target: "WidgetConfigureActivity (self)", specs: ["SPEC-18"] },

      { id: "folder_picker_value", ui: "MyTextView", desc: "选择文件夹", target: "WidgetConfigureActivity (self)", specs: ["SPEC-18"] },

      { id: "config_image_holder", ui: "RelativeLayout", desc: "选择文件夹", target: "WidgetConfigureActivity (self)", specs: ["SPEC-18"] },

      { id: "folder_picker_show_folder_name_holder", ui: "RelativeLayout", desc: "切换文件夹名显示", target: "WidgetConfigureActivity (self)", specs: ["SPEC-18"] },

      { id: "config_bg_seekbar", ui: "MySeekBar", desc: "背景透明度控制", target: "WidgetConfigureActivity (self)", specs: ["SPEC-18"] }

    ]

  },

  {

    name: "PhotoVideoActivity",

    desc: "外部 ACTION_VIEW 意图入口,根据文件类型路由到合适的查看器。",

    components: [

      { id: "fragment_viewer_toolbar (back)", ui: "Toolbar back", desc: "关闭页面", target: "返回", specs: ["SPEC-15"] },

      { id: "menu_set_as", ui: "MenuItem", desc: "设为壁纸/头像", target: "外部应用", specs: ["SPEC-15"] },

      { id: "menu_open_with", ui: "MenuItem", desc: "用其他应用打开", target: "外部应用", specs: ["SPEC-15"] },

      { id: "menu_share", ui: "MenuItem", desc: "分享媒体文件", target: "外部应用", specs: ["SPEC-15"] },

      { id: "menu_edit", ui: "MenuItem", desc: "打开外部编辑器", target: "外部应用", specs: ["SPEC-15"] },

      { id: "menu_properties", ui: "MenuItem", desc: "显示文件属性", target: "PhotoVideoActivity (self)", specs: ["SPEC-15"] },

      { id: "menu_show_on_map", ui: "MenuItem", desc: "地图显示GPS位置", target: "外部应用", specs: ["SPEC-15"] },

      { id: "bottom_edit", ui: "ImageView", desc: "打开外部编辑器", target: "外部应用", specs: ["SPEC-15"] },

      { id: "bottom_share", ui: "ImageView", desc: "分享媒体", target: "外部应用", specs: ["SPEC-15"] },

      { id: "bottom_set_as", ui: "ImageView", desc: "设为壁纸/头像", target: "外部应用", specs: ["SPEC-15"] },

      { id: "bottom_show_on_map", ui: "ImageView", desc: "地图显示位置", target: "外部应用", specs: ["SPEC-15"] },

      { id: "fragment_placeholder (tap)", ui: "Fragment content", desc: "切换全屏模式", target: "PhotoVideoActivity (self)", specs: ["SPEC-15"] },

      { id: "redirect: sendViewPagerIntent", ui: "程序化", desc: "有文件路径时跳转ViewPager", target: "ViewPagerActivity", specs: ["SPEC-15"] },

      { id: "redirect: launchVideoPlayer", ui: "程序化", desc: "视频跳转专用播放器", target: "VideoPlayerActivity/PanoramaVideoActivity", specs: ["SPEC-15"] },

      { id: "redirect: checkIntent fallback", ui: "程序化", desc: "无数据时跳转主页", target: "MainActivity", specs: ["SPEC-15"] }

    ]

  },

  {

    name: "PhotoActivity",

    desc: "PhotoVideoActivity 子类,仅处理 image/* 的 ACTION_VIEW 意图。",

    components: [

      { id: "(all)", ui: "(all)", desc: "与 PhotoVideoActivity 完全一致", target: "同 PhotoVideoActivity", specs: ["SPEC-15"] }

    ]

  },

  {

    name: "VideoActivity",

    desc: "PhotoVideoActivity 子类,仅处理 video/* 的 ACTION_VIEW 意图。",

    components: [

      { id: "(all)", ui: "(all)", desc: "与 PhotoVideoActivity 完全一致", target: "同 PhotoVideoActivity", specs: ["SPEC-15"] }

    ]

  },

  {

    name: "VideoPlayerActivity",

    desc: "ExoPlayer 视频播放器,支持播放控制、拖拽、手势亮度/音量调节。",

    components: [

      { id: "video_toolbar (back)", ui: "Toolbar back", desc: "关闭播放器", target: "返回", specs: ["SPEC-06"] },

      { id: "menu_change_orientation", ui: "MenuItem", desc: "切换横竖屏锁定", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "menu_open_with", ui: "MenuItem", desc: "用其他应用打开", target: "外部应用", specs: ["SPEC-06"] },

      { id: "menu_share", ui: "MenuItem", desc: "分享视频", target: "外部应用", specs: ["SPEC-06"] },

      { id: "video_toggle_play_pause", ui: "ImageView", desc: "播放/暂停切换", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "video_curr_time", ui: "TextView", desc: "点击后退10秒", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "video_duration", ui: "TextView", desc: "点击前进10秒", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "video_seekbar", ui: "SeekBar", desc: "拖动进度条定位", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "video_prev_file", ui: "ImageView", desc: "返回上一个文件", target: "返回 (结果)", specs: ["SPEC-06"] },

      { id: "video_next_file", ui: "ImageView", desc: "跳转下一个文件", target: "返回 (结果)", specs: ["SPEC-06"] },

      { id: "video_surface_frame", ui: "GestureFrameLayout", desc: "点击全屏/双击跳转/拖拽快进", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "video_brightness_controller", ui: "MediaSideScroll", desc: "亮度手势控制", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "video_volume_controller", ui: "MediaSideScroll", desc: "音量手势控制", target: "VideoPlayerActivity (self)", specs: ["SPEC-06"] },

      { id: "swipe-down gesture", ui: "Touch gesture", desc: "下滑关闭播放器", target: "返回", specs: ["SPEC-06"] }

    ]

  },

  {

    name: "PanoramaPhotoActivity",

    desc: "使用 Google VR SDK 显示 360 度全景照片。",

    components: [

      { id: "cardboard", ui: "ImageView", desc: "切换 Google Cardboard VR 模式", target: "PanoramaPhotoActivity (self)", specs: ["SPEC-07"] },

      { id: "explore", ui: "ImageView", desc: "切换触摸追踪平移", target: "PanoramaPhotoActivity (self)", specs: ["SPEC-07"] },

      { id: "panorama_view", ui: "VrPanoramaView", desc: "点击切换全屏模式", target: "PanoramaPhotoActivity (self)", specs: ["SPEC-07"] }

    ]

  },

  {

    name: "PanoramaVideoActivity",

    desc: "使用 Google VR SDK 播放 360 度全景视频。",

    components: [

      { id: "cardboard", ui: "ImageView", desc: "切换 Google Cardboard VR 模式", target: "PanoramaVideoActivity (self)", specs: ["SPEC-07"] },

      { id: "explore", ui: "ImageView", desc: "切换触摸追踪平移", target: "PanoramaVideoActivity (self)", specs: ["SPEC-07"] },

      { id: "vr_video_view", ui: "VrVideoView", desc: "点击切换全屏模式", target: "PanoramaVideoActivity (self)", specs: ["SPEC-07"] },

      { id: "video_toggle_play_pause", ui: "ImageView", desc: "切换视频播放", target: "PanoramaVideoActivity (self)", specs: ["SPEC-07"] },

      { id: "video_curr_time", ui: "TextView", desc: "点击后退2%进度", target: "PanoramaVideoActivity (self)", specs: ["SPEC-07"] },

      { id: "video_duration", ui: "TextView", desc: "点击前进2%进度", target: "PanoramaVideoActivity (self)", specs: ["SPEC-07"] },

      { id: "video_seekbar", ui: "SeekBar", desc: "拖动进度条定位", target: "PanoramaVideoActivity (self)", specs: ["SPEC-07"] }

    ]

  }

];



// ========== STATE ==========

let checkedSpecs = new Set();



// ========== RENDER ==========

function renderSpecs() {

  const grid = document.getElementById('specGrid');

  grid.innerHTML = SPECS.map(s => `

    <label class="spec-item ${checkedSpecs.has(s.id) ? 'checked' : ''}" data-spec="${s.id}">

      <input type="checkbox" ${checkedSpecs.has(s.id) ? 'checked' : ''} onchange="toggleSpec('${s.id}', this.checked)">

      <span class="spec-id">${s.id}</span>

      <span class="spec-name">${s.name}</span>

    </label>

  `).join('');

}



function getActivityStats(activity) {

  const total = activity.components.length;

  let covered = 0;

  let noSpec = 0;

  activity.components.forEach(c => {

    if (c.specs.length === 0) {

      noSpec++;

    } else if (c.specs.some(s => checkedSpecs.has(s))) {

      covered++;

    }

  });

  const coverable = total - noSpec;

  return { total, covered, noSpec, coverable };

}



function renderActivities() {

  const list = document.getElementById('activityList');

  list.innerHTML = ACTIVITIES.map((act, i) => {

    const stats = getActivityStats(act);

    const pct = stats.coverable > 0 ? Math.round(stats.covered / stats.coverable * 100) : (stats.total === stats.noSpec ? -1 : 0);

    const pctClass = pct === 100 ? 'full' : pct > 0 ? 'partial' : 'none';

    const pctDisplay = pct === -1 ? 'N/A' : pct + '%';

    const fillClass = pct === 100 ? 'full' : pct > 0 ? 'partial' : 'none';

    const fillWidth = pct === -1 ? 0 : (stats.coverable > 0 ? (stats.covered / stats.coverable * 100) : 0);



    return `

    <div class="activity-card" id="act-${i}">

      <div class="activity-header" onclick="toggleActivity(${i})">

        <svg class="chevron" id="chev-${i}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>

        <div class="activity-name">${act.name}</div>

        <div class="activity-progress-bar">

          <div class="activity-progress-fill ${fillClass}" style="width:${fillWidth}%"></div>

        </div>

        <div class="activity-stats">

          <span class="pct ${pctClass}">${pctDisplay}</span>

          <div style="font-size:11px">${stats.covered}/${stats.coverable}${stats.noSpec > 0 ? ` <span style="color:#F57F17">(+${stats.noSpec} N/A)</span>` : ''}</div>

        </div>

      </div>

      <div class="activity-body" id="body-${i}">

        <div class="activity-desc">${act.desc}</div>

        <table class="component-table">

          <thead>

            <tr>

              <th style="width:50px">状态</th>

              <th style="width:220px">组件 ID</th>

              <th style="width:140px">UI 组件</th>

              <th>功能描述</th>

              <th style="width:160px">目标</th>

              <th style="width:120px">关联 Spec</th>

            </tr>

          </thead>

          <tbody>

            ${act.components.map(c => {

              const isNoSpec = c.specs.length === 0;

              const isCovered = !isNoSpec && c.specs.some(s => checkedSpecs.has(s));

              const rowClass = isNoSpec ? 'no-spec' : (isCovered ? 'covered' : 'uncovered');

              const badge = isNoSpec ? '<span class="status-badge no-spec">无Spec</span>'

                : isCovered ? '<span class="status-badge covered">已覆盖</span>'

                : '<span class="status-badge uncovered">未覆盖</span>';

              const tags = c.specs.length > 0

                ? `<div class="spec-tags">${c.specs.map(s => `<span class="spec-tag ${checkedSpecs.has(s) ? 'active' : ''}">${s}</span>`).join('')}</div>`

                : '<span style="color:#F57F17;font-size:11px">外部/平台差异</span>';

              return `<tr class="${rowClass}">

                <td>${badge}</td>

                <td style="font-family:monospace;font-size:12px">${c.id}</td>

                <td style="font-size:12px">${c.ui}</td>

                <td>${c.desc}</td>

                <td style="font-size:12px">${c.target}</td>

                <td>${tags}</td>

              </tr>`;

            }).join('')}

          </tbody>

        </table>

      </div>

    </div>`;

  }).join('');

}



function updateGlobalStats() {

  let totalCoverable = 0, totalCovered = 0, totalAll = 0, totalNoSpec = 0;

  let actFullyCovered = 0;



  ACTIVITIES.forEach(act => {

    const stats = getActivityStats(act);

    totalAll += stats.total;

    totalCoverable += stats.coverable;

    totalCovered += stats.covered;

    totalNoSpec += stats.noSpec;

    if (stats.covered > 0) actFullyCovered++;

  });



  const globalPct = totalCoverable > 0 ? Math.round(totalCovered / totalCoverable * 100) : 0;

  document.getElementById('globalPct').textContent = globalPct + '%';

  document.getElementById('globalDetail').textContent = `${totalCovered} / ${totalCoverable} 功能点`;



  const specPct = SPECS.length > 0 ? Math.round(checkedSpecs.size / SPECS.length * 100) : 0;

  document.getElementById('specPct').textContent = specPct + '%';

  document.getElementById('specDetail').textContent = `${checkedSpecs.size} / ${SPECS.length} Spec`;



  const actPct = ACTIVITIES.length > 0 ? Math.round(actFullyCovered / ACTIVITIES.length * 100) : 0;

  document.getElementById('actPct').textContent = actPct + '%';

  document.getElementById('actDetail').textContent = `${actFullyCovered} / ${ACTIVITIES.length} Activity`;

}



function toggleSpec(id, checked) {

  if (checked) checkedSpecs.add(id); else checkedSpecs.delete(id);

  saveState();

  renderAll();

}



function selectAll() {

  SPECS.forEach(s => checkedSpecs.add(s.id));

  saveState();

  renderAll();

}



function deselectAll() {

  checkedSpecs.clear();

  saveState();

  renderAll();

}



let openActivities = new Set();

function toggleActivity(i) {

  const body = document.getElementById('body-' + i);

  const chev = document.getElementById('chev-' + i);

  if (openActivities.has(i)) {

    openActivities.delete(i);

    body.classList.remove('open');

    chev.classList.remove('open');

  } else {

    openActivities.add(i);

    body.classList.add('open');

    chev.classList.add('open');

  }

}



function renderAll() {

  renderSpecs();

  renderActivities();

  updateGlobalStats();

  // Restore open states

  openActivities.forEach(i => {

    const body = document.getElementById('body-' + i);

    const chev = document.getElementById('chev-' + i);

    if (body) { body.classList.add('open'); chev.classList.add('open'); }

  });

}



// Persist state in localStorage

function saveState() {

  try { localStorage.setItem('sg_checked_specs_v2', JSON.stringify([...checkedSpecs])); } catch(e) {}

}

function loadState() {

  try {

    const saved = localStorage.getItem('sg_checked_specs_v2');

    if (saved) { JSON.parse(saved).forEach(s => checkedSpecs.add(s)); }

  } catch(e) {}

}



function exportMarkdown() {

  let totalCoverable = 0, totalCovered = 0, totalNoSpec = 0;

  ACTIVITIES.forEach(act => {

    const s = getActivityStats(act);

    totalCoverable += s.coverable;

    totalCovered += s.covered;

    totalNoSpec += s.noSpec;

  });

  const globalPct = totalCoverable > 0 ? Math.round(totalCovered / totalCoverable * 100) : 0;

  const checkedList = SPECS.filter(s => checkedSpecs.has(s.id)).map(s => s.id + ' ' + s.name);



  let md = `# SimpleGallery Android \u2192 HarmonyOS \u529F\u80FD\u8986\u76D6\u6E05\u5355\n\n`;

  md += `> \u5BFC\u51FA\u65F6\u95F4\uFF1A${new Date().toLocaleString('zh-CN')}\n\n`;

  md += `**\u5DF2\u5B8C\u6210 Spec (${checkedSpecs.size}/${SPECS.length})\uFF1A** ${checkedList.length > 0 ? checkedList.join('\u3001') : '\u65E0'}\n\n`;

  md += `**\u603B\u4F53\u8986\u76D6\u7387\uFF1A${globalPct}%** \uFF08${totalCovered}/${totalCoverable} \u53EF\u8986\u76D6\u529F\u80FD\u70B9\uFF0C${totalNoSpec} \u4E2A\u65E0\u5BF9\u5E94Spec\u529F\u80FD\u70B9\uFF09\n\n`;



  md += `| \u9875\u9762 (Activity) | \u7EC4\u4EF6 / \u529F\u80FD\u70B9 | \u8986\u76D6\u72B6\u6001 |\n`;

  md += `|---|---|---|\n`;



  ACTIVITIES.forEach(act => {

    const stats = getActivityStats(act);

    const pct = stats.coverable > 0 ? Math.round(stats.covered / stats.coverable * 100) : (stats.total === stats.noSpec ? -1 : 0);

    const pctStr = pct === -1 ? 'N/A' : pct + '%';

    let first = true;

    act.components.forEach(c => {

      const isNoSpec = c.specs.length === 0;

      const isCovered = !isNoSpec && c.specs.some(s => checkedSpecs.has(s));

      const status = isNoSpec ? 'n/a' : (isCovered ? 'yes' : 'no');

      const specStr = c.specs.length > 0 ? ` [${c.specs.join(', ')}]` : '';

      const actCell = first ? `**${act.name}** (${pctStr})` : '';

      md += `| ${actCell} | \`${c.id}\` ${c.desc}${specStr} | ${status} |\n`;

      first = false;

    });

  });



  const blob = new Blob([md], { type: 'text/markdown;charset=utf-8' });

  const url = URL.createObjectURL(blob);

  const a = document.createElement('a');

  a.href = url;

  a.download = `coverage_report_${new Date().toISOString().slice(0, 10)}.md`;

  a.click();

  URL.revokeObjectURL(url);

}



loadState();

renderAll();

</script>

</body>

</html>