hisaruki commited on
Commit
12c2d4f
·
1 Parent(s): 3bd9141

Diff狩作成

Browse files
Files changed (1) hide show
  1. gemini.js +114 -8
gemini.js CHANGED
@@ -4,26 +4,44 @@ let lastTokenUpdateTimestamp = 0;
4
  let summeries = {};
5
  let lastIndexUpdateTimestamp = 0;
6
 
 
 
7
  function replaceProofRead(textarea, proofReadText) {
8
- let novelContent1TextLines = document.getElementById("novelContent1").value.split("\n");
9
  let proofReadTextLines = proofReadText.split("\n");
10
  let textareaTextLines = textarea.value.split("\n");
11
  let start = novelContent1TextLines.indexOf(textareaTextLines[0]);
12
  let end = novelContent1TextLines.indexOf(textareaTextLines[textareaTextLines.length - 1]);
13
  console.log(start, end);
 
 
 
 
 
14
  // novelContent1TextLinesから該当部分を削除し、proofReadTextLinesを挿入
15
  novelContent1TextLines.splice(start, end - start + 1, ...proofReadTextLines);
16
-
17
  // 更新された内容をnovelContent1に反映
18
  document.getElementById("novelContent1").value = novelContent1TextLines.join("\n");
19
-
20
  // textareaの内容も更新
21
  textarea.value = proofReadTextLines.join("\n");
22
-
23
  console.log("校正が完了しました。");
24
  }
25
 
26
 
 
 
 
 
 
 
 
 
 
 
 
27
  async function proofRead(textarea) {
28
  let content = textarea.value;
29
  const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-002:generateContent?key=${document.getElementById('geminiApiKey').value}`;
@@ -33,11 +51,37 @@ async function proofRead(textarea) {
33
  headers: {},
34
  body: JSON.stringify({
35
  contents: [{ parts: [{ text: prompt }] }],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  })
37
  };
38
  let proofReadText;
39
  const response = await fetch(ENDPOINT, payload);
40
- try{
41
  const data = await response.json();
42
  proofReadText = data.candidates[0].content.parts[0].text;
43
  } catch (error) {
@@ -91,7 +135,25 @@ async function summerize(text) {
91
  headers: {},
92
  body: JSON.stringify({
93
  contents: [{ parts: [{ text: prompt }] }],
94
- generationConfig: { temperature: 0.7, max_output_tokens: 256 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  })
96
  };
97
  try {
@@ -222,7 +284,7 @@ function loadFromUserStorage() {
222
  const savedData = localStorage.getItem('geminiClient');
223
  if (savedData) {
224
  const geminiClientData = JSON.parse(savedData);
225
- Object.keys(geminiClientData).forEach(key => {
226
  const elem = document.getElementById(key);
227
  if (elem) {
228
  if (elem.type === 'checkbox') {
@@ -242,6 +304,17 @@ function loadFromUserStorage() {
242
  console.debug(`要素が見つかりません: ${key}`);
243
  }
244
  });
 
 
 
 
 
 
 
 
 
 
 
245
  }
246
  }
247
 
@@ -316,7 +389,7 @@ function createPayload() {
316
  headers: {},
317
  body: JSON.stringify({
318
  contents: messages,
319
- "generationConfig": {
320
  "temperature": 1.0,
321
  "max_output_tokens": 4096
322
  },
@@ -1162,6 +1235,34 @@ function updateAllAccordionHeaderCounts() {
1162
  accordionIds.forEach(updateAccordionHeaderCount);
1163
  }
1164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1165
  document.addEventListener('DOMContentLoaded', function () {
1166
  // ページ読み込み時にデータを復元
1167
  loadFromUserStorage();
@@ -1227,4 +1328,9 @@ document.addEventListener('DOMContentLoaded', function () {
1227
  updateNavbarBrand();
1228
  generateIndexMenu(true);
1229
  updateAllAccordionHeaderCounts();
 
 
 
 
 
1230
  });
 
4
  let summeries = {};
5
  let lastIndexUpdateTimestamp = 0;
6
 
7
+ let replaceProofReadHistory = [];
8
+
9
  function replaceProofRead(textarea, proofReadText) {
10
+ let novelContent1TextLines = document.getElementById("novelContent1").value.split("\n");
11
  let proofReadTextLines = proofReadText.split("\n");
12
  let textareaTextLines = textarea.value.split("\n");
13
  let start = novelContent1TextLines.indexOf(textareaTextLines[0]);
14
  let end = novelContent1TextLines.indexOf(textareaTextLines[textareaTextLines.length - 1]);
15
  console.log(start, end);
16
+
17
+ // 差し替え前のテキストを保存
18
+ let originalText = novelContent1TextLines.slice(start, end + 1);
19
+ replaceProofReadHistory.push([originalText, proofReadTextLines]);
20
+
21
  // novelContent1TextLinesから該当部分を削除し、proofReadTextLinesを挿入
22
  novelContent1TextLines.splice(start, end - start + 1, ...proofReadTextLines);
23
+
24
  // 更新された内容をnovelContent1に反映
25
  document.getElementById("novelContent1").value = novelContent1TextLines.join("\n");
26
+
27
  // textareaの内容も更新
28
  textarea.value = proofReadTextLines.join("\n");
29
+
30
  console.log("校正が完了しました。");
31
  }
32
 
33
 
34
+ async function getModelList() {
35
+ const url = 'https://generativelanguage.googleapis.com/v1beta/models?key=' + document.getElementById('geminiApiKey').value;
36
+ const response = await fetch(url);
37
+ const data = await response.json();
38
+ return data.models
39
+ .filter(x => x.supportedGenerationMethods.includes("generateContent"))
40
+ .filter(x => {
41
+ return x.name.match(/^models\/gemini/);
42
+ });
43
+ }
44
+
45
  async function proofRead(textarea) {
46
  let content = textarea.value;
47
  const ENDPOINT = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-002:generateContent?key=${document.getElementById('geminiApiKey').value}`;
 
51
  headers: {},
52
  body: JSON.stringify({
53
  contents: [{ parts: [{ text: prompt }] }],
54
+ generationConfig: {
55
+ "temperature": 1.0,
56
+ "max_output_tokens": 4096
57
+ },
58
+ safetySettings: [
59
+ {
60
+ "category": "HARM_CATEGORY_HATE_SPEECH",
61
+ "threshold": "BLOCK_NONE"
62
+ },
63
+ {
64
+ "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
65
+ "threshold": "BLOCK_NONE"
66
+ },
67
+ {
68
+ "category": "HARM_CATEGORY_HARASSMENT",
69
+ "threshold": "BLOCK_NONE"
70
+ },
71
+ {
72
+ "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
73
+ "threshold": "BLOCK_NONE"
74
+ },
75
+ {
76
+ "category": "HARM_CATEGORY_CIVIC_INTEGRITY",
77
+ "threshold": "BLOCK_NONE"
78
+ }
79
+ ]
80
  })
81
  };
82
  let proofReadText;
83
  const response = await fetch(ENDPOINT, payload);
84
+ try {
85
  const data = await response.json();
86
  proofReadText = data.candidates[0].content.parts[0].text;
87
  } catch (error) {
 
135
  headers: {},
136
  body: JSON.stringify({
137
  contents: [{ parts: [{ text: prompt }] }],
138
+ generationConfig: { temperature: 0.7, max_output_tokens: 256 },
139
+ safetySettings: [
140
+ {
141
+ "category": "HARM_CATEGORY_HATE_SPEECH",
142
+ "threshold": "BLOCK_NONE"
143
+ },
144
+ {
145
+ "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
146
+ "threshold": "BLOCK_NONE"
147
+ },
148
+ {
149
+ "category": "HARM_CATEGORY_HARASSMENT",
150
+ "threshold": "BLOCK_NONE"
151
+ },
152
+ {
153
+ "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
154
+ "threshold": "BLOCK_NONE"
155
+ }
156
+ ]
157
  })
158
  };
159
  try {
 
284
  const savedData = localStorage.getItem('geminiClient');
285
  if (savedData) {
286
  const geminiClientData = JSON.parse(savedData);
287
+ Object.keys(geminiClientData).filter(key => key != "endpointSelect").forEach(key => {
288
  const elem = document.getElementById(key);
289
  if (elem) {
290
  if (elem.type === 'checkbox') {
 
304
  console.debug(`要素が見つかりません: ${key}`);
305
  }
306
  });
307
+ getModelList().then(models => {
308
+ const endpointSelect = document.getElementById('endpointSelect');
309
+ endpointSelect.innerHTML = '';
310
+ models.forEach(model => {
311
+ const option = document.createElement('option');
312
+ option.value = model.name;
313
+ option.textContent = model.name;
314
+ endpointSelect.appendChild(option);
315
+ });
316
+ endpointSelect.value = geminiClientData.endpointSelect;
317
+ });
318
  }
319
  }
320
 
 
389
  headers: {},
390
  body: JSON.stringify({
391
  contents: messages,
392
+ generationConfig: {
393
  "temperature": 1.0,
394
  "max_output_tokens": 4096
395
  },
 
1235
  accordionIds.forEach(updateAccordionHeaderCount);
1236
  }
1237
 
1238
+ function showDiffModal() {
1239
+ const diffContainer = document.getElementById('diffContainer');
1240
+ diffContainer.innerHTML = '';
1241
+
1242
+ if (replaceProofReadHistory.length === 0) {
1243
+ diffContainer.innerHTML = '<p>校正履歴がありません。</p>';
1244
+ return;
1245
+ }
1246
+
1247
+ replaceProofReadHistory.forEach((entry, index) => {
1248
+ const [original, corrected] = entry;
1249
+ const diff = Diff.diffLines(original.join('\n'), corrected.join('\n'));
1250
+
1251
+ const diffHtml = diff.map(part => {
1252
+ const color = part.added ? 'green' : part.removed ? 'red' : 'grey';
1253
+ const prefix = part.added ? '+' : part.removed ? '-' : ' ';
1254
+ return `<span style="color: ${color}">${prefix} ${part.value}</span>`;
1255
+ }).join('');
1256
+
1257
+ const entryDiv = document.createElement('div');
1258
+ entryDiv.innerHTML = `<h6>校正 ${index + 1}</h6><pre>${diffHtml}</pre><hr>`;
1259
+ diffContainer.appendChild(entryDiv);
1260
+ });
1261
+
1262
+ const modal = new bootstrap.Modal(document.getElementById('diffModal'));
1263
+ modal.show();
1264
+ }
1265
+
1266
  document.addEventListener('DOMContentLoaded', function () {
1267
  // ページ読み込み時にデータを復元
1268
  loadFromUserStorage();
 
1328
  updateNavbarBrand();
1329
  generateIndexMenu(true);
1330
  updateAllAccordionHeaderCounts();
1331
+
1332
+ // diff2htmlライブラリの読み込み
1333
+ const script = document.createElement('script');
1334
+ script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jsdiff/5.1.0/diff.min.js';
1335
+ document.head.appendChild(script);
1336
  });