{"id":26151,"date":"2025-09-01T04:59:26","date_gmt":"2025-08-31T19:59:26","guid":{"rendered":"http:\/\/www.tyosuke20xx.com\/blog\/?p=26151"},"modified":"2025-09-01T04:59:27","modified_gmt":"2025-08-31T19:59:27","slug":"xlogpro-html%e3%83%84%e3%82%a4%e3%83%bc%e3%83%88%e3%81%be%e3%81%a8%e3%82%81%e3%82%b5%e3%82%a4%e3%83%88","status":"publish","type":"post","link":"http:\/\/www.tyosuke20xx.com\/blog\/?p=26151","title":{"rendered":"XLogpro.html(\u30c4\u30a4\u30fc\u30c8\u307e\u3068\u3081\u30b5\u30a4\u30c8)"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html lang=\"ja\" data-theme=\"light\" style=\"--cols:3; --card-h:640px; --accent:#2563eb\">\n&lt;head>\n  &lt;meta charset=\"UTF-8\" \/>\n  &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/>\n  &lt;title>Xlog Pro \u2014 HTML\u3060\u3051\u3067\u52d5\u304f\u81ea\u52d5\u30c4\u30a4\u30fc\u30c8\u307e\u3068\u3081&lt;\/title>\n  &lt;link rel=\"preconnect\" href=\"https:\/\/platform.twitter.com\" crossorigin>\n  &lt;link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.5.0\/css\/all.min.css\"\/>\n  &lt;meta name=\"description\" content=\"HTML\u3060\u3051\uff0fAPI\u30ad\u30fc\u4e0d\u8981\u306eX\uff08Twitter\uff09\u307e\u3068\u3081\u30dc\u30fc\u30c9\u3002\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u30fb\u30cf\u30c3\u30b7\u30e5\u30bf\u30b0\u30fb\u691c\u7d22\u30fb\u30ea\u30b9\u30c8\u3092\u597d\u304d\u306a\u5217\u3067\u914d\u7f6e\u3057\u3001JSON\/HTML\u66f8\u304d\u51fa\u3057\u3084\u624b\u52d5\u30e9\u30f3\u30ad\u30f3\u30b0\u3001\u30dc\u30fc\u30c9\u5207\u66ff\u306b\u5bfe\u5fdc\u3002\">\n  &lt;style>\n    :root{\n      --bg: #0b0e14; --panel:#111827; --muted:#9aa4b2; --text:#e5e7eb; --border:#1f2937; --chip:#141a23; --card:#0f172a; --btn:#1f2937; --btn-text:#e5e7eb; --link:#60a5fa;\n    }\n    &#91;data-theme=\"light\"]{ --bg:#f8fafc; --panel:#ffffff; --muted:#64748b; --text:#0f172a; --border:#e2e8f0; --chip:#f1f5f9; --card:#ffffff; --btn:#0f172a; --btn-text:#ffffff; --link:#1d9bf0; }\n    *{box-sizing:border-box}\n    body{margin:0;background:var(--bg);color:var(--text);font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,\"Apple Color Emoji\",\"Segoe UI Emoji\"}\n    header{position:sticky;top:0;z-index:10;background:var(--panel);border-bottom:1px solid var(--border)}\n    .wrap{max-width:1280px;margin:0 auto;padding:12px 16px}\n    .row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}\n    .brand{display:flex;gap:10px;align-items:center;font-weight:800}\n    .brand i{color:var(--accent)}\n    .muted{color:var(--muted)}\n    .pill{display:inline-flex;gap:8px;align-items:center;background:var(--chip);border:1px solid var(--border);border-radius:999px;padding:6px 10px}\n    .input, select, textarea{background:transparent;border:1px solid var(--border);border-radius:10px;padding:8px 10px;color:var(--text)}\n    textarea{min-height:88px;width:100%;}\n    input&#91;type=\"text\"].input{min-width:220px}\n    button{cursor:pointer;border:none}\n    .btn{background:var(--btn);color:var(--btn-text);padding:9px 12px;border-radius:12px}\n    .btn.secondary{background:transparent;color:var(--text);border:1px solid var(--border)}\n    .btn.ghost{background:transparent;color:var(--text)}\n    .btn.badge{padding:6px 10px;border-radius:999px}\n    .grid{display:grid;grid-template-columns:320px 1fr;gap:16px}\n    @media (max-width:1080px){.grid{grid-template-columns:1fr}}\n    aside{background:var(--panel);border:1px solid var(--border);border-radius:16px;padding:14px;position:sticky;top:72px;height:max-content}\n    h2{margin:6px 0 12px 0;font-size:18px}\n    .list{display:flex;flex-direction:column;gap:12px}\n    .card{background:var(--card);border:1px solid var(--border);border-radius:16px;overflow:hidden}\n    .card .head{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--border)}\n    .card .head .title{display:flex;gap:8px;align-items:center;font-weight:700}\n    .card .body{padding:0;min-height:var(--card-h)}\n    .sources{display:flex;flex-wrap:wrap;gap:8px}\n    .chip{background:var(--chip);border:1px solid var(--border);border-radius:999px;padding:6px 10px;display:flex;gap:8px;align-items:center}\n    .chip b{color:var(--accent)}\n    .columns{display:grid;grid-template-columns:repeat(var(--cols),1fr);gap:16px}\n    @media (max-width:1200px){:root{--cols:2}}\n    @media (max-width:860px){:root{--cols:1}}\n    .drag{cursor:grab}\n    .toolbar{display:flex;gap:8px;flex-wrap:wrap}\n    .footer{padding:24px 16px;color:var(--muted);text-align:center}\n    .kbd{font-family:ui-monospace, Menlo, Monaco, Consolas; background:var(--chip); border:1px solid var(--border); padding:2px 6px; border-radius:6px}\n    .danger{color:#ef4444}\n    .accent{color:var(--accent)}\n    .section{background:var(--panel);border:1px solid var(--border);border-radius:16px;padding:14px}\n    .help{font-size:13px;color:var(--muted)}\n    .label{font-size:12px;color:var(--muted)}\n    .tiny{font-size:12px}\n    .row-wrap{display:flex;gap:8px;flex-wrap:wrap;align-items:center}\n    .w-100{width:100%}\n    .space{height:8px}\n  &lt;\/style>\n&lt;\/head>\n&lt;body>\n  &lt;header>\n    &lt;div class=\"wrap row\">\n      &lt;div class=\"brand\">&lt;i class=\"fa-solid fa-wave-square\">&lt;\/i> Xlog &lt;span class=\"muted\">Pro&lt;\/span>&lt;\/div>\n      &lt;div class=\"pill\">\n        &lt;i class=\"fa-solid fa-diagram-project\">&lt;\/i>\n        &lt;select id=\"boardSelect\" title=\"\u30dc\u30fc\u30c9\u5207\u66ff\">&lt;\/select>\n        &lt;button id=\"boardNew\" class=\"btn badge secondary\" title=\"\u65b0\u898f\u30dc\u30fc\u30c9\">&lt;i class=\"fa-solid fa-plus\">&lt;\/i>&lt;\/button>\n        &lt;button id=\"boardRename\" class=\"btn badge secondary\" title=\"\u540d\u524d\u5909\u66f4\">&lt;i class=\"fa-solid fa-pen\">&lt;\/i>&lt;\/button>\n        &lt;button id=\"boardDelete\" class=\"btn badge secondary danger\" title=\"\u524a\u9664\">&lt;i class=\"fa-regular fa-trash-can\">&lt;\/i>&lt;\/button>\n      &lt;\/div>\n      &lt;div class=\"pill\" title=\"\u30c6\u30fc\u30de\u5207\u66ff\">&lt;i class=\"fa-solid fa-circle-half-stroke\">&lt;\/i>\n        &lt;label class=\"row-wrap\">&lt;input id=\"themeToggle\" type=\"checkbox\" \/> \u30c0\u30fc\u30af&lt;\/label>\n      &lt;\/div>\n      &lt;div class=\"pill\" title=\"\u30a2\u30af\u30bb\u30f3\u30c8\u30ab\u30e9\u30fc\">\n        &lt;i class=\"fa-solid fa-palette\">&lt;\/i>\n        &lt;input id=\"accentPicker\" type=\"color\" value=\"#2563eb\" \/>\n      &lt;\/div>\n      &lt;div class=\"pill\" title=\"\u5217\u6570\">&lt;i class=\"fa-solid fa-table-columns\">&lt;\/i>\n        &lt;input id=\"colsRange\" type=\"range\" min=\"1\" max=\"4\" step=\"1\" value=\"3\"\/>\n        &lt;span id=\"colsVal\" class=\"tiny\">&lt;\/span>\n      &lt;\/div>\n      &lt;div class=\"pill\" title=\"\u30ab\u30fc\u30c9\u9ad8\u3055\">&lt;i class=\"fa-solid fa-up-down\">&lt;\/i>\n        &lt;input id=\"heightRange\" type=\"range\" min=\"360\" max=\"1200\" step=\"40\" value=\"640\"\/>\n        &lt;span id=\"heightVal\" class=\"tiny\">&lt;\/span>\n      &lt;\/div>\n      &lt;div class=\"pill\" title=\"\u81ea\u52d5\u518d\u8aad\u307f\u8fbc\u307f\">\n        &lt;label class=\"row-wrap\">&lt;input id=\"autoRefreshToggle\" type=\"checkbox\"\/> \u81ea\u52d5&lt;\/label>\n        &lt;select id=\"refreshMinutes\">\n          &lt;option value=\"3\">3\u5206&lt;\/option>\n          &lt;option value=\"5\" selected>5\u5206&lt;\/option>\n          &lt;option value=\"10\">10\u5206&lt;\/option>\n          &lt;option value=\"30\">30\u5206&lt;\/option>\n        &lt;\/select>\n      &lt;\/div>\n      &lt;div class=\"pill help tiny\">\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8: &lt;span class=\"kbd\">N&lt;\/span> \u8ffd\u52a0 \/ &lt;span class=\"kbd\">R&lt;\/span> \u518d\u63cf\u753b \/ &lt;span class=\"kbd\">G&lt;\/span> \u30b0\u30ea\u30c3\u30c9- \/ &lt;span class=\"kbd\">H&lt;\/span> \u9ad8\u3055-&lt;\/div>\n    &lt;\/div>\n  &lt;\/header>\n\n  &lt;main class=\"wrap grid\">\n    &lt;aside>\n      &lt;div class=\"list\">\n        &lt;div class=\"section\">\n          &lt;h2>\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0&lt;\/h2>\n          &lt;div class=\"toolbar row-wrap\">\n            &lt;select id=\"sourceType\">\n              &lt;option value=\"profile\">\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb&lt;\/option>\n              &lt;option value=\"hashtag\">\u30cf\u30c3\u30b7\u30e5\u30bf\u30b0&lt;\/option>\n              &lt;option value=\"search\">\u691c\u7d22\u30ad\u30fc\u30ef\u30fc\u30c9&lt;\/option>\n              &lt;option value=\"list\">\u30ea\u30b9\u30c8URL&lt;\/option>\n            &lt;\/select>\n            &lt;input id=\"sourceValue\" class=\"input\" type=\"text\" placeholder=\"@username \/ #tag \/ \u30ad\u30fc\u30ef\u30fc\u30c9 \/ \u30ea\u30b9\u30c8URL\" \/>\n            &lt;input id=\"sourceLabel\" class=\"input\" type=\"text\" placeholder=\"\u8868\u793a\u540d\uff08\u4efb\u610f\uff09\" \/>\n            &lt;button id=\"addBtn\" class=\"btn\">&lt;i class=\"fa-solid fa-plus\">&lt;\/i> \u8ffd\u52a0&lt;\/button>\n          &lt;\/div>\n          &lt;div class=\"space\">&lt;\/div>\n          &lt;label class=\"label\">\u307e\u3068\u3081\u3066\u8ffd\u52a0\uff08\u6539\u884c\uff0f\u30ab\u30f3\u30de\u533a\u5207\u308aOK\uff09&lt;\/label>\n          &lt;textarea id=\"bulkArea\" placeholder=\"@OpenAI, #UnrealEngine, Unity URP, https:\/\/twitter.com\/i\/lists\/123...\\n@EpicGames\">&lt;\/textarea>\n          &lt;div class=\"row-wrap\">\n            &lt;button id=\"bulkAdd\" class=\"btn secondary\">&lt;i class=\"fa-solid fa-download\">&lt;\/i> \u53d6\u308a\u8fbc\u307f&lt;\/button>\n            &lt;button id=\"bulkClear\" class=\"btn ghost\">&lt;i class=\"fa-solid fa-eraser\">&lt;\/i> \u30af\u30ea\u30a2&lt;\/button>\n          &lt;\/div>\n          &lt;p class=\"help\" style=\"margin-top:8px\">\u5f62\u5f0f\u306f\u81ea\u52d5\u5224\u5b9a\uff1a&lt;span class=\"kbd\">@id&lt;\/span> \u2192 \u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u3001&lt;span class=\"kbd\">#tag&lt;\/span> \u2192 \u30cf\u30c3\u30b7\u30e5\u30bf\u30b0\u3001&lt;span class=\"kbd\">twitter.com\/i\/lists&lt;\/span> \u2192 \u30ea\u30b9\u30c8\u3001\u305d\u308c\u4ee5\u5916\u306f\u691c\u7d22\u3002&lt;\/p>\n          &lt;div class=\"space\">&lt;\/div>\n          &lt;div class=\"row-wrap help tiny\">\u30af\u30a4\u30c3\u30af\u8ffd\u52a0\uff1a&lt;\/div>\n          &lt;div class=\"row-wrap\">\n            &lt;button class=\"btn badge secondary quick\" data-type=\"hashtag\" data-val=\"#UnrealEngine\">#UnrealEngine&lt;\/button>\n            &lt;button class=\"btn badge secondary quick\" data-type=\"hashtag\" data-val=\"#Unity3D\">#Unity3D&lt;\/button>\n            &lt;button class=\"btn badge secondary quick\" data-type=\"search\" data-val=\"VRM OR \\\"Meta Quest\\\"\">VR\/Quest&lt;\/button>\n            &lt;button class=\"btn badge secondary quick\" data-type=\"profile\" data-val=\"@OpenAI\">@OpenAI&lt;\/button>\n          &lt;\/div>\n        &lt;\/div>\n\n        &lt;div class=\"section\">\n          &lt;h2>\u4fdd\u5b58\u30fb\u66f8\u304d\u51fa\u3057&lt;\/h2>\n          &lt;div class=\"toolbar row-wrap\">\n            &lt;button id=\"exportBtn\" class=\"btn secondary\">&lt;i class=\"fa-solid fa-file-export\">&lt;\/i> JSON&lt;\/button>\n            &lt;label class=\"btn secondary\" for=\"importFile\">&lt;i class=\"fa-solid fa-file-import\">&lt;\/i> JSON\u8aad\u8fbc&lt;\/label>\n            &lt;input id=\"importFile\" type=\"file\" accept=\"application\/json\" hidden \/>\n            &lt;button id=\"exportHtmlBtn\" class=\"btn\">&lt;i class=\"fa-regular fa-file-code\">&lt;\/i> \u5358\u4e00HTML&lt;\/button>\n            &lt;button id=\"clearBtn\" class=\"btn ghost danger\">&lt;i class=\"fa-regular fa-trash-can\">&lt;\/i> \u3059\u3079\u3066\u524a\u9664&lt;\/button>\n          &lt;\/div>\n          &lt;p class=\"help\">\u5358\u4e00HTML: \u3044\u307e\u306e\u30ec\u30a4\u30a2\u30a6\u30c8\u3068\u8a2d\u5b9a\u3092\u57cb\u3081\u8fbc\u3093\u3060\u81ea\u7acbHTML\u3092\u751f\u6210\u3057\u307e\u3059\u3002&lt;\/p>\n        &lt;\/div>\n\n        &lt;div class=\"section\">\n          &lt;h2>\u624b\u52d5\u30e9\u30f3\u30ad\u30f3\u30b0&lt;\/h2>\n          &lt;div class=\"toolbar row-wrap\">\n            &lt;input id=\"tweetUrl\" class=\"input\" type=\"text\" placeholder=\"\u30c4\u30a4\u30fc\u30c8URL\u3092\u8cbc\u308a\u4ed8\u3051\" \/>\n            &lt;button id=\"addTweetBtn\" class=\"btn\">&lt;i class=\"fa-brands fa-x-twitter\">&lt;\/i> \u8ffd\u52a0&lt;\/button>\n          &lt;\/div>\n          &lt;label class=\"label\">\u30e1\u30e2\uff08\u4efb\u610f\u30fb\u6b21\u56de\u4ee5\u964d\u3082\u4fdd\u6301\uff09&lt;\/label>\n          &lt;textarea id=\"tweetNote\" placeholder=\"\u3053\u306e\u30c4\u30a4\u30fc\u30c8\u306e\u8981\u70b9\u3084\u30bf\u30b0\uff08\u4f8b: #UE5 #VRM\uff09\">&lt;\/textarea>\n          &lt;p class=\"help\">\u203bHTML\u306e\u307f\u306e\u5236\u7d04\u3067\u81ea\u52d5\u96c6\u8a08\u306f\u4e0d\u53ef\u3002URL\u3092\u30ab\u30fc\u30c9\u5316\u3057\u3066\u624b\u52d5\u3067\u9806\u5e8f\u3092\u6c7a\u3081\u3089\u308c\u307e\u3059\u3002&lt;\/p>\n        &lt;\/div>\n\n        &lt;div class=\"section\">\n          &lt;h2>RSS\u751f\u6210\uff08\u30e9\u30f3\u30ad\u30f3\u30b0\u2192RSS\uff09&lt;\/h2>\n          &lt;div class=\"toolbar row-wrap\">\n            &lt;input id=\"rssTitle\" class=\"input\" type=\"text\" placeholder=\"RSS\u30bf\u30a4\u30c8\u30eb\uff08\u4f8b: Xlog\u30e9\u30f3\u30ad\u30f3\u30b0\uff09\"\/>\n            &lt;button id=\"rssExport\" class=\"btn secondary\">&lt;i class=\"fa-solid fa-rss\">&lt;\/i> RSS\u3092\u66f8\u304d\u51fa\u3057&lt;\/button>\n          &lt;\/div>\n          &lt;p class=\"help\">\u30e9\u30f3\u30ad\u30f3\u30b0\u306b\u767b\u9332\u3057\u305f\u30c4\u30a4\u30fc\u30c8URL\u304b\u3089\u7c21\u6613RSS\uff08XML\uff09\u3092\u751f\u6210\u3057\u3001\u30d5\u30a1\u30a4\u30eb\u3068\u3057\u3066\u4fdd\u5b58\u3057\u307e\u3059\u3002&lt;\/p>\n        &lt;\/div>\n\n        &lt;div class=\"section\">\n          &lt;h2>\u30d8\u30eb\u30d7&lt;\/h2>\n          &lt;div class=\"help\">\n            \u30fb\u5217\u306e\u4e26\u3079\u66ff\u3048\u306f\u30ab\u30fc\u30c9\u306e &lt;span class=\"kbd\">\u22ef&lt;\/span> \u30a2\u30a4\u30b3\u30f3\u3092\u30c9\u30e9\u30c3\u30b0\u3002&lt;br>\n            \u30fb&lt;span class=\"kbd\">R&lt;\/span> \u3067\u5168\u30ab\u30e9\u30e0\u3092\u518d\u63cf\u753b\u3002&lt;br>\n            \u30fbURL\u30cf\u30c3\u30b7\u30e5 &lt;span class=\"kbd\">#data=&lt;\/span> \u306b\u8a2d\u5b9a\u3092Base64\u3067\u57cb\u3081\u8fbc\u3093\u3067\u5171\u6709\u53ef\u80fd\uff08\u30e1\u30cb\u30e5\u30fc\u304b\u3089\u81ea\u52d5\u751f\u6210\u4e88\u5b9a\uff09\u3002\n          &lt;\/div>\n        &lt;\/div>\n      &lt;\/div>\n    &lt;\/aside>\n\n    &lt;section>\n      &lt;div class=\"card\" style=\"margin-bottom:16px\">\n        &lt;div class=\"head\">\n          &lt;div class=\"title\">&lt;i class=\"fa-solid fa-layer-group drag\">&lt;\/i> \u30de\u30a4\u307e\u3068\u3081 &lt;span class=\"muted tiny\" id=\"boardInfo\">&lt;\/span>&lt;\/div>\n          &lt;div class=\"sources\" id=\"activeChips\">&lt;\/div>\n        &lt;\/div>\n        &lt;div class=\"body\" style=\"padding:14px\">\n          &lt;div id=\"columns\" class=\"columns\">&lt;\/div>\n        &lt;\/div>\n      &lt;\/div>\n\n      &lt;div class=\"card\">\n        &lt;div class=\"head\">\n          &lt;div class=\"title\">&lt;i class=\"fa-regular fa-star\">&lt;\/i> \u624b\u52d5\u30e9\u30f3\u30ad\u30f3\u30b0&lt;\/div>\n          &lt;div class=\"help\">\u30c9\u30e9\u30c3\u30b0\u3067\u9806\u5e8f\u5909\u66f4\uff0f\ud83d\uddd1\u3067\u524a\u9664\uff0f\u270e\u3067\u30e1\u30e2\u7de8\u96c6&lt;\/div>\n        &lt;\/div>\n        &lt;div class=\"body\" style=\"padding:14px\">\n          &lt;div id=\"ranking\" class=\"columns\">&lt;\/div>\n        &lt;\/div>\n      &lt;\/div>\n\n      &lt;div class=\"footer\">Xlog Pro v2 \u2014 HTML Only \/ Embedded Timelines. No API keys. &lt;span class=\"muted\">Made for you.&lt;\/span>&lt;\/div>\n    &lt;\/section>\n  &lt;\/main>\n\n  &lt;script async src=\"https:\/\/platform.twitter.com\/widgets.js\">&lt;\/script>\n  &lt;script>\n    \/\/ ========== \u57fa\u672c\u30e6\u30fc\u30c6\u30a3\u30ea\u30c6\u30a3 ==========\n    const $ = (s, d=document)=>d.querySelector(s);\n    const $$ = (s, d=document)=>Array.from(d.querySelectorAll(s));\n\n    const defaultBoard = ()=>({sources:&#91;], tweets:&#91;]});\n    const defaultState = ()=>({\n      version:2,\n      dark:false,\n      accent:'#2563eb',\n      autoRefresh:false,\n      minutes:5,\n      columns:3,\n      cardHeight:640,\n      boards:{'Default': defaultBoard()},\n      activeBoard:'Default'\n    });\n\n    const store = {\n      key: 'xlog-pro-v2',\n      load(){\n        try{ return JSON.parse(localStorage.getItem(this.key)) || defaultState(); }\n        catch(e){ return defaultState(); }\n      },\n      save(v){ localStorage.setItem(this.key, JSON.stringify(v)); }\n    };\n\n    function migrate(s){\n      const base = defaultState();\n      if (!s || typeof s !== 'object') return base;\n      \/\/ v1\u4e92\u63db\uff08sources\/tweets\u76f4\u4e0b \u2192 boards.Default\uff09\n      if (s.sources || s.tweets){\n        base.boards.Default.sources = s.sources||&#91;];\n        base.boards.Default.tweets = s.tweets||&#91;];\n      }\n      \/\/ \u65e2\u5b58\u30ad\u30fc\u4e0a\u66f8\u304d\n      for (const k of &#91;'dark','accent','autoRefresh','minutes','columns','cardHeight','boards','activeBoard']){\n        if (k in s) base&#91;k]=s&#91;k];\n      }\n      return base;\n    }\n\n    \/\/ \u30cf\u30c3\u30b7\u30e5 (#data=BASE64) \u304b\u3089\u8aad\u307f\u8fbc\u307f\n    function loadFromHash(){\n      const h = location.hash || '';\n      if (!h.startsWith('#data=')) return null;\n      try{\n        const b64 = decodeURIComponent(h.slice(6));\n        const json = atob(b64);\n        return JSON.parse(json);\n      }catch(e){ return null; }\n    }\n\n    let embedded = (typeof window.__XLOG_INITIAL_STATE__!== 'undefined') ? window.__XLOG_INITIAL_STATE__ : null;\n    if (!embedded){\n      const el = document.getElementById('xlog-init');\n      if (el) { try{ embedded = JSON.parse(el.textContent); }catch(_e){} }\n    }\n\n    let state = migrate( embedded || loadFromHash() || store.load() );\n\n    \/\/ ========== \u30c6\u30fc\u30de\/\u30a2\u30af\u30bb\u30f3\u30c8\/\u30ec\u30a4\u30a2\u30a6\u30c8\u9069\u7528 ==========\n    function applySkin(){\n      document.documentElement.setAttribute('data-theme', state.dark ? 'dark' : 'light');\n      document.documentElement.style.setProperty('--cols', state.columns);\n      document.documentElement.style.setProperty('--card-h', state.cardHeight+'px');\n      document.documentElement.style.setProperty('--accent', state.accent || '#2563eb');\n      $('#themeToggle').checked = !!state.dark;\n      $('#colsRange').value = String(state.columns);\n      $('#colsVal').textContent = state.columns+'\u5217';\n      $('#heightRange').value = String(state.cardHeight);\n      $('#heightVal').textContent = state.cardHeight+'px';\n      $('#accentPicker').value = state.accent || '#2563eb';\n    }\n\n    \/\/ ========== X\u57cb\u3081\u8fbc\u307f ==========\n    function waitTwttr(){\n      return new Promise(res=>{\n        if (window.twttr &amp;&amp; twttr.widgets) return res();\n        const timer = setInterval(()=>{ if(window.twttr &amp;&amp; twttr.widgets){ clearInterval(timer); res(); } }, 200);\n      });\n    }\n\n    function timelineOptions(){\n      return {\n        height: state.cardHeight,\n        theme: state.dark ? 'dark' : 'light',\n        chrome: 'nofooter noborders transparent',\n        linkColor: getComputedStyle(document.documentElement).getPropertyValue('--link').trim() || '#1d9bf0'\n      };\n    }\n\n    async function createTimeline(el, src){\n      await waitTwttr();\n      const opts = timelineOptions();\n      const t = (src.type||'profile');\n      if (t==='profile'){\n        const screenName = src.value.replace(\/^@\/,'');\n        return twttr.widgets.createTimeline({ sourceType:'profile', screenName }, el, opts);\n      }\n      if (t==='list'){\n        return twttr.widgets.createTimeline({ sourceType:'url', url: src.value }, el, opts);\n      }\n      if (t==='hashtag'){\n        const tag = src.value.replace(\/^#\/,'');\n        const url = `https:\/\/twitter.com\/hashtag\/${encodeURIComponent(tag)}?f=live`;\n        return twttr.widgets.createTimeline({ sourceType:'url', url }, el, opts);\n      }\n      if (t==='search'){\n        const url = `https:\/\/twitter.com\/search?q=${encodeURIComponent(src.value)}&amp;f=live`;\n        return twttr.widgets.createTimeline({ sourceType:'url', url }, el, opts);\n      }\n    }\n\n    \/\/ ========== \u73fe\u5728\u30dc\u30fc\u30c9\u306e\u53c2\u7167 ==========\n    function board(){ return state.boards&#91;state.activeBoard] || (state.boards&#91;state.activeBoard]=defaultBoard()); }\n\n    \/\/ ========== \u63cf\u753b ==========\n    function chipNode(src, idx){\n      const chip = document.createElement('span');\n      chip.className='chip';\n      const kind = {profile:'@',hashtag:'#',search:'\u691c\u7d22:',list:'\u30ea\u30b9\u30c8'}&#91;src.type] || '';\n      chip.innerHTML = `&lt;b>${kind}&lt;\/b> ${src.label || src.value} &lt;a class=\"muted\" href=\"${openUrl(src)}\" target=\"_blank\" title=\"X\u3067\u958b\u304f\">&lt;i class=\"fa-solid fa-arrow-up-right-from-square\">&lt;\/i>&lt;\/a> &lt;button title=\"\u524a\u9664\" data-del=\"${idx}\" class=\"muted\">&lt;i class=\"fa-solid fa-xmark\">&lt;\/i>&lt;\/button>`;\n      chip.querySelector('button').onclick = ()=>{ board().sources.splice(idx,1); store.save(state); renderAll(); };\n      return chip;\n    }\n\n    function openUrl(src){\n      if (src.type==='profile') return `https:\/\/twitter.com\/${src.value.replace(\/^@\/,'')}`;\n      if (src.type==='hashtag') return `https:\/\/twitter.com\/hashtag\/${src.value.replace(\/^#\/,'')}`;\n      if (src.type==='list') return src.value;\n      return `https:\/\/twitter.com\/search?q=${encodeURIComponent(src.value)}&amp;f=live`;\n    }\n\n    function columnCard(src, idx){\n      const card = document.createElement('div');\n      card.className='card';\n      card.draggable=true; card.dataset.idx=idx;\n      card.innerHTML = `\n        &lt;div class=\"head\">\n          &lt;div class=\"title\">&lt;i class=\"fa-solid fa-grip-vertical drag\">&lt;\/i> ${src.label || prettyLabel(src)}&lt;\/div>\n          &lt;div class=\"toolbar\">\n            &lt;a class=\"btn ghost\" href=\"${openUrl(src)}\" target=\"_blank\" title=\"X\u3067\u958b\u304f\">&lt;i class=\"fa-solid fa-arrow-up-right-from-square\">&lt;\/i>&lt;\/a>\n            &lt;button class=\"btn ghost\" title=\"\u518d\u8aad\u307f\u8fbc\u307f\" data-refresh=\"${idx}\">&lt;i class=\"fa-solid fa-rotate\">&lt;\/i>&lt;\/button>\n            &lt;button class=\"btn ghost danger\" title=\"\u524a\u9664\" data-remove=\"${idx}\">&lt;i class=\"fa-regular fa-trash-can\">&lt;\/i>&lt;\/button>\n          &lt;\/div>\n        &lt;\/div>\n        &lt;div class=\"body\">&lt;div class=\"embed\" style=\"min-height:120px\">&lt;\/div>&lt;\/div>`;\n\n      \/\/ DnD \u4e26\u3079\u66ff\u3048\n      card.addEventListener('dragstart', e=>{ e.dataTransfer.setData('text\/plain', idx); card.style.opacity='0.6'; });\n      card.addEventListener('dragend', ()=>{ card.style.opacity='1'; });\n      card.addEventListener('dragover', e=>{ e.preventDefault(); card.style.outline='2px dashed var(--accent)'; });\n      card.addEventListener('dragleave', ()=>{ card.style.outline='none'; });\n      card.addEventListener('drop', e=>{\n        e.preventDefault(); card.style.outline='none';\n        const from = +e.dataTransfer.getData('text\/plain');\n        const to = +card.dataset.idx;\n        if (from===to) return;\n        const arr = board().sources;\n        const &#91;moved] = arr.splice(from,1);\n        arr.splice(to,0,moved);\n        store.save(state); renderAll();\n      });\n\n      \/\/ \u64cd\u4f5c\n      card.querySelector('&#91;data-remove]')?.addEventListener('click', ()=>{ board().sources.splice(idx,1); store.save(state); renderAll(); });\n      card.querySelector('&#91;data-refresh]')?.addEventListener('click', ()=>{ mountTimeline(card, src); });\n      \/\/ \u521d\u56de\u63cf\u753b\n      mountTimeline(card, src);\n      return card;\n    }\n\n    function mountTimeline(card, src){\n      const holder = card.querySelector('.embed');\n      holder.innerHTML = '&lt;div style=\"padding:14px\" class=\"muted\">\u8aad\u307f\u8fbc\u307f\u4e2d\u2026&lt;\/div>';\n      createTimeline(holder, src).catch(()=>{\n        holder.innerHTML = '&lt;div style=\"padding:14px\" class=\"danger\">\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u5024\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002&lt;\/div>';\n      });\n    }\n\n    function prettyLabel(src){\n      if (src.type==='profile') return '@'+src.value.replace(\/^@\/,'');\n      if (src.type==='hashtag') return '#'+src.value.replace(\/^#\/,'');\n      if (src.type==='search') return '\u691c\u7d22: '+src.value;\n      if (src.type==='list') return '\u30ea\u30b9\u30c8';\n      return src.value;\n    }\n\n    function renderAll(){\n      \/\/ \u30dc\u30fc\u30c9\u60c5\u5831\n      const info = $('#boardInfo');\n      const b = board();\n      info.textContent = `\uff08${state.activeBoard}\uff5c${b.sources.length}\u5217 \/ ${b.tweets.length}\u4ef6\uff09`;\n\n      \/\/ \u30c1\u30c3\u30d7\n      const chips = $('#activeChips'); chips.innerHTML='';\n      b.sources.forEach((s,i)=> chips.appendChild(chipNode(s,i)) );\n      \/\/ \u30ab\u30e9\u30e0\n      const col = $('#columns'); col.innerHTML='';\n      b.sources.forEach((s,i)=> col.appendChild(columnCard(s,i)) );\n      \/\/ \u30e9\u30f3\u30ad\u30f3\u30b0\n      renderRanking();\n    }\n\n    \/\/ ========== \u30e9\u30f3\u30ad\u30f3\u30b0 ==========\n    function parseTweetId(url){ const m = (url||'').match(\/status\\\/(\\d{5,})\/); return m? m&#91;1] : null; }\n    function tweetUrlFromId(id){ return `https:\/\/twitter.com\/i\/web\/status\/${id}`; }\n\n    async function addTweet(url, note){\n      const id = parseTweetId(url);\n      if (!id) return alert('\u30c4\u30a4\u30fc\u30c8URL\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093');\n      board().tweets.push({id, note: (note||'')});\n      store.save(state); renderRanking();\n    }\n\n    async function renderRanking(){\n      await waitTwttr();\n      const root = $('#ranking'); root.innerHTML='';\n      const arr = board().tweets;\n      arr.forEach((t, idx)=>{\n        const card = document.createElement('div'); card.className='card'; card.draggable=true; card.dataset.idx=idx;\n        card.innerHTML = `\n          &lt;div class=\"head\">\n            &lt;div class=\"title\">&lt;i class=\"fa-solid fa-grip-vertical drag\">&lt;\/i> \u30a8\u30f3\u30c8\u30ea #${idx+1}&lt;\/div>\n            &lt;div class=\"toolbar\">\n              &lt;button class=\"btn ghost\" data-edit=\"${idx}\" title=\"\u30e1\u30e2\u7de8\u96c6\">&lt;i class=\"fa-regular fa-pen-to-square\">&lt;\/i>&lt;\/button>\n              &lt;a class=\"btn ghost\" href=\"${tweetUrlFromId(t.id)}\" target=\"_blank\" title=\"X\u3067\u958b\u304f\">&lt;i class=\"fa-solid fa-arrow-up-right-from-square\">&lt;\/i>&lt;\/a>\n              &lt;button class=\"btn ghost danger\" title=\"\u524a\u9664\" data-del-rank=\"${idx}\">&lt;i class=\"fa-regular fa-trash-can\">&lt;\/i>&lt;\/button>\n            &lt;\/div>\n          &lt;\/div>\n          &lt;div class=\"body\">\n            &lt;div class=\"embed\">&lt;\/div>\n            &lt;div style=\"padding:10px 14px;border-top:1px solid var(--border)\" class=\"tiny\">&lt;span class=\"muted\">\u30e1\u30e2:&lt;\/span> &lt;span class=\"note\">${escapeHtml(t.note||'')}&lt;\/span>&lt;\/div>\n          &lt;\/div>`;\n\n        \/\/ \u30a4\u30d9\u30f3\u30c8\n        card.querySelector('&#91;data-del-rank]')?.addEventListener('click', ()=>{ arr.splice(idx,1); store.save(state); renderRanking(); });\n        card.querySelector('&#91;data-edit]')?.addEventListener('click', ()=>{\n          const newNote = prompt('\u30e1\u30e2\u3092\u7de8\u96c6', t.note||'');\n          if (newNote!==null){ t.note = newNote; store.save(state); renderRanking(); }\n        });\n\n        \/\/ DnD \u4e26\u3079\u66ff\u3048\n        card.addEventListener('dragstart', e=>{ e.dataTransfer.setData('text\/plain', 'rank:'+idx); card.style.opacity='0.6'; });\n        card.addEventListener('dragend', ()=>{ card.style.opacity='1'; });\n        card.addEventListener('dragover', e=>{ e.preventDefault(); card.style.outline='2px dashed var(--accent)'; });\n        card.addEventListener('dragleave', ()=>{ card.style.outline='none'; });\n        card.addEventListener('drop', e=>{\n          e.preventDefault(); card.style.outline='none';\n          const data = e.dataTransfer.getData('text\/plain'); if (!data.startsWith('rank:')) return;\n          const from = +data.split(':')&#91;1]; const to = +card.dataset.idx;\n          const &#91;moved] = arr.splice(from,1); arr.splice(to,0,moved);\n          store.save(state); renderRanking();\n        });\n\n        const holder = card.querySelector('.embed');\n        twttr.widgets.createTweet(t.id, holder, { theme: state.dark ? 'dark' : 'light' });\n        root.appendChild(card);\n      });\n    }\n\n    function escapeHtml(s){ return (s||'').replace(\/&#91;&amp;&lt;>\"']\/g, m=> ({'&amp;':'&amp;amp;','&lt;':'&amp;lt;','>':'&amp;gt;','\"':'&amp;quot;','\\'':'&amp;#39;'}&#91;m])); }\n\n    \/\/ ========== \u81ea\u52d5\u518d\u63cf\u753b ==========\n    let refreshTimer = null;\n    function applyAutoRefresh(){\n      if (refreshTimer) { clearInterval(refreshTimer); refreshTimer=null; }\n      if (state.autoRefresh){\n        const ms = Math.max(1, +state.minutes) * 60 * 1000;\n        refreshTimer = setInterval(()=>{\n          $$('#columns .card').forEach((card, i)=>{\n            const src = board().sources&#91;i]; if (src) mountTimeline(card, src);\n          });\n        }, ms);\n      }\n    }\n\n    \/\/ ========== \u30dc\u30fc\u30c9\u7ba1\u7406 ==========\n    function refreshBoardSelect(){\n      const sel = $('#boardSelect'); sel.innerHTML='';\n      Object.keys(state.boards).forEach(name=>{\n        const opt = document.createElement('option'); opt.value=name; opt.textContent=name; sel.appendChild(opt);\n      });\n      sel.value = state.activeBoard;\n    }\n\n    function addBoard(name){\n      if (!name) return;\n      if (state.boards&#91;name]) return alert('\u540c\u540d\u306e\u30dc\u30fc\u30c9\u304c\u5b58\u5728\u3057\u307e\u3059');\n      state.boards&#91;name] = defaultBoard(); state.activeBoard = name; store.save(state);\n      refreshBoardSelect(); renderAll();\n    }\n\n    function renameBoard(newName){\n      if (!newName) return;\n      if (state.boards&#91;newName]) return alert('\u540c\u540d\u306e\u30dc\u30fc\u30c9\u304c\u5b58\u5728\u3057\u307e\u3059');\n      const old = state.activeBoard;\n      state.boards&#91;newName] = state.boards&#91;old];\n      delete state.boards&#91;old];\n      state.activeBoard = newName; store.save(state);\n      refreshBoardSelect(); renderAll();\n    }\n\n    function deleteBoard(){\n      const names = Object.keys(state.boards);\n      if (names.length&lt;=1) return alert('\u6700\u5f8c\u306e\u30dc\u30fc\u30c9\u306f\u524a\u9664\u3067\u304d\u307e\u305b\u3093');\n      if (!confirm(`\u30dc\u30fc\u30c9\u300c${state.activeBoard}\u300d\u3092\u524a\u9664\u3057\u307e\u3059\u304b\uff1f`)) return;\n      delete state.boards&#91;state.activeBoard];\n      state.activeBoard = Object.keys(state.boards)&#91;0];\n      store.save(state); refreshBoardSelect(); renderAll();\n    }\n\n    \/\/ ========== \u5171\u6709\uff08URL\u30cf\u30c3\u30b7\u30e5\u751f\u6210\uff09 ==========\n    function exportHashUrl(){\n      const cloned = JSON.parse(JSON.stringify(state));\n      const json = JSON.stringify(cloned);\n      const b64 = btoa(json);\n      const url = location.origin + location.pathname + '#data=' + encodeURIComponent(b64);\n      return url;\n    }\n\n    \/\/ ========== \u5358\u4e00HTML\u51fa\u529b ==========\n    function download(filename, text){\n      const blob = new Blob(&#91;text], {type:'text\/html'});\n      const a = document.createElement('a'); a.href=URL.createObjectURL(blob); a.download=filename; a.click(); URL.revokeObjectURL(a.href);\n    }\n\n    function exportSingleHtml(){\n      \/\/ \u73fe\u5728\u306eHTML\u306b\u521d\u671f\u72b6\u614b\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u5dee\u3057\u8fbc\u3080\n      let html = document.documentElement.outerHTML;\n      const idx = html.indexOf('&lt;head>');\n      const inject = `&lt;head>\\n  &lt;script>window.__XLOG_INITIAL_STATE__=${JSON.stringify(state)}&lt;\\\/script>`;\n      if (idx>=0){ html = html.replace('&lt;head>', inject); }\n      download('xlog-pro.html', '&lt;!DOCTYPE html>\\n' + html);\n    }\n\n    \/\/ ========== RSS\u751f\u6210 ==========\n    function exportRss(){\n      const title = $('#rssTitle').value.trim() || 'Xlog Ranking';\n      const items = board().tweets.map(t=>({\n        title: (t.note||'Tweet '+t.id).replace(\/&#91;\\r\\n]+\/g,' ').slice(0,120),\n        link: tweetUrlFromId(t.id),\n        guid: t.id,\n        description: escapeHtml(t.note||''),\n        pubDate: new Date().toUTCString()\n      }));\n      const xml = `&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n&lt;rss version=\"2.0\">&lt;channel>\\n&lt;title>${escapeXml(title)}&lt;\/title>\\n&lt;link>${escapeXml(location.href)}&lt;\/link>\\n&lt;description>Generated by Xlog Pro&lt;\/description>\\n${items.map(i=>`&lt;item>&lt;title>${escapeXml(i.title)}&lt;\/title>&lt;link>${escapeXml(i.link)}&lt;\/link>&lt;guid isPermaLink=\\\"false\\\">${escapeXml(i.guid)}&lt;\/guid>&lt;description>${escapeXml(i.description)}&lt;\/description>&lt;pubDate>${i.pubDate}&lt;\/pubDate>&lt;\/item>`).join('')}\\n&lt;\/channel>&lt;\/rss>`;\n      const blob = new Blob(&#91;xml], {type:'application\/rss+xml'});\n      const a = document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='xlog-ranking.xml'; a.click(); URL.revokeObjectURL(a.href);\n    }\n\n    function escapeXml(s){ return (s||'').replace(\/&#91;&lt;>&amp;\\\"']\/g, m=> ({'&lt;':'&amp;lt;','>':'&amp;gt;','&amp;':'&amp;amp;','\\\"':'&amp;quot;','\\'':'&amp;apos;'}&#91;m])); }\n\n    \/\/ ========== \u5165\u529b\u30d8\u30eb\u30d1 ==========\n    function detectType(v){\n      if (\/^@\/.test(v)) return 'profile';\n      if (\/^#\/.test(v)) return 'hashtag';\n      if (\/twitter\\.com\\\/i\\\/lists\\\/\/.test(v)) return 'list';\n      return 'search';\n    }\n\n    function addSource(type, value, label){\n      const src = {type, value:value.trim(), label:(label||'').trim()};\n      board().sources.push(src); store.save(state); renderAll();\n    }\n\n    function bulkAddFromText(txt){\n      const parts = txt.split(\/&#91;\\n,]+\/).map(s=>s.trim()).filter(Boolean);\n      let count = 0;\n      for (const p of parts){ addSource(detectType(p), p, ''); count++; }\n      return count;\n    }\n\n    \/\/ ========== \u30ad\u30fc\u30a4\u30d9\u30f3\u30c8 ==========\n    function setupShortcuts(){\n      window.addEventListener('keydown', (e)=>{\n        if (&#91;'INPUT','TEXTAREA','SELECT'].includes(document.activeElement.tagName)) return;\n        if (e.key==='n' || e.key==='N'){ $('#sourceValue').focus(); }\n        if (e.key==='r' || e.key==='R'){ renderAll(); }\n        if (e.key==='g' || e.key==='G'){ state.columns=Math.max(1,state.columns-1); applySkin(); store.save(state); }\n        if (e.key==='h' || e.key==='H'){ state.cardHeight=Math.max(360,state.cardHeight-40); applySkin(); store.save(state); renderAll(); }\n      });\n    }\n\n    \/\/ ========== \u8a2d\u5b9a\u3068\u8d77\u52d5 ==========\n    window.addEventListener('DOMContentLoaded', ()=>{\n      \/\/ \u30b9\u30ad\u30f3\n      applySkin();\n\n      \/\/ \u30dc\u30fc\u30c9\u9078\u629e\n      refreshBoardSelect();\n      $('#boardSelect').addEventListener('change', (e)=>{ state.activeBoard = e.target.value; store.save(state); renderAll(); });\n      $('#boardNew').addEventListener('click', ()=>{ const name = prompt('\u65b0\u3057\u3044\u30dc\u30fc\u30c9\u540d','Board '+(Object.keys(state.boards).length+1)); addBoard(name); });\n      $('#boardRename').addEventListener('click', ()=>{ const name = prompt('\u65b0\u3057\u3044\u540d\u524d', state.activeBoard); if (name) renameBoard(name); });\n      $('#boardDelete').addEventListener('click', deleteBoard);\n\n      \/\/ \u30c6\u30fc\u30de\/\u30a2\u30af\u30bb\u30f3\u30c8\/\u30ec\u30a4\u30a2\u30a6\u30c8\n      $('#themeToggle').addEventListener('change', e=>{ state.dark = e.target.checked; store.save(state); applySkin(); renderAll(); });\n      $('#accentPicker').addEventListener('input', e=>{ state.accent = e.target.value; store.save(state); applySkin(); });\n      $('#colsRange').addEventListener('input', e=>{ state.columns = +e.target.value; store.save(state); applySkin(); });\n      $('#heightRange').addEventListener('input', e=>{ state.cardHeight = +e.target.value; store.save(state); applySkin(); renderAll(); });\n\n      \/\/ \u30bd\u30fc\u30b9\u8ffd\u52a0\n      $('#addBtn').addEventListener('click', ()=>{\n        const type = $('#sourceType').value;\n        const val = $('#sourceValue').value.trim();\n        const label = $('#sourceLabel').value.trim();\n        if (!val) return alert('\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044');\n        addSource(type, val, label);\n        $('#sourceValue').value=''; $('#sourceLabel').value='';\n      });\n      $$('.quick').forEach(btn=> btn.addEventListener('click', ()=> addSource(btn.dataset.type, btn.dataset.val, '')) );\n\n      \/\/ \u307e\u3068\u3081\u3066\u8ffd\u52a0\n      $('#bulkAdd').addEventListener('click', ()=>{ const n = bulkAddFromText($('#bulkArea').value); alert(n+'\u4ef6\u8ffd\u52a0\u3057\u307e\u3057\u305f'); $('#bulkArea').value=''; });\n      $('#bulkClear').addEventListener('click', ()=> $('#bulkArea').value='' );\n\n      \/\/ \u30e9\u30f3\u30ad\u30f3\u30b0\n      $('#addTweetBtn').addEventListener('click', ()=>{\n        const url = $('#tweetUrl').value.trim();\n        const note = $('#tweetNote').value.trim();\n        if (!url) return;\n        addTweet(url, note); $('#tweetUrl').value=''; $('#tweetNote').value='';\n      });\n\n      \/\/ \u8a2d\u5b9a\n      $('#autoRefreshToggle').checked = !!state.autoRefresh;\n      $('#refreshMinutes').value = String(state.minutes||5);\n      $('#autoRefreshToggle').addEventListener('change', e=>{ state.autoRefresh = e.target.checked; store.save(state); applyAutoRefresh(); });\n      $('#refreshMinutes').addEventListener('change', e=>{ state.minutes = +e.target.value; store.save(state); applyAutoRefresh(); });\n\n      \/\/ \u66f8\u304d\u51fa\u3057\/\u8aad\u307f\u8fbc\u307f\n      $('#exportBtn').addEventListener('click', ()=>{\n        const blob = new Blob(&#91;JSON.stringify(state,null,2)], {type:'application\/json'});\n        const a = document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='xlog-pro-config.json'; a.click(); URL.revokeObjectURL(a.href);\n      });\n      $('#importFile').addEventListener('change', e=>{\n        const file = e.target.files?.&#91;0]; if (!file) return;\n        const fr = new FileReader();\n        fr.onload = () => {\n          try{ const obj = JSON.parse(fr.result); state = migrate(obj); store.save(state); applySkin(); refreshBoardSelect(); renderAll(); applyAutoRefresh(); }\n          catch(err){ alert('JSON\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f'); }\n        };\n        fr.readAsText(file);\n      });\n      $('#exportHtmlBtn').addEventListener('click', exportSingleHtml);\n      $('#clearBtn').addEventListener('click', ()=>{\n        if (!confirm('\u73fe\u5728\u306e\u30dc\u30fc\u30c9\u306e\u30bd\u30fc\u30b9\u3068\u30e9\u30f3\u30ad\u30f3\u30b0\u3092\u524a\u9664\u3057\u307e\u3059\u304b\uff1f')) return;\n        const b = board(); b.sources = &#91;]; b.tweets=&#91;]; store.save(state); renderAll();\n      });\n\n      \/\/ RSS\n      $('#rssExport').addEventListener('click', exportRss);\n\n      \/\/ \u521d\u671f\u63cf\u753b\n      renderAll();\n      applyAutoRefresh();\n      setupShortcuts();\n    });\n  &lt;\/script>\n&lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[81,80,78,6,87],"tags":[3],"class_list":{"0":"post-26151","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"hentry","6":"category-css","7":"category-html","8":"category-javascript","9":"category-web","11":"tag-programming"},"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/26151","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=26151"}],"version-history":[{"count":1,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/26151\/revisions"}],"predecessor-version":[{"id":26152,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/26151\/revisions\/26152"}],"wp:attachment":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=26151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=26151"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=26151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}