python WEBブラウザー

import tkinter as tk
from tkinter import ttk, messagebox
import webbrowser
import os

class WebBrowser(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Web Browser")
        self.geometry("800x600")

        self.notebook = ttk.Notebook(self)
        self.notebook.pack(fill="both", expand=True)

        self.tabs = []

        self.add_new_tab()

    def add_new_tab(self):
        tab = ttk.Frame(self.notebook)
        self.notebook.add(tab, text="New Tab")

        url_entry = ttk.Entry(tab, width=70)
        url_entry.grid(row=0, column=1, padx=5, pady=5, sticky="ew")
        url_entry.bind("<Return>", lambda event: self.open_webpage(url_entry.get()))

        go_button = ttk.Button(tab, text="Go", command=lambda: self.open_webpage(url_entry.get()))
        go_button.grid(row=0, column=2, padx=5, pady=5)

        back_button = ttk.Button(tab, text="Back", command=lambda: self.back(tab))
        back_button.grid(row=0, column=0, padx=5, pady=5)

        forward_button = ttk.Button(tab, text="Forward", command=lambda: self.forward(tab))
        forward_button.grid(row=0, column=3, padx=5, pady=5)

        close_button = ttk.Button(tab, text="X", command=lambda: self.close_tab(tab))
        close_button.grid(row=0, column=4, padx=5, pady=5)

        progress_bar = ttk.Progressbar(tab, orient="horizontal", mode="indeterminate")
        progress_bar.grid(row=1, column=1, columnspan=2, sticky="ew")

        web_browser = ttk.Frame(tab)
        web_browser.grid(row=2, column=0, columnspan=5, padx=5, pady=5, sticky="nsew")

        self.tabs.append({
            "tab": tab,
            "url_entry": url_entry,
            "go_button": go_button,
            "back_button": back_button,
            "forward_button": forward_button,
            "close_button": close_button,
            "progress_bar": progress_bar,
            "web_browser": web_browser,
            "browser": webbrowser.get(),
            "current_page": None
        })

    def open_webpage(self, url):
        if not url.startswith("http://") and not url.startswith("https://"):
            url = "http://" + url

        tab = self.notebook.select()
        tab_index = self.notebook.index(tab)
        tab_info = self.tabs[tab_index]

        tab_info["browser"].open_new(url)
        tab_info["current_page"] = url

    def back(self, tab):
        tab_index = self.notebook.index(tab)
        tab_info = self.tabs[tab_index]
        tab_info["browser"].back()

    def forward(self, tab):
        tab_index = self.notebook.index(tab)
        tab_info = self.tabs[tab_index]
        tab_info["browser"].forward()

    def close_tab(self, tab):
        tab_index = self.notebook.index(tab)
        self.notebook.forget(tab_index)
        del self.tabs[tab_index]

if __name__ == "__main__":
    app = WebBrowser()
    app.mainloop()

つぶやきアプリ「ELDER」

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ELDER</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h1>ELDER</h1>
    </header>

    <main>
        <section id="post-form">
            <h2>つぶやく</h2>
            <form id="tweet-form">
                <input type="text" id="user-name" placeholder="ユーザー名">
                <textarea id="tweet-content" placeholder="今何をつぶやく?" maxlength="280"></textarea>
                <div id="counter">0 / 280</div>
                <button type="submit">つぶやく</button>
            </form>
        </section>

        <section id="tweets">
            <h2>つぶやき</h2>
            <!-- つぶやきの表示領域 -->
        </section>
    </main>

    <footer>
        <p>© 2024 ELDER</p>
    </footer>

    <script src="script.js"></script>
</body>
</html>

styles.css

/* Reset CSS */
body, h1, h2, form, textarea, button, input {
    margin: 0;
    padding: 0;
}

body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    background-color: #f0f0f0;
}

header {
    background-color: #333;
    color: #fff;
    text-align: center;
    padding: 10px 0;
}

main {
    margin-top: 20px;
}

#post-form, #tweets {
    background-color: #fff;
    padding: 20px;
    margin-bottom: 20px;
    border-radius: 5px;
}

input[type="text"], textarea {
    width: 100%;
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid #ccc;
    border-radius: 3px;
    resize: vertical;
}

#counter {
    margin-bottom: 10px;
    color: #666;
}

button {
    padding: 10px 20px;
    background-color: #333;
    color: #fff;
    border: none;
    border-radius: 3px;
    cursor: pointer;
}

button:hover {
    background-color: #555;
}

.tweet {
    border-bottom: 1px solid #ccc;
    padding: 10px 0;
}

.tweet-content {
    margin-bottom: 5px;
}

.tweet-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.like-button, .comment-button {
    background-color: transparent;
    border: none;
    color: #666;
    cursor: pointer;
}

.like-button:hover, .comment-button:hover {
    color: #333;
}

.comments {
    margin-top: 10px;
    padding: 10px;
    background-color: #f9f9f9;
    border-radius: 3px;
}

.comment-input {
    width: calc(100% - 80px);
    margin-bottom: 10px;
}

.comment-list {
    list-style: none;
    padding: 0;
}

.comment-item {
    border-bottom: 1px solid #ccc;
    padding: 5px 0;
}

.comment-author {
    font-weight: bold;
    margin-bottom: 5px;
}

.comment-content {
    margin-left: 20px;
}

script.js

document.addEventListener("DOMContentLoaded", function() {
    const tweetForm = document.getElementById("tweet-form");
    const userNameInput = document.getElementById("user-name");
    const tweetContent = document.getElementById("tweet-content");
    const tweetsSection = document.getElementById("tweets");
    const counter = document.getElementById("counter");

    // ローカルストレージからデータを取得
    let tweets = JSON.parse(localStorage.getItem("tweets")) || [];

    // ページ読み込み時に保存されたつぶやきを表示
    tweets.forEach(function(tweet) {
        displayTweet(tweet);
    });

    // つぶやきを投稿するイベントリスナー
    tweetForm.addEventListener("submit", function(event) {
        event.preventDefault(); // フォームのデフォルトの動作をキャンセル

        const content = tweetContent.value.trim();
        const userName = userNameInput.value.trim();
        if (userName === "") {
            alert("ユーザー名を入力してください!");
            return;
        }
        if (content === "") {
            alert("つぶやきを入力してください!");
            return;
        }

        if (content.length > 280) {
            alert("つぶやきは280文字以内で入力してください!");
            return;
        }

        // つぶやきを表示する
        displayTweet({userName: userName, content: content, likes: 0});

        // ローカルストレージにデータを保存
        tweets.push({userName: userName, content: content, likes: 0});
        localStorage.setItem("tweets", JSON.stringify(tweets));

        // フォームをクリアする
        tweetContent.value = "";
        userNameInput.value = "";
        counter.textContent = "0 / 280";
    });

    // 文字数カウンターの更新
    tweetContent.addEventListener("input", function() {
        const contentLength = tweetContent.value.length;
        counter.textContent = contentLength + " / 280";
    });

    // つぶやきを表示する関数
    function displayTweet(tweet) {
        const tweetDiv = document.createElement("div");
        tweetDiv.classList.add("tweet");

        const tweetContentDiv = document.createElement("div");
        tweetContentDiv.classList.add("tweet-content");
        tweetContentDiv.textContent = tweet.content;

        const tweetActionsDiv = document.createElement("div");
        tweetActionsDiv.classList.add("tweet-actions");

        const likeButton = document.createElement("button");
        likeButton.classList.add("like-button");
        likeButton.textContent = "いいね";
        likeButton.addEventListener("click", function() {
            tweet.likes++;
            localStorage.setItem("tweets", JSON.stringify(tweets));
            updateTweet(tweet, tweetDiv);
        });

        const commentButton = document.createElement("button");
        commentButton.classList.add("comment-button");
        commentButton.textContent = "コメント";

        tweetActionsDiv.appendChild(likeButton);
        tweetActionsDiv.appendChild(commentButton);

        tweetDiv.appendChild(tweetContentDiv);
        tweetDiv.appendChild(tweetActionsDiv);

        updateTweet(tweet, tweetDiv);

        tweetsSection.prepend(tweetDiv); // 新しいつぶやきを上に表示
    }

    // つぶやきの表示を更新する関数
    function updateTweet(tweet, tweetDiv) {
        tweetDiv.innerHTML = ""; // 既存の表示をクリア

        const tweetContentDiv = document.createElement("div");
        tweetContentDiv.classList.add("tweet-content");
        tweetContentDiv.textContent = `${tweet.userName}: ${tweet.content}`;

        const tweetActionsDiv = document.createElement("div");
        tweetActionsDiv.classList.add("tweet-actions");
        const likeButton = document.createElement("button");
        likeButton.classList.add("like-button");
        likeButton.textContent = `いいね (${tweet.likes})`;
        likeButton.addEventListener("click", function() {
            tweet.likes++;
            localStorage.setItem("tweets", JSON.stringify(tweets));
            updateTweet(tweet, tweetDiv);
        });

        const commentButton = document.createElement("button");
        commentButton.classList.add("comment-button");
        commentButton.textContent = "コメント";

        tweetActionsDiv.appendChild(likeButton);
        tweetActionsDiv.appendChild(commentButton);

        tweetDiv.appendChild(tweetContentDiv);
        tweetDiv.appendChild(tweetActionsDiv);
    }
});

http://tyosuke20xx.com/ELDER/index.html

Toheart3 の企画書

プロジェクト名: Toheart3 – 未来の約束

概要:
Toheart3 – 未来の約束は、感動的なストーリーと美しいグラフィックで綴られるノベルゲームです。プレイヤーは主人公となり、様々な選択や出来事を通じて物語を進め、キャラクターたちとの絆を深めていきます。心温まるストーリーと共に、プレイヤー自身の選択が物語の結末に影響を与える、没入感のあるゲーム体験を提供します。

コンセプト:
Toheart3 – 未来の約束は、感動と感情移入を中心に据えたゲームです。プレイヤーは、主人公として物語の中心に立ち、友情や愛情、成長と決断を通じて、キャラクターたちとの絆を築いていきます。プレイヤーの選択が物語の進行や結末に影響を与えることで、ユーザーはストーリーにより一層没入感を感じることでしょう。

目標:

感動的なストーリーとキャラクターによるプレイヤーの感情移入を促進する。
高品質なグラフィックと音楽により、没入感のあるゲーム体験を提供する。
プレイヤーの選択によって物語が変化する、分岐点を持つストーリーラインの実装。
プレイヤーが自らの選択に責任を持ち、その結果に納得感を持てるような、厚みのあるストーリーテリングの提供。
ゲームの特徴:

感動的なストーリー: キャラクターたちの成長や友情、愛情をテーマにした心温まるストーリーを提供。
選択と結末: プレイヤーの選択によって物語の進行や結末が変化する、分岐点を持つストーリーライン。
美しいグラフィックと音楽: 高品質なグラフィックと美しい音楽により、物語の世界に没入感をもたらす。
キャラクターの絆: プレイヤーはキャラクターたちとの絆を深めながら、物語を進めることができる。
ターゲットオーディエンス:
Toheart3 – 未来の約束は、感動的なストーリーとキャラクターに魅了される、幅広い年齢層のプレイヤーを対象としています。特に以下のようなプレイヤーにアピールします。

ノベルゲームやストーリー重視のゲーム好きなプレイヤー。
感動的な物語やキャラクターに共感するプレイヤー。
自分の選択が物語に影響を与えるタイプのゲームを好むプレイヤー。
開発プロセス:

ストーリーラインの作成とキャラクターデザインの決定。
グラフィックと音楽の制作。
プロトタイプの作成とテストプレイ。
選択肢と結末の設計と実装。
フィードバックの収集と改善。
最終テストと修正。
リリースおよびプロモーション活動の開始。
予算:
Toheart3 – 未来の約束の開発およびマーケティングには、十分な資金が必要です。予算は以下の項目に割り当てられます。

開発チームの給与
グラフィックおよび音楽制作費
マーケティングおよびプロモーション費用
テストおよび品質管理のコスト
その他の運営費用
期待される成果:
Toheart3 – 未来の約束の成功により、以下のような成果が期待されます。

ユーザーからの高い評価と支持を得る。
ノベルゲームジャンルにおける新たなトレンドを生み出す。
収益の増加と持続可能なビジネスモデルの構築。
以上がToheart3 – 未来の約束の企画書の概要です。

レジェンド・オブ・アーキテクト企画書

ゲームタイトル: レジェンド・オブ・アーキテクト

  1. ゲームの概要:
    『レジェンド・オブ・アーキテクト』は、ファンタジー世界での冒険をテーマにしたアクションアドベンチャーゲームです。プレイヤーは、神秘的な力を持つ伝説の建築家として、古代の遺跡を探索し、挑戦に立ち向かい、新しい世界を創造します。プレイヤーはパズルを解き、モンスターと戦い、自分だけの城や街を建設して強化することができます。
  2. ゲームプレイの特徴:
    探索と冒険: プレイヤーは美しくデザインされたオープンワールドを探索し、古代の遺跡や未知の場所を発見します。
    建築と戦略: プレイヤーは自分だけの城や街を建設し、資源を管理して防御を強化します。同時に、城や街を拡張し、新しい施設や機能を解放します。
    パズルとミステリー: 古代の遺跡やダンジョンには、謎やパズルが隠されています。プレイヤーはこれらの謎を解き明かし、報酬を手に入れます。
    戦闘とアクション: プレイヤーは敵と戦い、さまざまな武器や魔法を使って戦闘を行います。バトルはスリリングで戦略的なアクションに焦点を当てています。
  3. 開発チーム:
    プロデューサー: John Smith
    ゲームデザイナー: Emily Johnson
    プログラマー: David Lee
    アーティスト: Sarah Thompson
    サウンドデザイナー: Michael Davis
  4. 開発スケジュール:
    プレプロダクション: 3ヶ月
    コンセプトアートの作成
    ゲームデザインの詳細な策定
    テクニカルプロトタイプの作成
    本番: 12ヶ月
    ゲームエンジンの開発
    グラフィックスおよびアートアセットの制作
    ゲームプレイの実装
    バグ修正およびテスト
    ポストプロダクション: 1ヶ月
    最終調整と修正
    マーケティングキャンペーンの準備
    リリース準備
  5. ターゲットプラットフォーム:
    PC(Windows、macOS)
    PlayStation 5
    Xbox Series X
  6. ターゲットオーディエンス:
    年齢層: 13歳以上
    ジャンル愛好家:ファンタジーアクションアドベンチャーゲームに興味があるプレイヤー
    ターゲット市場:世界中のゲームプレイヤー、特に北米、ヨーロッパ、およびアジア地域の市場を対象としています。

テイルズオブデスティニー3企画書

テイルズ オブ デスティニー3 企画書

1. 概要

タイトル: テイルズ オブ デスティニー3

開発会社: バンダイナムコエンターテインメント

ジャンル: アクションRPG

プラットフォーム: PlayStation 5, Nintendo Switch, PC

2. コンセプト

世界観: 「テイルズ オブ デスティニー」シリーズの伝統を受け継ぎつつ、新たな惑星「セリア」を舞台に、運命に翻弄される若者たちの冒険と成長を描く。

ストーリー: 主人公「リオン」は、失われた古代文明の秘宝を巡る争いに巻き込まれる。運命の輪が動き出し、リオンと仲間たちは世界の平和を守るため、未知なる力に立ち向かう。

キャラクター: 多彩なバックグラウンドを持つキャラクターたちが集結。彼らの過去と秘密が物語に深みを与える。

3. ゲームプレイ

戦闘システム: 「リニアモーションバトルシステム」を継承しつつ、新たな「ダイナミックアクション」要素を導入。プレイヤーの戦略と反射神経が試される。

成長システム: キャラクターごとにカスタマイズ可能な「スキルツリー」を採用。プレイスタイルに合わせて成長させることができる。

マルチプレイヤー: オンラインでの協力プレイに対応。特定のダンジョンやボス戦で友達と共闘する。

4. 技術要求

グラフィック: 高解像度の3Dグラフィックとアニメーションを実現。シリーズ伝統の美しいアートワークを現代の技術で表現。

サウンド: シリーズお馴染みの作曲家による壮大なオーケストラサウンドトラック。環境音との調和を重視。

ネットワーク: 安定したオンラインプレイを実現するための高度なネットワークコードの最適化。

5. マーケティング戦略

プロモーション: ゲームショウでのデモプレイ、トレーラーの公開、SNSを活用した情報発信。

コラボレーション: アニメやマンガとのコラボレーションを通じて、シリーズファン以外にもアピール。

特典: 予約購入特典として、限定アイテムやオリジナルサウンドトラックの提供。

Javascript classList

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My JavaScript</title>
  <style>
    .pink-bg {
      background: pink;
    }

    .red-border {
      border: 2px solid red;
    }

    .green-color {
      color: green;
    }
  </style>
</head>
<body>
  <p class="green-color">Hello</p>
  <button>OK</button>

  <script src="main.js"></script>
</body>
</html>

main.js

'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    // console.log(document.querySelector('p').classList.contains('pink-bg')); // false
    // if (document.querySelector('p').classList.contains('pink-bg') === false) {
    //   document.querySelector('p').classList.add('pink-bg');
    // } else {
    //   document.querySelector('p').classList.remove('pink-bg');
    // }
    document.querySelector('p').classList.toggle('pink-bg');
  });
}

検索エンジン「Voogle」

import requests
from flask import Flask, request, jsonify

app = Flask(__name__)

class SearchEngine:
    def __init__(self, documents):
        self.documents = documents

    def search_local(self, query):
        results = []
        for doc in self.documents:
            if query.lower() in doc["text"].lower():
                results.append(doc)
        return results

    def search_wikipedia(self, query, lang='ja'):
        base_url = f"https://{lang}.wikipedia.org/w/api.php"
        params = {
            'action': 'query',
            'list': 'search',
            'srsearch': query,
            'format': 'json'
        }
        response = requests.get(base_url, params=params)
        if response.status_code == 200:
            search_results = response.json().get('query', {}).get('search', [])
            return [{'id': result['pageid'], 'text': result['snippet']} for result in search_results]
        else:
            return []

# サンプルドキュメントデータ
documents = [
    {"id": 1, "text": "Pythonは汎用の高水準言語です。"},
    {"id": 2, "text": "検索エンジンは情報を検索するためのツールです。"},
    {"id": 3, "text": "人工知能はコンピュータによる知的な振る舞いを実現する技術です。"},
    {"id": 4, "text": "Web開発では、HTML、CSS、JavaScriptなどの技術が使われます。"},
    {"id": 5, "text": "データサイエンティストはデータから有益な情報を引き出す専門家です。"}
]

# SearchEngineインスタンスの作成
search_engine = SearchEngine(documents)

@app.route("/", methods=["GET", "POST"])
def search():
    # 以前の関数の内容は変更なし
    if request.method == "POST":
        query = request.form["query"]
        local_results = search_engine.search_local(query)
        wiki_results = search_engine.search_wikipedia(query)
        all_results = local_results + wiki_results
        if not all_results:
            return "検索結果はありません。"
        else:
            result_text = "<br>".join([f"<div><strong>ID:</strong> {result['id']}, <strong>Text:</strong> {result['text']}</div>" for result in all_results])
            return f"""
            <!DOCTYPE html>
            <html>
            <head>
                <title>検索エンジン</title>
                <style>
                    body {{
                        font-family: Arial, sans-serif;
                        margin: 0 auto;
                        max-width: 800px;
                        padding: 20px;
                    }}
                    h1 {{
                        color: #333;
                    }}
                    form {{
                        margin-bottom: 20px;
                    }}
                    input[type="text"] {{
                        margin-right: 10px;
                        padding: 10px;
                        width: calc(100% - 122px);
                    }}
                    input[type="submit"] {{
                        padding: 10px 20px;
                        background-color: #4CAF50;
                        color: white;
                        border: none;
                        cursor: pointer;
                    }}
                    input[type="submit"]:hover {{
                        background-color: #45a049;
                    }}
                    div {{
                        margin-bottom: 10px;
                        padding: 10px;
                        background-color: #f2f2f2;
                        border-left: 4px solid #4CAF50;
                    }}
                </style>
            </head>
            <body>
                <h1>検索エンジン</h1>
                <form method="POST">
                    <label for="query">検索キーワード:</label>
                    <input type="text" name="query" id="query" required>
                    <input type="submit" value="検索">
                </form>
                {result_text}
            </body>
            </html>
            """
    return """
    <!DOCTYPE html>
    <html>
    <head>
        <title>検索エンジン</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                margin: 0 auto;
                max-width: 800px;
                padding: 20px;
            }
            h1 {
                color: #333;
            }
            form {
                margin-bottom: 20px;
            }
            input[type="text"] {
                margin-right: 10px;
                padding: 10px;
                width: calc(100% - 122px);
            }
            input[type="submit"] {
                padding: 10px 20px;
                background-color: #4CAF50;
                color: white;
                border: none;
                cursor: pointer;
            }
            input[type="submit"]:hover {
                background-color: #45a049;
            }
        </style>
    </head>
    <body>
        <h1>検索エンジン</h1>
        <form method="POST">
            <label for="query">検索キーワード:</label>
            <input type="text" name="query" id="query" required>
            <input type="submit" value="検索">
        </form>
    </body>
    </html>
    """

if __name__ == "__main__":
    app.run(debug=True)

https://voogle.onrender.com/

GPT-2とWikipediaを使って生成するAI

GPT-2.py

from flask import Flask, render_template, request, redirect, url_for
from transformers import GPT2Tokenizer, GPT2LMHeadModel
import wikipedia

app = Flask(__name__)

# GPT-2のトークナイザーとモデルをロード
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
model = GPT2LMHeadModel.from_pretrained("gpt2")

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/generate', methods=['POST'])
def generate_text():
    # ユーザーからの入力を取得
    prompt_text = request.form['prompt']
    
    try:
        # Wikipediaからテキストを取得
        wikipedia_text = wikipedia.summary(prompt_text)
        
        # テキストの生成
        inputs = tokenizer.encode(wikipedia_text, return_tensors="pt")
        outputs = model.generate(inputs, max_length=100, num_return_sequences=1, temperature=0.7)
        
        # 生成されたテキストをデコードしてHTMLコードに組み込む
        generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
        
        # 生成されたテキストとWikipediaのテキストと共にHTMLを返す
        return render_template('index.html', prompt_text=prompt_text, generated_text=generated_text, wikipedia_text=wikipedia_text)
    
    except wikipedia.exceptions.DisambiguationError as e:
        # 曖昧性がある場合は、候補のリストを表示
        options = e.options
        return render_template('disambiguation.html', options=options)
    
    except wikipedia.exceptions.PageError:
        wikipedia_text = "Wikipediaにそのトピックが見つかりませんでした。"
        return render_template('index.html', prompt_text=prompt_text, wikipedia_text=wikipedia_text)

@app.route('/generate_with_option/<option>', methods=['GET'])
def generate_with_option(option):
    try:
        # Wikipediaからテキストを取得
        wikipedia_text = wikipedia.summary(option)
        
        # テキストの生成
        inputs = tokenizer.encode(wikipedia_text, return_tensors="pt")
        outputs = model.generate(inputs, max_length=100, num_return_sequences=1, temperature=0.7)
        
        # 生成されたテキストをデコードしてHTMLコードに組み込む
        generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
        
        # 生成されたテキストとWikipediaのテキストと共にHTMLを返す
        return render_template('index.html', prompt_text=option, generated_text=generated_text, wikipedia_text=wikipedia_text)
    
    except wikipedia.exceptions.PageError:
        wikipedia_text = "Wikipediaにそのトピックが見つかりませんでした。"
        return render_template('index.html', prompt_text=option, wikipedia_text=wikipedia_text)

if __name__ == '__main__':
    app.run(debug=True)

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Generate Text</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
        }

        h1 {
            text-align: center;
            margin-top: 50px;
        }

        form {
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        label {
            font-weight: bold;
        }

        input[type="text"] {
            width: 100%;
            padding: 10px;
            margin: 10px 0;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        button {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        button:hover {
            background-color: #0056b3;
        }

        .response {
            max-width: 600px;
            margin: 20px auto;
            padding: 20px;
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        .generated-text {
            margin-top: 20px;
        }

        .tweet-link {
            display: block;
            margin-top: 10px;
            text-align: center;
        }
    </style>
</head>
<body>
    <h1>Generate Text</h1>
    <form action="/generate" method="POST">
        <label for="prompt">Enter your prompt:</label><br>
        <input type="text" id="prompt" name="prompt"><br><br>
        <button type="submit">Generate</button>
    </form>

    <!-- 生成されたテキストを表示 -->
    {% if generated_text %}
    <div class="response">
        <h2>Generated Text:</h2>
        <p class="generated-text">{{ generated_text }}</p>
        <a href="https://twitter.com/intent/tweet?text={{ generated_text }}" class="tweet-link" target="_blank">Tweet</a>
    </div>
    {% endif %}
</body>
</html>

templates/disambiguation.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Disambiguation Page</title>
</head>
<body>
    <h1>Disambiguation</h1>
    <p>Multiple meanings were found for the provided prompt. Please select the intended meaning:</p>
    <ul>
        {% for option in options %}
            <li><a href="{{ url_for('generate_with_option', option=option) }}">{{ option }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>

Javascript classList

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My JavaScript</title>
  <style>
    .pink-bg{
      background: pink;
    }

    .red-border{
      border: 2px solid red;
    }

    .green-color{
      color: green;
    }
  </style>
</head>
<body>
  <p>Hello</p>
  <button>OK</button>
  
  <script src="main.js"></script>
</body>
</html>

main.js

'use strict'

{
    document.querySelector('button').addEventListener('click', ()=> {
        //console.log('Clicked');
        document.querySelector('p').classList.add('pink-bg', 'red-border');
        document.querySelector('p').classList.add('green-color');
    });

    //console.log('Hello');
}

Javascript textContent

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My JavaScript</title>
</head>
<body>
  <p>Hello</p>
  <button>OK</button>
  
  <script src="main.js"></script>
</body>
</html>

main.js

'use strict'

{
    document.querySelector('button').addEventListener('click', ()=> {
        //console.log('Clicked');
        document.querySelector('p').textContent = document.querySelector('button').textContent;
    });

    //console.log('Hello');
}