要約:
検出言語:
日本語訳:
type
値/* 改行調整: 行内の * の直前に改行を入れる */
const insertBreakBeforeAsterisk = txt => txt.replace(/([^\n])\s*\*/g, '$1\n*');
/* API 初期化ヘルパ */
async function initSummarizer(opt) {
if (await Summarizer.availability() === 'unavailable')
throw new Error('Summarizer API 未対応です');
return Summarizer.create({...opt, format: 'plain-text'});
}
async function initLanguageDetector() {
if (await LanguageDetector.availability() === 'unavailable')
throw new Error('LanguageDetector API 未対応です');
return LanguageDetector.create();
}
async function initTranslator(src) {
if (await Translator.availability({sourceLanguage: src, targetLanguage: 'ja'}) === 'unavailable')
throw new Error('Translator API がこの言語ペアをサポートしていません');
return Translator.create({sourceLanguage: src, targetLanguage: 'ja'});
}
// localhost以外でのHTTPアクセス時の早期リジェクト
/*
if (location.protocol === 'http:') {
alert('HTTPS でアクセスしてください');
}
*/
/* メイン処理 */
document.getElementById('run').addEventListener('click', async () => {
const raw = document.getElementById('input').value.trim();
if (!raw) return alert('テキストを入力してください');
const type = document.getElementById('type').value;
const length = document.getElementById('length').value;
const useStreaming = document.getElementById('streaming').checked;
const summaryBox = document.getElementById('summary');
const detectedBox = document.getElementById('detected');
const translationBox = document.getElementById('translation');
summaryBox.innerHTML = '⏳ 要約中...';
detectedBox.textContent = '';
translationBox.innerHTML = '';
try {
const summarizer = await initSummarizer({type, length});
let summary = '';
/* --- 1) 要約 --- */
if (useStreaming && summarizer.summarizeStreaming) {
const stream = await summarizer.summarizeStreaming(raw);
const reader = stream.getReader();
while (true) {
const {value, done} = await reader.read();
if (done) break;
summary += value;
summaryBox.innerHTML = marked.parse(summary); // 部分更新
}
} else {
summary = await summarizer.summarize(raw);
summaryBox.innerHTML = marked.parse(summary);
}
/* --- 2) 言語判定 --- */
const detector = await initLanguageDetector();
const [best] = await detector.detect(summary);
detectedBox.textContent =
`${best.detectedLanguage} (信頼度 ${best.confidence.toFixed(2)})`;
/* --- 3) 翻訳 --- */
if (best.detectedLanguage !== 'ja') {
const translator = await initTranslator(best.detectedLanguage);
const jpFixed = insertBreakBeforeAsterisk(await translator.translate(summary));
// markedでMarkdownフォーマットの表示
translationBox.innerHTML = marked.parse(jpFixed);
} else {
translationBox.innerHTML = marked.parse('要約はすでに日本語です。');
}
} catch (err) {
alert(err.message);
summaryBox.innerHTML = detectedBox.textContent =
translationBox.innerHTML = '';
}
});