<?xml version="1.0" encoding="UTF-8" ?><rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://w.atwiki.jp/tontool/">
    <title>tontool @ ウィキ</title>
    <link>http://w.atwiki.jp/tontool/</link>
    <atom:link href="https://w.atwiki.jp/tontool/rss10.xml" rel="self" type="application/rss+xml" />
    <atom:link rel="hub" href="https://pubsubhubbub.appspot.com" />
    <description>tontool @ ウィキ</description>

    <dc:language>ja</dc:language>
    <dc:date>2026-06-01T15:55:24+09:00</dc:date>
    <utime>1780296924</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/1.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/15.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/14.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/13.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/11.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/12.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/10.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/9.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/8.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/tontool/pages/7.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/1.html">
    <title>トップページ</title>
    <link>https://w.atwiki.jp/tontool/pages/1.html</link>
    <description>
      *ツール一覧

[[ToN周回ビンゴ]]

[[ラウンドランダム生成]]

[[アップデートチェックラウンドガチャ]]

[[全虹ミッドちぇっかー]]

[[ToNで学ぶ英単語]]

[[ガーデン・リジェクト]]    </description>
    <dc:date>2026-06-01T15:55:24+09:00</dc:date>
    <utime>1780296924</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/15.html">
    <title>ガーデン・リジェクト</title>
    <link>https://w.atwiki.jp/tontool/pages/15.html</link>
    <description>
      #javascript(){
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;テラー/アンバウンド選出ツール&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: &#039;Segoe UI&#039;, Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f7f9;
            color: #333;
            padding: 20px;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background-color: #fff;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
        }
        h1 {
            color: #007bff;
            text-align: center;
            margin-bottom: 30px;
            border-bottom: 2px solid #e0e0e0;
            padding-bottom: 10px;
        }
        .controls, .result-section {
            margin-bottom: 25px;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 8px;
            background-color: #fafafa;
        }
        .controls label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }
        .controls select, .controls button {
            padding: 10px;
            margin-right: 15px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 16px;
        }
        .controls button {
            background-color: #28a745;
            color: white;
            cursor: pointer;
            border: none;
            transition: background-color 0.3s;
        }
        .controls button:hover {
            background-color: #218838;
        }
        /* ボタン無効化時のスタイル */
        .controls button:disabled {
            background-color: #90ee90; /* 薄い緑 */
            cursor: not-allowed;
        }
        .checkbox-group {
            display: flex;
            align-items: center;
            margin-top: 15px;
            gap: 20px;
        }
        .checkbox-group input {
            transform: scale(1.5);
            margin-right: 5px;
        }

        #results-display {
            border: 3px solid #007bff;
            padding: 20px;
            border-radius: 10px;
            background-color: #eaf3ff;
            min-height: 100px;
        }
        .result-item {
            font-size: 24px;
            margin-bottom: 15px;
            padding: 10px;
            background-color: #fff;
            border-left: 5px solid #007bff;
            border-radius: 5px;
        }
        .result-item:last-child {
            margin-bottom: 0;
        }
        /* Bloodbathの昇格表示 */
        .result-item strong {
            color: #d9534f;
        }
        /* Monarchの特殊装飾 (Midnight/赤太字) */
        .monarch-terror {
            color: #FF0000;
            font-weight: bold;
        }
        /* Crackedの装飾 (変換されたテラーのみ/紫色) */
        .cracked-terror {
            color: #800080; 
        }
        /* Midnightの装飾 (変換されたテラーのみ/赤色) */
        .midnight-terror {
            color: #FF0000; 
        }
        /* Blue Haketの特殊装飾 (Midnight/青色) */
        .blue-midnight-terror {
            color: #0000FF; 
        }
        /* S.O.S.からのThose Olden Days置き換え（茶色太字）*/
        .sos-replacement-terror {
            color: #964B00; /* Brown color */
            font-weight: bold;
        }
        /* Fusion Pilot特殊装飾: Alternate/青太字 */
        .its-so-over-blue {
            color: #00008b; /* Dark Blue */
            font-weight: bold;
        }
        /* Fusion Pilot特殊装飾: Midnight/赤太字 */
        .its-so-over-red {
            color: #ff0000; /* Red */
            font-weight: bold;
        }
        
        /* HFAの装飾 (緑太字) */
        .hfa-prefix {
            color: #006400; /* Dark Green */
            font-weight: bold;
        }
        /* HFAで太字化されるテラーの装飾 (黒色太字、他の色装飾より優先) */
        .hfa-terror {
            font-weight: bold !important;
            color: #000000; /* Black */
        }
        
        /* MEの装飾 (青太字) */
        .me-terror {
             color: #00008b; /* Dark Blue */
            font-weight: bold;
        }
        
        /* --- MOON COLORS --- */
        .moon-twilight { 
            color: #FFD700; /* Yellow */
            font-weight: bold;
        }
        .moon-mystic { 
            color: #0000FF; /* Blue */
            font-weight: bold;
        }
        .moon-blood { 
            color: #FF0000; /* Red */
            font-weight: bold;
        }
        .moon-solstice { 
            color: #008000; /* Green */
            font-weight: bold;
        }

        /* --- Notification Toast Style --- */
        .notification-toast {
            visibility: hidden; 
            min-width: 250px;
            background-color: #d9534f; 
            color: #fff;
            text-align: center;
            border-radius: 5px;
            padding: 16px;
            position: fixed;
            z-index: 100; 
            left: 50%;
            top: 50%; 
            transform: translate(-50%, -50%);
            font-size: 28px;
            font-weight: bold;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
            opacity: 0;
            transition: opacity 0.3s, visibility 0.3s;
        }
        
        #sosNotification {
             background-color: #964B00; /* Brown */
        }
        
        #tbhAchievementNotification {
             background-color: #008080; /* Teal/濃い水色 */
        }
        
        #glorboNotification { /* 新しい通知のスタイル */
            background-color: #8A2BE2; /* BlueViolet/青紫 */
            color: #FFFFFF;
        }

        .notification-toast.show {
            visibility: visible;
            opacity: 1;
        }
        
        /* 累計回数表示 */
        .result-title-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
        }
        .total-draws {
            font-size: 1.2em;
            font-weight: bold;
            color: #007bff;
            background-color: #e0f7fa;
            padding: 5px 10px;
            border-radius: 5px;
            border: 1px solid #00bcd4;
        }

        #saveImage {
            background-color: #f0ad4e;
            color: white;
            margin-top: 10px;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        #saveImage:hover {
            background-color: #ec971f;
        }
        .result-title {
            font-size: 1.2em;
            font-weight: bold;
            color: #007bff;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div class=&quot;container&quot;&gt;
    &lt;h1&gt;テラー/アンバウンド選出ツール ver1.7&lt;/h1&gt;

    &lt;div class=&quot;controls&quot;&gt;
        &lt;label for=&quot;roundSelect&quot;&gt;ラウンドを選ぶ:&lt;/label&gt;
        &lt;select id=&quot;roundSelect&quot;&gt;
            &lt;option value=&quot;Classic&quot;&gt;Classic / クラシック&lt;/option&gt;
            &lt;option value=&quot;Alternate&quot;&gt;Alternate / オルタネイト&lt;/option&gt;
            &lt;option value=&quot;Punished&quot;&gt;Punished / パニッシュ&lt;/option&gt;
            &lt;option value=&quot;Cracked&quot;&gt;Cracked / 狂気&lt;/option&gt;
            &lt;option value=&quot;Sabotage&quot;&gt;Sabotage / サボタージュ&lt;/option&gt;
            &lt;option value=&quot;Bloodbath&quot;&gt;Bloodbath / ブラッドバス&lt;/option&gt;
            &lt;option value=&quot;Midnight&quot;&gt;Midnight / ミッドナイト&lt;/option&gt;
            &lt;option value=&quot;Unbound&quot;&gt;Unbound / アンバウンド&lt;/option&gt;
        &lt;/select&gt;

        &lt;label for=&quot;countSelect&quot; style=&quot;margin-top: 15px;&quot;&gt;連数を選ぶ:&lt;/label&gt;
        &lt;select id=&quot;countSelect&quot;&gt;
            &lt;option value=&quot;1&quot;&gt;1連&lt;/option&gt;
            &lt;option value=&quot;10&quot;&gt;10連&lt;/option&gt;
            &lt;option value=&quot;20&quot;&gt;20連&lt;/option&gt;
            &lt;option value=&quot;30&quot;&gt;30連&lt;/option&gt;
            &lt;option value=&quot;40&quot;&gt;40連&lt;/option&gt;
            &lt;option value=&quot;50&quot;&gt;50連&lt;/option&gt;
        &lt;/select&gt;
        
        &lt;div class=&quot;checkbox-group&quot;&gt;
            &lt;label for=&quot;moonOverwrite&quot;&gt;
                &lt;input type=&quot;checkbox&quot; id=&quot;moonOverwrite&quot;&gt;
                ムーン上書きを有効にする (1/80)
            &lt;/label&gt;
        &lt;/div&gt;

        &lt;button id=&quot;runButton&quot; onclick=&quot;runSelection()&quot;&gt;選出！&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;result-section&quot;&gt;
        &lt;div class=&quot;result-title-container&quot;&gt;
            &lt;div class=&quot;result-title&quot;&gt;✨ 選出結果 ✨&lt;/div&gt;
            &lt;div class=&quot;total-draws&quot;&gt;累計選出回数: &lt;span id=&quot;totalDrawCount&quot;&gt;0&lt;/span&gt; 回&lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&quot;results-display&quot;&gt;
            &lt;/div&gt;
        &lt;button id=&quot;saveImage&quot; onclick=&quot;saveAsImage()&quot;&gt;結果を画像として保存&lt;/button&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;exNotification&quot; class=&quot;notification-toast&quot;&gt;
    EXが選出されました！
&lt;/div&gt;

&lt;div id=&quot;itsSoOverNotification&quot; class=&quot;notification-toast&quot;&gt;
    It&#039;s so overが選出されました！
&lt;/div&gt;

&lt;div id=&quot;meNotification&quot; class=&quot;notification-toast&quot;&gt;
    ME (Mega Evolution) が選出されました！
&lt;/div&gt;

&lt;div id=&quot;sosNotification&quot; class=&quot;notification-toast&quot;&gt;
    S.O.S.の特殊置換が発生しました！
&lt;/div&gt;

&lt;div id=&quot;tbhAchievementNotification&quot; class=&quot;notification-toast&quot;&gt;
    TBHの実績を獲得しました！
&lt;/div&gt;

&lt;div id=&quot;glorboNotification&quot; class=&quot;notification-toast&quot;&gt;
    テラー名がGlorboに上書きされました！
&lt;/div&gt;


&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
    // --- データ一覧 ---
    const CLASSIC_TERRORS = [
        &quot;Huggy&quot;, &quot;Corrupted Toys&quot;, &quot;Demented Spongebob&quot;, &quot;Specimen 8&quot;, &quot;HER&quot;, &quot;Tails Doll&quot;, &quot;Black Sun&quot;, &quot;Aku Ball&quot;, &quot;Ao Oni&quot;, &quot;Toren&#039;s Shadow&quot;,
        &quot;[CENSORED]&quot;, &quot;WhiteNight&quot;, &quot;An Arbiter&quot;, &quot;Specimen 5&quot;, &quot;Comedy&quot;, &quot;Purple Guy&quot;, &quot;Spongefly Swarm&quot;, &quot;Hush&quot;, &quot;MopeMope&quot;, &quot;Sawrunner&quot;,
        &quot;Imposter&quot;, &quot;Something&quot;, &quot;Starved&quot;, &quot;The Painter&quot;, &quot;The Guidance&quot;, &quot;With Many Voices&quot;, &quot;Nextbots&quot;, &quot;Harvest&quot;, &quot;Smileghost&quot;, &quot;Karol_Corpse&quot;,
        &quot;MX&quot;, &quot;Big Bird&quot;, &quot;Dev Bytes&quot;, &quot;Luigi &amp; Luigi Dolls&quot;, &quot;V2&quot;, &quot;Withered Bonnie&quot;, &quot;The Boys&quot;, &quot;Something Wicked&quot;, &quot;Seek&quot;, &quot;Rush&quot;,
        &quot;Sonic&quot;, &quot;Bad Batter&quot;, &quot;Signus&quot;, &quot;Mirror&quot;, &quot;Legs&quot;, &quot;Mona &amp; The Mountain&quot;, &quot;Judgement Bird&quot;, &quot;Slender&quot;, &quot;Maul-A-Child&quot;, &quot;Garten Goers&quot;,
        &quot;Don&#039;t Touch Me&quot;, &quot;Specimen 2&quot;, &quot;Specimen 10&quot;, &quot;The LifeBringer&quot;, &quot;Pale Association&quot;, &quot;Toy Enforcer&quot;, &quot;TBH&quot;, &quot;DoomBox&quot;, &quot;Christian Brutal Sniper&quot;, &quot;Nosk&quot;,
        &quot;Apocrean Harvester&quot;, &quot;Arkus&quot;, &quot;Cartoon Cat&quot;, &quot;Wario Apparition&quot;, &quot;Shinto&quot;, &quot;Hell Bell&quot;, &quot;Security&quot;, &quot;The Swarm&quot;, &quot;Shiteyanyo&quot;, &quot;Bacteria&quot;,
        &quot;Tiffany&quot;, &quot;HoovyDundy&quot;, &quot;Haket&quot;, &quot;Akumii-Kari&quot;, &quot;Lunatic Cultist&quot;, &quot;Sturm&quot;, &quot;Punishing Bird&quot;, &quot;Prisoner&quot;, &quot;Red Bus&quot;, &quot;Waterwraith&quot;,
        &quot;Astrum Aureus&quot;, &quot;Snarbolax&quot;, &quot;All-Around-Helpers&quot;, &quot;lain&quot;, &quot;Sakuya Izayoi&quot;, &quot;Arrival&quot;, &quot;Miros Birds&quot;, &quot;BFF&quot;, &quot;Scavenger&quot;, &quot;Tinky Winky&quot;,
        &quot;Tricky&quot;, &quot;Yolm&quot;, &quot;Red Fanatic&quot;, &quot;Dr. Tox&quot;, &quot;Ink Demon&quot;, &quot;Retep&quot;, &quot;Those Olden Days&quot;, &quot;S.O.S&quot;, &quot;Bigger Boot&quot;, &quot;The Pursuer&quot;,
        &quot;Spamton&quot;, &quot;Immortal Snail&quot;, &quot;Charlotte&quot;, &quot;Herobrine&quot;, &quot;Peepy&quot;, &quot;The Jester&quot;, &quot;Wild Yet Curious Creature&quot;, &quot;Manti&quot;, &quot;Horseless Headless Horsemann&quot;, &quot;Ghost Girl&quot;,
        &quot;Cubor&#039;s Revenge&quot;, &quot;Poly&quot;, &quot;Dog Mimic&quot;, &quot;Warden&quot;, &quot;Fox Squad&quot;, &quot;Express Train To Hell&quot;, &quot;Deleted&quot;, &quot;Killer Fish&quot;, &quot;Terror of Nowhere&quot;, &quot;Beyond&quot;,
        &quot;The Origin&quot;, &quot;Time Ripper&quot;, &quot;This Killer does not exist&quot;, &quot;Parhelion&#039;s Victims&quot;, &quot;Bed Mecha&quot;, &quot;Killer Rabbit&quot;, &quot;Bravera&quot;, &quot;MissingNo&quot;, &quot;Living Shadow&quot;, &quot;The Plague Doctor&quot;,
        &quot;The Rat&quot;, &quot;Waldo&quot;, &quot;Clockey&quot;, &quot;Malicious Twins&quot;
    ];

    const ALTERNATE_TERRORS = [
        &quot;Decayed Sponge&quot;, &quot;WHITEFACE&quot;, &quot;Sanic&quot;, &quot;Parhelion&quot;, &quot;,D@;Q7Y&quot;, &quot;Chomper&quot;, &quot;The Knight of Toren&quot;, &quot;Tragedy&quot;, &quot;Apathy&quot;, &quot;MR.MEGA&quot;,
        &quot;sm64.z64&quot;, &quot;Convict Squad&quot;, &quot;Paradise Bird&quot;, &quot;Angry Munci&quot;, &quot;Lord&#039;s Signal&quot;, &quot;Feddys&quot;, &quot;TBH SPY&quot;, &quot;The Observation&quot;, &quot;Lisa&quot;, &quot;Judas&quot;,
        &quot;Glaggle Gang&quot;, &quot;Try Not To Touch Me&quot;, &quot;Ambush&quot;, &quot;Teuthida&quot;, &quot;Eggman&#039;s Announcement&quot;, &quot;S.T.G.M&quot;, &quot;Army in Black&quot;, &quot;Bliss&quot;, &quot;Roblander&quot;, &quot;Fusion Pilot&quot;,
        &quot;Joy&quot;, &quot;The Red Mist&quot;, &quot;Sakuya The Ripper&quot;, &quot;Walpurgisnacht&quot;, &quot;Dev Maulers&quot;, &quot;Restless Creator&quot;
    ];

    const UNBOUNDS = [
        &quot;Guidance &amp; The Booboo&#039;s&quot;, &quot;Red vs Blue&quot;, &quot;Third Trumpet&quot;, &quot;Forest Gurdians&quot;, &quot;Higher Beings&quot;, &quot;Quadruple Sponge&quot;, &quot;Your Best Friends&quot;, &quot;Hotel Monsters&quot;, &quot;Squibb Squad&quot;, &quot;Garden Rejects&quot;,
        &quot;Judgement Day&quot;, &quot;Me and My Shadow&quot;, &quot;Meltdown&quot;, &quot;Faceless Mafia&quot;, &quot;Mansion Monsters&quot;, &quot;Copyright Infringement&quot;, &quot;Purple Bros&quot;, &quot;Scavengers&quot;, &quot;Life &amp; Death&quot;, &quot;Labyrinth&quot;,
        &quot;Spiteful Shadows&quot;, &quot;Triple Munci&quot;, &quot;Daycare&quot;, &quot;Huggy Horde&quot;, &quot;Infection&quot;, &quot;Triple Hush&quot;, &quot;[CENSORED]&quot;, &quot;Byte Horde&quot;, &quot;SawMarathon&quot;, &quot;TAKE THE NAMI CHALLENGE&quot;,
        &quot;Thunderstorm&quot;, &quot;END OF THE WORLD&quot;, &quot;Fragmented Memories&quot;, &quot;Mona &amp; Mona &amp; Mona &amp; Mona&quot;, &quot;Seekers&quot;, &quot;Nugget Squad&quot;, &quot;Saul&#039;s goodmen&quot;, &quot;Something Old,Something New&quot;, &quot;POV: Bug&quot;, &quot;Punishing Birdemic&quot;,
        &quot;Double Ao Oni&quot;, &quot;Too Many Voices&quot;, &quot;Memory Crypts&quot;, &quot;Zumbo Sauce&quot;, &quot;Freaks&quot;, &quot;Lunatic Cult&quot;, &quot;Transportation Trio &amp; The Drifter&quot;, &quot;Father Son Bonding&quot;, &quot;WHAT IS MY NAME&quot;, &quot;Glaggleland Cremators&quot;,
        &quot;Triple Signus&quot;, &quot;Triple Akumii Kari&quot;, &quot;Black &amp; White&quot;, &quot;[LESSER CENSORED]&quot;, &quot;Blue Monsters&quot;, &quot;Drones&quot;, &quot;Scrapyard Takers&quot;, &quot;Luigi Dolls&quot;, &quot;Meteor Shower&quot;, &quot;Triple TBH&quot;,
        &quot;Lost Souls&quot;, &quot;Ballin&quot;, &quot;Reunion&quot;, &quot;Angels&quot;, &quot;Ordinary Apocalypse Bird&quot;, &quot;Pack of Wild Yet Curious Creatures&quot;, &quot;ToN X SlashCo Collab&quot;, &quot;Pack of Yolm&quot;, &quot;Threepy&quot;, &quot;???&quot;,
        &quot;Delete Me&quot;, &quot;Spamton Spam&quot;, &quot;Death From Above&quot;, &quot;It Came From Bus To Nowhere&quot;, &quot;Zombie Apocalypse&quot;, &quot;Eating Contest&quot;, &quot;Triple Clockey&quot;, &quot;Triple Killer Fish&quot;, &quot;Lethal League&quot;, &quot;Trollage&quot;,
        &quot;Mopemopemopemopemopemope&quot;, &quot;Triple Trouble&quot;, &quot;Triple Living Shadow&quot;, &quot;Beyond&#039;s Masks&quot;
    ];

    const STAGES = [
        &quot;Alter&quot;, &quot;Ancient&quot;, &quot;Astral&quot;, &quot;Baseplate&quot;, &quot;Backrooms&quot;, &quot;Challenge Cube&quot;, &quot;Black Forest&quot;, &quot;Cheese Maze&quot;,
        &quot;Chess&quot;, &quot;Construct&quot;, &quot;Desktop&quot;, &quot;Development&quot;, &quot;Dots&quot;, &quot;Dust&quot;, &quot;Elevator&quot;, &quot;Engine&quot;, &quot;Escape Route&quot;,
        &quot;Experimentation&quot;, &quot;Forest&quot;, &quot;Gaol&quot;, &quot;Gardens&quot;, &quot;Garten&quot;, &quot;Isolation&quot;, &quot;Have&quot;, &quot;Harvest&quot;, &quot;Heaven&quot;, &quot;Hell&quot;,
        &quot;Hightower&quot;, &quot;Iteration_0&quot;, &quot;Hole&quot;, &quot;Hotel&quot;, &quot;Hub&quot;, &quot;Inner Tower&quot;, &quot;Innyume&quot;, &quot;Lounge&quot;, &quot;Luna Hills&quot;, &quot;Mall&quot;,
        &quot;Mineshaft&quot;, &quot;Museum&quot;, &quot;Neon Towers (紫)&quot;, &quot;Neon Towers (緑)&quot;, &quot;Nexus&quot;, &quot;Nightlife&quot;, &quot;Orange&quot;, &quot;Park&quot;, &quot;Pizzeria&quot;, &quot;Playplace&quot;,
        &quot;Pools&quot;, &quot;Robland&quot;, &quot;Sanctum&quot;, &quot;Schoolhouse&quot;, &quot;Scrapyard&quot;, &quot;Sea Base&quot;, &quot;Secret&quot;, &quot;Sewers&quot;, &quot;Skyscraper&quot;, &quot;Slashco HQ&quot;,
        &quot;Snowfield&quot;, &quot;Space Colony&quot;, &quot;Spaceless&quot;, &quot;Subway&quot;, &quot;Supply Route&quot;, &quot;TBH&quot;, &quot;The Fishbowl&quot;, &quot;The Wall&quot;, &quot;This Map Does Not Exist&quot;, &quot;Throne&quot;,
        &quot;Tunnels&quot;, &quot;Vents&quot;, &quot;Wafflehouse&quot;, &quot;Warehouse&quot;, &quot;Blackspace&quot;, &quot;Carpark&quot; 
    ];
    
    const CRACKED_TRANSFORM = {
        &quot;Withered Bonnie&quot;: &quot;Epic Bonnie&quot;,
        &quot;TBH&quot;: &quot;TBH SANS&quot;
    };

    const MIDNIGHT_TRANSFORM = {
        &quot;Haket&quot;: &quot;Blue Haket&quot;,
        &quot;Roblander&quot;: &quot;Inverted Roblander&quot;,
        &quot;The Knight of Toren&quot;: &quot;Kimera&quot;,
        &quot;Judas&quot;: &quot;Monarch&quot;,
        &quot;BFF&quot;: &quot;Nameless&quot;,
        &quot;Snarbolax&quot;: &quot;Rabid Snarbolax&quot;,
        &quot;Sonic&quot;: &quot;Rewrite&quot;,
        &quot;Withered Bonnie&quot;: &quot;Ruinborn Afton&quot;,
        &quot;The LifeBringer&quot;: &quot;Scrapyard Machine&quot;,
        &quot;Dev Bytes&quot;: &quot;Search and Destroy&quot;,
        &quot;Slender&quot;: &quot;Slendy&quot;,
        &quot;Bad Batter&quot;: &quot;The Batter&quot;
    };
    
    // 変換元テラーのリスト
    const CRACKED_TRANSFORM_SOURCES = Object.keys(CRACKED_TRANSFORM);
    const MIDNIGHT_TRANSFORM_SOURCES = Object.keys(MIDNIGHT_TRANSFORM);

    const CRACKED_TRANSFORMED_NAMES = Object.values(CRACKED_TRANSFORM);
    const MIDNIGHT_TRANSFORMED_NAMES = Object.values(MIDNIGHT_TRANSFORM);
    
    // --- HFAの組み合わせデータ構造 ---
    const HFA_COMBINATIONS = [
        { stage: &quot;Hotel&quot;, terrors: [&quot;Seek&quot;, &quot;Rush&quot;, &quot;Ambush&quot;] }, 
        { stage: [&quot;Hightower&quot;, &quot;Harvest&quot;], terrors: [&quot;Christian Brutal Sniper&quot;, &quot;Horseless Headless Horsemann&quot;, &quot;HoovyDundy&quot;] }, 
        { stage: &quot;Blackspace&quot;, terrors: [&quot;Something&quot;] },
        { stage: &quot;Scrapyard&quot;, terrors: [&quot;The LifeBringer&quot;] },
        { stage: &quot;Robland&quot;, terrors: [&quot;Roblander&quot;] },
        { stage: &quot;Isolation&quot;, terrors: [&quot;Specimen 2&quot;, &quot;Specimen 5&quot;, &quot;Specimen 8&quot;, &quot;Specimen 10&quot;, &quot;Lisa&quot;] },
        { stage: &quot;Secret&quot;, terrors: [&quot;V2&quot;, &quot;Something Wicked&quot;] },
        { stage: &quot;Innyume&quot;, terrors: [&quot;Smileghost&quot;] },
        { stage: &quot;Pizzeria&quot;, terrors: [&quot;Withered Bonnie&quot;, &quot;Purple Guy&quot;, &quot;The Origin&quot;, &quot;Feddys&quot;] },
        { stage: &quot;Carpark&quot;, terrors: [&quot;HER&quot;, &quot;WHITEFACE&quot;] },
        { stage: &quot;TBH&quot;, terrors: [&quot;TBH&quot;, &quot;TBH SPY&quot;] },
        { stage: &quot;Experimentation&quot;, terrors: [&quot;The Jester&quot;, &quot;Ghost Girl&quot;] },
        { stage: &quot;Backrooms&quot;, terrors: [&quot;Bacteria&quot;] },
        { stage: &quot;Gaol&quot;, terrors: [&quot;Prisoner&quot;, &quot;Security&quot;, &quot;The Swarm&quot;, &quot;Poly&quot;] },
        { stage: &quot;Slashco HQ&quot;, terrors: [&quot;Comedy&quot;, &quot;Manti&quot;] },
        { stage: &quot;Have&quot;, terrors: [&quot;Terror of Nowhere&quot;] },
        { stage: &quot;Garten&quot;, terrors: [&quot;Garten Goers&quot;] },
        { stage: &quot;Astral&quot;, terrors: [&quot;Astrum Aureus&quot;] },
        { stage: &quot;Hell&quot;, terrors: [&quot;Parhelion&quot;] },
        { stage: &quot;Hub&quot;, terrors: [&quot;Mirror&quot;, &quot;Terror of Nowhere&quot;, &quot;BFF&quot;] },
        { stage: &quot;Luna Hills&quot;, terrors: [&quot;Judas&quot;] },
        { stage: &quot;Throne&quot;, terrors: [&quot;Beyond&quot;] },
        { stage: &quot;Challenge Cube&quot;, terrors: [&quot;Apathy&quot;, &quot;Maul-A-Child&quot;, &quot;Killer Fish&quot;, &quot;Joy&quot;] }
    ];
    
    // --- MOONデータ構造 ---
    const MOON_TYPES = [
        { name: &quot;Twilight&quot;, css: &quot;moon-twilight&quot; },
        { name: &quot;Mystic Moon&quot;, css: &quot;moon-mystic&quot; },
        { name: &quot;Blood Moon&quot;, &quot;css&quot;: &quot;moon-blood&quot; },
        { name: &quot;Solstice&quot;, css: &quot;moon-solstice&quot; }
    ];
    const STANDARD_MOONS = MOON_TYPES.slice(1); // Twilight以外

    /**
     * HFA条件に合致するかチェックし、合致したテラー名を返す
     * @param {string[]} terrors - HFA判定に使うテラー名（変換前のテラー名）
     * @param {string} stage - 選出されたステージ名
     * @returns {{ isHFA: boolean, hfaTerrors: string[] }}
     */
    function checkHFA(terrors, stage) {
        const hfaTerrors = [];
        let isHFA = false;

        for (const combo of HFA_COMBINATIONS) {
            const stagesToCheck = Array.isArray(combo.stage) ? combo.stage : [combo.stage];
            
            if (stagesToCheck.includes(stage)) {
                
                for (const terror of terrors) {
                    if (combo.terrors.includes(terror)) {
                        isHFA = true;
                        if (!hfaTerrors.includes(terror)) {
                            hfaTerrors.push(terror);
                        }
                    }
                }
            }
        }

        return { isHFA, hfaTerrors: isHFA ? hfaTerrors : [] };
    }


    // --- 累計回数管理 ---
    let totalDraws = 0;
    let lastSelectedRound = null;

    function loadTotalDrawCount() {
        const storedDraws = localStorage.getItem(&#039;totalDraws&#039;);
        const storedRound = localStorage.getItem(&#039;lastSelectedRound&#039;);
        
        totalDraws = parseInt(storedDraws, 10) || 0;
        lastSelectedRound = storedRound || document.getElementById(&#039;roundSelect&#039;).value; 
        
        updateTotalDrawDisplay();
    }

    function saveTotalDrawCount() {
        localStorage.setItem(&#039;totalDraws&#039;, totalDraws.toString());
        localStorage.setItem(&#039;lastSelectedRound&#039;, document.getElementById(&#039;roundSelect&#039;).value);
    }

    function updateTotalDrawDisplay() {
        document.getElementById(&#039;totalDrawCount&#039;).textContent = totalDraws;
    }

    function resetDrawCountIfRoundChanged() {
        const currentRound = document.getElementById(&#039;roundSelect&#039;).value;
        
        if (lastSelectedRound !== null &amp;&amp; lastSelectedRound !== currentRound) {
            totalDraws = 0;
            lastSelectedRound = currentRound;
            localStorage.setItem(&#039;totalDraws&#039;, &#039;0&#039;);
        } else {
            lastSelectedRound = currentRound;
        }
        localStorage.setItem(&#039;lastSelectedRound&#039;, currentRound);
        updateTotalDrawDisplay();
    }


    // --- ユーティリティ関数 ---

    function selectRandom(arr) {
        if (!arr || arr.length === 0) return null;
        const index = Math.floor(Math.random() * arr.length);
        return arr[index];
    }

    function selectUniqueRandom(arr, count) {
        if (count &gt; arr.length) count = arr.length;
        const shuffled = arr.slice().sort(() =&gt; 0.5 - Math.random());
        return shuffled.slice(0, count);
    }
    
    function setButtonState(disabled) {
        document.getElementById(&#039;runButton&#039;).disabled = disabled;
    }

    // [EX] 通知関数
    function showEXNotification() {
        const notification = document.getElementById(&#039;exNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }

    // [It&#039;s so over] 通知関数 
    function showItsSoOverNotification() {
        const notification = document.getElementById(&#039;itsSoOverNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }
    
    // [ME] 通知関数 
    function showMENotification() {
        const notification = document.getElementById(&#039;meNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }

    // [S.O.S.特殊置換] 通知関数 
    function showSOSNotification() {
        const notification = document.getElementById(&#039;sosNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }
    
    // [TBH実績] 通知関数
    function showTBHAchievementNotification() {
        const notification = document.getElementById(&#039;tbhAchievementNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }
    
    // [Glorbo] 通知関数 (新規追加)
    function showGlorboNotification() {
        const notification = document.getElementById(&#039;glorboNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }


    // --- メインロジック関数 ---

    /**
     * テラー選出のメインロジック
     */
    function selectTerrorsAndStage(round) {
        let initialTerrors = [];
        let stage = selectRandom(STAGES);
        let isSOSReplacementEvent = false;

        // 1. テラーの初期選出
        if (round === &quot;Classic&quot; || round === &quot;Punished&quot; || round === &quot;Cracked&quot; || round === &quot;Sabotage&quot;) {
            initialTerrors.push(selectRandom(CLASSIC_TERRORS));
        } else if (round === &quot;Alternate&quot;) {
            initialTerrors.push(selectRandom(ALTERNATE_TERRORS));
        } else if (round === &quot;Bloodbath&quot;) {
            for (let i = 0; i &lt; 3; i++) {
                initialTerrors.push(selectRandom(CLASSIC_TERRORS));
            }
        } else if (round === &quot;Midnight&quot;) {
            const classic2 = selectUniqueRandom(CLASSIC_TERRORS, 2);
            initialTerrors.push(classic2[0], classic2[1], selectRandom(ALTERNATE_TERRORS)); 
        } else if (round === &quot;Unbound&quot;) {
            initialTerrors.push(selectRandom(UNBOUNDS));
        }

        // --- 2. S.O.S.置き換え (Those Olden Daysへの特殊置換) ---
        const sosCheckStages = [&quot;Spaceless&quot;, &quot;Heaven&quot;, &quot;Escape Route&quot;];
        const needsSOSHighlight = [&quot;Punished&quot;, &quot;Bloodbath&quot;, &quot;Midnight&quot;].includes(round);
        
        let terrorsAfterSOSReplacement = initialTerrors.map(t =&gt; {
            if (t === &quot;S.O.S&quot; &amp;&amp; sosCheckStages.includes(stage) &amp;&amp; needsSOSHighlight) {
                isSOSReplacementEvent = true; // 特殊イベントフラグを立てる
                return &quot;Those Olden Days&quot;; 
            }
            return t;
        });
        
        // --- 3. ラウンド別出禁の適用 (Those Olden Daysは出禁だが、S.O.S.からの特殊置換の場合は除く) ---
        let bannedList = [];
        if (round === &quot;Bloodbath&quot;) {
            bannedList = [&quot;Luigi &amp; Luigi Dolls&quot;, &quot;Akumii-Kari&quot;, &quot;Those Olden Days&quot;, &quot;Deleted&quot;];
        } else if (round === &quot;Midnight&quot;) {
            bannedList = [&quot;Luigi &amp; Luigi Dolls&quot;, &quot;Akumii-Kari&quot;, &quot;Those Olden Days&quot;, &quot;Deleted&quot;, &quot;Specimen 5&quot;];
        } else if (round === &quot;Punished&quot;) {
            bannedList = [&quot;Those Olden Days&quot;, &quot;Cubor&#039;s Revenge&quot;];
        }

        let isMidnightBannedSubstitution = false;
        
        let terrorsAfterBanning = terrorsAfterSOSReplacement.map((t, index) =&gt; {
            // S.O.S.の特殊置換によるThose Olden Daysは出禁にしない
            if (isSOSReplacementEvent &amp;&amp; t === &quot;Those Olden Days&quot;) {
                return t;
            }

            // 標準の出禁ロジック
            if (bannedList.includes(t)) {
                if (round === &quot;Midnight&quot; &amp;&amp; index &lt; 2) { 
                    isMidnightBannedSubstitution = true;
                }
                return &quot;Comedy&quot;; 
            }
            return t;
        });

        // HFAチェック用のテラー名リスト (テラー名変更前の最終的なリスト)
        let terrorsForHFACheckBase = terrorsAfterBanning;

        // --- 4. HFA無効化チェック (Midnight/Crackedで変換されるテラーがHFA条件を満たす場合、無効化) ---
        let HFA_DISABLED_BY_TRANSFORM = [];
        if (round === &quot;Midnight&quot; || round === &quot;Cracked&quot;) {
            const transformSources = (round === &quot;Midnight&quot; ? MIDNIGHT_TRANSFORM_SOURCES : CRACKED_TRANSFORM_SOURCES);
            
            terrorsForHFACheckBase.forEach(t =&gt; {
                if (transformSources.includes(t)) {
                    for (const combo of HFA_COMBINATIONS) {
                        const stagesToCheck = Array.isArray(combo.stage) ? combo.stage : [combo.stage];
                        if (stagesToCheck.includes(stage) &amp;&amp; combo.terrors.includes(t)) {
                            HFA_DISABLED_BY_TRANSFORM.push(t);
                            break; 
                        }
                    }
                }
            });
        }
        
        // HFA判定に使う最終テラーリスト
        let terrorsForHFACheck = terrorsForHFACheckBase.filter(t =&gt; !HFA_DISABLED_BY_TRANSFORM.includes(t)); 


        // --- 5. ラウンド固有のテラー名変更と特殊タグ付け (表示用) ---
        let terrorsForDisplay = terrorsForHFACheckBase.slice();
        
        // S.O.S.特殊置換テラーにタグを付ける
        terrorsForDisplay = terrorsForDisplay.map(t =&gt; {
            if (isSOSReplacementEvent &amp;&amp; t === &quot;Those Olden Days&quot;) {
                t += &quot;&lt;SOS&gt;&quot;;
            }
            return t;
        });
        
        // Cracked/Midnightの変換
        if (round === &quot;Cracked&quot;) {
            terrorsForDisplay = terrorsForDisplay.map(t =&gt; CRACKED_TRANSFORM[t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;)] || t);
        } else if (round === &quot;Midnight&quot;) {
            terrorsForDisplay = terrorsForDisplay.map(t =&gt; MIDNIGHT_TRANSFORM[t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;)] || t);
        }

        // --- 6. BloodbathとMidnightの最終選出ロジック (表示用とHFAチェック用を分離して処理) ---
        let finalTerrors = [];
        let finalHfaCheckTerrors = []; 
        
        if (round === &quot;Bloodbath&quot;) {
            const terrorsNoTags = terrorsForDisplay.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim()); 
            const baseTerrorsNoTags = terrorsForHFACheckBase.map(t =&gt; t.split(&#039;(&#039;)[0].trim()); 

            const countMap = {};
            terrorsNoTags.forEach(t =&gt; countMap[t] = (countMap[t] || 0) + 1);
            const uniqueTerrors = Object.keys(countMap);
            
            const randomChance = Math.random(); 

            if (randomChance &lt; 3 / 35) {
                if (uniqueTerrors.length === 1) {
                    finalTerrors = [`EX (${uniqueTerrors[0]})`];
                    finalHfaCheckTerrors = [baseTerrorsNoTags[0]].filter(t =&gt; terrorsForHFACheck.includes(t)); 
                } else {
                    const uniqueIndices = [0, 1, 2].sort(() =&gt; 0.5 - Math.random()).slice(0, 2);
                    const selectedNames = [baseTerrorsNoTags[uniqueIndices[0]], baseTerrorsNoTags[uniqueIndices[1]]].filter((v, i, a) =&gt; a.indexOf(v) === i);

                    finalTerrors = [terrorsNoTags.find(t =&gt; t === selectedNames[0]), terrorsNoTags.find(t =&gt; t === selectedNames[1])].filter(Boolean);
                    finalTerrors.unshift(&quot;Double Trouble&quot;);
                    
                    finalHfaCheckTerrors = selectedNames.filter(t =&gt; terrorsForHFACheck.includes(t));
                }
            } else {
                if (uniqueTerrors.length === 3) {
                    finalTerrors = terrorsForDisplay; 
                    finalHfaCheckTerrors = baseTerrorsNoTags.filter(t =&gt; terrorsForHFACheck.includes(t)); 
                } else if (uniqueTerrors.length === 2) {
                    const doubleTerrorName = uniqueTerrors.find(t =&gt; countMap[t] === 2);
                    const singleTerrorName = uniqueTerrors.find(t =&gt; countMap[t] === 1);
                    
                    const doubleTerror = terrorsForDisplay.find(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim() === doubleTerrorName);
                    const singleTerror = terrorsForDisplay.find(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim() === singleTerrorName);
                    
                    finalTerrors = [doubleTerror, singleTerror];
                    finalTerrors.unshift(&quot;Double Trouble&quot;);

                    const baseDouble = baseTerrorsNoTags.find(t =&gt; t === doubleTerrorName);
                    const baseSingle = baseTerrorsNoTags.find(t =&gt; t === singleTerrorName);
                    
                    finalHfaCheckTerrors = [baseDouble, baseSingle].filter(t =&gt; terrorsForHFACheck.includes(t));
                    
                } else if (uniqueTerrors.length === 1) {
                    finalTerrors = [`EX (${uniqueTerrors[0]})`];
                    finalHfaCheckTerrors = [baseTerrorsNoTags[0]].filter(t =&gt; terrorsForHFACheck.includes(t));
                } else {
                    finalTerrors = terrorsForDisplay; 
                    finalHfaCheckTerrors = baseTerrorsNoTags.filter(t =&gt; terrorsForHFACheck.includes(t));
                }
            }
        } else if (round === &quot;Midnight&quot;) {
            const [c1, c2, alternate] = terrorsForDisplay; // 変換後/表示用
            const [base_c1, base_c2, base_alternate] = terrorsForHFACheckBase; // 変換前/HFAチェック用

            if (isMidnightBannedSubstitution) {
                 finalTerrors = [&quot;Comedy&quot;, alternate];
                 finalHfaCheckTerrors = [&quot;Comedy&quot;, base_alternate].filter(t =&gt; terrorsForHFACheck.includes(t)); 
            } else {
                finalTerrors = [c1, c2, alternate];
                finalHfaCheckTerrors = [base_c1, base_c2, base_alternate].filter(t =&gt; terrorsForHFACheck.includes(t)); 
            }
            
            // Eyesの特殊ルール適用
            const finalTerrorsNoTags = finalTerrors.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;));
            const hasRushOrAmbush = finalTerrorsNoTags.includes(&quot;Rush&quot;) || finalTerrorsNoTags.includes(&quot;Ambush&quot;);
            
            if (hasRushOrAmbush) {
                if (finalTerrors.length === 3) { 
                     finalTerrors.splice(2, 0, &quot;Eyes&quot;); 
                     finalHfaCheckTerrors.splice(2, 0, &quot;Eyes&quot;); 
                } else if (finalTerrors.length === 2) { 
                     finalTerrors.splice(1, 0, &quot;Eyes&quot;); 
                     finalHfaCheckTerrors.splice(1, 0, &quot;Eyes&quot;); 
                }
            }
        } else {
            finalTerrors = terrorsForDisplay;
            finalHfaCheckTerrors = terrorsForHFACheckBase.filter(t =&gt; terrorsForHFACheck.includes(t));
        }
        
        // --- 7. Fusion Pilot特殊チェック ([It&#039;s so over] 条件) ---
        let itsSoOverColor = null; 
        
        const finalTerrorsNoTags = finalTerrors.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim()); 
        
        if (stage === &quot;Challenge Cube&quot;) {
            if (round === &quot;Alternate&quot; &amp;&amp; finalTerrorsNoTags.includes(&quot;Fusion Pilot&quot;)) {
                itsSoOverColor = &#039;blue&#039;;
            } else if (round === &quot;Midnight&quot;) {
                const alternateTerror = finalTerrorsNoTags[finalTerrorsNoTags.length - 1];
                if (alternateTerror === &quot;Fusion Pilot&quot;) {
                    itsSoOverColor = &#039;red&#039;;
                }
            }
        }
        
        // --- 8. MEチェック (Alternate &amp; Roblander @ Robland) ---
        let isME = false;
        if (round === &quot;Alternate&quot; &amp;&amp; stage === &quot;Robland&quot; &amp;&amp; finalTerrorsNoTags.includes(&quot;Roblander&quot;)) {
             isME = true;
        }

        // --- 9. TBH実績チェック (TBH or TBH SPY or TBH SANS @ TBH) ---
        let isTBHAchievement = false;
        
        let terrorsForAchievement = [];

        if (round === &quot;Cracked&quot;) {
            terrorsForAchievement = [&quot;TBH SANS&quot;];
        } else {
            terrorsForAchievement = [&quot;TBH&quot;, &quot;TBH SPY&quot;, &quot;TBH SANS&quot;];
        }

        const hasTargetTerror = finalTerrorsNoTags.some(t =&gt; terrorsForAchievement.includes(t));

        if (stage === &quot;TBH&quot; &amp;&amp; hasTargetTerror) {
             isTBHAchievement = true;
        }


        // --- 10. HFAチェック ([HFA] 条件) ---
        const hfaCheckList = finalHfaCheckTerrors.filter(t =&gt; t !== &quot;Eyes&quot; &amp;&amp; t !== &quot;Roblander&quot;); 
        const hfaResult = checkHFA(hfaCheckList, stage);
        
        // --- 11. Glorbo上書きチェック (Punished &amp; Sewers) (新規追加) ---
        let isGlorbo = false;
        if (round === &quot;Punished&quot; &amp;&amp; stage === &quot;Sewers&quot; &amp;&amp; Math.random() &lt; 1 / 10000) {
            isGlorbo = true;
        }
        
        // --- 12. MOON上書きチェック (すべての判定が完了した後) ---
        let selectedMoon = null;
        let isMoon = false;
        const moonOverwriteEnabled = document.getElementById(&#039;moonOverwrite&#039;).checked;
        const nonMoonRounds = [&quot;Classic&quot;, &quot;Alternate&quot;];
        
        if (!isGlorbo &amp;&amp; moonOverwriteEnabled &amp;&amp; !nonMoonRounds.includes(round) &amp;&amp; Math.random() &lt; 1 / 80) {
            isMoon = true;
            if (stage === &quot;Black Forest&quot;) {
                selectedMoon = selectRandom(MOON_TYPES); // Twilight含む全て
            } else {
                selectedMoon = selectRandom(STANDARD_MOONS); // Twilight以外
            }
        }

        // 最終的な結果オブジェクトを返す
        return { 
            terrors: finalTerrors, 
            stage, 
            itsSoOverColor, 
            isHFA: hfaResult.isHFA, 
            hfaTerrors: hfaResult.hfaTerrors, 
            isME: isME,
            isMoon: isMoon, 
            selectedMoon: selectedMoon, 
            isSOSReplacementEvent: isSOSReplacementEvent,
            isTBHAchievement: isTBHAchievement, // TBH実績フラグ
            isGlorbo: isGlorbo // Glorboフラグ
        };
    }

    /**
     * 結果表示用の文字列を整形する。
     */
    function formatResult(round, result) {
        const { terrors, stage, itsSoOverColor, isHFA, hfaTerrors, isME, isMoon, selectedMoon, isSOSReplacementEvent, isGlorbo } = result;
        
        // --- 0. Glorbo上書き表示 (最優先) ---
        if (isGlorbo) {
             return `&lt;span style=&quot;font-weight: bold; color: #8A2BE2;&quot;&gt;Glorbo&lt;/span&gt; @ ${stage}`;
        }

        // --- 1. ムーン上書きプレフィックスの構築 (次に優先) ---
        let moonPrefixHtml = &quot;&quot;;
        if (isMoon) {
            moonPrefixHtml = `&lt;span class=&quot;${selectedMoon.css}&quot;&gt;[${selectedMoon.name}]&lt;/span&gt; `;
        }
        
        // --- 2. ME表示 (ムーンがなければ次に優先) ---
        if (isME &amp;&amp; !isMoon) {
            return `&lt;span class=&quot;me-terror&quot;&gt;ME&lt;/span&gt; @ ${stage}`;
        }
        
        if (round === &quot;Unbound&quot;) {
            // Unboundはテラーが1つ
            let prefix = moonPrefixHtml;
            if (itsSoOverColor === &#039;blue&#039;) {
                prefix += `&lt;span class=&quot;its-so-over-blue&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
            } else if (itsSoOverColor === &#039;red&#039;) {
                prefix += `&lt;span class=&quot;its-so-over-red&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
            }
            if (isHFA) {
                prefix += `&lt;span class=&quot;hfa-prefix&quot;&gt;[HFA]&lt;/span&gt; `;
            }
            
            const terrorNoTag = terrors[0].replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;);
            const isSOSReplacementUnbound = terrors[0].includes(&#039;&lt;SOS&gt;&#039;);
            
            let terrorDisplay = terrorNoTag;
            if (isSOSReplacementUnbound) {
                 terrorDisplay = `&lt;span class=&quot;sos-replacement-terror&quot;&gt;${terrorNoTag}&lt;/span&gt;`;
            } else {
                 terrorDisplay = terrorNoTag;
            }

            return `${prefix}${terrorDisplay} @ ${stage}`;
        }
        
        let terrorsHtml = [];

        for(let terror of terrors) {
            let formattedTerror = terror;
            const isSOSReplacement = terror.endsWith(&quot;&lt;SOS&gt;&quot;);
            
            let baseTerrorName = terror.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim(); 
            
            if (isSOSReplacement) {
                formattedTerror = formattedTerror.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;);
            }
            
            // HFAで太字化すべきテラー名 (変換前の名前) が、現在の表示名（変換後）と一致するかを判定
            let isCurrentTerrorHFA = false;
            let originalName = baseTerrorName;
            
            const allTransforms = { ...CRACKED_TRANSFORM, ...MIDNIGHT_TRANSFORM };
            const reverseTransform = Object.entries(allTransforms).find(([, v]) =&gt; v === baseTerrorName);
            if (reverseTransform) originalName = reverseTransform[0];
            
            if (isHFA &amp;&amp; hfaTerrors.includes(originalName)) {
                 isCurrentTerrorHFA = true;
            }


            // --- 既存の装飾ロジック ---
            
            // 1. Bloodbathの昇格チェック
            if (terror.startsWith(&quot;Double Trouble&quot;) || terror.startsWith(&quot;EX&quot;)) {
                 formattedTerror = `&lt;strong&gt;${baseTerrorName}&lt;/strong&gt;`;
            } 
            // 2. SOS Replacementチェック (茶色太字)
            else if (isSOSReplacement) {
                formattedTerror = `&lt;span class=&quot;sos-replacement-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
            }
            // 3. Crackedのテラー名変更チェック
            else if (round === &quot;Cracked&quot; &amp;&amp; CRACKED_TRANSFORMED_NAMES.includes(baseTerrorName)) {
                 formattedTerror = `&lt;span class=&quot;cracked-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
            } 
            // 4. Midnightのテラー名変更チェック
            else if (round === &quot;Midnight&quot; &amp;&amp; (terror.startsWith(&quot;EX&quot;) || terror.startsWith(&quot;Double Trouble&quot;) ? true : MIDNIGHT_TRANSFORMED_NAMES.includes(baseTerrorName))) {
                if (baseTerrorName === &quot;Monarch&quot;) {
                     formattedTerror = `&lt;span class=&quot;monarch-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                } else if (baseTerrorName === &quot;Blue Haket&quot;) {
                     formattedTerror = `&lt;span class=&quot;blue-midnight-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                } else {
                    formattedTerror = `&lt;span class=&quot;midnight-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                }
            }
            // 5. その他 (装飾がない場合はそのまま)
            else {
                formattedTerror = baseTerrorName;
            }
            
            // --- HFAの太字装飾の適用 (既存の装飾を上書きするため最後に適用) ---
            if (isCurrentTerrorHFA) {
                if (terror.includes(&#039;(&#039;) &amp;&amp; terror.includes(&#039;)&#039;)) {
                    const parts = terror.match(/(.+?)\s*\((.+?)\)/);
                    if (parts) {
                        formattedTerror = `${parts[1]} (&lt;span class=&quot;hfa-terror&quot;&gt;${parts[2]}&lt;/span&gt;)`;
                    }
                } else {
                    formattedTerror = `&lt;span class=&quot;hfa-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                }
            }
            
            // BloodbathのEX/DoubleTroubleの装飾を再適用 (HFAの黒太字を上書きしないように)
            if (terror.startsWith(&quot;Double Trouble&quot;) || terror.startsWith(&quot;EX&quot;)) {
                 formattedTerror = `&lt;strong&gt;${formattedTerror}&lt;/strong&gt;`;
            }
            
            terrorsHtml.push(formattedTerror);
        }
        
        
        // --- プレフィックスの結合 ---
        let finalPrefixHtml = moonPrefixHtml;
        
        if (itsSoOverColor === &#039;blue&#039;) {
            finalPrefixHtml += `&lt;span class=&quot;its-so-over-blue&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
        } else if (itsSoOverColor === &#039;red&#039;) {
            finalPrefixHtml += `&lt;span class=&quot;its-so-over-red&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
        }
        
        if (isHFA) {
            finalPrefixHtml += `&lt;span class=&quot;hfa-prefix&quot;&gt;[HFA]&lt;/span&gt; `;
        }

        // Bloodbathの特殊フォーマットを処理
        if (round === &quot;Bloodbath&quot; &amp;&amp; (terrors[0].startsWith(&quot;Double Trouble&quot;) || terrors[0].startsWith(&quot;EX&quot;))) {
            const type = terrorsHtml.shift(); 
            
            if (terrors[0].startsWith(&quot;EX&quot;)) {
                 return `${finalPrefixHtml}${type} @ ${stage}`; 
            } 
            
            const terrorList = terrorsHtml.join(&#039; / &#039;);
            const typeNoTag = type.replace(/&lt;[^&gt;]*&gt;/g, &#039;&#039;);
            return `${finalPrefixHtml}${typeNoTag} (${terrorList}) @ ${stage}`;
            
        }
        
        // その他のラウンドの表示
        const terrorDisplay = terrorsHtml.join(&#039; / &#039;);
        
        return `${finalPrefixHtml}${terrorDisplay} @ ${stage}`;
    }

    // --- メイン実行関数 ---
    function runSelection() {
        const round = document.getElementById(&#039;roundSelect&#039;).value;
        const countSelect = document.getElementById(&#039;countSelect&#039;);
        const count = parseInt(countSelect.value, 10);
        const resultsDisplay = document.getElementById(&#039;results-display&#039;);
        resultsDisplay.innerHTML = &#039;&#039;; 

        if (isNaN(count) || count &lt; 1) {
            resultsDisplay.innerHTML = &#039;&lt;p&gt;連数を正しく選択してください。&lt;/p&gt;&#039;;
            return;
        }
        
        // 累計回数を更新
        totalDraws += count;
        saveTotalDrawCount();
        updateTotalDrawDisplay();

        for (let i = 0; i &lt; count; i++) {
            const result = selectTerrorsAndStage(round);
            
            // 通知チェック (優先度順: Glorbo &gt; ムーン &gt; TBH実績 &gt; ME &gt; SOS &gt; EX &gt; It&#039;s so over)
            if (result.isGlorbo) {
                showGlorboNotification();
            } else if (result.isMoon) {
                // ムーン通知は不要 (表示で十分)
            } else if (result.isTBHAchievement) { // TBH実績通知チェック
                showTBHAchievementNotification();
            } else if (result.isME) { // ME通知チェック
                showMENotification();
            } else if (result.isSOSReplacementEvent) { // S.O.S.特殊置換通知チェック
                showSOSNotification();
            } else if (round === &quot;Bloodbath&quot; &amp;&amp; result.terrors.length &gt; 0 &amp;&amp; result.terrors[0].startsWith(&quot;EX (&quot;)) {
                 showEXNotification();
            } else if (result.itsSoOverColor) {
                showItsSoOverNotification();
            } 

            const formattedResult = formatResult(round, result);

            const resultDiv = document.createElement(&#039;div&#039;);
            resultDiv.classList.add(&#039;result-item&#039;);
            resultDiv.innerHTML = `${i + 1}連目: ${formattedResult}`;
            resultsDisplay.appendChild(resultDiv);
        }
    }

    // --- 画像保存関数 ---
    function saveAsImage() {
        const node = document.getElementById(&#039;results-display&#039;);
        
        domtoimage.toPng(node)
            .then(function (dataUrl) {
                const link = document.createElement(&#039;a&#039;);
                link.download = `選出結果_${document.getElementById(&#039;roundSelect&#039;).value}_${new Date().toLocaleTimeString().replace(/:/g, &#039;-&#039;)}.png`;
                link.href = dataUrl;
                link.click();
            })
            .catch(function (error) {
                console.error(&#039;画像保存に失敗しました:&#039;, error);
                alert(&#039;結果を画像として保存できませんでした。ブラウザのコンソールを確認してください。&#039;);
            });
    }

    // --- 初期化 ---
    document.addEventListener(&#039;DOMContentLoaded&#039;, () =&gt; {
        loadTotalDrawCount();
        
        document.getElementById(&#039;results-display&#039;).innerHTML = &#039;&lt;p style=&quot;text-align: center; color: #777;&quot;&gt;ラウンドと連数を選択し、「選出！」ボタンを押してください。&lt;/p&gt;&#039;;
        document.getElementById(&#039;exNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;itsSoOverNotification&#039;).classList.remove(&#039;show&#039;); 
        document.getElementById(&#039;meNotification&#039;).classList.remove(&#039;show&#039;); 
        document.getElementById(&#039;sosNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;tbhAchievementNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;glorboNotification&#039;).classList.remove(&#039;show&#039;);
        setButtonState(false);
        
        // ラウンド変更時のリセットイベントを設定
        document.getElementById(&#039;roundSelect&#039;).addEventListener(&#039;change&#039;, resetDrawCountIfRoundChanged);
    });

&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
}


ver1.1
・狂気とミッドナイトのシナジーが出た場合に名前を変更して色が付くようにしました
ver1.1.1
・おるでんが出禁ラウンドでS.O.Sの塗り替えで出た場合に太文字の茶色で表示されるようにしました
ver1.1.2
・ぶるはけは青色で表示されるようにしました
ver1.2
・何回ガチャを回したかの表示
・ブラバでEXが出た時に通知+1秒間ボタンを押せなくして連打をしてもEXがしっかり見れるようにしました
ver1.3
・It&#039;s so overを表示するようにしました
ver1.3.1
・It&#039;s so overが選出されると通知が出るようにしました
ver1.4
・HFAを表示するようにしました
ver1.4.1
・ミッドナイトでラウンド選出が不可能になるバグを修正しました
ver1.4.2
・MEを表示するようにしました
ver1.5
・ムーン上書きボタンを追加しました
クラシック、オルタネイト以外で1/80でムーン上書きをし、そこから3種類(ブラフォレのみ4種類)のムーンをランダムで上書きとして出すようにしました
※ムーン上書きには諸説ありますが、ネタのサイトという事で許してください
ver1.5.1
・出禁ラウンドでおるでんが選出されると通知が出るようにしました
・ムーン上書きによるバグを修正しました
ver1.6
・TBHまたはTBH SPYをステージ：TBHで引いた時に通知を追加しました
ver1.7
・Glorboを追加しました
※バグ等見つかればぜひamutoppoのDiscordのDMまで！    </description>
    <dc:date>2026-04-11T16:28:11+09:00</dc:date>
    <utime>1775892491</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/14.html">
    <title>全虹ミッドちぇっかー</title>
    <link>https://w.atwiki.jp/tontool/pages/14.html</link>
    <description>
      #javascript(){

&lt;style&gt;
    /* このツール専用のスタイル定義 */
    .ton-calc-widget {
        /* 変数定義（このウィジェット内のみ有効） */
        --tcw-bg: #ffffff;
        --tcw-text: #333333;
        --tcw-sub: #666666;
        --tcw-border: #e1e4e8;
        --tcw-input-bg: #f8f9fa;
        --tcw-primary: #3b82f6;
        --tcw-primary-hover: #2563eb;
        --tcw-bb: #ef4444;
        --tcw-mn: #8b5cf6;
        --tcw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
        
        font-family: inherit;
        background-color: var(--tcw-bg);
        color: var(--tcw-text);
        padding: 20px;
        border-radius: 12px;
        box-shadow: var(--tcw-shadow);
        border: 1px solid var(--tcw-border);
        max-width: 450px;
        margin: 20px auto;
        box-sizing: border-box;
    }

    /* ダークモード対応 */
    @media (prefers-color-scheme: dark) {
        .ton-calc-widget {
            --tcw-bg: #1f2937;
            --tcw-text: #f3f4f6;
            --tcw-sub: #9ca3af;
            --tcw-border: #374151;
            --tcw-input-bg: #111827;
            --tcw-primary: #60a5fa;
            --tcw-primary-hover: #3b82f6;
            --tcw-bb: #f87171;
            --tcw-mn: #a78bfa;
            --tcw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
        }
    }

    .ton-calc-widget h2.widget-title {
        text-align: center;
        font-size: 1.25rem;
        margin: 0 0 1.5rem 0;
        font-weight: 700;
        color: var(--tcw-text);
        border: none;
        line-height: 1.5;
    }

    .ton-calc-widget .input-group {
        margin-bottom: 1rem;
    }

    .ton-calc-widget label {
        display: block;
        margin-bottom: 0.4rem;
        font-weight: 600;
        font-size: 0.9rem;
        color: var(--tcw-text);
    }

    .ton-calc-widget .input-wrapper {
        position: relative;
        display: flex;
        align-items: center;
    }

    .ton-calc-widget input[type=&quot;number&quot;] {
        width: 100%;
        padding: 10px 14px;
        padding-right: 60px; 
        box-sizing: border-box;
        border: 2px solid var(--tcw-border);
        border-radius: 8px;
        background-color: var(--tcw-input-bg);
        color: var(--tcw-text);
        font-size: 1rem;
        outline: none;
        transition: border-color 0.2s;
    }

    .ton-calc-widget input[type=&quot;number&quot;]:focus {
        border-color: var(--tcw-primary);
    }

    .ton-calc-widget .helper-text {
        position: absolute;
        right: 14px;
        color: var(--tcw-sub);
        font-size: 0.85rem;
        pointer-events: none;
    }

    .ton-calc-widget button.calc-btn {
        width: 100%;
        padding: 12px;
        background-color: var(--tcw-primary);
        color: #ffffff;
        border: none;
        border-radius: 8px;
        font-size: 1rem;
        font-weight: 600;
        cursor: pointer;
        margin-top: 0.5rem;
        transition: opacity 0.2s;
    }

    .ton-calc-widget button.calc-btn:hover {
        opacity: 0.9;
    }

    .ton-calc-widget .results-container {
        margin-top: 1.5rem;
        display: none;
        gap: 10px;
        flex-direction: column;
    }

    .ton-calc-widget .result-card {
        background-color: var(--tcw-input-bg);
        padding: 12px 16px;
        border-radius: 8px;
        border-left-width: 5px;
        border-left-style: solid;
    }

    .ton-calc-widget .result-card.bb { border-left-color: var(--tcw-bb); }
    .ton-calc-widget .result-card.mn { border-left-color: var(--tcw-mn); }

    .ton-calc-widget .res-head {
        display: flex;
        justify-content: space-between;
        font-size: 0.85rem;
        font-weight: 700;
        text-transform: uppercase;
        margin-bottom: 4px;
    }
    
    .ton-calc-widget .bb .res-head { color: var(--tcw-bb); }
    .ton-calc-widget .mn .res-head { color: var(--tcw-mn); }

    .ton-calc-widget .res-val {
        font-size: 1.4rem;
        font-weight: 700;
        color: var(--tcw-text);
        line-height: 1.2;
    }

    .ton-calc-widget .res-sub {
        font-size: 0.8rem;
        color: var(--tcw-sub);
        margin-top: 4px;
    }

    .ton-calc-widget .note {
        margin-top: 1rem;
        font-size: 0.75rem;
        color: var(--tcw-sub);
        text-align: center;
        line-height: 1.4;
    }
&lt;/style&gt;

&lt;div class=&quot;ton-calc-widget&quot;&gt;
    &lt;h2 class=&quot;widget-title&quot;&gt;全虹確率計算機&lt;/h2&gt;

    &lt;div class=&quot;input-group&quot;&gt;
        &lt;label&gt;クラシックテラー虹数&lt;/label&gt;
        &lt;div class=&quot;input-wrapper&quot;&gt;
            &lt;input type=&quot;number&quot; id=&quot;tcw-classic&quot; placeholder=&quot;0&quot; min=&quot;0&quot; max=&quot;130&quot;&gt;
            &lt;span class=&quot;helper-text&quot;&gt;/ 130&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;input-group&quot;&gt;
        &lt;label&gt;オルタネイトテラー虹数&lt;/label&gt;
        &lt;div class=&quot;input-wrapper&quot;&gt;
            &lt;input type=&quot;number&quot; id=&quot;tcw-alt&quot; placeholder=&quot;0&quot; min=&quot;0&quot; max=&quot;36&quot;&gt;
            &lt;span class=&quot;helper-text&quot;&gt;/ 36&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;button class=&quot;calc-btn&quot; onclick=&quot;tcwCalculate()&quot;&gt;計算する&lt;/button&gt;

    &lt;div id=&quot;tcw-results&quot; class=&quot;results-container&quot;&gt;
        &lt;div class=&quot;result-card bb&quot;&gt;
            &lt;div class=&quot;res-head&quot;&gt;Bloodbath&lt;/div&gt;
            &lt;div class=&quot;res-val&quot; id=&quot;tcw-res-bb&quot;&gt;-%&lt;/div&gt;
            &lt;div class=&quot;res-sub&quot; id=&quot;tcw-sub-bb&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;result-card mn&quot;&gt;
            &lt;div class=&quot;res-head&quot;&gt;Midnight&lt;/div&gt;
            &lt;div class=&quot;res-val&quot; id=&quot;tcw-res-mn&quot;&gt;-%&lt;/div&gt;
            &lt;div class=&quot;res-sub&quot; id=&quot;tcw-sub-mn&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;note&quot;&gt;※ダブルトラブル、EX、Lv2ミッドナイト等は考慮していません出禁ではないテラーの虹の数を入力してください。&lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
    function tcwCalculate() {
        // DOM要素の取得
        const elA = document.getElementById(&#039;tcw-classic&#039;);
        const elB = document.getElementById(&#039;tcw-alt&#039;);
        
        // 数値変換
        let a = parseInt(elA.value);
        let b = parseInt(elB.value);

        // 数値でない場合の処理
        if (isNaN(a)) a = 0;
        if (isNaN(b)) b = 0;

        // 範囲補正 (Classic上限を130に変更)
        const MAX_CLASSIC = 130;
        const MAX_ALT = 36;

        if (a &lt; 0) a = 0; 
        if (a &gt; MAX_CLASSIC) a = MAX_CLASSIC;
        
        if (b &lt; 0) b = 0; 
        if (b &gt; MAX_ALT) b = MAX_ALT;
        
        // 入力欄に補正値を反映
        elA.value = a;
        elB.value = b;

        // 計算ロジック
        // Bloodbath: クラシック(130)から3体選出
        // 式: a/130 * (a-1)/129 * (a-2)/128
        let probBB = 0;
        if (a &gt;= 3) {
            probBB = (a / 130) * ((a - 1) / 129) * ((a - 2) / 128);
        }

        // Midnight: クラシック(130)から2体 + オルタネイト(36)から1体選出
        // 式: a/130 * (a-1)/129 * b/36
        let probMN = 0;
        if (a &gt;= 2 &amp;&amp; b &gt;= 1) {
            probMN = (a / 130) * ((a - 1) / 129) * (b / 36);
        }

        // 表示整形関数
        const fmtP = function(v) {
            return (v * 100).toFixed(4) + &quot;%&quot;;
        };
        
        const fmtS = function(v) {
            if (v &lt;= 0) return &quot;発生なし&quot;;
            if (v &gt;= 1) return &quot;確定&quot;;
            // 「1 / 確率」を四捨五入して「およそN回に1回」の形にする
            const frac = Math.round(1 / v);
            return &quot;約 &quot; + frac.toLocaleString() + &quot; 回に1回&quot;;
        };

        // 結果のDOM反映
        document.getElementById(&#039;tcw-res-bb&#039;).textContent = fmtP(probBB);
        document.getElementById(&#039;tcw-sub-bb&#039;).textContent = fmtS(probBB);

        document.getElementById(&#039;tcw-res-mn&#039;).textContent = fmtP(probMN);
        document.getElementById(&#039;tcw-sub-mn&#039;).textContent = fmtS(probMN);

        // 結果表示エリアを表示（display:flexに変更）
        document.getElementById(&#039;tcw-results&#039;).style.display = &#039;flex&#039;;
    }
&lt;/script&gt;

}    </description>
    <dc:date>2026-04-11T16:27:40+09:00</dc:date>
    <utime>1775892460</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/13.html">
    <title>アップデートチェックラウンドガチャ</title>
    <link>https://w.atwiki.jp/tontool/pages/13.html</link>
    <description>
      #javascript(){
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;テラー/アンバウンド選出ツール&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: &#039;Segoe UI&#039;, Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f7f9;
            color: #333;
            padding: 20px;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background-color: #fff;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
        }
        h1 {
            color: #007bff;
            text-align: center;
            margin-bottom: 30px;
            border-bottom: 2px solid #e0e0e0;
            padding-bottom: 10px;
        }
        .controls, .result-section {
            margin-bottom: 25px;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 8px;
            background-color: #fafafa;
        }
        .controls label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }
        .controls select, .controls button {
            padding: 10px;
            margin-right: 15px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 16px;
        }
        .controls button {
            background-color: #28a745;
            color: white;
            cursor: pointer;
            border: none;
            transition: background-color 0.3s;
        }
        .controls button:hover {
            background-color: #218838;
        }
        /* ボタン無効化時のスタイル */
        .controls button:disabled {
            background-color: #90ee90; /* 薄い緑 */
            cursor: not-allowed;
            opacity: 0.6;
        }
        .checkbox-group {
            display: flex;
            align-items: center;
            margin-top: 15px;
            gap: 20px;
        }
        .checkbox-group input {
            transform: scale(1.5);
            margin-right: 5px;
        }

        #results-display {
            border: 3px solid #007bff;
            padding: 20px;
            border-radius: 10px;
            background-color: #eaf3ff;
            min-height: 100px;
        }
        .result-item {
            font-size: 24px;
            margin-bottom: 15px;
            padding: 10px;
            background-color: #fff;
            border-left: 5px solid #007bff;
            border-radius: 5px;
        }
        .result-item:last-child {
            margin-bottom: 0;
        }
        /* Bloodbathの昇格表示 */
        .result-item strong {
            color: #d9534f;
        }
        /* Monarchの特殊装飾 (Midnight/赤太字) */
        .monarch-terror {
            color: #FF0000;
            font-weight: bold;
        }
        /* Crackedの装飾 (変換されたテラーのみ/紫色) */
        .cracked-terror {
            color: #800080; 
        }
        /* Midnightの装飾 (変換されたテラーのみ/赤色) */
        .midnight-terror {
            color: #FF0000; 
        }
        /* Blue Haketの特殊装飾 (Midnight/青色) */
        .blue-midnight-terror {
            color: #0000FF; 
        }
        /* S.O.S.からのThose Olden Days置き換え（茶色太字）*/
        .sos-replacement-terror {
            color: #964B00; /* Brown color */
            font-weight: bold;
        }
        /* Fusion Pilot特殊装飾: Alternate/青太字 */
        .its-so-over-blue {
            color: #00008b; /* Dark Blue */
            font-weight: bold;
        }
        /* Fusion Pilot特殊装飾: Midnight/赤太字 */
        .its-so-over-red {
            color: #ff0000; /* Red */
            font-weight: bold;
        }
        
        /* HFAの装飾 (緑太字) */
        .hfa-prefix {
            color: #006400; /* Dark Green */
            font-weight: bold;
        }
        /* HFAで太字化されるテラーの装飾 (黒色太字、他の色装飾より優先) */
        .hfa-terror {
            font-weight: bold !important;
            color: #000000; /* Black */
        }
        
        /* MEの装飾 (青太字) */
        .me-terror {
             color: #00008b; /* Dark Blue */
            font-weight: bold;
        }
        
        /* --- MOON COLORS --- */
        .moon-twilight { 
            color: #FFD700; /* Yellow */
            font-weight: bold;
        }
        .moon-mystic { 
            color: #0000FF; /* Blue */
            font-weight: bold;
        }
        .moon-blood { 
            color: #FF0000; /* Red */
            font-weight: bold;
        }
        .moon-solstice { 
            color: #008000; /* Green */
            font-weight: bold;
        }

        /* --- Notification Toast Style --- */
        .notification-toast {
            visibility: hidden; 
            min-width: 250px;
            background-color: #d9534f; 
            color: #fff;
            text-align: center;
            border-radius: 5px;
            padding: 16px;
            position: fixed;
            z-index: 100; 
            left: 50%;
            top: 50%; 
            transform: translate(-50%, -50%);
            font-size: 28px;
            font-weight: bold;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
            opacity: 0;
            transition: opacity 0.3s, visibility 0.3s;
        }
        
        #sosNotification {
             background-color: #964B00; /* Brown */
        }
        
        #tbhAchievementNotification {
             background-color: #008080; /* Teal/濃い水色 */
        }
        
        #glorboNotification { /* 新しい通知のスタイル */
            background-color: #8A2BE2; /* BlueViolet/青紫 */
            color: #FFFFFF;
        }

        .notification-toast.show {
            visibility: visible;
            opacity: 1;
        }
        
        /* 累計回数表示 */
        .result-title-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
        }
        .total-draws {
            font-size: 1.2em;
            font-weight: bold;
            color: #007bff;
            background-color: #e0f7fa;
            padding: 5px 10px;
            border-radius: 5px;
            border: 1px solid #00bcd4;
        }

        #saveImage {
            background-color: #f0ad4e;
            color: white;
            margin-top: 10px;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        #saveImage:hover {
            background-color: #ec971f;
        }
        .result-title {
            font-size: 1.2em;
            font-weight: bold;
            color: #007bff;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div class=&quot;container&quot;&gt;
    &lt;h1&gt;テラー/アンバウンド選出ツール ver1.7.1&lt;/h1&gt;

    &lt;div class=&quot;controls&quot;&gt;
        &lt;label for=&quot;roundSelect&quot;&gt;ラウンドを選ぶ:&lt;/label&gt;
        &lt;select id=&quot;roundSelect&quot;&gt;
            &lt;option value=&quot;Classic&quot;&gt;Classic / クラシック&lt;/option&gt;
            &lt;option value=&quot;Alternate&quot;&gt;Alternate / オルタネイト&lt;/option&gt;
            &lt;option value=&quot;Punished&quot;&gt;Punished / パニッシュ&lt;/option&gt;
            &lt;option value=&quot;Cracked&quot;&gt;Cracked / 狂気&lt;/option&gt;
            &lt;option value=&quot;Sabotage&quot;&gt;Sabotage / サボタージュ&lt;/option&gt;
            &lt;option value=&quot;Bloodbath&quot;&gt;Bloodbath / ブラッドバス&lt;/option&gt;
            &lt;option value=&quot;Midnight&quot;&gt;Midnight / ミッドナイト&lt;/option&gt;
            &lt;option value=&quot;Unbound&quot;&gt;Unbound / アンバウンド&lt;/option&gt;
        &lt;/select&gt;

        &lt;label for=&quot;countSelect&quot; style=&quot;margin-top: 15px;&quot;&gt;連数を選ぶ:&lt;/label&gt;
        &lt;select id=&quot;countSelect&quot;&gt;
            &lt;option value=&quot;1&quot;&gt;1連&lt;/option&gt;
            &lt;option value=&quot;10&quot;&gt;10連&lt;/option&gt;
            &lt;option value=&quot;20&quot;&gt;20連&lt;/option&gt;
            &lt;option value=&quot;30&quot;&gt;30連&lt;/option&gt;
            &lt;option value=&quot;40&quot;&gt;40連&lt;/option&gt;
            &lt;option value=&quot;50&quot;&gt;50連&lt;/option&gt;
        &lt;/select&gt;
        
        &lt;div class=&quot;checkbox-group&quot;&gt;
            &lt;label for=&quot;moonOverwrite&quot;&gt;
                &lt;input type=&quot;checkbox&quot; id=&quot;moonOverwrite&quot;&gt;
                ムーン上書きを有効にする (1/80)
            &lt;/label&gt;
        &lt;/div&gt;

        &lt;button id=&quot;runButton&quot; onclick=&quot;runSelection()&quot;&gt;選出！&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;result-section&quot;&gt;
        &lt;div class=&quot;result-title-container&quot;&gt;
            &lt;div class=&quot;result-title&quot;&gt;✨ 選出結果 ✨&lt;/div&gt;
            &lt;div class=&quot;total-draws&quot;&gt;累計選出回数: &lt;span id=&quot;totalDrawCount&quot;&gt;0&lt;/span&gt; 回&lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&quot;results-display&quot;&gt;
            &lt;/div&gt;
        &lt;button id=&quot;saveImage&quot; onclick=&quot;saveAsImage()&quot;&gt;結果を画像として保存&lt;/button&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;exNotification&quot; class=&quot;notification-toast&quot;&gt;
    EXが選出されました！
&lt;/div&gt;

&lt;div id=&quot;itsSoOverNotification&quot; class=&quot;notification-toast&quot;&gt;
    It&#039;s so overが選出されました！
&lt;/div&gt;

&lt;div id=&quot;meNotification&quot; class=&quot;notification-toast&quot;&gt;
    ME (Mega Evolution) が選出されました！
&lt;/div&gt;

&lt;div id=&quot;sosNotification&quot; class=&quot;notification-toast&quot;&gt;
    S.O.S.の特殊置換が発生しました！
&lt;/div&gt;

&lt;div id=&quot;tbhAchievementNotification&quot; class=&quot;notification-toast&quot;&gt;
    TBHの実績を獲得しました！
&lt;/div&gt;

&lt;div id=&quot;glorboNotification&quot; class=&quot;notification-toast&quot;&gt;
    テラー名がGlorboに上書きされました！
&lt;/div&gt;


&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
    // --- データ一覧 ---
    const CLASSIC_TERRORS = [
        &quot;Huggy&quot;, &quot;Corrupted Toys&quot;, &quot;Demented Spongebob&quot;, &quot;Specimen 8&quot;, &quot;HER&quot;, &quot;Tails Doll&quot;, &quot;Black Sun&quot;, &quot;Aku Ball&quot;, &quot;Ao Oni&quot;, &quot;Toren&#039;s Shadow&quot;,
        &quot;[CENSORED]&quot;, &quot;WhiteNight&quot;, &quot;An Arbiter&quot;, &quot;Specimen 5&quot;, &quot;Comedy&quot;, &quot;Purple Guy&quot;, &quot;Spongefly Swarm&quot;, &quot;Hush&quot;, &quot;MopeMope&quot;, &quot;Sawrunner&quot;,
        &quot;Imposter&quot;, &quot;Something&quot;, &quot;Starved&quot;, &quot;The Painter&quot;, &quot;The Guidance&quot;, &quot;With Many Voices&quot;, &quot;Nextbots&quot;, &quot;Harvest&quot;, &quot;Smileghost&quot;, &quot;Karol_Corpse&quot;,
        &quot;MX&quot;, &quot;Big Bird&quot;, &quot;Dev Bytes&quot;, &quot;Luigi &amp; Luigi Dolls&quot;, &quot;V2&quot;, &quot;Withered Bonnie&quot;, &quot;The Boys&quot;, &quot;Something Wicked&quot;, &quot;Seek&quot;, &quot;Rush&quot;,
        &quot;Sonic&quot;, &quot;Bad Batter&quot;, &quot;Signus&quot;, &quot;Mirror&quot;, &quot;Legs&quot;, &quot;Mona &amp; The Mountain&quot;, &quot;Judgement Bird&quot;, &quot;Slender&quot;, &quot;Maul-A-Child&quot;, &quot;Garten Goers&quot;,
        &quot;Don&#039;t Touch Me&quot;, &quot;Specimen 2&quot;, &quot;Specimen 10&quot;, &quot;The LifeBringer&quot;, &quot;Pale Association&quot;, &quot;Toy Enforcer&quot;, &quot;TBH&quot;, &quot;DoomBox&quot;, &quot;Christian Brutal Sniper&quot;, &quot;Nosk&quot;,
        &quot;Apocrean Harvester&quot;, &quot;Arkus&quot;, &quot;Cartoon Cat&quot;, &quot;Wario Apparition&quot;, &quot;Shinto&quot;, &quot;Hell Bell&quot;, &quot;Security&quot;, &quot;The Swarm&quot;, &quot;Shiteyanyo&quot;, &quot;Bacteria&quot;,
        &quot;Tiffany&quot;, &quot;HoovyDundy&quot;, &quot;Haket&quot;, &quot;Akumii-Kari&quot;, &quot;Lunatic Cultist&quot;, &quot;Sturm&quot;, &quot;Punishing Bird&quot;, &quot;Prisoner&quot;, &quot;Red Bus&quot;, &quot;Waterwraith&quot;,
        &quot;Astrum Aureus&quot;, &quot;Snarbolax&quot;, &quot;All-Around-Helpers&quot;, &quot;lain&quot;, &quot;Sakuya Izayoi&quot;, &quot;Arrival&quot;, &quot;Miros Birds&quot;, &quot;BFF&quot;, &quot;Scavenger&quot;, &quot;Tinky Winky&quot;,
        &quot;Tricky&quot;, &quot;Yolm&quot;, &quot;Red Fanatic&quot;, &quot;Dr. Tox&quot;, &quot;Ink Demon&quot;, &quot;Retep&quot;, &quot;Those Olden Days&quot;, &quot;S.O.S&quot;, &quot;Bigger Boot&quot;, &quot;The Pursuer&quot;,
        &quot;Spamton&quot;, &quot;Immortal Snail&quot;, &quot;Charlotte&quot;, &quot;Herobrine&quot;, &quot;Peepy&quot;, &quot;The Jester&quot;, &quot;Wild Yet Curious Creature&quot;, &quot;Manti&quot;, &quot;Horseless Headless Horsemann&quot;, &quot;Ghost Girl&quot;,
        &quot;Cubor&#039;s Revenge&quot;, &quot;Poly&quot;, &quot;Dog Mimic&quot;, &quot;Warden&quot;, &quot;Fox Squad&quot;, &quot;Express Train To Hell&quot;, &quot;Deleted&quot;, &quot;Killer Fish&quot;, &quot;Terror of Nowhere&quot;, &quot;Beyond&quot;,
        &quot;The Origin&quot;, &quot;Time Ripper&quot;, &quot;This Killer does not exist&quot;, &quot;Parhelion&#039;s Victims&quot;, &quot;Bed Mecha&quot;, &quot;Killer Rabbit&quot;, &quot;Bravera&quot;, &quot;MissingNo&quot;, &quot;Living Shadow&quot;, &quot;The Plague Doctor&quot;,
        &quot;The Rat&quot;, &quot;Waldo&quot;, &quot;Clockey&quot;, &quot;Malicious Twins&quot;
    ];

    const ALTERNATE_TERRORS = [
        &quot;Decayed Sponge&quot;, &quot;WHITEFACE&quot;, &quot;Sanic&quot;, &quot;Parhelion&quot;, &quot;,D@;Q7Y&quot;, &quot;Chomper&quot;, &quot;The Knight of Toren&quot;, &quot;Tragedy&quot;, &quot;Apathy&quot;, &quot;MR.MEGA&quot;,
        &quot;sm64.z64&quot;, &quot;Convict Squad&quot;, &quot;Paradise Bird&quot;, &quot;Angry Munci&quot;, &quot;Lord&#039;s Signal&quot;, &quot;Feddys&quot;, &quot;TBH SPY&quot;, &quot;The Observation&quot;, &quot;Lisa&quot;, &quot;Judas&quot;,
        &quot;Glaggle Gang&quot;, &quot;Try Not To Touch Me&quot;, &quot;Ambush&quot;, &quot;Teuthida&quot;, &quot;Eggman&#039;s Announcement&quot;, &quot;S.T.G.M&quot;, &quot;Army in Black&quot;, &quot;Bliss&quot;, &quot;Roblander&quot;, &quot;Fusion Pilot&quot;,
        &quot;Joy&quot;, &quot;The Red Mist&quot;, &quot;Sakuya The Ripper&quot;, &quot;Walpurgisnacht&quot;, &quot;Dev Maulers&quot;, &quot;Restless Creator&quot;
    ];

    const UNBOUNDS = [
        &quot;Guidance &amp; The Booboo&#039;s&quot;, &quot;Red vs Blue&quot;, &quot;Third Trumpet&quot;, &quot;Forest Gurdians&quot;, &quot;Higher Beings&quot;, &quot;Quadruple Sponge&quot;, &quot;Your Best Friends&quot;, &quot;Hotel Monsters&quot;, &quot;Squibb Squad&quot;, &quot;Garden Rejects&quot;,
        &quot;Judgement Day&quot;, &quot;Me and My Shadow&quot;, &quot;Meltdown&quot;, &quot;Faceless Mafia&quot;, &quot;Mansion Monsters&quot;, &quot;Copyright Infringement&quot;, &quot;Purple Bros&quot;, &quot;Scavengers&quot;, &quot;Life &amp; Death&quot;, &quot;Labyrinth&quot;,
        &quot;Spiteful Shadows&quot;, &quot;Triple Munci&quot;, &quot;Daycare&quot;, &quot;Huggy Horde&quot;, &quot;Infection&quot;, &quot;Triple Hush&quot;, &quot;[CENSORED]&quot;, &quot;Byte Horde&quot;, &quot;SawMarathon&quot;, &quot;TAKE THE NAMI CHALLENGE&quot;,
        &quot;Thunderstorm&quot;, &quot;END OF THE WORLD&quot;, &quot;Fragmented Memories&quot;, &quot;Mona &amp; Mona &amp; Mona &amp; Mona&quot;, &quot;Seekers&quot;, &quot;Nugget Squad&quot;, &quot;Saul&#039;s goodmen&quot;, &quot;Something Old,Something New&quot;, &quot;POV: Bug&quot;, &quot;Punishing Birdemic&quot;,
        &quot;Double Ao Oni&quot;, &quot;Too Many Voices&quot;, &quot;Memory Crypts&quot;, &quot;Zumbo Sauce&quot;, &quot;Freaks&quot;, &quot;Lunatic Cult&quot;, &quot;Transportation Trio &amp; The Drifter&quot;, &quot;Father Son Bonding&quot;, &quot;WHAT IS MY NAME&quot;, &quot;Glaggleland Cremators&quot;,
        &quot;Triple Signus&quot;, &quot;Triple Akumii Kari&quot;, &quot;Black &amp; White&quot;, &quot;[LESSER CENSORED]&quot;, &quot;Blue Monsters&quot;, &quot;Drones&quot;, &quot;Scrapyard Takers&quot;, &quot;Luigi Dolls&quot;, &quot;Meteor Shower&quot;, &quot;Triple TBH&quot;,
        &quot;Lost Souls&quot;, &quot;Ballin&quot;, &quot;Reunion&quot;, &quot;Angels&quot;, &quot;Ordinary Apocalypse Bird&quot;, &quot;Pack of Wild Yet Curious Creatures&quot;, &quot;ToN X SlashCo Collab&quot;, &quot;Pack of Yolm&quot;, &quot;Threepy&quot;, &quot;???&quot;,
        &quot;Delete Me&quot;, &quot;Spamton Spam&quot;, &quot;Death From Above&quot;, &quot;It Came From Bus To Nowhere&quot;, &quot;Zombie Apocalypse&quot;, &quot;Eating Contest&quot;, &quot;Triple Clockey&quot;, &quot;Triple Killer Fish&quot;, &quot;Lethal League&quot;, &quot;Trollage&quot;,
        &quot;Mopemopemopemopemopemope&quot;, &quot;Triple Trouble&quot;, &quot;Triple Living Shadow&quot;, &quot;Beyond&#039;s Masks&quot;
    ];

    const STAGES = [
        &quot;Alter&quot;, &quot;Ancient&quot;, &quot;Astral&quot;, &quot;Baseplate&quot;, &quot;Backrooms&quot;, &quot;Challenge Cube&quot;, &quot;Black Forest&quot;, &quot;Cheese Maze&quot;,
        &quot;Chess&quot;, &quot;Construct&quot;, &quot;Desktop&quot;, &quot;Development&quot;, &quot;Dots&quot;, &quot;Dust&quot;, &quot;Elevator&quot;, &quot;Engine&quot;, &quot;Escape Route&quot;,
        &quot;Experimentation&quot;, &quot;Forest&quot;, &quot;Gaol&quot;, &quot;Gardens&quot;, &quot;Garten&quot;, &quot;Isolation&quot;, &quot;Have&quot;, &quot;Harvest&quot;, &quot;Heaven&quot;, &quot;Hell&quot;,
        &quot;Hightower&quot;, &quot;Iteration_0&quot;, &quot;Hole&quot;, &quot;Hotel&quot;, &quot;Hub&quot;, &quot;Inner Tower&quot;, &quot;Innyume&quot;, &quot;Lounge&quot;, &quot;Luna Hills&quot;, &quot;Mall&quot;,
        &quot;Mineshaft&quot;, &quot;Museum&quot;, &quot;Neon Towers (紫)&quot;, &quot;Neon Towers (緑)&quot;, &quot;Nexus&quot;, &quot;Nightlife&quot;, &quot;Orange&quot;, &quot;Park&quot;, &quot;Pizzeria&quot;, &quot;Playplace&quot;,
        &quot;Pools&quot;, &quot;Robland&quot;, &quot;Sanctum&quot;, &quot;Schoolhouse&quot;, &quot;Scrapyard&quot;, &quot;Sea Base&quot;, &quot;Secret&quot;, &quot;Sewers&quot;, &quot;Skyscraper&quot;, &quot;Slashco HQ&quot;,
        &quot;Snowfield&quot;, &quot;Space Colony&quot;, &quot;Spaceless&quot;, &quot;Subway&quot;, &quot;Supply Route&quot;, &quot;TBH&quot;, &quot;The Fishbowl&quot;, &quot;The Wall&quot;, &quot;This Map Does Not Exist&quot;, &quot;Throne&quot;,
        &quot;Tunnels&quot;, &quot;Vents&quot;, &quot;Wafflehouse&quot;, &quot;Warehouse&quot;, &quot;Blackspace&quot;, &quot;Carpark&quot; 
    ];
    
    const CRACKED_TRANSFORM = {
        &quot;Withered Bonnie&quot;: &quot;Epic Bonnie&quot;,
        &quot;TBH&quot;: &quot;TBH SANS&quot;
    };

    const MIDNIGHT_TRANSFORM = {
        &quot;Haket&quot;: &quot;Blue Haket&quot;,
        &quot;Roblander&quot;: &quot;Inverted Roblander&quot;,
        &quot;The Knight of Toren&quot;: &quot;Kimera&quot;,
        &quot;Judas&quot;: &quot;Monarch&quot;,
        &quot;BFF&quot;: &quot;Nameless&quot;,
        &quot;Snarbolax&quot;: &quot;Rabid Snarbolax&quot;,
        &quot;Sonic&quot;: &quot;Rewrite&quot;,
        &quot;Withered Bonnie&quot;: &quot;Ruinborn Afton&quot;,
        &quot;The LifeBringer&quot;: &quot;Scrapyard Machine&quot;,
        &quot;Dev Bytes&quot;: &quot;Search and Destroy&quot;,
        &quot;Slender&quot;: &quot;Slendy&quot;,
        &quot;Bad Batter&quot;: &quot;The Batter&quot;
    };
    
    // 変換元テラーのリスト
    const CRACKED_TRANSFORM_SOURCES = Object.keys(CRACKED_TRANSFORM);
    const MIDNIGHT_TRANSFORM_SOURCES = Object.keys(MIDNIGHT_TRANSFORM);

    const CRACKED_TRANSFORMED_NAMES = Object.values(CRACKED_TRANSFORM);
    const MIDNIGHT_TRANSFORMED_NAMES = Object.values(MIDNIGHT_TRANSFORM);
    
    // --- HFAの組み合わせデータ構造 ---
    const HFA_COMBINATIONS = [
        { stage: &quot;Hotel&quot;, terrors: [&quot;Seek&quot;, &quot;Rush&quot;, &quot;Ambush&quot;] }, 
        { stage: [&quot;Hightower&quot;, &quot;Harvest&quot;], terrors: [&quot;Christian Brutal Sniper&quot;, &quot;Horseless Headless Horsemann&quot;, &quot;HoovyDundy&quot;] }, 
        { stage: &quot;Blackspace&quot;, terrors: [&quot;Something&quot;] },
        { stage: &quot;Scrapyard&quot;, terrors: [&quot;The LifeBringer&quot;] },
        { stage: &quot;Robland&quot;, terrors: [&quot;Roblander&quot;] },
        { stage: &quot;Isolation&quot;, terrors: [&quot;Specimen 2&quot;, &quot;Specimen 5&quot;, &quot;Specimen 8&quot;, &quot;Specimen 10&quot;, &quot;Lisa&quot;] },
        { stage: &quot;Secret&quot;, terrors: [&quot;V2&quot;, &quot;Something Wicked&quot;] },
        { stage: &quot;Innyume&quot;, terrors: [&quot;Smileghost&quot;] },
        { stage: &quot;Pizzeria&quot;, terrors: [&quot;Withered Bonnie&quot;, &quot;Purple Guy&quot;, &quot;The Origin&quot;, &quot;Feddys&quot;] },
        { stage: &quot;Carpark&quot;, terrors: [&quot;HER&quot;, &quot;WHITEFACE&quot;] },
        { stage: &quot;TBH&quot;, terrors: [&quot;TBH&quot;, &quot;TBH SPY&quot;] },
        { stage: &quot;Experimentation&quot;, terrors: [&quot;The Jester&quot;, &quot;Ghost Girl&quot;] },
        { stage: &quot;Backrooms&quot;, terrors: [&quot;Bacteria&quot;] },
        { stage: &quot;Gaol&quot;, terrors: [&quot;Prisoner&quot;, &quot;Security&quot;, &quot;The Swarm&quot;, &quot;Poly&quot;] },
        { stage: &quot;Slashco HQ&quot;, terrors: [&quot;Comedy&quot;, &quot;Manti&quot;] },
        { stage: &quot;Have&quot;, terrors: [&quot;Terror of Nowhere&quot;] },
        { stage: &quot;Garten&quot;, terrors: [&quot;Garten Goers&quot;] },
        { stage: &quot;Astral&quot;, terrors: [&quot;Astrum Aureus&quot;] },
        { stage: &quot;Hell&quot;, terrors: [&quot;Parhelion&quot;] },
        { stage: &quot;Hub&quot;, terrors: [&quot;Mirror&quot;, &quot;Terror of Nowhere&quot;, &quot;BFF&quot;] },
        { stage: &quot;Luna Hills&quot;, terrors: [&quot;Judas&quot;] },
        { stage: &quot;Throne&quot;, terrors: [&quot;Beyond&quot;] },
        { stage: &quot;Challenge Cube&quot;, terrors: [&quot;Apathy&quot;, &quot;Maul-A-Child&quot;, &quot;Killer Fish&quot;, &quot;Joy&quot;] }
    ];
    
    // --- MOONデータ構造 ---
    const MOON_TYPES = [
        { name: &quot;Twilight&quot;, css: &quot;moon-twilight&quot; },
        { name: &quot;Mystic Moon&quot;, css: &quot;moon-mystic&quot; },
        { name: &quot;Blood Moon&quot;, &quot;css&quot;: &quot;moon-blood&quot; },
        { name: &quot;Solstice&quot;, css: &quot;moon-solstice&quot; }
    ];
    const STANDARD_MOONS = MOON_TYPES.slice(1); // Twilight以外

    /**
     * HFA条件に合致するかチェックし、合致したテラー名を返す
     * @param {string[]} terrors - HFA判定に使うテラー名（変換前のテラー名）
     * @param {string} stage - 選出されたステージ名
     * @returns {{ isHFA: boolean, hfaTerrors: string[] }}
     */
    function checkHFA(terrors, stage) {
        const hfaTerrors = [];
        let isHFA = false;

        for (const combo of HFA_COMBINATIONS) {
            const stagesToCheck = Array.isArray(combo.stage) ? combo.stage : [combo.stage];
            
            if (stagesToCheck.includes(stage)) {
                
                for (const terror of terrors) {
                    if (combo.terrors.includes(terror)) {
                        isHFA = true;
                        if (!hfaTerrors.includes(terror)) {
                            hfaTerrors.push(terror);
                        }
                    }
                }
            }
        }

        return { isHFA, hfaTerrors: isHFA ? hfaTerrors : [] };
    }


    // --- 累計回数管理 ---
    let totalDraws = 0;
    let lastSelectedRound = null;

    function loadTotalDrawCount() {
        const storedDraws = localStorage.getItem(&#039;totalDraws&#039;);
        const storedRound = localStorage.getItem(&#039;lastSelectedRound&#039;);
        
        totalDraws = parseInt(storedDraws, 10) || 0;
        lastSelectedRound = storedRound || document.getElementById(&#039;roundSelect&#039;).value; 
        
        updateTotalDrawDisplay();
    }

    function saveTotalDrawCount() {
        localStorage.setItem(&#039;totalDraws&#039;, totalDraws.toString());
        localStorage.setItem(&#039;lastSelectedRound&#039;, document.getElementById(&#039;roundSelect&#039;).value);
    }

    function updateTotalDrawDisplay() {
        document.getElementById(&#039;totalDrawCount&#039;).textContent = totalDraws;
    }

    function resetDrawCountIfRoundChanged() {
        const currentRound = document.getElementById(&#039;roundSelect&#039;).value;
        
        if (lastSelectedRound !== null &amp;&amp; lastSelectedRound !== currentRound) {
            totalDraws = 0;
            lastSelectedRound = currentRound;
            localStorage.setItem(&#039;totalDraws&#039;, &#039;0&#039;);
        } else {
            lastSelectedRound = currentRound;
        }
        localStorage.setItem(&#039;lastSelectedRound&#039;, currentRound);
        updateTotalDrawDisplay();
    }


    // --- ユーティリティ関数 ---

    function selectRandom(arr) {
        if (!arr || arr.length === 0) return null;
        const index = Math.floor(Math.random() * arr.length);
        return arr[index];
    }

    function selectUniqueRandom(arr, count) {
        if (count &gt; arr.length) count = arr.length;
        const shuffled = arr.slice().sort(() =&gt; 0.5 - Math.random());
        return shuffled.slice(0, count);
    }
    
    function setButtonState(disabled) {
        document.getElementById(&#039;runButton&#039;).disabled = disabled;
    }

    // --- 通知管理システム (Queue) ---
    // 重複した通知を順番に処理するための関数群
    
    function showNotification(elementId, duration = 1000) {
        return new Promise((resolve) =&gt; {
            const notification = document.getElementById(elementId);
            
            notification.classList.remove(&#039;show&#039;); 
            void notification.offsetWidth; // Reflow triggers
            notification.classList.add(&#039;show&#039;);
            
            setTimeout(() =&gt; {
                notification.classList.remove(&#039;show&#039;);
                // 少しだけ待機してから次へ (視認性向上)
                setTimeout(resolve, 200); 
            }, duration);
        });
    }

    async function processNotificationQueue(queue) {
        if (queue.length === 0) {
            setButtonState(false);
            return;
        }
        
        setButtonState(true); // 再生中はボタン無効

        for (const notificationId of queue) {
            await showNotification(notificationId);
        }

        setButtonState(false); // 全て終わったらボタン有効
    }


    // --- メインロジック関数 ---

    /**
     * テラー選出のメインロジック
     */
    function selectTerrorsAndStage(round) {
        let initialTerrors = [];
        let stage = selectRandom(STAGES);
        let isSOSReplacementEvent = false;

        // 1. テラーの初期選出
        if (round === &quot;Classic&quot; || round === &quot;Punished&quot; || round === &quot;Cracked&quot; || round === &quot;Sabotage&quot;) {
            initialTerrors.push(selectRandom(CLASSIC_TERRORS));
        } else if (round === &quot;Alternate&quot;) {
            initialTerrors.push(selectRandom(ALTERNATE_TERRORS));
        } else if (round === &quot;Bloodbath&quot;) {
            for (let i = 0; i &lt; 3; i++) {
                initialTerrors.push(selectRandom(CLASSIC_TERRORS));
            }
        } else if (round === &quot;Midnight&quot;) {
            const classic2 = selectUniqueRandom(CLASSIC_TERRORS, 2);
            initialTerrors.push(classic2[0], classic2[1], selectRandom(ALTERNATE_TERRORS)); 
        } else if (round === &quot;Unbound&quot;) {
            initialTerrors.push(selectRandom(UNBOUNDS));
        }

        // --- 2. S.O.S.置き換え (Those Olden Daysへの特殊置換) ---
        const sosCheckStages = [&quot;Spaceless&quot;, &quot;Heaven&quot;, &quot;Escape Route&quot;];
        const needsSOSHighlight = [&quot;Punished&quot;, &quot;Bloodbath&quot;, &quot;Midnight&quot;].includes(round);
        
        let terrorsAfterSOSReplacement = initialTerrors.map(t =&gt; {
            if (t === &quot;S.O.S&quot; &amp;&amp; sosCheckStages.includes(stage) &amp;&amp; needsSOSHighlight) {
                isSOSReplacementEvent = true; // 特殊イベントフラグを立てる
                return &quot;Those Olden Days&quot;; 
            }
            return t;
        });
        
        // --- 3. ラウンド別出禁の適用 (Those Olden Daysは出禁だが、S.O.S.からの特殊置換の場合は除く) ---
        let bannedList = [];
        if (round === &quot;Bloodbath&quot;) {
            bannedList = [&quot;Luigi &amp; Luigi Dolls&quot;, &quot;Akumii-Kari&quot;, &quot;Those Olden Days&quot;, &quot;Deleted&quot;];
        } else if (round === &quot;Midnight&quot;) {
            bannedList = [&quot;Luigi &amp; Luigi Dolls&quot;, &quot;Akumii-Kari&quot;, &quot;Those Olden Days&quot;, &quot;Deleted&quot;, &quot;Specimen 5&quot;];
        } else if (round === &quot;Punished&quot;) {
            bannedList = [&quot;Those Olden Days&quot;, &quot;Cubor&#039;s Revenge&quot;];
        }

        let isMidnightBannedSubstitution = false;
        
        let terrorsAfterBanning = terrorsAfterSOSReplacement.map((t, index) =&gt; {
            // S.O.S.の特殊置換によるThose Olden Daysは出禁にしない
            if (isSOSReplacementEvent &amp;&amp; t === &quot;Those Olden Days&quot;) {
                return t;
            }

            // 標準の出禁ロジック
            if (bannedList.includes(t)) {
                if (round === &quot;Midnight&quot; &amp;&amp; index &lt; 2) { 
                    isMidnightBannedSubstitution = true;
                }
                return &quot;Comedy&quot;; 
            }
            return t;
        });

        // HFAチェック用のテラー名リスト (テラー名変更前の最終的なリスト)
        let terrorsForHFACheckBase = terrorsAfterBanning;

        // --- 4. HFA無効化チェック (Midnight/Crackedで変換されるテラーがHFA条件を満たす場合、無効化) ---
        let HFA_DISABLED_BY_TRANSFORM = [];
        if (round === &quot;Midnight&quot; || round === &quot;Cracked&quot;) {
            const transformSources = (round === &quot;Midnight&quot; ? MIDNIGHT_TRANSFORM_SOURCES : CRACKED_TRANSFORM_SOURCES);
            
            terrorsForHFACheckBase.forEach(t =&gt; {
                if (transformSources.includes(t)) {
                    for (const combo of HFA_COMBINATIONS) {
                        const stagesToCheck = Array.isArray(combo.stage) ? combo.stage : [combo.stage];
                        if (stagesToCheck.includes(stage) &amp;&amp; combo.terrors.includes(t)) {
                            HFA_DISABLED_BY_TRANSFORM.push(t);
                            break; 
                        }
                    }
                }
            });
        }
        
        // HFA判定に使う最終テラーリスト
        let terrorsForHFACheck = terrorsForHFACheckBase.filter(t =&gt; !HFA_DISABLED_BY_TRANSFORM.includes(t)); 


        // --- 5. ラウンド固有のテラー名変更と特殊タグ付け (表示用) ---
        let terrorsForDisplay = terrorsForHFACheckBase.slice();
        
        // S.O.S.特殊置換テラーにタグを付ける
        terrorsForDisplay = terrorsForDisplay.map(t =&gt; {
            if (isSOSReplacementEvent &amp;&amp; t === &quot;Those Olden Days&quot;) {
                t += &quot;&lt;SOS&gt;&quot;;
            }
            return t;
        });
        
        // Cracked/Midnightの変換
        if (round === &quot;Cracked&quot;) {
            terrorsForDisplay = terrorsForDisplay.map(t =&gt; CRACKED_TRANSFORM[t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;)] || t);
        } else if (round === &quot;Midnight&quot;) {
            terrorsForDisplay = terrorsForDisplay.map(t =&gt; MIDNIGHT_TRANSFORM[t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;)] || t);
        }

        // --- 6. BloodbathとMidnightの最終選出ロジック (表示用とHFAチェック用を分離して処理) ---
        let finalTerrors = [];
        let finalHfaCheckTerrors = []; 
        
        if (round === &quot;Bloodbath&quot;) {
            const terrorsNoTags = terrorsForDisplay.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim()); 
            const baseTerrorsNoTags = terrorsForHFACheckBase.map(t =&gt; t.split(&#039;(&#039;)[0].trim()); 

            const countMap = {};
            terrorsNoTags.forEach(t =&gt; countMap[t] = (countMap[t] || 0) + 1);
            const uniqueTerrors = Object.keys(countMap);
            
            const randomChance = Math.random(); 

            if (randomChance &lt; 3 / 35) {
                if (uniqueTerrors.length === 1) {
                    finalTerrors = [`EX (${uniqueTerrors[0]})`];
                    finalHfaCheckTerrors = [baseTerrorsNoTags[0]].filter(t =&gt; terrorsForHFACheck.includes(t)); 
                } else {
                    const uniqueIndices = [0, 1, 2].sort(() =&gt; 0.5 - Math.random()).slice(0, 2);
                    const selectedNames = [baseTerrorsNoTags[uniqueIndices[0]], baseTerrorsNoTags[uniqueIndices[1]]].filter((v, i, a) =&gt; a.indexOf(v) === i);

                    finalTerrors = [terrorsNoTags.find(t =&gt; t === selectedNames[0]), terrorsNoTags.find(t =&gt; t === selectedNames[1])].filter(Boolean);
                    finalTerrors.unshift(&quot;Double Trouble&quot;);
                    
                    finalHfaCheckTerrors = selectedNames.filter(t =&gt; terrorsForHFACheck.includes(t));
                }
            } else {
                if (uniqueTerrors.length === 3) {
                    finalTerrors = terrorsForDisplay; 
                    finalHfaCheckTerrors = baseTerrorsNoTags.filter(t =&gt; terrorsForHFACheck.includes(t)); 
                } else if (uniqueTerrors.length === 2) {
                    const doubleTerrorName = uniqueTerrors.find(t =&gt; countMap[t] === 2);
                    const singleTerrorName = uniqueTerrors.find(t =&gt; countMap[t] === 1);
                    
                    const doubleTerror = terrorsForDisplay.find(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim() === doubleTerrorName);
                    const singleTerror = terrorsForDisplay.find(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim() === singleTerrorName);
                    
                    finalTerrors = [doubleTerror, singleTerror];
                    finalTerrors.unshift(&quot;Double Trouble&quot;);

                    const baseDouble = baseTerrorsNoTags.find(t =&gt; t === doubleTerrorName);
                    const baseSingle = baseTerrorsNoTags.find(t =&gt; t === singleTerrorName);
                    
                    finalHfaCheckTerrors = [baseDouble, baseSingle].filter(t =&gt; terrorsForHFACheck.includes(t));
                    
                } else if (uniqueTerrors.length === 1) {
                    finalTerrors = [`EX (${uniqueTerrors[0]})`];
                    finalHfaCheckTerrors = [baseTerrorsNoTags[0]].filter(t =&gt; terrorsForHFACheck.includes(t));
                } else {
                    finalTerrors = terrorsForDisplay; 
                    finalHfaCheckTerrors = baseTerrorsNoTags.filter(t =&gt; terrorsForHFACheck.includes(t));
                }
            }
        } else if (round === &quot;Midnight&quot;) {
            const [c1, c2, alternate] = terrorsForDisplay; // 変換後/表示用
            const [base_c1, base_c2, base_alternate] = terrorsForHFACheckBase; // 変換前/HFAチェック用

            if (isMidnightBannedSubstitution) {
                 finalTerrors = [&quot;Comedy&quot;, alternate];
                 finalHfaCheckTerrors = [&quot;Comedy&quot;, base_alternate].filter(t =&gt; terrorsForHFACheck.includes(t)); 
            } else {
                finalTerrors = [c1, c2, alternate];
                finalHfaCheckTerrors = [base_c1, base_c2, base_alternate].filter(t =&gt; terrorsForHFACheck.includes(t)); 
            }
            
            // Eyesの特殊ルール適用
            const finalTerrorsNoTags = finalTerrors.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;));
            const hasRushOrAmbush = finalTerrorsNoTags.includes(&quot;Rush&quot;) || finalTerrorsNoTags.includes(&quot;Ambush&quot;);
            
            if (hasRushOrAmbush) {
                if (finalTerrors.length === 3) { 
                     finalTerrors.splice(2, 0, &quot;Eyes&quot;); 
                     finalHfaCheckTerrors.splice(2, 0, &quot;Eyes&quot;); 
                } else if (finalTerrors.length === 2) { 
                     finalTerrors.splice(1, 0, &quot;Eyes&quot;); 
                     finalHfaCheckTerrors.splice(1, 0, &quot;Eyes&quot;); 
                }
            }
        } else {
            finalTerrors = terrorsForDisplay;
            finalHfaCheckTerrors = terrorsForHFACheckBase.filter(t =&gt; terrorsForHFACheck.includes(t));
        }
        
        // --- 7. Fusion Pilot特殊チェック ([It&#039;s so over] 条件) ---
        let itsSoOverColor = null; 
        
        const finalTerrorsNoTags = finalTerrors.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim()); 
        
        if (stage === &quot;Challenge Cube&quot;) {
            if (round === &quot;Alternate&quot; &amp;&amp; finalTerrorsNoTags.includes(&quot;Fusion Pilot&quot;)) {
                itsSoOverColor = &#039;blue&#039;;
            } else if (round === &quot;Midnight&quot;) {
                const alternateTerror = finalTerrorsNoTags[finalTerrorsNoTags.length - 1];
                if (alternateTerror === &quot;Fusion Pilot&quot;) {
                    itsSoOverColor = &#039;red&#039;;
                }
            }
        }
        
        // --- 8. MEチェック (Alternate &amp; Roblander @ Robland) ---
        let isME = false;
        if (round === &quot;Alternate&quot; &amp;&amp; stage === &quot;Robland&quot; &amp;&amp; finalTerrorsNoTags.includes(&quot;Roblander&quot;)) {
             isME = true;
        }

        // --- 9. TBH実績チェック (TBH or TBH SPY or TBH SANS @ TBH) ---
        let isTBHAchievement = false;
        
        let terrorsForAchievement = [];

        if (round === &quot;Cracked&quot;) {
            terrorsForAchievement = [&quot;TBH SANS&quot;];
        } else {
            terrorsForAchievement = [&quot;TBH&quot;, &quot;TBH SPY&quot;, &quot;TBH SANS&quot;];
        }

        const hasTargetTerror = finalTerrorsNoTags.some(t =&gt; terrorsForAchievement.includes(t));

        if (stage === &quot;TBH&quot; &amp;&amp; hasTargetTerror) {
             isTBHAchievement = true;
        }


        // --- 10. HFAチェック ([HFA] 条件) ---
        const hfaCheckList = finalHfaCheckTerrors.filter(t =&gt; t !== &quot;Eyes&quot; &amp;&amp; t !== &quot;Roblander&quot;); 
        const hfaResult = checkHFA(hfaCheckList, stage);
        
        // --- 11. Glorbo上書きチェック (Punished &amp; Sewers) (新規追加) ---
        let isGlorbo = false;
        if (round === &quot;Punished&quot; &amp;&amp; stage === &quot;Sewers&quot; &amp;&amp; Math.random() &lt; 1 / 10000) {
            isGlorbo = true;
        }
        
        // --- 12. MOON上書きチェック (すべての判定が完了した後) ---
        let selectedMoon = null;
        let isMoon = false;
        const moonOverwriteEnabled = document.getElementById(&#039;moonOverwrite&#039;).checked;
        const nonMoonRounds = [&quot;Classic&quot;, &quot;Alternate&quot;];
        
        if (!isGlorbo &amp;&amp; moonOverwriteEnabled &amp;&amp; !nonMoonRounds.includes(round) &amp;&amp; Math.random() &lt; 1 / 80) {
            isMoon = true;
            if (stage === &quot;Black Forest&quot;) {
                selectedMoon = selectRandom(MOON_TYPES); // Twilight含む全て
            } else {
                selectedMoon = selectRandom(STANDARD_MOONS); // Twilight以外
            }
        }

        // 最終的な結果オブジェクトを返す
        return { 
            terrors: finalTerrors, 
            stage, 
            itsSoOverColor, 
            isHFA: hfaResult.isHFA, 
            hfaTerrors: hfaResult.hfaTerrors, 
            isME: isME,
            isMoon: isMoon, 
            selectedMoon: selectedMoon, 
            isSOSReplacementEvent: isSOSReplacementEvent,
            isTBHAchievement: isTBHAchievement, // TBH実績フラグ
            isGlorbo: isGlorbo // Glorboフラグ
        };
    }

    /**
     * 結果表示用の文字列を整形する。
     */
    function formatResult(round, result) {
        const { terrors, stage, itsSoOverColor, isHFA, hfaTerrors, isME, isMoon, selectedMoon, isSOSReplacementEvent, isGlorbo } = result;
        
        // --- 0. Glorbo上書き表示 (最優先) ---
        if (isGlorbo) {
             return `&lt;span style=&quot;font-weight: bold; color: #8A2BE2;&quot;&gt;Glorbo&lt;/span&gt; @ ${stage}`;
        }

        // --- 1. ムーン上書きプレフィックスの構築 (次に優先) ---
        let moonPrefixHtml = &quot;&quot;;
        if (isMoon) {
            moonPrefixHtml = `&lt;span class=&quot;${selectedMoon.css}&quot;&gt;[${selectedMoon.name}]&lt;/span&gt; `;
        }
        
        // --- 2. ME表示 (ムーンがなければ次に優先) ---
        if (isME &amp;&amp; !isMoon) {
            return `&lt;span class=&quot;me-terror&quot;&gt;ME&lt;/span&gt; @ ${stage}`;
        }
        
        if (round === &quot;Unbound&quot;) {
            // Unboundはテラーが1つ
            let prefix = moonPrefixHtml;
            if (itsSoOverColor === &#039;blue&#039;) {
                prefix += `&lt;span class=&quot;its-so-over-blue&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
            } else if (itsSoOverColor === &#039;red&#039;) {
                prefix += `&lt;span class=&quot;its-so-over-red&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
            }
            if (isHFA) {
                prefix += `&lt;span class=&quot;hfa-prefix&quot;&gt;[HFA]&lt;/span&gt; `;
            }
            
            const terrorNoTag = terrors[0].replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;);
            const isSOSReplacementUnbound = terrors[0].includes(&#039;&lt;SOS&gt;&#039;);
            
            let terrorDisplay = terrorNoTag;
            if (isSOSReplacementUnbound) {
                 terrorDisplay = `&lt;span class=&quot;sos-replacement-terror&quot;&gt;${terrorNoTag}&lt;/span&gt;`;
            } else {
                 terrorDisplay = terrorNoTag;
            }

            return `${prefix}${terrorDisplay} @ ${stage}`;
        }
        
        let terrorsHtml = [];

        for(let terror of terrors) {
            let formattedTerror = terror;
            const isSOSReplacement = terror.endsWith(&quot;&lt;SOS&gt;&quot;);
            
            let baseTerrorName = terror.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim(); 

            // [FIX] Bloodbath EXの名前抽出ロジックを追加
            if (round === &quot;Bloodbath&quot; &amp;&amp; terror.startsWith(&quot;EX (&quot;)) {
                const match = terror.match(/EX \((.+)\)/);
                if (match) {
                    baseTerrorName = match[1];
                }
            }
            
            if (isSOSReplacement) {
                formattedTerror = formattedTerror.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;);
            }
            
            // HFAで太字化すべきテラー名 (変換前の名前) が、現在の表示名（変換後）と一致するかを判定
            let isCurrentTerrorHFA = false;
            let originalName = baseTerrorName;
            
            const allTransforms = { ...CRACKED_TRANSFORM, ...MIDNIGHT_TRANSFORM };
            const reverseTransform = Object.entries(allTransforms).find(([, v]) =&gt; v === baseTerrorName);
            if (reverseTransform) originalName = reverseTransform[0];
            
            if (isHFA &amp;&amp; hfaTerrors.includes(originalName)) {
                 isCurrentTerrorHFA = true;
            }


            // --- 既存の装飾ロジック ---
            
            // 1. Bloodbathの昇格チェック
            if (terror.startsWith(&quot;Double Trouble&quot;) || terror.startsWith(&quot;EX&quot;)) {
                 formattedTerror = `&lt;strong&gt;${baseTerrorName}&lt;/strong&gt;`;
            } 
            // 2. SOS Replacementチェック (茶色太字)
            else if (isSOSReplacement) {
                formattedTerror = `&lt;span class=&quot;sos-replacement-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
            }
            // 3. Crackedのテラー名変更チェック
            else if (round === &quot;Cracked&quot; &amp;&amp; CRACKED_TRANSFORMED_NAMES.includes(baseTerrorName)) {
                 formattedTerror = `&lt;span class=&quot;cracked-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
            } 
            // 4. Midnightのテラー名変更チェック
            else if (round === &quot;Midnight&quot; &amp;&amp; (terror.startsWith(&quot;EX&quot;) || terror.startsWith(&quot;Double Trouble&quot;) ? true : MIDNIGHT_TRANSFORMED_NAMES.includes(baseTerrorName))) {
                if (baseTerrorName === &quot;Monarch&quot;) {
                     formattedTerror = `&lt;span class=&quot;monarch-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                } else if (baseTerrorName === &quot;Blue Haket&quot;) {
                     formattedTerror = `&lt;span class=&quot;blue-midnight-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                } else {
                    formattedTerror = `&lt;span class=&quot;midnight-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                }
            }
            // 5. その他 (装飾がない場合はそのまま)
            else {
                formattedTerror = baseTerrorName;
            }
            
            // --- HFAの太字装飾の適用 (既存の装飾を上書きするため最後に適用) ---
            if (isCurrentTerrorHFA) {
                if (terror.includes(&#039;(&#039;) &amp;&amp; terror.includes(&#039;)&#039;)) {
                    const parts = terror.match(/(.+?)\s*\((.+?)\)/);
                    if (parts) {
                        formattedTerror = `${parts[1]} (&lt;span class=&quot;hfa-terror&quot;&gt;${parts[2]}&lt;/span&gt;)`;
                    }
                } else {
                    formattedTerror = `&lt;span class=&quot;hfa-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                }
            }
            
            // BloodbathのEX/DoubleTroubleの装飾を再適用 (HFAの黒太字を上書きしないように)
            if (terror.startsWith(&quot;Double Trouble&quot;) || terror.startsWith(&quot;EX&quot;)) {
                 formattedTerror = `&lt;strong&gt;${formattedTerror}&lt;/strong&gt;`;
            }
            
            terrorsHtml.push(formattedTerror);
        }
        
        
        // --- プレフィックスの結合 ---
        let finalPrefixHtml = moonPrefixHtml;
        
        if (itsSoOverColor === &#039;blue&#039;) {
            finalPrefixHtml += `&lt;span class=&quot;its-so-over-blue&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
        } else if (itsSoOverColor === &#039;red&#039;) {
            finalPrefixHtml += `&lt;span class=&quot;its-so-over-red&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
        }
        
        if (isHFA) {
            finalPrefixHtml += `&lt;span class=&quot;hfa-prefix&quot;&gt;[HFA]&lt;/span&gt; `;
        }

        // Bloodbathの特殊フォーマットを処理
        if (round === &quot;Bloodbath&quot; &amp;&amp; (terrors[0].startsWith(&quot;Double Trouble&quot;) || terrors[0].startsWith(&quot;EX&quot;))) {
            const type = terrorsHtml.shift(); 
            
            if (terrors[0].startsWith(&quot;EX&quot;)) {
                 // [FIX] EXの場合は &quot;EX [テラー名] @ [ステージ]&quot; の形式にする
                 return `${finalPrefixHtml}&lt;strong&gt;EX&lt;/strong&gt; ${type} @ ${stage}`; 
            } 
            
            const terrorList = terrorsHtml.join(&#039; / &#039;);
            const typeNoTag = type.replace(/&lt;[^&gt;]*&gt;/g, &#039;&#039;);
            return `${finalPrefixHtml}${typeNoTag} (${terrorList}) @ ${stage}`;
            
        }
        
        // その他のラウンドの表示
        const terrorDisplay = terrorsHtml.join(&#039; / &#039;);
        
        return `${finalPrefixHtml}${terrorDisplay} @ ${stage}`;
    }

    // --- メイン実行関数 ---
    function runSelection() {
        const round = document.getElementById(&#039;roundSelect&#039;).value;
        const countSelect = document.getElementById(&#039;countSelect&#039;);
        const count = parseInt(countSelect.value, 10);
        const resultsDisplay = document.getElementById(&#039;results-display&#039;);
        resultsDisplay.innerHTML = &#039;&#039;; 

        if (isNaN(count) || count &lt; 1) {
            resultsDisplay.innerHTML = &#039;&lt;p&gt;連数を正しく選択してください。&lt;/p&gt;&#039;;
            return;
        }
        
        // 累計回数を更新
        totalDraws += count;
        saveTotalDrawCount();
        updateTotalDrawDisplay();

        let notificationQueue = [];

        for (let i = 0; i &lt; count; i++) {
            const result = selectTerrorsAndStage(round);
            
            // 通知チェック (優先度順: Glorbo &gt; ムーン &gt; TBH実績 &gt; ME &gt; SOS &gt; EX &gt; It&#039;s so over)
            // queueへの追加処理に変更
            if (result.isGlorbo) {
                notificationQueue.push(&#039;glorboNotification&#039;);
            } else if (result.isMoon) {
                // ムーン通知は不要
            } else if (result.isTBHAchievement) { 
                notificationQueue.push(&#039;tbhAchievementNotification&#039;);
            } else if (result.isME) { 
                notificationQueue.push(&#039;meNotification&#039;);
            } else if (result.isSOSReplacementEvent) { 
                notificationQueue.push(&#039;sosNotification&#039;);
            } else if (round === &quot;Bloodbath&quot; &amp;&amp; result.terrors.length &gt; 0 &amp;&amp; result.terrors[0].startsWith(&quot;EX (&quot;)) {
                 notificationQueue.push(&#039;exNotification&#039;);
            } else if (result.itsSoOverColor) {
                notificationQueue.push(&#039;itsSoOverNotification&#039;);
            } 

            const formattedResult = formatResult(round, result);

            const resultDiv = document.createElement(&#039;div&#039;);
            resultDiv.classList.add(&#039;result-item&#039;);
            resultDiv.innerHTML = `${i + 1}連目: ${formattedResult}`;
            resultsDisplay.appendChild(resultDiv);
        }

        // 通知キューの処理開始
        if (notificationQueue.length &gt; 0) {
            processNotificationQueue(notificationQueue);
        }
    }

    // --- 画像保存関数 ---
    function saveAsImage() {
        const node = document.getElementById(&#039;results-display&#039;);
        
        domtoimage.toPng(node)
            .then(function (dataUrl) {
                const link = document.createElement(&#039;a&#039;);
                link.download = `選出結果_${document.getElementById(&#039;roundSelect&#039;).value}_${new Date().toLocaleTimeString().replace(/:/g, &#039;-&#039;)}.png`;
                link.href = dataUrl;
                link.click();
            })
            .catch(function (error) {
                console.error(&#039;画像保存に失敗しました:&#039;, error);
                alert(&#039;結果を画像として保存できませんでした。ブラウザのコンソールを確認してください。&#039;);
            });
    }

    // --- 初期化 ---
    document.addEventListener(&#039;DOMContentLoaded&#039;, () =&gt; {
        loadTotalDrawCount();
        
        document.getElementById(&#039;results-display&#039;).innerHTML = &#039;&lt;p style=&quot;text-align: center; color: #777;&quot;&gt;ラウンドと連数を選択し、「選出！」ボタンを押してください。&lt;/p&gt;&#039;;
        document.getElementById(&#039;exNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;itsSoOverNotification&#039;).classList.remove(&#039;show&#039;); 
        document.getElementById(&#039;meNotification&#039;).classList.remove(&#039;show&#039;); 
        document.getElementById(&#039;sosNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;tbhAchievementNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;glorboNotification&#039;).classList.remove(&#039;show&#039;);
        setButtonState(false);
        
        // ラウンド変更時のリセットイベントを設定
        document.getElementById(&#039;roundSelect&#039;).addEventListener(&#039;change&#039;, resetDrawCountIfRoundChanged);
    });

&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

}    </description>
    <dc:date>2025-12-07T21:48:26+09:00</dc:date>
    <utime>1765111706</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/11.html">
    <title>ラウンドランダム生成</title>
    <link>https://w.atwiki.jp/tontool/pages/11.html</link>
    <description>
      #javascript(){
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;テラー/アンバウンド選出ツール&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: &#039;Segoe UI&#039;, Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f7f9;
            color: #333;
            padding: 20px;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background-color: #fff;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
        }
        h1 {
            color: #007bff;
            text-align: center;
            margin-bottom: 30px;
            border-bottom: 2px solid #e0e0e0;
            padding-bottom: 10px;
        }
        .controls, .result-section {
            margin-bottom: 25px;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 8px;
            background-color: #fafafa;
        }
        .controls label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }
        .controls select, .controls button {
            padding: 10px;
            margin-right: 15px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 16px;
        }
        .controls button {
            background-color: #28a745;
            color: white;
            cursor: pointer;
            border: none;
            transition: background-color 0.3s;
        }
        .controls button:hover {
            background-color: #218838;
        }
        /* ボタン無効化時のスタイル */
        .controls button:disabled {
            background-color: #90ee90; /* 薄い緑 */
            cursor: not-allowed;
        }
        .checkbox-group {
            display: flex;
            align-items: center;
            margin-top: 15px;
            gap: 20px;
        }
        .checkbox-group input {
            transform: scale(1.5);
            margin-right: 5px;
        }

        #results-display {
            border: 3px solid #007bff;
            padding: 20px;
            border-radius: 10px;
            background-color: #eaf3ff;
            min-height: 100px;
        }
        .result-item {
            font-size: 24px;
            margin-bottom: 15px;
            padding: 10px;
            background-color: #fff;
            border-left: 5px solid #007bff;
            border-radius: 5px;
        }
        .result-item:last-child {
            margin-bottom: 0;
        }
        /* Bloodbathの昇格表示 */
        .result-item strong {
            color: #d9534f;
        }
        /* Monarchの特殊装飾 (Midnight/赤太字) */
        .monarch-terror {
            color: #FF0000;
            font-weight: bold;
        }
        /* Crackedの装飾 (変換されたテラーのみ/紫色) */
        .cracked-terror {
            color: #800080; 
        }
        /* Midnightの装飾 (変換されたテラーのみ/赤色) */
        .midnight-terror {
            color: #FF0000; 
        }
        /* Blue Haketの特殊装飾 (Midnight/青色) */
        .blue-midnight-terror {
            color: #0000FF; 
        }
        /* S.O.S.からのThose Olden Days置き換え（茶色太字）*/
        .sos-replacement-terror {
            color: #964B00; /* Brown color */
            font-weight: bold;
        }
        /* Fusion Pilot特殊装飾: Alternate/青太字 */
        .its-so-over-blue {
            color: #00008b; /* Dark Blue */
            font-weight: bold;
        }
        /* Fusion Pilot特殊装飾: Midnight/赤太字 */
        .its-so-over-red {
            color: #ff0000; /* Red */
            font-weight: bold;
        }
        
        /* HFAの装飾 (緑太字) */
        .hfa-prefix {
            color: #006400; /* Dark Green */
            font-weight: bold;
        }
        /* HFAで太字化されるテラーの装飾 (黒色太字、他の色装飾より優先) */
        .hfa-terror {
            font-weight: bold !important;
            color: #000000; /* Black */
        }
        
        /* MEの装飾 (青太字) */
        .me-terror {
             color: #00008b; /* Dark Blue */
            font-weight: bold;
        }
        
        /* --- MOON COLORS --- */
        .moon-twilight { 
            color: #FFD700; /* Yellow */
            font-weight: bold;
        }
        .moon-mystic { 
            color: #0000FF; /* Blue */
            font-weight: bold;
        }
        .moon-blood { 
            color: #FF0000; /* Red */
            font-weight: bold;
        }
        .moon-solstice { 
            color: #008000; /* Green */
            font-weight: bold;
        }

        /* --- Notification Toast Style --- */
        .notification-toast {
            visibility: hidden; 
            min-width: 250px;
            background-color: #d9534f; 
            color: #fff;
            text-align: center;
            border-radius: 5px;
            padding: 16px;
            position: fixed;
            z-index: 100; 
            left: 50%;
            top: 50%; 
            transform: translate(-50%, -50%);
            font-size: 28px;
            font-weight: bold;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
            opacity: 0;
            transition: opacity 0.3s, visibility 0.3s;
        }
        
        #sosNotification {
             background-color: #964B00; /* Brown */
        }
        
        #tbhAchievementNotification {
             background-color: #008080; /* Teal/濃い水色 */
        }
        
        #glorboNotification { /* 新しい通知のスタイル */
            background-color: #8A2BE2; /* BlueViolet/青紫 */
            color: #FFFFFF;
        }

        .notification-toast.show {
            visibility: visible;
            opacity: 1;
        }
        
        /* 累計回数表示 */
        .result-title-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
        }
        .total-draws {
            font-size: 1.2em;
            font-weight: bold;
            color: #007bff;
            background-color: #e0f7fa;
            padding: 5px 10px;
            border-radius: 5px;
            border: 1px solid #00bcd4;
        }

        #saveImage {
            background-color: #f0ad4e;
            color: white;
            margin-top: 10px;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        #saveImage:hover {
            background-color: #ec971f;
        }
        .result-title {
            font-size: 1.2em;
            font-weight: bold;
            color: #007bff;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div class=&quot;container&quot;&gt;
    &lt;h1&gt;テラー/アンバウンド選出ツール ver1.7&lt;/h1&gt;

    &lt;div class=&quot;controls&quot;&gt;
        &lt;label for=&quot;roundSelect&quot;&gt;ラウンドを選ぶ:&lt;/label&gt;
        &lt;select id=&quot;roundSelect&quot;&gt;
            &lt;option value=&quot;Classic&quot;&gt;Classic / クラシック&lt;/option&gt;
            &lt;option value=&quot;Alternate&quot;&gt;Alternate / オルタネイト&lt;/option&gt;
            &lt;option value=&quot;Punished&quot;&gt;Punished / パニッシュ&lt;/option&gt;
            &lt;option value=&quot;Cracked&quot;&gt;Cracked / 狂気&lt;/option&gt;
            &lt;option value=&quot;Sabotage&quot;&gt;Sabotage / サボタージュ&lt;/option&gt;
            &lt;option value=&quot;Bloodbath&quot;&gt;Bloodbath / ブラッドバス&lt;/option&gt;
            &lt;option value=&quot;Midnight&quot;&gt;Midnight / ミッドナイト&lt;/option&gt;
            &lt;option value=&quot;Unbound&quot;&gt;Unbound / アンバウンド&lt;/option&gt;
        &lt;/select&gt;

        &lt;label for=&quot;countSelect&quot; style=&quot;margin-top: 15px;&quot;&gt;連数を選ぶ:&lt;/label&gt;
        &lt;select id=&quot;countSelect&quot;&gt;
            &lt;option value=&quot;1&quot;&gt;1連&lt;/option&gt;
            &lt;option value=&quot;10&quot;&gt;10連&lt;/option&gt;
            &lt;option value=&quot;20&quot;&gt;20連&lt;/option&gt;
            &lt;option value=&quot;30&quot;&gt;30連&lt;/option&gt;
            &lt;option value=&quot;40&quot;&gt;40連&lt;/option&gt;
            &lt;option value=&quot;50&quot;&gt;50連&lt;/option&gt;
        &lt;/select&gt;
        
        &lt;div class=&quot;checkbox-group&quot;&gt;
            &lt;label for=&quot;moonOverwrite&quot;&gt;
                &lt;input type=&quot;checkbox&quot; id=&quot;moonOverwrite&quot;&gt;
                ムーン上書きを有効にする (1/80)
            &lt;/label&gt;
        &lt;/div&gt;

        &lt;button id=&quot;runButton&quot; onclick=&quot;runSelection()&quot;&gt;選出！&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;result-section&quot;&gt;
        &lt;div class=&quot;result-title-container&quot;&gt;
            &lt;div class=&quot;result-title&quot;&gt;✨ 選出結果 ✨&lt;/div&gt;
            &lt;div class=&quot;total-draws&quot;&gt;累計選出回数: &lt;span id=&quot;totalDrawCount&quot;&gt;0&lt;/span&gt; 回&lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&quot;results-display&quot;&gt;
            &lt;/div&gt;
        &lt;button id=&quot;saveImage&quot; onclick=&quot;saveAsImage()&quot;&gt;結果を画像として保存&lt;/button&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;exNotification&quot; class=&quot;notification-toast&quot;&gt;
    EXが選出されました！
&lt;/div&gt;

&lt;div id=&quot;itsSoOverNotification&quot; class=&quot;notification-toast&quot;&gt;
    It&#039;s so overが選出されました！
&lt;/div&gt;

&lt;div id=&quot;meNotification&quot; class=&quot;notification-toast&quot;&gt;
    ME (Mega Evolution) が選出されました！
&lt;/div&gt;

&lt;div id=&quot;sosNotification&quot; class=&quot;notification-toast&quot;&gt;
    S.O.S.の特殊置換が発生しました！
&lt;/div&gt;

&lt;div id=&quot;tbhAchievementNotification&quot; class=&quot;notification-toast&quot;&gt;
    TBHの実績を獲得しました！
&lt;/div&gt;

&lt;div id=&quot;glorboNotification&quot; class=&quot;notification-toast&quot;&gt;
    テラー名がGlorboに上書きされました！
&lt;/div&gt;


&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
    // --- データ一覧 ---
    const CLASSIC_TERRORS = [
        &quot;Huggy&quot;, &quot;Corrupted Toys&quot;, &quot;Demented Spongebob&quot;, &quot;Specimen 8&quot;, &quot;HER&quot;, &quot;Tails Doll&quot;, &quot;Black Sun&quot;, &quot;Aku Ball&quot;, &quot;Ao Oni&quot;, &quot;Toren&#039;s Shadow&quot;,
        &quot;[CENSORED]&quot;, &quot;WhiteNight&quot;, &quot;An Arbiter&quot;, &quot;Specimen 5&quot;, &quot;Comedy&quot;, &quot;Purple Guy&quot;, &quot;Spongefly Swarm&quot;, &quot;Hush&quot;, &quot;MopeMope&quot;, &quot;Sawrunner&quot;,
        &quot;Imposter&quot;, &quot;Something&quot;, &quot;Starved&quot;, &quot;The Painter&quot;, &quot;The Guidance&quot;, &quot;With Many Voices&quot;, &quot;Nextbots&quot;, &quot;Harvest&quot;, &quot;Smileghost&quot;, &quot;Karol_Corpse&quot;,
        &quot;MX&quot;, &quot;Big Bird&quot;, &quot;Dev Bytes&quot;, &quot;Luigi &amp; Luigi Dolls&quot;, &quot;V2&quot;, &quot;Withered Bonnie&quot;, &quot;The Boys&quot;, &quot;Something Wicked&quot;, &quot;Seek&quot;, &quot;Rush&quot;,
        &quot;Sonic&quot;, &quot;Bad Batter&quot;, &quot;Signus&quot;, &quot;Mirror&quot;, &quot;Legs&quot;, &quot;Mona &amp; The Mountain&quot;, &quot;Judgement Bird&quot;, &quot;Slender&quot;, &quot;Maul-A-Child&quot;, &quot;Garten Goers&quot;,
        &quot;Don&#039;t Touch Me&quot;, &quot;Specimen 2&quot;, &quot;Specimen 10&quot;, &quot;The LifeBringer&quot;, &quot;Pale Association&quot;, &quot;Toy Enforcer&quot;, &quot;TBH&quot;, &quot;DoomBox&quot;, &quot;Christian Brutal Sniper&quot;, &quot;Nosk&quot;,
        &quot;Apocrean Harvester&quot;, &quot;Arkus&quot;, &quot;Cartoon Cat&quot;, &quot;Wario Apparition&quot;, &quot;Shinto&quot;, &quot;Hell Bell&quot;, &quot;Security&quot;, &quot;The Swarm&quot;, &quot;Shiteyanyo&quot;, &quot;Bacteria&quot;,
        &quot;Tiffany&quot;, &quot;HoovyDundy&quot;, &quot;Haket&quot;, &quot;Akumii-Kari&quot;, &quot;Lunatic Cultist&quot;, &quot;Sturm&quot;, &quot;Punishing Bird&quot;, &quot;Prisoner&quot;, &quot;Red Bus&quot;, &quot;Waterwraith&quot;,
        &quot;Astrum Aureus&quot;, &quot;Snarbolax&quot;, &quot;All-Around-Helpers&quot;, &quot;lain&quot;, &quot;Sakuya Izayoi&quot;, &quot;Arrival&quot;, &quot;Miros Birds&quot;, &quot;BFF&quot;, &quot;Scavenger&quot;, &quot;Tinky Winky&quot;,
        &quot;Tricky&quot;, &quot;Yolm&quot;, &quot;Red Fanatic&quot;, &quot;Dr. Tox&quot;, &quot;Ink Demon&quot;, &quot;Retep&quot;, &quot;Those Olden Days&quot;, &quot;S.O.S&quot;, &quot;Bigger Boot&quot;, &quot;The Pursuer&quot;,
        &quot;Spamton&quot;, &quot;Immortal Snail&quot;, &quot;Charlotte&quot;, &quot;Herobrine&quot;, &quot;Peepy&quot;, &quot;The Jester&quot;, &quot;Wild Yet Curious Creature&quot;, &quot;Manti&quot;, &quot;Horseless Headless Horsemann&quot;, &quot;Ghost Girl&quot;,
        &quot;Cubor&#039;s Revenge&quot;, &quot;Poly&quot;, &quot;Dog Mimic&quot;, &quot;Warden&quot;, &quot;Fox Squad&quot;, &quot;Express Train To Hell&quot;, &quot;Deleted&quot;, &quot;Killer Fish&quot;, &quot;Terror of Nowhere&quot;, &quot;Beyond&quot;,
        &quot;The Origin&quot;, &quot;Time Ripper&quot;, &quot;This Killer does not exist&quot;, &quot;Parhelion&#039;s Victims&quot;, &quot;Bed Mecha&quot;, &quot;Killer Rabbit&quot;, &quot;Bravera&quot;, &quot;MissingNo&quot;, &quot;Living Shadow&quot;, &quot;The Plague Doctor&quot;,
        &quot;The Rat&quot;, &quot;Waldo&quot;, &quot;Clockey&quot;, &quot;Malicious Twins&quot;
    ];

    const ALTERNATE_TERRORS = [
        &quot;Decayed Sponge&quot;, &quot;WHITEFACE&quot;, &quot;Sanic&quot;, &quot;Parhelion&quot;, &quot;,D@;Q7Y&quot;, &quot;Chomper&quot;, &quot;The Knight of Toren&quot;, &quot;Tragedy&quot;, &quot;Apathy&quot;, &quot;MR.MEGA&quot;,
        &quot;sm64.z64&quot;, &quot;Convict Squad&quot;, &quot;Paradise Bird&quot;, &quot;Angry Munci&quot;, &quot;Lord&#039;s Signal&quot;, &quot;Feddys&quot;, &quot;TBH SPY&quot;, &quot;The Observation&quot;, &quot;Lisa&quot;, &quot;Judas&quot;,
        &quot;Glaggle Gang&quot;, &quot;Try Not To Touch Me&quot;, &quot;Ambush&quot;, &quot;Teuthida&quot;, &quot;Eggman&#039;s Announcement&quot;, &quot;S.T.G.M&quot;, &quot;Army in Black&quot;, &quot;Bliss&quot;, &quot;Roblander&quot;, &quot;Fusion Pilot&quot;,
        &quot;Joy&quot;, &quot;The Red Mist&quot;, &quot;Sakuya The Ripper&quot;, &quot;Walpurgisnacht&quot;, &quot;Dev Maulers&quot;, &quot;Restless Creator&quot;
    ];

    const UNBOUNDS = [
        &quot;Guidance &amp; The Booboo&#039;s&quot;, &quot;Red vs Blue&quot;, &quot;Third Trumpet&quot;, &quot;Forest Gurdians&quot;, &quot;Higher Beings&quot;, &quot;Quadruple Sponge&quot;, &quot;Your Best Friends&quot;, &quot;Hotel Monsters&quot;, &quot;Squibb Squad&quot;, &quot;Garden Rejects&quot;,
        &quot;Judgement Day&quot;, &quot;Me and My Shadow&quot;, &quot;Meltdown&quot;, &quot;Faceless Mafia&quot;, &quot;Mansion Monsters&quot;, &quot;Copyright Infringement&quot;, &quot;Purple Bros&quot;, &quot;Scavengers&quot;, &quot;Life &amp; Death&quot;, &quot;Labyrinth&quot;,
        &quot;Spiteful Shadows&quot;, &quot;Triple Munci&quot;, &quot;Daycare&quot;, &quot;Huggy Horde&quot;, &quot;Infection&quot;, &quot;Triple Hush&quot;, &quot;[CENSORED]&quot;, &quot;Byte Horde&quot;, &quot;SawMarathon&quot;, &quot;TAKE THE NAMI CHALLENGE&quot;,
        &quot;Thunderstorm&quot;, &quot;END OF THE WORLD&quot;, &quot;Fragmented Memories&quot;, &quot;Mona &amp; Mona &amp; Mona &amp; Mona&quot;, &quot;Seekers&quot;, &quot;Nugget Squad&quot;, &quot;Saul&#039;s goodmen&quot;, &quot;Something Old,Something New&quot;, &quot;POV: Bug&quot;, &quot;Punishing Birdemic&quot;,
        &quot;Double Ao Oni&quot;, &quot;Too Many Voices&quot;, &quot;Memory Crypts&quot;, &quot;Zumbo Sauce&quot;, &quot;Freaks&quot;, &quot;Lunatic Cult&quot;, &quot;Transportation Trio &amp; The Drifter&quot;, &quot;Father Son Bonding&quot;, &quot;WHAT IS MY NAME&quot;, &quot;Glaggleland Cremators&quot;,
        &quot;Triple Signus&quot;, &quot;Triple Akumii Kari&quot;, &quot;Black &amp; White&quot;, &quot;[LESSER CENSORED]&quot;, &quot;Blue Monsters&quot;, &quot;Drones&quot;, &quot;Scrapyard Takers&quot;, &quot;Luigi Dolls&quot;, &quot;Meteor Shower&quot;, &quot;Triple TBH&quot;,
        &quot;Lost Souls&quot;, &quot;Ballin&quot;, &quot;Reunion&quot;, &quot;Angels&quot;, &quot;Ordinary Apocalypse Bird&quot;, &quot;Pack of Wild Yet Curious Creatures&quot;, &quot;ToN X SlashCo Collab&quot;, &quot;Pack of Yolm&quot;, &quot;Threepy&quot;, &quot;???&quot;,
        &quot;Delete Me&quot;, &quot;Spamton Spam&quot;, &quot;Death From Above&quot;, &quot;It Came From Bus To Nowhere&quot;, &quot;Zombie Apocalypse&quot;, &quot;Eating Contest&quot;, &quot;Triple Clockey&quot;, &quot;Triple Killer Fish&quot;, &quot;Lethal League&quot;, &quot;Trollage&quot;,
        &quot;Mopemopemopemopemopemope&quot;, &quot;Triple Trouble&quot;, &quot;Triple Living Shadow&quot;, &quot;Beyond&#039;s Masks&quot;
    ];

    const STAGES = [
        &quot;Alter&quot;, &quot;Ancient&quot;, &quot;Astral&quot;, &quot;Baseplate&quot;, &quot;Backrooms&quot;, &quot;Challenge Cube&quot;, &quot;Black Forest&quot;, &quot;Cheese Maze&quot;,
        &quot;Chess&quot;, &quot;Construct&quot;, &quot;Desktop&quot;, &quot;Development&quot;, &quot;Dots&quot;, &quot;Dust&quot;, &quot;Elevator&quot;, &quot;Engine&quot;, &quot;Escape Route&quot;,
        &quot;Experimentation&quot;, &quot;Forest&quot;, &quot;Gaol&quot;, &quot;Gardens&quot;, &quot;Garten&quot;, &quot;Isolation&quot;, &quot;Have&quot;, &quot;Harvest&quot;, &quot;Heaven&quot;, &quot;Hell&quot;,
        &quot;Hightower&quot;, &quot;Iteration_0&quot;, &quot;Hole&quot;, &quot;Hotel&quot;, &quot;Hub&quot;, &quot;Inner Tower&quot;, &quot;Innyume&quot;, &quot;Lounge&quot;, &quot;Luna Hills&quot;, &quot;Mall&quot;,
        &quot;Mineshaft&quot;, &quot;Museum&quot;, &quot;Neon Towers (紫)&quot;, &quot;Neon Towers (緑)&quot;, &quot;Nexus&quot;, &quot;Nightlife&quot;, &quot;Orange&quot;, &quot;Park&quot;, &quot;Pizzeria&quot;, &quot;Playplace&quot;,
        &quot;Pools&quot;, &quot;Robland&quot;, &quot;Sanctum&quot;, &quot;Schoolhouse&quot;, &quot;Scrapyard&quot;, &quot;Sea Base&quot;, &quot;Secret&quot;, &quot;Sewers&quot;, &quot;Skyscraper&quot;, &quot;Slashco HQ&quot;,
        &quot;Snowfield&quot;, &quot;Space Colony&quot;, &quot;Spaceless&quot;, &quot;Subway&quot;, &quot;Supply Route&quot;, &quot;TBH&quot;, &quot;The Fishbowl&quot;, &quot;The Wall&quot;, &quot;This Map Does Not Exist&quot;, &quot;Throne&quot;,
        &quot;Tunnels&quot;, &quot;Vents&quot;, &quot;Wafflehouse&quot;, &quot;Warehouse&quot;, &quot;Blackspace&quot;, &quot;Carpark&quot; 
    ];
    
    const CRACKED_TRANSFORM = {
        &quot;Withered Bonnie&quot;: &quot;Epic Bonnie&quot;,
        &quot;TBH&quot;: &quot;TBH SANS&quot;
    };

    const MIDNIGHT_TRANSFORM = {
        &quot;Haket&quot;: &quot;Blue Haket&quot;,
        &quot;Roblander&quot;: &quot;Inverted Roblander&quot;,
        &quot;The Knight of Toren&quot;: &quot;Kimera&quot;,
        &quot;Judas&quot;: &quot;Monarch&quot;,
        &quot;BFF&quot;: &quot;Nameless&quot;,
        &quot;Snarbolax&quot;: &quot;Rabid Snarbolax&quot;,
        &quot;Sonic&quot;: &quot;Rewrite&quot;,
        &quot;Withered Bonnie&quot;: &quot;Ruinborn Afton&quot;,
        &quot;The LifeBringer&quot;: &quot;Scrapyard Machine&quot;,
        &quot;Dev Bytes&quot;: &quot;Search and Destroy&quot;,
        &quot;Slender&quot;: &quot;Slendy&quot;,
        &quot;Bad Batter&quot;: &quot;The Batter&quot;
    };
    
    // 変換元テラーのリスト
    const CRACKED_TRANSFORM_SOURCES = Object.keys(CRACKED_TRANSFORM);
    const MIDNIGHT_TRANSFORM_SOURCES = Object.keys(MIDNIGHT_TRANSFORM);

    const CRACKED_TRANSFORMED_NAMES = Object.values(CRACKED_TRANSFORM);
    const MIDNIGHT_TRANSFORMED_NAMES = Object.values(MIDNIGHT_TRANSFORM);
    
    // --- HFAの組み合わせデータ構造 ---
    const HFA_COMBINATIONS = [
        { stage: &quot;Hotel&quot;, terrors: [&quot;Seek&quot;, &quot;Rush&quot;, &quot;Ambush&quot;] }, 
        { stage: [&quot;Hightower&quot;, &quot;Harvest&quot;], terrors: [&quot;Christian Brutal Sniper&quot;, &quot;Horseless Headless Horsemann&quot;, &quot;HoovyDundy&quot;] }, 
        { stage: &quot;Blackspace&quot;, terrors: [&quot;Something&quot;] },
        { stage: &quot;Scrapyard&quot;, terrors: [&quot;The LifeBringer&quot;] },
        { stage: &quot;Robland&quot;, terrors: [&quot;Roblander&quot;] },
        { stage: &quot;Isolation&quot;, terrors: [&quot;Specimen 2&quot;, &quot;Specimen 5&quot;, &quot;Specimen 8&quot;, &quot;Specimen 10&quot;, &quot;Lisa&quot;] },
        { stage: &quot;Secret&quot;, terrors: [&quot;V2&quot;, &quot;Something Wicked&quot;] },
        { stage: &quot;Innyume&quot;, terrors: [&quot;Smileghost&quot;] },
        { stage: &quot;Pizzeria&quot;, terrors: [&quot;Withered Bonnie&quot;, &quot;Purple Guy&quot;, &quot;The Origin&quot;, &quot;Feddys&quot;] },
        { stage: &quot;Carpark&quot;, terrors: [&quot;HER&quot;, &quot;WHITEFACE&quot;] },
        { stage: &quot;TBH&quot;, terrors: [&quot;TBH&quot;, &quot;TBH SPY&quot;] },
        { stage: &quot;Experimentation&quot;, terrors: [&quot;The Jester&quot;, &quot;Ghost Girl&quot;] },
        { stage: &quot;Backrooms&quot;, terrors: [&quot;Bacteria&quot;] },
        { stage: &quot;Gaol&quot;, terrors: [&quot;Prisoner&quot;, &quot;Security&quot;, &quot;The Swarm&quot;, &quot;Poly&quot;] },
        { stage: &quot;Slashco HQ&quot;, terrors: [&quot;Comedy&quot;, &quot;Manti&quot;] },
        { stage: &quot;Have&quot;, terrors: [&quot;Terror of Nowhere&quot;] },
        { stage: &quot;Garten&quot;, terrors: [&quot;Garten Goers&quot;] },
        { stage: &quot;Astral&quot;, terrors: [&quot;Astrum Aureus&quot;] },
        { stage: &quot;Hell&quot;, terrors: [&quot;Parhelion&quot;] },
        { stage: &quot;Hub&quot;, terrors: [&quot;Mirror&quot;, &quot;Terror of Nowhere&quot;, &quot;BFF&quot;] },
        { stage: &quot;Luna Hills&quot;, terrors: [&quot;Judas&quot;] },
        { stage: &quot;Throne&quot;, terrors: [&quot;Beyond&quot;] },
        { stage: &quot;Challenge Cube&quot;, terrors: [&quot;Apathy&quot;, &quot;Maul-A-Child&quot;, &quot;Killer Fish&quot;, &quot;Joy&quot;] }
    ];
    
    // --- MOONデータ構造 ---
    const MOON_TYPES = [
        { name: &quot;Twilight&quot;, css: &quot;moon-twilight&quot; },
        { name: &quot;Mystic Moon&quot;, css: &quot;moon-mystic&quot; },
        { name: &quot;Blood Moon&quot;, &quot;css&quot;: &quot;moon-blood&quot; },
        { name: &quot;Solstice&quot;, css: &quot;moon-solstice&quot; }
    ];
    const STANDARD_MOONS = MOON_TYPES.slice(1); // Twilight以外

    /**
     * HFA条件に合致するかチェックし、合致したテラー名を返す
     * @param {string[]} terrors - HFA判定に使うテラー名（変換前のテラー名）
     * @param {string} stage - 選出されたステージ名
     * @returns {{ isHFA: boolean, hfaTerrors: string[] }}
     */
    function checkHFA(terrors, stage) {
        const hfaTerrors = [];
        let isHFA = false;

        for (const combo of HFA_COMBINATIONS) {
            const stagesToCheck = Array.isArray(combo.stage) ? combo.stage : [combo.stage];
            
            if (stagesToCheck.includes(stage)) {
                
                for (const terror of terrors) {
                    if (combo.terrors.includes(terror)) {
                        isHFA = true;
                        if (!hfaTerrors.includes(terror)) {
                            hfaTerrors.push(terror);
                        }
                    }
                }
            }
        }

        return { isHFA, hfaTerrors: isHFA ? hfaTerrors : [] };
    }


    // --- 累計回数管理 ---
    let totalDraws = 0;
    let lastSelectedRound = null;

    function loadTotalDrawCount() {
        const storedDraws = localStorage.getItem(&#039;totalDraws&#039;);
        const storedRound = localStorage.getItem(&#039;lastSelectedRound&#039;);
        
        totalDraws = parseInt(storedDraws, 10) || 0;
        lastSelectedRound = storedRound || document.getElementById(&#039;roundSelect&#039;).value; 
        
        updateTotalDrawDisplay();
    }

    function saveTotalDrawCount() {
        localStorage.setItem(&#039;totalDraws&#039;, totalDraws.toString());
        localStorage.setItem(&#039;lastSelectedRound&#039;, document.getElementById(&#039;roundSelect&#039;).value);
    }

    function updateTotalDrawDisplay() {
        document.getElementById(&#039;totalDrawCount&#039;).textContent = totalDraws;
    }

    function resetDrawCountIfRoundChanged() {
        const currentRound = document.getElementById(&#039;roundSelect&#039;).value;
        
        if (lastSelectedRound !== null &amp;&amp; lastSelectedRound !== currentRound) {
            totalDraws = 0;
            lastSelectedRound = currentRound;
            localStorage.setItem(&#039;totalDraws&#039;, &#039;0&#039;);
        } else {
            lastSelectedRound = currentRound;
        }
        localStorage.setItem(&#039;lastSelectedRound&#039;, currentRound);
        updateTotalDrawDisplay();
    }


    // --- ユーティリティ関数 ---

    function selectRandom(arr) {
        if (!arr || arr.length === 0) return null;
        const index = Math.floor(Math.random() * arr.length);
        return arr[index];
    }

    function selectUniqueRandom(arr, count) {
        if (count &gt; arr.length) count = arr.length;
        const shuffled = arr.slice().sort(() =&gt; 0.5 - Math.random());
        return shuffled.slice(0, count);
    }
    
    function setButtonState(disabled) {
        document.getElementById(&#039;runButton&#039;).disabled = disabled;
    }

    // [EX] 通知関数
    function showEXNotification() {
        const notification = document.getElementById(&#039;exNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }

    // [It&#039;s so over] 通知関数 
    function showItsSoOverNotification() {
        const notification = document.getElementById(&#039;itsSoOverNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }
    
    // [ME] 通知関数 
    function showMENotification() {
        const notification = document.getElementById(&#039;meNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }

    // [S.O.S.特殊置換] 通知関数 
    function showSOSNotification() {
        const notification = document.getElementById(&#039;sosNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }
    
    // [TBH実績] 通知関数
    function showTBHAchievementNotification() {
        const notification = document.getElementById(&#039;tbhAchievementNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }
    
    // [Glorbo] 通知関数 (新規追加)
    function showGlorboNotification() {
        const notification = document.getElementById(&#039;glorboNotification&#039;);
        
        setButtonState(true); 
        
        notification.classList.remove(&#039;show&#039;); 
        void notification.offsetWidth; 
        notification.classList.add(&#039;show&#039;);
        
        setTimeout(() =&gt; {
            notification.classList.remove(&#039;show&#039;);
            setButtonState(false); 
        }, 1000);
    }


    // --- メインロジック関数 ---

    /**
     * テラー選出のメインロジック
     */
    function selectTerrorsAndStage(round) {
        let initialTerrors = [];
        let stage = selectRandom(STAGES);
        let isSOSReplacementEvent = false;

        // 1. テラーの初期選出
        if (round === &quot;Classic&quot; || round === &quot;Punished&quot; || round === &quot;Cracked&quot; || round === &quot;Sabotage&quot;) {
            initialTerrors.push(selectRandom(CLASSIC_TERRORS));
        } else if (round === &quot;Alternate&quot;) {
            initialTerrors.push(selectRandom(ALTERNATE_TERRORS));
        } else if (round === &quot;Bloodbath&quot;) {
            for (let i = 0; i &lt; 3; i++) {
                initialTerrors.push(selectRandom(CLASSIC_TERRORS));
            }
        } else if (round === &quot;Midnight&quot;) {
            const classic2 = selectUniqueRandom(CLASSIC_TERRORS, 2);
            initialTerrors.push(classic2[0], classic2[1], selectRandom(ALTERNATE_TERRORS)); 
        } else if (round === &quot;Unbound&quot;) {
            initialTerrors.push(selectRandom(UNBOUNDS));
        }

        // --- 2. S.O.S.置き換え (Those Olden Daysへの特殊置換) ---
        const sosCheckStages = [&quot;Spaceless&quot;, &quot;Heaven&quot;, &quot;Escape Route&quot;];
        const needsSOSHighlight = [&quot;Punished&quot;, &quot;Bloodbath&quot;, &quot;Midnight&quot;].includes(round);
        
        let terrorsAfterSOSReplacement = initialTerrors.map(t =&gt; {
            if (t === &quot;S.O.S&quot; &amp;&amp; sosCheckStages.includes(stage) &amp;&amp; needsSOSHighlight) {
                isSOSReplacementEvent = true; // 特殊イベントフラグを立てる
                return &quot;Those Olden Days&quot;; 
            }
            return t;
        });
        
        // --- 3. ラウンド別出禁の適用 (Those Olden Daysは出禁だが、S.O.S.からの特殊置換の場合は除く) ---
        let bannedList = [];
        if (round === &quot;Bloodbath&quot;) {
            bannedList = [&quot;Luigi &amp; Luigi Dolls&quot;, &quot;Akumii-Kari&quot;, &quot;Those Olden Days&quot;, &quot;Deleted&quot;];
        } else if (round === &quot;Midnight&quot;) {
            bannedList = [&quot;Luigi &amp; Luigi Dolls&quot;, &quot;Akumii-Kari&quot;, &quot;Those Olden Days&quot;, &quot;Deleted&quot;, &quot;Specimen 5&quot;];
        } else if (round === &quot;Punished&quot;) {
            bannedList = [&quot;Those Olden Days&quot;, &quot;Cubor&#039;s Revenge&quot;];
        }

        let isMidnightBannedSubstitution = false;
        
        let terrorsAfterBanning = terrorsAfterSOSReplacement.map((t, index) =&gt; {
            // S.O.S.の特殊置換によるThose Olden Daysは出禁にしない
            if (isSOSReplacementEvent &amp;&amp; t === &quot;Those Olden Days&quot;) {
                return t;
            }

            // 標準の出禁ロジック
            if (bannedList.includes(t)) {
                if (round === &quot;Midnight&quot; &amp;&amp; index &lt; 2) { 
                    isMidnightBannedSubstitution = true;
                }
                return &quot;Comedy&quot;; 
            }
            return t;
        });

        // HFAチェック用のテラー名リスト (テラー名変更前の最終的なリスト)
        let terrorsForHFACheckBase = terrorsAfterBanning;

        // --- 4. HFA無効化チェック (Midnight/Crackedで変換されるテラーがHFA条件を満たす場合、無効化) ---
        let HFA_DISABLED_BY_TRANSFORM = [];
        if (round === &quot;Midnight&quot; || round === &quot;Cracked&quot;) {
            const transformSources = (round === &quot;Midnight&quot; ? MIDNIGHT_TRANSFORM_SOURCES : CRACKED_TRANSFORM_SOURCES);
            
            terrorsForHFACheckBase.forEach(t =&gt; {
                if (transformSources.includes(t)) {
                    for (const combo of HFA_COMBINATIONS) {
                        const stagesToCheck = Array.isArray(combo.stage) ? combo.stage : [combo.stage];
                        if (stagesToCheck.includes(stage) &amp;&amp; combo.terrors.includes(t)) {
                            HFA_DISABLED_BY_TRANSFORM.push(t);
                            break; 
                        }
                    }
                }
            });
        }
        
        // HFA判定に使う最終テラーリスト
        let terrorsForHFACheck = terrorsForHFACheckBase.filter(t =&gt; !HFA_DISABLED_BY_TRANSFORM.includes(t)); 


        // --- 5. ラウンド固有のテラー名変更と特殊タグ付け (表示用) ---
        let terrorsForDisplay = terrorsForHFACheckBase.slice();
        
        // S.O.S.特殊置換テラーにタグを付ける
        terrorsForDisplay = terrorsForDisplay.map(t =&gt; {
            if (isSOSReplacementEvent &amp;&amp; t === &quot;Those Olden Days&quot;) {
                t += &quot;&lt;SOS&gt;&quot;;
            }
            return t;
        });
        
        // Cracked/Midnightの変換
        if (round === &quot;Cracked&quot;) {
            terrorsForDisplay = terrorsForDisplay.map(t =&gt; CRACKED_TRANSFORM[t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;)] || t);
        } else if (round === &quot;Midnight&quot;) {
            terrorsForDisplay = terrorsForDisplay.map(t =&gt; MIDNIGHT_TRANSFORM[t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;)] || t);
        }

        // --- 6. BloodbathとMidnightの最終選出ロジック (表示用とHFAチェック用を分離して処理) ---
        let finalTerrors = [];
        let finalHfaCheckTerrors = []; 
        
        if (round === &quot;Bloodbath&quot;) {
            const terrorsNoTags = terrorsForDisplay.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim()); 
            const baseTerrorsNoTags = terrorsForHFACheckBase.map(t =&gt; t.split(&#039;(&#039;)[0].trim()); 

            const countMap = {};
            terrorsNoTags.forEach(t =&gt; countMap[t] = (countMap[t] || 0) + 1);
            const uniqueTerrors = Object.keys(countMap);
            
            const randomChance = Math.random(); 

            if (randomChance &lt; 3 / 35) {
                if (uniqueTerrors.length === 1) {
                    finalTerrors = [`EX (${uniqueTerrors[0]})`];
                    finalHfaCheckTerrors = [baseTerrorsNoTags[0]].filter(t =&gt; terrorsForHFACheck.includes(t)); 
                } else {
                    const uniqueIndices = [0, 1, 2].sort(() =&gt; 0.5 - Math.random()).slice(0, 2);
                    const selectedNames = [baseTerrorsNoTags[uniqueIndices[0]], baseTerrorsNoTags[uniqueIndices[1]]].filter((v, i, a) =&gt; a.indexOf(v) === i);

                    finalTerrors = [terrorsNoTags.find(t =&gt; t === selectedNames[0]), terrorsNoTags.find(t =&gt; t === selectedNames[1])].filter(Boolean);
                    finalTerrors.unshift(&quot;Double Trouble&quot;);
                    
                    finalHfaCheckTerrors = selectedNames.filter(t =&gt; terrorsForHFACheck.includes(t));
                }
            } else {
                if (uniqueTerrors.length === 3) {
                    finalTerrors = terrorsForDisplay; 
                    finalHfaCheckTerrors = baseTerrorsNoTags.filter(t =&gt; terrorsForHFACheck.includes(t)); 
                } else if (uniqueTerrors.length === 2) {
                    const doubleTerrorName = uniqueTerrors.find(t =&gt; countMap[t] === 2);
                    const singleTerrorName = uniqueTerrors.find(t =&gt; countMap[t] === 1);
                    
                    const doubleTerror = terrorsForDisplay.find(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim() === doubleTerrorName);
                    const singleTerror = terrorsForDisplay.find(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim() === singleTerrorName);
                    
                    finalTerrors = [doubleTerror, singleTerror];
                    finalTerrors.unshift(&quot;Double Trouble&quot;);

                    const baseDouble = baseTerrorsNoTags.find(t =&gt; t === doubleTerrorName);
                    const baseSingle = baseTerrorsNoTags.find(t =&gt; t === singleTerrorName);
                    
                    finalHfaCheckTerrors = [baseDouble, baseSingle].filter(t =&gt; terrorsForHFACheck.includes(t));
                    
                } else if (uniqueTerrors.length === 1) {
                    finalTerrors = [`EX (${uniqueTerrors[0]})`];
                    finalHfaCheckTerrors = [baseTerrorsNoTags[0]].filter(t =&gt; terrorsForHFACheck.includes(t));
                } else {
                    finalTerrors = terrorsForDisplay; 
                    finalHfaCheckTerrors = baseTerrorsNoTags.filter(t =&gt; terrorsForHFACheck.includes(t));
                }
            }
        } else if (round === &quot;Midnight&quot;) {
            const [c1, c2, alternate] = terrorsForDisplay; // 変換後/表示用
            const [base_c1, base_c2, base_alternate] = terrorsForHFACheckBase; // 変換前/HFAチェック用

            if (isMidnightBannedSubstitution) {
                 finalTerrors = [&quot;Comedy&quot;, alternate];
                 finalHfaCheckTerrors = [&quot;Comedy&quot;, base_alternate].filter(t =&gt; terrorsForHFACheck.includes(t)); 
            } else {
                finalTerrors = [c1, c2, alternate];
                finalHfaCheckTerrors = [base_c1, base_c2, base_alternate].filter(t =&gt; terrorsForHFACheck.includes(t)); 
            }
            
            // Eyesの特殊ルール適用
            const finalTerrorsNoTags = finalTerrors.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;));
            const hasRushOrAmbush = finalTerrorsNoTags.includes(&quot;Rush&quot;) || finalTerrorsNoTags.includes(&quot;Ambush&quot;);
            
            if (hasRushOrAmbush) {
                if (finalTerrors.length === 3) { 
                     finalTerrors.splice(2, 0, &quot;Eyes&quot;); 
                     finalHfaCheckTerrors.splice(2, 0, &quot;Eyes&quot;); 
                } else if (finalTerrors.length === 2) { 
                     finalTerrors.splice(1, 0, &quot;Eyes&quot;); 
                     finalHfaCheckTerrors.splice(1, 0, &quot;Eyes&quot;); 
                }
            }
        } else {
            finalTerrors = terrorsForDisplay;
            finalHfaCheckTerrors = terrorsForHFACheckBase.filter(t =&gt; terrorsForHFACheck.includes(t));
        }
        
        // --- 7. Fusion Pilot特殊チェック ([It&#039;s so over] 条件) ---
        let itsSoOverColor = null; 
        
        const finalTerrorsNoTags = finalTerrors.map(t =&gt; t.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim()); 
        
        if (stage === &quot;Challenge Cube&quot;) {
            if (round === &quot;Alternate&quot; &amp;&amp; finalTerrorsNoTags.includes(&quot;Fusion Pilot&quot;)) {
                itsSoOverColor = &#039;blue&#039;;
            } else if (round === &quot;Midnight&quot;) {
                const alternateTerror = finalTerrorsNoTags[finalTerrorsNoTags.length - 1];
                if (alternateTerror === &quot;Fusion Pilot&quot;) {
                    itsSoOverColor = &#039;red&#039;;
                }
            }
        }
        
        // --- 8. MEチェック (Alternate &amp; Roblander @ Robland) ---
        let isME = false;
        if (round === &quot;Alternate&quot; &amp;&amp; stage === &quot;Robland&quot; &amp;&amp; finalTerrorsNoTags.includes(&quot;Roblander&quot;)) {
             isME = true;
        }

        // --- 9. TBH実績チェック (TBH or TBH SPY or TBH SANS @ TBH) ---
        let isTBHAchievement = false;
        
        let terrorsForAchievement = [];

        if (round === &quot;Cracked&quot;) {
            terrorsForAchievement = [&quot;TBH SANS&quot;];
        } else {
            terrorsForAchievement = [&quot;TBH&quot;, &quot;TBH SPY&quot;, &quot;TBH SANS&quot;];
        }

        const hasTargetTerror = finalTerrorsNoTags.some(t =&gt; terrorsForAchievement.includes(t));

        if (stage === &quot;TBH&quot; &amp;&amp; hasTargetTerror) {
             isTBHAchievement = true;
        }


        // --- 10. HFAチェック ([HFA] 条件) ---
        const hfaCheckList = finalHfaCheckTerrors.filter(t =&gt; t !== &quot;Eyes&quot; &amp;&amp; t !== &quot;Roblander&quot;); 
        const hfaResult = checkHFA(hfaCheckList, stage);
        
        // --- 11. Glorbo上書きチェック (Punished &amp; Sewers) (新規追加) ---
        let isGlorbo = false;
        if (round === &quot;Punished&quot; &amp;&amp; stage === &quot;Sewers&quot; &amp;&amp; Math.random() &lt; 1 / 10000) {
            isGlorbo = true;
        }
        
        // --- 12. MOON上書きチェック (すべての判定が完了した後) ---
        let selectedMoon = null;
        let isMoon = false;
        const moonOverwriteEnabled = document.getElementById(&#039;moonOverwrite&#039;).checked;
        const nonMoonRounds = [&quot;Classic&quot;, &quot;Alternate&quot;];
        
        if (!isGlorbo &amp;&amp; moonOverwriteEnabled &amp;&amp; !nonMoonRounds.includes(round) &amp;&amp; Math.random() &lt; 1 / 80) {
            isMoon = true;
            if (stage === &quot;Black Forest&quot;) {
                selectedMoon = selectRandom(MOON_TYPES); // Twilight含む全て
            } else {
                selectedMoon = selectRandom(STANDARD_MOONS); // Twilight以外
            }
        }

        // 最終的な結果オブジェクトを返す
        return { 
            terrors: finalTerrors, 
            stage, 
            itsSoOverColor, 
            isHFA: hfaResult.isHFA, 
            hfaTerrors: hfaResult.hfaTerrors, 
            isME: isME,
            isMoon: isMoon, 
            selectedMoon: selectedMoon, 
            isSOSReplacementEvent: isSOSReplacementEvent,
            isTBHAchievement: isTBHAchievement, // TBH実績フラグ
            isGlorbo: isGlorbo // Glorboフラグ
        };
    }

    /**
     * 結果表示用の文字列を整形する。
     */
    function formatResult(round, result) {
        const { terrors, stage, itsSoOverColor, isHFA, hfaTerrors, isME, isMoon, selectedMoon, isSOSReplacementEvent, isGlorbo } = result;
        
        // --- 0. Glorbo上書き表示 (最優先) ---
        if (isGlorbo) {
             return `&lt;span style=&quot;font-weight: bold; color: #8A2BE2;&quot;&gt;Glorbo&lt;/span&gt; @ ${stage}`;
        }

        // --- 1. ムーン上書きプレフィックスの構築 (次に優先) ---
        let moonPrefixHtml = &quot;&quot;;
        if (isMoon) {
            moonPrefixHtml = `&lt;span class=&quot;${selectedMoon.css}&quot;&gt;[${selectedMoon.name}]&lt;/span&gt; `;
        }
        
        // --- 2. ME表示 (ムーンがなければ次に優先) ---
        if (isME &amp;&amp; !isMoon) {
            return `&lt;span class=&quot;me-terror&quot;&gt;ME&lt;/span&gt; @ ${stage}`;
        }
        
        if (round === &quot;Unbound&quot;) {
            // Unboundはテラーが1つ
            let prefix = moonPrefixHtml;
            if (itsSoOverColor === &#039;blue&#039;) {
                prefix += `&lt;span class=&quot;its-so-over-blue&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
            } else if (itsSoOverColor === &#039;red&#039;) {
                prefix += `&lt;span class=&quot;its-so-over-red&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
            }
            if (isHFA) {
                prefix += `&lt;span class=&quot;hfa-prefix&quot;&gt;[HFA]&lt;/span&gt; `;
            }
            
            const terrorNoTag = terrors[0].replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;);
            const isSOSReplacementUnbound = terrors[0].includes(&#039;&lt;SOS&gt;&#039;);
            
            let terrorDisplay = terrorNoTag;
            if (isSOSReplacementUnbound) {
                 terrorDisplay = `&lt;span class=&quot;sos-replacement-terror&quot;&gt;${terrorNoTag}&lt;/span&gt;`;
            } else {
                 terrorDisplay = terrorNoTag;
            }

            return `${prefix}${terrorDisplay} @ ${stage}`;
        }
        
        let terrorsHtml = [];

        for(let terror of terrors) {
            let formattedTerror = terror;
            const isSOSReplacement = terror.endsWith(&quot;&lt;SOS&gt;&quot;);
            
            let baseTerrorName = terror.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;).split(&#039;(&#039;)[0].trim(); 
            
            if (isSOSReplacement) {
                formattedTerror = formattedTerror.replace(&#039;&lt;SOS&gt;&#039;, &#039;&#039;);
            }
            
            // HFAで太字化すべきテラー名 (変換前の名前) が、現在の表示名（変換後）と一致するかを判定
            let isCurrentTerrorHFA = false;
            let originalName = baseTerrorName;
            
            const allTransforms = { ...CRACKED_TRANSFORM, ...MIDNIGHT_TRANSFORM };
            const reverseTransform = Object.entries(allTransforms).find(([, v]) =&gt; v === baseTerrorName);
            if (reverseTransform) originalName = reverseTransform[0];
            
            if (isHFA &amp;&amp; hfaTerrors.includes(originalName)) {
                 isCurrentTerrorHFA = true;
            }


            // --- 既存の装飾ロジック ---
            
            // 1. Bloodbathの昇格チェック
            if (terror.startsWith(&quot;Double Trouble&quot;) || terror.startsWith(&quot;EX&quot;)) {
                 formattedTerror = `&lt;strong&gt;${baseTerrorName}&lt;/strong&gt;`;
            } 
            // 2. SOS Replacementチェック (茶色太字)
            else if (isSOSReplacement) {
                formattedTerror = `&lt;span class=&quot;sos-replacement-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
            }
            // 3. Crackedのテラー名変更チェック
            else if (round === &quot;Cracked&quot; &amp;&amp; CRACKED_TRANSFORMED_NAMES.includes(baseTerrorName)) {
                 formattedTerror = `&lt;span class=&quot;cracked-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
            } 
            // 4. Midnightのテラー名変更チェック
            else if (round === &quot;Midnight&quot; &amp;&amp; (terror.startsWith(&quot;EX&quot;) || terror.startsWith(&quot;Double Trouble&quot;) ? true : MIDNIGHT_TRANSFORMED_NAMES.includes(baseTerrorName))) {
                if (baseTerrorName === &quot;Monarch&quot;) {
                     formattedTerror = `&lt;span class=&quot;monarch-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                } else if (baseTerrorName === &quot;Blue Haket&quot;) {
                     formattedTerror = `&lt;span class=&quot;blue-midnight-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                } else {
                    formattedTerror = `&lt;span class=&quot;midnight-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                }
            }
            // 5. その他 (装飾がない場合はそのまま)
            else {
                formattedTerror = baseTerrorName;
            }
            
            // --- HFAの太字装飾の適用 (既存の装飾を上書きするため最後に適用) ---
            if (isCurrentTerrorHFA) {
                if (terror.includes(&#039;(&#039;) &amp;&amp; terror.includes(&#039;)&#039;)) {
                    const parts = terror.match(/(.+?)\s*\((.+?)\)/);
                    if (parts) {
                        formattedTerror = `${parts[1]} (&lt;span class=&quot;hfa-terror&quot;&gt;${parts[2]}&lt;/span&gt;)`;
                    }
                } else {
                    formattedTerror = `&lt;span class=&quot;hfa-terror&quot;&gt;${baseTerrorName}&lt;/span&gt;`;
                }
            }
            
            // BloodbathのEX/DoubleTroubleの装飾を再適用 (HFAの黒太字を上書きしないように)
            if (terror.startsWith(&quot;Double Trouble&quot;) || terror.startsWith(&quot;EX&quot;)) {
                 formattedTerror = `&lt;strong&gt;${formattedTerror}&lt;/strong&gt;`;
            }
            
            terrorsHtml.push(formattedTerror);
        }
        
        
        // --- プレフィックスの結合 ---
        let finalPrefixHtml = moonPrefixHtml;
        
        if (itsSoOverColor === &#039;blue&#039;) {
            finalPrefixHtml += `&lt;span class=&quot;its-so-over-blue&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
        } else if (itsSoOverColor === &#039;red&#039;) {
            finalPrefixHtml += `&lt;span class=&quot;its-so-over-red&quot;&gt;[It&#039;s so over]&lt;/span&gt; `;
        }
        
        if (isHFA) {
            finalPrefixHtml += `&lt;span class=&quot;hfa-prefix&quot;&gt;[HFA]&lt;/span&gt; `;
        }

        // Bloodbathの特殊フォーマットを処理
        if (round === &quot;Bloodbath&quot; &amp;&amp; (terrors[0].startsWith(&quot;Double Trouble&quot;) || terrors[0].startsWith(&quot;EX&quot;))) {
            const type = terrorsHtml.shift(); 
            
            if (terrors[0].startsWith(&quot;EX&quot;)) {
                 return `${finalPrefixHtml}${type} @ ${stage}`; 
            } 
            
            const terrorList = terrorsHtml.join(&#039; / &#039;);
            const typeNoTag = type.replace(/&lt;[^&gt;]*&gt;/g, &#039;&#039;);
            return `${finalPrefixHtml}${typeNoTag} (${terrorList}) @ ${stage}`;
            
        }
        
        // その他のラウンドの表示
        const terrorDisplay = terrorsHtml.join(&#039; / &#039;);
        
        return `${finalPrefixHtml}${terrorDisplay} @ ${stage}`;
    }

    // --- メイン実行関数 ---
    function runSelection() {
        const round = document.getElementById(&#039;roundSelect&#039;).value;
        const countSelect = document.getElementById(&#039;countSelect&#039;);
        const count = parseInt(countSelect.value, 10);
        const resultsDisplay = document.getElementById(&#039;results-display&#039;);
        resultsDisplay.innerHTML = &#039;&#039;; 

        if (isNaN(count) || count &lt; 1) {
            resultsDisplay.innerHTML = &#039;&lt;p&gt;連数を正しく選択してください。&lt;/p&gt;&#039;;
            return;
        }
        
        // 累計回数を更新
        totalDraws += count;
        saveTotalDrawCount();
        updateTotalDrawDisplay();

        for (let i = 0; i &lt; count; i++) {
            const result = selectTerrorsAndStage(round);
            
            // 通知チェック (優先度順: Glorbo &gt; ムーン &gt; TBH実績 &gt; ME &gt; SOS &gt; EX &gt; It&#039;s so over)
            if (result.isGlorbo) {
                showGlorboNotification();
            } else if (result.isMoon) {
                // ムーン通知は不要 (表示で十分)
            } else if (result.isTBHAchievement) { // TBH実績通知チェック
                showTBHAchievementNotification();
            } else if (result.isME) { // ME通知チェック
                showMENotification();
            } else if (result.isSOSReplacementEvent) { // S.O.S.特殊置換通知チェック
                showSOSNotification();
            } else if (round === &quot;Bloodbath&quot; &amp;&amp; result.terrors.length &gt; 0 &amp;&amp; result.terrors[0].startsWith(&quot;EX (&quot;)) {
                 showEXNotification();
            } else if (result.itsSoOverColor) {
                showItsSoOverNotification();
            } 

            const formattedResult = formatResult(round, result);

            const resultDiv = document.createElement(&#039;div&#039;);
            resultDiv.classList.add(&#039;result-item&#039;);
            resultDiv.innerHTML = `${i + 1}連目: ${formattedResult}`;
            resultsDisplay.appendChild(resultDiv);
        }
    }

    // --- 画像保存関数 ---
    function saveAsImage() {
        const node = document.getElementById(&#039;results-display&#039;);
        
        domtoimage.toPng(node)
            .then(function (dataUrl) {
                const link = document.createElement(&#039;a&#039;);
                link.download = `選出結果_${document.getElementById(&#039;roundSelect&#039;).value}_${new Date().toLocaleTimeString().replace(/:/g, &#039;-&#039;)}.png`;
                link.href = dataUrl;
                link.click();
            })
            .catch(function (error) {
                console.error(&#039;画像保存に失敗しました:&#039;, error);
                alert(&#039;結果を画像として保存できませんでした。ブラウザのコンソールを確認してください。&#039;);
            });
    }

    // --- 初期化 ---
    document.addEventListener(&#039;DOMContentLoaded&#039;, () =&gt; {
        loadTotalDrawCount();
        
        document.getElementById(&#039;results-display&#039;).innerHTML = &#039;&lt;p style=&quot;text-align: center; color: #777;&quot;&gt;ラウンドと連数を選択し、「選出！」ボタンを押してください。&lt;/p&gt;&#039;;
        document.getElementById(&#039;exNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;itsSoOverNotification&#039;).classList.remove(&#039;show&#039;); 
        document.getElementById(&#039;meNotification&#039;).classList.remove(&#039;show&#039;); 
        document.getElementById(&#039;sosNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;tbhAchievementNotification&#039;).classList.remove(&#039;show&#039;);
        document.getElementById(&#039;glorboNotification&#039;).classList.remove(&#039;show&#039;);
        setButtonState(false);
        
        // ラウンド変更時のリセットイベントを設定
        document.getElementById(&#039;roundSelect&#039;).addEventListener(&#039;change&#039;, resetDrawCountIfRoundChanged);
    });

&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
}


ver1.1
・狂気とミッドナイトのシナジーが出た場合に名前を変更して色が付くようにしました
ver1.1.1
・おるでんが出禁ラウンドでS.O.Sの塗り替えで出た場合に太文字の茶色で表示されるようにしました
ver1.1.2
・ぶるはけは青色で表示されるようにしました
ver1.2
・何回ガチャを回したかの表示
・ブラバでEXが出た時に通知+1秒間ボタンを押せなくして連打をしてもEXがしっかり見れるようにしました
ver1.3
・It&#039;s so overを表示するようにしました
ver1.3.1
・It&#039;s so overが選出されると通知が出るようにしました
ver1.4
・HFAを表示するようにしました
ver1.4.1
・ミッドナイトでラウンド選出が不可能になるバグを修正しました
ver1.4.2
・MEを表示するようにしました
ver1.5
・ムーン上書きボタンを追加しました
クラシック、オルタネイト以外で1/80でムーン上書きをし、そこから3種類(ブラフォレのみ4種類)のムーンをランダムで上書きとして出すようにしました
※ムーン上書きには諸説ありますが、ネタのサイトという事で許してください
ver1.5.1
・出禁ラウンドでおるでんが選出されると通知が出るようにしました
・ムーン上書きによるバグを修正しました
ver1.6
・TBHまたはTBH SPYをステージ：TBHで引いた時に通知を追加しました
ver1.7
・Glorboを追加しました
※バグ等見つかればぜひamutoppoのDiscordのDMまで！    </description>
    <dc:date>2025-12-01T01:40:39+09:00</dc:date>
    <utime>1764520839</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/12.html">
    <title>ラウンドガチャ</title>
    <link>https://w.atwiki.jp/tontool/pages/12.html</link>
    <description>
          </description>
    <dc:date>2025-11-30T20:24:30+09:00</dc:date>
    <utime>1764501870</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/10.html">
    <title>ToN周回ビンゴ</title>
    <link>https://w.atwiki.jp/tontool/pages/10.html</link>
    <description>
      #javascript(){
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;ToNGO ジェネレーター&lt;/title&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        body { 
            font-family: &#039;Arial Black&#039;, sans-serif; 
            display: flex; 
            flex-direction: column; 
            align-items: center; 
            padding: 10px; 
            background-color: #f0f0f0;
        }

        /* ToNGO タイトル - 表示用 */
        .page-title {
            text-align: center;
            margin-bottom: 10px; 
            font-size: 36px;
            font-weight: bold;
            color: #333; 
        }
        @media (max-width: 600px) {
            .page-title {
                font-size: 30px; 
            }
        }

        /* ToNGO タイトル - 画像キャプチャ用 */
        .capture-title-wrapper {
            display: flex;
            justify-content: center;
            width: 100%; 
            margin-bottom: 20px; 
        }
        .capture-title {
            display: inline-block; 
            padding: 0;
            background: none;
            border-radius: 0;
            font-size: 48px; 
            font-weight: bold;
            letter-spacing: normal; 
            color: #333; 
            text-shadow: none; 
            box-shadow: none; 
        }
        @media (max-width: 600px) {
            .capture-title {
                font-size: 36px; 
                padding: 0;
            }
        }


        .controls {
            margin-bottom: 20px;
            display: flex;
            flex-wrap: wrap; 
            gap: 10px; 
            justify-content: center;
        }

        button {
            padding: 10px 15px;
            font-size: 14px;
            cursor: pointer;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
            transition: background-color 0.2s ease;
        }
        button:hover {
            background-color: #0056b3;
        }
        button.active-color {
            border: 2px solid yellow; 
        }

        /* 画像キャプチャ用のメインコンテナ */
        .image-capture-area {
            display: flex;
            flex-direction: column;
            align-items: center; 
            width: 100%; 
            max-width: 500px; 
            padding: 20px; 
            background-color: #f0f0f0; 
            border-radius: 10px; 
            box-sizing: border-box; 
            margin: 0 auto; 
        }


        .bingo-container { 
            max-width: 400px; 
            width: 100%; 
        }
        .bingo-grid {
            display: grid;
            grid-template-columns: repeat(5, 1fr); 
            grid-auto-rows: 80px; 
            border: 5px solid #333; 
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 
            background-color: #f9f9f9;
            transition: border-color 0.3s ease; 
        }
        /* 縁のカラーバリエーション */
        .bingo-grid.color-default { border-color: #333; }
        .bingo-grid.color-red { border-color: #d9534f; }
        .bingo-grid.color-blue { border-color: #007bff; }
        .bingo-grid.color-green { border-color: #28a745; }
        .bingo-grid.color-purple { border-color: #6f42c1; }
        .bingo-grid.color-gold { border-color: #ffc107; }


        .cell {
            border: 1px solid #aaa;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 2px;
            text-align: center;
            font-weight: bold;
            word-break: break-all; 
            background-color: #fff; 
        }
        .cell span {
            display: block; 
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            line-height: 1.2; 
            padding: 2px; 
            box-sizing: border-box;
        }
        .free-cell {
            background-color: #ffe0e0; 
            color: #d9534f;
            font-size: 18px;
            border: 2px dashed #d9534f; 
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;h1 class=&quot;page-title&quot;&gt;ToNGO&lt;/h1&gt;
    &lt;p style=&quot;font-size: 12px; text-align: center;&quot;&gt;「シート作成＆画像保存」で新しいシートを作成し、画像としてダウンロードします。&lt;br&gt;
        もし周回でどうしても達成できないものがある場合は達成した扱いとしてください。&lt;/p&gt;

    &lt;div class=&quot;controls&quot;&gt;
        &lt;button onclick=&quot;generateAndSaveBingo()&quot;&gt;シート作成＆画像保存&lt;/button&gt;
        &lt;button onclick=&quot;changeBorderColor(&#039;default&#039;)&quot; class=&quot;active-color&quot; data-color=&quot;default&quot;&gt;デフォルト&lt;/button&gt;
        &lt;button onclick=&quot;changeBorderColor(&#039;red&#039;)&quot; data-color=&quot;red&quot;&gt;赤&lt;/button&gt;
        &lt;button onclick=&quot;changeBorderColor(&#039;blue&#039;)&quot; data-color=&quot;blue&quot;&gt;青&lt;/button&gt;
        &lt;button onclick=&quot;changeBorderColor(&#039;green&#039;)&quot; data-color=&quot;green&quot;&gt;緑&lt;/button&gt;
        &lt;button onclick=&quot;changeBorderColor(&#039;purple&#039;)&quot; data-color=&quot;purple&quot;&gt;紫&lt;/button&gt;
        &lt;button onclick=&quot;changeBorderColor(&#039;gold&#039;)&quot; data-color=&quot;gold&quot;&gt;金&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;image-capture-area&quot; id=&quot;imageCaptureArea&quot;&gt;
        &lt;div class=&quot;capture-title-wrapper&quot;&gt;
            &lt;span class=&quot;capture-title&quot;&gt;ToNGO&lt;/span&gt; 
        &lt;/div&gt;
        &lt;div class=&quot;bingo-container&quot; id=&quot;bingoContainer&quot;&gt;
            &lt;div class=&quot;bingo-grid&quot; id=&quot;bingoGrid&quot;&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // --- 1. 定義 ---
        const difficultyLayout = [
            [1, 2, 1, 3, 1],
            [2, 1, 4, 1, 2],
            [1, 3, &#039;FREE&#039;, 2, 1], 
            [3, 2, 1, 5, 4],
            [1, 4, 2, 1, 1]
        ];

        const missionsByDifficulty = {
            1: [
                &#039;視認ダメージを受ける&#039;,
                &#039;アンバウンドに遭遇する&#039;,
                &#039;ゴーストに遭遇する&#039;,
                &#039;Shady（実績部屋にいる魚）にEphを与える&#039;,
                &#039;ミスティックムーンを開放する&#039;,
                &#039;制限時間を200秒に再セットするラウンドに遭遇する。&#039;,
                &#039;インス内にいる全員でラウンドを開始する。&#039;,
                &#039;8ページに持ち込み可能アイテムを持っていく。&#039;,
                &#039;1回の休憩時間で3色別のEphクリスタルを砕く&#039;,
                &#039;Solstice,Bigger Boot,FP,Garten Goers,Kimera,Eggmanのいずれかに遭遇する。&#039;,
                &#039;FPかクラシックFP(カロル)に遭遇する&#039;,
                &#039;マップ全域にダメージを与えてくるテラーに遭遇する。&#039;,
                &#039;執行猶予を付与してくるテラーいずれかに遭遇する。&#039;,
                &#039;3回連続でクラシック以外のラウンドに遭遇&#039;,
                &#039;ダブルトラブルに遭遇する&#039;,
                &#039;Eph所持量1000を超える&#039;,
            ],
            2: [
                &#039;テラー又は作者のBeyondに遭遇する&#039;,
                &#039;Arkusに遭遇&#039;,
                &#039;MX, Luigi, Wario Apparitionのいずれかに遭遇する。&#039;,
                &#039;最も小さいテラー(Immortal Snail)に遭遇する。&#039;,
                &#039;Eph所持量3000を超える&#039;,
                &#039;サボタージュのマーダーになる&#039;,
                &#039;何らかのラウンドシナジーテラーに遭遇&#039;,
                &#039;2連続で同じマップを引く&#039;,
                &#039;Hotel Monstersで出現するテラー(Rush,Seek,Eyes)のいずれかに遭遇する。&#039;,
                &#039;名前がGから始まるテラーかアンバウンドに遭遇する。&#039;,
                &#039;クラシックではないスパムトンに遭遇する&#039;,
                &#039;An Arbiter, The Red Mistのいずれかに遭遇する&#039;,
                &#039;seekのいるブラッドバスに遭遇する&#039;,
                &#039;Joyに殺される&#039;,
                &#039;クラシックのWaldoに160秒までに触れて自爆する&#039;
            ],
            3: [
                &#039;Immortal Snailを踏んで死亡する&#039;,
                &#039;確定特殊ラウンドで8ページを引く。&#039;,
                &#039;接触即死テラーに霧ラウンドで遭遇する。&#039;,
                &#039;段差の無いマップで、もぺもぺに遭遇する。&#039;,
                &#039;トワイライト前にミロスバードか極楽鳥またはアンバウンドの終末鳥か罰鳥に遭遇する。&#039;,
                &#039;1回のラウンドで1000ダメージ以上を受ける。&#039;,
                &#039;オルタネイトがクラシックを上書きする。&#039;,
                &#039;FPで全滅する。&#039;,
                &#039;Apocalypse Bird(終末鳥)に遭遇する。&#039;,
                &#039;3大オルタ（FP・ロブ・ブリス）のいずれかに遭遇する&#039;,
                &#039;Challenge Cubeに4体以上のテラーがスポーンする(ブラッドバス、ミッドナイト含む)&#039;,
                &#039;偽Compass(Kimera以外でのBGM:Compassなミッド)に遭遇する&#039;,
                &#039;最も大きいテラー(Apocalypse Bird)に遭遇する。&#039;,
                &#039;Map.challenge cubeでオルタネイトに遭遇する&#039;,
                &#039;Nextbotsから出たSaul(アンバウンドも可)を見る。&#039;
            ],
            4: [
                &#039;ミッドナイトシナジーのテラーに遭遇する&#039;,
                &#039;TBH SANS又はEpic Bonnieに遭遇&#039;,
                &#039;Nexusでオルタネイトに遭遇する&#039;,
                &#039;同じテラーに2回連続で遭遇する(ラウンドは問わない)&#039;,
                &#039;ホープレスに遭遇する&#039;,
                &#039;アンバウンドでオルタネイトテラーに遭遇する&#039;,
                &#039;baldiにschoolhouse以外で遭遇&#039;,
                &#039;5大オルタネイトの内3体に遭遇する(FP ザッパー レスレス パヘ Joy)&#039;,
                &#039;RUNの扉に入って死ぬ(RUNスキップなら遭遇のみ)&#039;,
                &#039;テラー生存の実績を掲げている状態でそのテラーに遭遇する&#039;,
                &#039;Variantテラーに遭遇&#039;,
                &#039;8ぺのオルタネイツに遭遇する&#039;,
                &#039;ミッドナイトで誰も死なずにホープレスになる&#039;
            ],
            5: [
                &#039;Wild Yet Bloodthirsty Creatureに特殊ラウンドで遭遇&#039;,
                &#039;Monarchに遭遇する&#039;,
                &#039;TBH SANSに遭遇&#039;,
                &#039;ラウンドタイプ、ゴーストのオルタネイトに遭遇する&#039;,
                &#039;DotsでMidnightに遭遇する&#039;,
                &#039;任意のMidnightに遭遇した次のラウンドでNexusもしくはHeavenに訪れる&#039;,
                &#039;Heaven、またはNexusでWHITEFACEに遭遇する&#039;
            ]
        };

        let currentBorderColorClass = &#039;color-default&#039;; 

        // --- 2. シャッフル関数 ---
        function shuffle(array) {
            for (let i = array.length - 1; i &gt; 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
        }

        /**
         * 文字列の長さに基づいてフォントサイズを決定する関数
         */
        function getFontSize(text) {
            const length = text.length;
            
            if (length &lt;= 15) {
                return 14; 
            } else if (length &lt;= 25) {
                return 12;
            } else if (length &lt;= 35) {
                return 10;
            } else {
                return 8; 
            }
        }

        // --- 3. シート生成ロジック ---
        function generateBingoSheet() {
            const grid = document.getElementById(&#039;bingoGrid&#039;);
            grid.innerHTML = &#039;&#039;; 

            const availableMissions = {};
            for (const diff in missionsByDifficulty) {
                availableMissions[diff] = [...missionsByDifficulty[diff]];
                shuffle(availableMissions[diff]);
            }

            for (let r = 0; r &lt; 5; r++) { 
                for (let c = 0; c &lt; 5; c++) { 
                    const difficulty = difficultyLayout[r][c];
                    const cell = document.createElement(&#039;div&#039;);
                    cell.classList.add(&#039;cell&#039;);

                    if (difficulty === &#039;FREE&#039;) {
                        cell.classList.add(&#039;free-cell&#039;);
                        cell.innerHTML = `&lt;span&gt;FREE&lt;/span&gt;`;
                    } else {
                        const missionList = availableMissions[difficulty];
                        if (missionList.length &gt; 0) {
                            const mission = missionList.pop(); 
                            const fontSize = getFontSize(mission); 
                            
                            cell.innerHTML = `&lt;span style=&quot;font-size: ${fontSize}px;&quot;&gt;${mission}&lt;/span&gt;`;
                        } else {
                            cell.innerHTML = `&lt;span&gt;ERROR: Out of D${difficulty} missions&lt;/span&gt;`;
                            console.error(`Difficulty ${difficulty} missions ran out.`);
                        }
                    }
                    grid.appendChild(cell);
                }
            }
        }

        // --- 4. 縁の色変更ロジック ---
        function changeBorderColor(color) {
            const bingoGrid = document.getElementById(&#039;bingoGrid&#039;);
            bingoGrid.classList.remove(currentBorderColorClass);

            currentBorderColorClass = `color-${color}`;
            bingoGrid.classList.add(currentBorderColorClass);
            
            document.querySelectorAll(&#039;.controls button&#039;).forEach(button =&gt; {
                button.classList.remove(&#039;active-color&#039;);
                if (button.dataset.color === color) {
                    button.classList.add(&#039;active-color&#039;);
                }
            });
        }

        // --- 5. 画像保存ロジック ---
        function saveAsImage() {
            const captureArea = document.getElementById(&#039;imageCaptureArea&#039;);
            
            html2canvas(captureArea, {
                scale: 3, 
                useCORS: true,
                backgroundColor: null,
            }).then(canvas =&gt; {
                const imageURL = canvas.toDataURL(&#039;image/png&#039;);
                const link = document.createElement(&#039;a&#039;);
                link.href = imageURL;
                link.download = `ToNGO_Sheet_${new Date().getTime()}.png`;
                
                requestAnimationFrame(() =&gt; {
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                });
            }).catch(err =&gt; {
                console.error(&quot;画像保存中にエラーが発生しました:&quot;, err);
                alert(&quot;画像保存に失敗しました。コンソールを確認してください。&quot;);
            });
        }

        // --- 6. メイン実行関数 ---
        function generateAndSaveBingo() {
            generateBingoSheet();
            setTimeout(() =&gt; {
                saveAsImage();
            }, 500); 
        }
        
        generateBingoSheet(); 
        changeBorderColor(&#039;default&#039;);
    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

}    </description>
    <dc:date>2025-11-30T13:32:09+09:00</dc:date>
    <utime>1764477129</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/9.html">
    <title>プラグイン/コメント</title>
    <link>https://w.atwiki.jp/tontool/pages/9.html</link>
    <description>
          </description>
    <dc:date>2025-11-16T19:23:15+09:00</dc:date>
    <utime>1763288595</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/8.html">
    <title>プラグイン</title>
    <link>https://w.atwiki.jp/tontool/pages/8.html</link>
    <description>
          </description>
    <dc:date>2025-11-16T19:23:15+09:00</dc:date>
    <utime>1763288595</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/tontool/pages/7.html">
    <title>プラグイン/動画(Youtube)</title>
    <link>https://w.atwiki.jp/tontool/pages/7.html</link>
    <description>
          </description>
    <dc:date>2025-11-16T19:23:15+09:00</dc:date>
    <utime>1763288595</utime>
  </item>
  </rdf:RDF>
