Spaces:
Running
Running
Upload index.html
Browse files- index.html +456 -19
index.html
CHANGED
@@ -1,19 +1,456 @@
|
|
1 |
-
<!
|
2 |
-
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="ja">
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<meta charset="UTF-8">
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
+
<title>Gemini Prompt Generator</title>
|
8 |
+
<link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
|
9 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
|
10 |
+
crossorigin="anonymous">
|
11 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/json5/2.2.3/index.min.js"
|
12 |
+
integrity="sha512-44jdhc+R2TFfzBflS3/dGNEABiNUxBkkrqwO7GWTvGsj3HkQNr3GESvI9PUvAxmqxSnTosR0Ij9y3+o+6J1hig=="
|
13 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
14 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/i18next/23.14.0/i18next.min.js"
|
15 |
+
integrity="sha512-8ANNUVMWPf6aWGXZqDhS4OXJWBCRxfjlW7lKfupuiG1FZah0ST6LiI2qnEb1L5mp05v/+0hn3s2FO4EwIbIgfA=="
|
16 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
17 |
+
<script
|
18 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/i18next-browser-languagedetector/8.0.0/i18nextBrowserLanguageDetector.min.js"
|
19 |
+
integrity="sha512-8/RTkAM23B3lQzi6fmPs+Yf9qhIHzrzRpeSZsBsQ8OEmo95mbVp+68dB647VDCuyQIBbF+OIbS9b30aTWUkoog=="
|
20 |
+
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
21 |
+
</head>
|
22 |
+
|
23 |
+
<body data-bs-theme="dark">
|
24 |
+
<div class="container">
|
25 |
+
<div class="row m-0 border-start border-end border-2">
|
26 |
+
<div class="row">
|
27 |
+
<div id="inputQuery" class="col-md-6 mb-4">
|
28 |
+
<div class="card h-100">
|
29 |
+
<div class="card-header bg-primary text-white">
|
30 |
+
<h5 class="mb-0" id="inputQueryTitle">入力クエリ</h5>
|
31 |
+
</div>
|
32 |
+
<div class="card-body">
|
33 |
+
<div class="form-group">
|
34 |
+
<textarea class="form-control" id="query" rows="16"
|
35 |
+
placeholder="ここにクエリを入力してください"></textarea>
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
<div class="card-footer d-flex align-items-center">
|
39 |
+
<button id="generatePromptButton" class="btn btn-primary flex-grow-1 me-2"
|
40 |
+
onclick="generatePrompt()">
|
41 |
+
<i class="fas fa-magic me-2"></i><span id="generateButtonText">プロンプト生成</span>
|
42 |
+
<i class="fas fa-spinner fa-spin me-2 d-none" id="loading"></i>
|
43 |
+
</button>
|
44 |
+
<div class="form-check form-switch" id="splitStringsSwitchWrapper">
|
45 |
+
<input class="form-check-input" type="checkbox" id="splitStringsSwitch">
|
46 |
+
<label class="form-check-label" for="splitStringsSwitch">
|
47 |
+
<i class="fas fa-shield-alt" id="splitStrings">分割送信</i>
|
48 |
+
</label>
|
49 |
+
</div>
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
</div>
|
53 |
+
<div id="outputPrompt" class="col-md-6 mb-4">
|
54 |
+
<div class="card h-100">
|
55 |
+
<div class="card-header bg-success text-white">
|
56 |
+
<h5 class="mb-0" id="outputPromptTitle">生成されたプロンプト</h5>
|
57 |
+
</div>
|
58 |
+
<div class="card-body">
|
59 |
+
<div class="form-group">
|
60 |
+
<textarea class="form-control" id="promptEn" rows="8"
|
61 |
+
placeholder="英語のプロンプトがここに表示されます"></textarea>
|
62 |
+
</div>
|
63 |
+
<div class="form-group mt-3">
|
64 |
+
<textarea class="form-control" id="promptMyLanguage" rows="8" disabled
|
65 |
+
placeholder="日本訳がここに表示されます"></textarea>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
+
</div>
|
69 |
+
</div>
|
70 |
+
<div class="col-12 mb-4">
|
71 |
+
<div class="card">
|
72 |
+
<div class="card-header bg-primary text-white">
|
73 |
+
<h5 class="mb-0" id="settingsTitle">設定</h5>
|
74 |
+
</div>
|
75 |
+
<div class="card-body">
|
76 |
+
<div class="form-group mb-3">
|
77 |
+
<label for="apiKey" class="form-label" id="apiKeyLabel"><a
|
78 |
+
href="https://aistudio.google.com/app/apikey?hl=ja"
|
79 |
+
target="_blank">APIキー</a></label>
|
80 |
+
<input type="text" class="form-control" id="apiKey" placeholder="APIキーを入力してください">
|
81 |
+
</div>
|
82 |
+
<div class="form-group">
|
83 |
+
<label for="characterCount" class="form-label" id="characterCountLabel">文字数</label>
|
84 |
+
<input type="number" value="320" class="form-control" id="characterCount"
|
85 |
+
placeholder="生成するプロンプトの文字数を入力してください">
|
86 |
+
</div>
|
87 |
+
<div class="form-group">
|
88 |
+
<label for="languageSelect" class="form-label" id="languageSelectLabel">Language</label>
|
89 |
+
<select class="form-select" id="languageSelect">
|
90 |
+
<option value="ja">日本語</option>
|
91 |
+
<option value="en">English</option>
|
92 |
+
<option value="zh">中文</option>
|
93 |
+
<option value="ko">한국어</option>
|
94 |
+
<option value="fr">Français</option>
|
95 |
+
<option value="es">Español</option>
|
96 |
+
<option value="de">Deutsch</option>
|
97 |
+
<option value="it">Italiano</option>
|
98 |
+
</select>
|
99 |
+
</div>
|
100 |
+
</div>
|
101 |
+
</div>
|
102 |
+
</div>
|
103 |
+
</div>
|
104 |
+
</div>
|
105 |
+
</div>
|
106 |
+
<script>
|
107 |
+
let language;
|
108 |
+
const translations = {
|
109 |
+
ja: {
|
110 |
+
inputQueryTitle: "入力クエリ",
|
111 |
+
generateButtonText: "プロンプト生成",
|
112 |
+
splitStrings: "分割送信",
|
113 |
+
outputPromptTitle: "生成されたプロンプト",
|
114 |
+
settingsTitle: "設定",
|
115 |
+
apiKeyLabel: "APIキー",
|
116 |
+
characterCountLabel: "文字数",
|
117 |
+
languageSelectLabel: "言語",
|
118 |
+
promptEnPlaceholder: "英語のプロンプトがここに表示されます",
|
119 |
+
promptMyLanguagePlaceholder: "日本訳がここに表示されます",
|
120 |
+
apiKeyPlaceholder: "APIキーを入力してください",
|
121 |
+
characterCountPlaceholder: "生成するプロンプトの文字数を入力してください"
|
122 |
+
},
|
123 |
+
en: {
|
124 |
+
inputQueryTitle: "Input Query",
|
125 |
+
generateButtonText: "Generate Prompt",
|
126 |
+
splitStrings: "Split Strings",
|
127 |
+
outputPromptTitle: "Generated Prompt",
|
128 |
+
settingsTitle: "Settings",
|
129 |
+
apiKeyLabel: "API Key",
|
130 |
+
characterCountLabel: "Character Count",
|
131 |
+
languageSelectLabel: "Language",
|
132 |
+
promptEnPlaceholder: "English prompt will be displayed here",
|
133 |
+
promptMyLanguagePlaceholder: "Translation will be displayed here",
|
134 |
+
apiKeyPlaceholder: "Enter your API key",
|
135 |
+
characterCountPlaceholder: "Enter the number of characters for the generated prompt"
|
136 |
+
},
|
137 |
+
zh: {
|
138 |
+
inputQueryTitle: "输入查询",
|
139 |
+
generateButtonText: "生成提示",
|
140 |
+
splitStrings: "分割字符串",
|
141 |
+
outputPromptTitle: "生成的提示",
|
142 |
+
settingsTitle: "设置",
|
143 |
+
apiKeyLabel: "API密钥",
|
144 |
+
characterCountLabel: "字符数",
|
145 |
+
languageSelectLabel: "语言",
|
146 |
+
promptEnPlaceholder: "英文提示将显示在这里",
|
147 |
+
promptMyLanguagePlaceholder: "翻译将显示在这里",
|
148 |
+
apiKeyPlaceholder: "请输入您的API密钥",
|
149 |
+
characterCountPlaceholder: "请输入生成提示的字符数"
|
150 |
+
},
|
151 |
+
ko: {
|
152 |
+
inputQueryTitle: "입력 쿼리",
|
153 |
+
generateButtonText: "프롬프트 생성",
|
154 |
+
splitStrings: "문자열 분할",
|
155 |
+
outputPromptTitle: "생성된 프롬프트",
|
156 |
+
settingsTitle: "설정",
|
157 |
+
apiKeyLabel: "API 키",
|
158 |
+
characterCountLabel: "문자 수",
|
159 |
+
languageSelectLabel: "언어",
|
160 |
+
promptEnPlaceholder: "영어 프롬프트가 여기에 표시됩니다",
|
161 |
+
promptMyLanguagePlaceholder: "번역이 여기에 표시됩니다",
|
162 |
+
apiKeyPlaceholder: "API 키를 입력하세요",
|
163 |
+
characterCountPlaceholder: "생성할 프롬프트의 문자 수를 입력하세요"
|
164 |
+
},
|
165 |
+
fr: {
|
166 |
+
inputQueryTitle: "Requête d'entrée",
|
167 |
+
generateButtonText: "Générer le prompt",
|
168 |
+
splitStrings: "Diviser les chaînes",
|
169 |
+
outputPromptTitle: "Prompt généré",
|
170 |
+
settingsTitle: "Paramètres",
|
171 |
+
apiKeyLabel: "Clé API",
|
172 |
+
characterCountLabel: "Nombre de caractères",
|
173 |
+
languageSelectLabel: "Langue",
|
174 |
+
promptEnPlaceholder: "Le prompt en anglais s'affichera ici",
|
175 |
+
promptMyLanguagePlaceholder: "La traduction s'affichera ici",
|
176 |
+
apiKeyPlaceholder: "Entrez votre clé API",
|
177 |
+
characterCountPlaceholder: "Entrez le nombre de caractères pour le prompt généré"
|
178 |
+
},
|
179 |
+
es: {
|
180 |
+
inputQueryTitle: "Consulta de entrada",
|
181 |
+
generateButtonText: "Generar prompt",
|
182 |
+
splitStrings: "Dividir cadenas",
|
183 |
+
outputPromptTitle: "Prompt generado",
|
184 |
+
settingsTitle: "Configuración",
|
185 |
+
apiKeyLabel: "Clave API",
|
186 |
+
characterCountLabel: "Recuento de caracteres",
|
187 |
+
languageSelectLabel: "Idioma",
|
188 |
+
promptEnPlaceholder: "El prompt en inglés se mostrará aquí",
|
189 |
+
promptMyLanguagePlaceholder: "La traducción se mostrará aquí",
|
190 |
+
apiKeyPlaceholder: "Ingrese su clave API",
|
191 |
+
characterCountPlaceholder: "Ingrese el número de caracteres para el prompt generado"
|
192 |
+
},
|
193 |
+
de: {
|
194 |
+
inputQueryTitle: "Eingabeabfrage",
|
195 |
+
generateButtonText: "Prompt generieren",
|
196 |
+
splitStrings: "Zeichenketten aufteilen",
|
197 |
+
outputPromptTitle: "Generierter Prompt",
|
198 |
+
settingsTitle: "Einstellungen",
|
199 |
+
apiKeyLabel: "API-Schlüssel",
|
200 |
+
characterCountLabel: "Zeichenanzahl",
|
201 |
+
languageSelectLabel: "Sprache",
|
202 |
+
promptEnPlaceholder: "Der englische Prompt wird hier angezeigt",
|
203 |
+
promptMyLanguagePlaceholder: "Die Übersetzung wird hier angezeigt",
|
204 |
+
apiKeyPlaceholder: "Geben Sie Ihren API-Schlüssel ein",
|
205 |
+
characterCountPlaceholder: "Geben Sie die Anzahl der Zeichen für den generierten Prompt ein"
|
206 |
+
},
|
207 |
+
it: {
|
208 |
+
inputQueryTitle: "Query di input",
|
209 |
+
generateButtonText: "Genera prompt",
|
210 |
+
splitStrings: "Dividi stringhe",
|
211 |
+
outputPromptTitle: "Prompt generato",
|
212 |
+
settingsTitle: "Impostazioni",
|
213 |
+
apiKeyLabel: "Chiave API",
|
214 |
+
characterCountLabel: "Conteggio caratteri",
|
215 |
+
languageSelectLabel: "Lingua",
|
216 |
+
promptEnPlaceholder: "Il prompt in inglese verrà visualizzato qui",
|
217 |
+
promptMyLanguagePlaceholder: "La traduzione verrà visualizzata qui",
|
218 |
+
apiKeyPlaceholder: "Inserisci la tua chiave API",
|
219 |
+
characterCountPlaceholder: "Inserisci il numero di caratteri per il prompt generato"
|
220 |
+
}
|
221 |
+
}
|
222 |
+
const resources = {
|
223 |
+
ja: {
|
224 |
+
translation: translations.ja
|
225 |
+
},
|
226 |
+
en: {
|
227 |
+
translation: translations.en
|
228 |
+
},
|
229 |
+
zh: {
|
230 |
+
translation: translations.zh
|
231 |
+
},
|
232 |
+
ko: {
|
233 |
+
translation: translations.ko
|
234 |
+
},
|
235 |
+
fr: {
|
236 |
+
translation: translations.fr
|
237 |
+
},
|
238 |
+
es: {
|
239 |
+
translation: translations.es
|
240 |
+
},
|
241 |
+
de: {
|
242 |
+
translation: translations.de
|
243 |
+
},
|
244 |
+
it: {
|
245 |
+
translation: translations.it
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
// 既存のスクリプトの前に追加
|
250 |
+
document.addEventListener('DOMContentLoaded', function () {
|
251 |
+
i18next
|
252 |
+
.use(i18nextBrowserLanguageDetector)
|
253 |
+
.init({
|
254 |
+
fallbackLng: 'ja', // デフォルト言語
|
255 |
+
resources: resources
|
256 |
+
})
|
257 |
+
.then(function (t) {
|
258 |
+
document.getElementById('languageSelect').value = i18next.language;
|
259 |
+
document.getElementById('languageSelect').dispatchEvent(new Event('change'));
|
260 |
+
});
|
261 |
+
});
|
262 |
+
|
263 |
+
function updateContent() {
|
264 |
+
// 各要素のテキストを更新
|
265 |
+
document.getElementById('inputQueryTitle').textContent = i18next.t('inputQueryTitle');
|
266 |
+
document.getElementById('generateButtonText').textContent = i18next.t('generateButtonText');
|
267 |
+
document.getElementById('splitStrings').textContent = i18next.t('splitStrings');
|
268 |
+
document.getElementById('outputPromptTitle').textContent = i18next.t('outputPromptTitle');
|
269 |
+
document.getElementById('settingsTitle').textContent = i18next.t('settingsTitle');
|
270 |
+
document.getElementById('apiKeyLabel').textContent = i18next.t('apiKeyLabel');
|
271 |
+
document.getElementById('characterCountLabel').textContent = i18next.t('characterCountLabel');
|
272 |
+
document.getElementById('languageSelectLabel').textContent = i18next.t('languageSelectLabel');
|
273 |
+
|
274 |
+
// プレースホルダーを更新
|
275 |
+
document.getElementById('promptEn').placeholder = i18next.t('promptEnPlaceholder');
|
276 |
+
document.getElementById('promptMyLanguage').placeholder = i18next.t('promptMyLanguagePlaceholder');
|
277 |
+
document.getElementById('apiKey').placeholder = i18next.t('apiKeyPlaceholder');
|
278 |
+
document.getElementById('characterCount').placeholder = i18next.t('characterCountPlaceholder');
|
279 |
+
}
|
280 |
+
|
281 |
+
// 言語切り替え関数
|
282 |
+
function changeLang(language) {
|
283 |
+
i18next.changeLanguage(language, (err, t) => {
|
284 |
+
if (err) return console.error('言語切り替えエラー', err);
|
285 |
+
updateContent();
|
286 |
+
});
|
287 |
+
}
|
288 |
+
|
289 |
+
document.getElementById('languageSelect').addEventListener('change', function () {
|
290 |
+
changeLang(this.value);
|
291 |
+
});
|
292 |
+
</script>
|
293 |
+
|
294 |
+
<script>
|
295 |
+
function generatePrompt() {
|
296 |
+
if (!document.getElementById('apiKey').value) {
|
297 |
+
alert("APIキーを入力してください");
|
298 |
+
return;
|
299 |
+
}
|
300 |
+
let query = document.getElementById('query').value;
|
301 |
+
let textFormat = 'str';
|
302 |
+
|
303 |
+
if (document.getElementById('splitStringsSwitch').checked) {
|
304 |
+
query = Array.from(document.getElementById('query').value).join(":::");
|
305 |
+
//textFormat = 'array, # テキストは1character(not word)ずつ格納した配列にして返すこと。 Example: ["I", "t", " ", "i", "s", " ", "a", " ", "p", "e", "n", "."], ["こ", "れ", "は", " ", "ペ", "ン", "で", "す", "。"], ';
|
306 |
+
}
|
307 |
+
|
308 |
+
let anotherLanguage = "";
|
309 |
+
|
310 |
+
if (!["en", "ja"].includes(i18next.language)) {
|
311 |
+
anotherLanguage = `,
|
312 |
+
{
|
313 |
+
"language": "${i18next.language}",
|
314 |
+
"text": ${textFormat}
|
315 |
+
}`;
|
316 |
+
}
|
317 |
+
|
318 |
+
|
319 |
+
const text = `「 ${query} 」をテーマに画像生成AIに送るプロンプトを考えてください。
|
320 |
+
背景や小物のディテイール、構図、視覚効果など視覚的な情報のみに言及すること。
|
321 |
+
その上で長文を日本語と英語で返信してください。
|
322 |
+
返答は以下のフォーマットのjson形式でのみ行う。json以外の内容をレスポンスに含めないこと。
|
323 |
+
\`\`\`json
|
324 |
+
{
|
325 |
+
"results": [
|
326 |
+
{
|
327 |
+
"language": "en",
|
328 |
+
"text": ${textFormat} # ${document.getElementById('characterCount').value}文字程度,
|
329 |
+
},
|
330 |
+
{
|
331 |
+
"language": "ja",
|
332 |
+
"text": ${textFormat}
|
333 |
+
}${anotherLanguage}
|
334 |
+
]
|
335 |
+
}
|
336 |
+
\`\`\`
|
337 |
+
`;
|
338 |
+
const url = "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-flash:generateContent?key=" + document.getElementById('apiKey').value;
|
339 |
+
const payload = {
|
340 |
+
contents: [
|
341 |
+
{
|
342 |
+
parts: [
|
343 |
+
{ text: text }
|
344 |
+
]
|
345 |
+
}
|
346 |
+
],
|
347 |
+
generation_config: {
|
348 |
+
max_output_tokens: 4095,
|
349 |
+
temperature: 1,
|
350 |
+
top_p: 1,
|
351 |
+
top_k: 32
|
352 |
+
}
|
353 |
+
};
|
354 |
+
|
355 |
+
console.debug(text);
|
356 |
+
|
357 |
+
// fetchを使用してリクエストを送信
|
358 |
+
// ローディングアイコンを表示
|
359 |
+
document.getElementById('loading').classList.remove('d-none');
|
360 |
+
// generatePromptボタンを無効化
|
361 |
+
document.getElementById('generatePromptButton').disabled = true;
|
362 |
+
document.getElementById('generatePromptButton').classList.remove('btn-primary');
|
363 |
+
document.getElementById('generatePromptButton').classList.remove('btn-danger');
|
364 |
+
document.getElementById('generatePromptButton').classList.add('btn-secondary');
|
365 |
+
fetch(url, {
|
366 |
+
method: 'POST',
|
367 |
+
headers: {
|
368 |
+
'Content-Type': 'application/json'
|
369 |
+
},
|
370 |
+
body: JSON.stringify(payload)
|
371 |
+
})
|
372 |
+
.then(response => response.json())
|
373 |
+
.then(data => {
|
374 |
+
console.debug(data.candidates[0].content);
|
375 |
+
// レスポンスからテキストを抽出
|
376 |
+
const responseText = data.candidates[0].content.parts[0].text
|
377 |
+
console.debug(responseText);
|
378 |
+
|
379 |
+
let jsonString = responseText.replace(/```json|```/g, '').trim();
|
380 |
+
console.debug(jsonString);
|
381 |
+
// JSONをパース
|
382 |
+
const parsedData = JSON5.parse(jsonString);
|
383 |
+
|
384 |
+
// 結果を表示
|
385 |
+
console.debug(parsedData);
|
386 |
+
let promptEn = parsedData.results.find(x => x.language === 'en').text;
|
387 |
+
let promptMyLanguage = parsedData.results.find(x => x.language === i18next.language).text;
|
388 |
+
[promptEn, promptMyLanguage] = [promptEn, promptMyLanguage].map(x => {
|
389 |
+
return Array.isArray(x) ? x.join("") : x;
|
390 |
+
});
|
391 |
+
document.getElementById('promptEn').value = promptEn.replace(/\. ?/g, '.\n\n');
|
392 |
+
document.getElementById('promptEn').value = document.getElementById('promptEn').value.replace(/^ */g, '');
|
393 |
+
document.getElementById('promptMyLanguage').value = promptMyLanguage.replace(/\。 ?/g, '。\n\n');
|
394 |
+
|
395 |
+
|
396 |
+
// ローディングアイコンを非表示
|
397 |
+
document.getElementById('loading').classList.add('d-none');
|
398 |
+
document.getElementById('generatePromptButton').disabled = false;
|
399 |
+
document.getElementById('generatePromptButton').classList.remove('btn-secondary');
|
400 |
+
document.getElementById('generatePromptButton').classList.add('btn-primary');
|
401 |
+
saveToUserStorage(true);
|
402 |
+
})
|
403 |
+
.catch(error => {
|
404 |
+
console.error(error);
|
405 |
+
// エラー時もローディングアイコンを非表示
|
406 |
+
document.getElementById('loading').classList.add('d-none');
|
407 |
+
document.getElementById('generatePromptButton').disabled = false;
|
408 |
+
document.getElementById('generatePromptButton').classList.remove('btn-secondary');
|
409 |
+
document.getElementById('generatePromptButton').classList.add('btn-danger');
|
410 |
+
});
|
411 |
+
};
|
412 |
+
let lastSaveTimestamp = new Date();
|
413 |
+
function saveToUserStorage(force = false) {
|
414 |
+
const currentTime = new Date();
|
415 |
+
if (!force && currentTime - lastSaveTimestamp < 5000) {
|
416 |
+
return;
|
417 |
+
}
|
418 |
+
const data = {};
|
419 |
+
document.querySelectorAll('input, textarea').forEach(input => {
|
420 |
+
data[input.id] = input.value;
|
421 |
+
});
|
422 |
+
localStorage.setItem('gemini_prompt', JSON.stringify(data));
|
423 |
+
lastSaveTimestamp = currentTime;
|
424 |
+
return true;
|
425 |
+
}
|
426 |
+
function loadFromUserStorage() {
|
427 |
+
const data = JSON.parse(localStorage.getItem('gemini_prompt')) || {};
|
428 |
+
document.querySelectorAll('input, textarea').forEach(input => {
|
429 |
+
let v = data[input.id] || "";
|
430 |
+
if (v) {
|
431 |
+
if (input.type === "number") {
|
432 |
+
v = parseInt(v);
|
433 |
+
}
|
434 |
+
input.value = v;
|
435 |
+
}
|
436 |
+
});
|
437 |
+
}
|
438 |
+
loadFromUserStorage();
|
439 |
+
// 60秒ごとに自動保存を実行
|
440 |
+
setInterval(() => {
|
441 |
+
saveToUserStorage();
|
442 |
+
}, 60000);
|
443 |
+
document.querySelectorAll('input, textarea').forEach(input => {
|
444 |
+
input.addEventListener('input', saveToUserStorage);
|
445 |
+
});
|
446 |
+
// Ctrl+Enterでプロンプト生成を実行する
|
447 |
+
document.addEventListener('keydown', function (event) {
|
448 |
+
if (event.ctrlKey && event.key === 'Enter') {
|
449 |
+
event.preventDefault(); // デフォルトの動作を防ぐ
|
450 |
+
generatePrompt(); // プロンプト生成関数を呼び出す
|
451 |
+
}
|
452 |
+
});
|
453 |
+
</script>
|
454 |
+
</body>
|
455 |
+
|
456 |
+
</html>
|