From 05218901c7e5a904f40bdcb66db83c11c3ab40ec Mon Sep 17 00:00:00 2001 From: Kodai Aoyama Date: Fri, 31 Mar 2023 19:27:53 +0900 Subject: [PATCH] release production --- package.json | 4 +- src-tauri/src/main.rs | 42 +++ src-tauri/src/module/mod.rs | 2 +- src-tauri/src/module/record.rs | 13 +- src-tauri/src/module/transcription.rs | 48 +++- src-tauri/tauri.conf.json | 2 +- src/App.tsx | 2 +- src/components/SideMenu.tsx | 26 +- src/components/molecules/MemoFilterButton.tsx | 5 +- .../molecules/RecordStartButton.tsx | 4 +- src/components/molecules/Speech.tsx | 19 +- src/components/molecules/SpeechHistory.tsx | 23 +- src/components/molecules/TraceStartButton.tsx | 53 ++++ src/components/molecules/TraceStopButton.tsx | 41 +++ src/components/organisms/NoteFooter.tsx | 9 +- src/components/organisms/NoteMain.tsx | 22 +- src/components/organisms/SettingsMain.tsx | 6 +- src/lib/sqlite.ts | 2 +- src/store/atoms/traceState.ts | 32 +++ src/store/atoms/tracingNoteState.ts | 6 + src/store/atoms/tracingState.ts | 6 + yarn.lock | 247 +++++++++++++++++- 22 files changed, 556 insertions(+), 58 deletions(-) create mode 100644 src/components/molecules/TraceStartButton.tsx create mode 100644 src/components/molecules/TraceStopButton.tsx create mode 100644 src/store/atoms/traceState.ts create mode 100644 src/store/atoms/tracingNoteState.ts create mode 100644 src/store/atoms/tracingState.ts diff --git a/package.json b/package.json index 3fb284b..9f9d3ec 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,9 @@ "react-dom": "^18.2.0", "react-h5-audio-player": "^3.8.6", "recoil": "^0.7.7", - "tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql#release" + "tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql#release", + "zenn-content-css": "^0.1.141", + "zenn-markdown-html": "^0.1.141" }, "devDependencies": { "@tauri-apps/cli": "^1.2.3", diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index a77cdbc..e06a01a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -6,6 +6,7 @@ use crossbeam_channel::Sender; use module::model_type_vosk::ModelTypeVosk; use module::model_type_whisper::ModelTypeWhisper; +use module::transcription::TraceCompletion; use tauri::http::HttpRange; use tauri::http::ResponseBuilder; use tauri::Manager; @@ -93,6 +94,45 @@ fn stop_command(state: State<'_, RecordState>) { } } +#[tauri::command] +fn start_trace_command( + state: State<'_, RecordState>, + window: tauri::Window, + speaker_language: String, + transcription_accuracy: String, + note_id: u64, +) { + let mut lock = state.0.lock().unwrap(); + let (stop_convert_tx, stop_convert_rx) = unbounded(); + *lock = Some(stop_convert_tx); + + std::thread::spawn(move || { + let mut transcription = module::transcription::Transcription::new( + window.app_handle(), + transcription_accuracy, + speaker_language, + note_id, + ); + transcription.start(stop_convert_rx, true); + }); +} + +#[tauri::command] +fn stop_trace_command(state: State<'_, RecordState>, window: tauri::Window) { + let mut lock = state.0.lock().unwrap(); + if let Some(stop_convert_tx) = lock.take() { + stop_convert_tx.send(()).unwrap_or_else(|_| { + window + .app_handle() + .emit_all( + "traceCompletion", + TraceCompletion {}, + ) + .unwrap(); + }) + } +} + fn main() { tauri::Builder::default() .register_uri_scheme_protocol("stream", move |_app, request| { @@ -158,6 +198,8 @@ fn main() { list_devices_command, start_command, stop_command, + start_trace_command, + stop_trace_command, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/module/mod.rs b/src-tauri/src/module/mod.rs index a0e701f..9833013 100644 --- a/src-tauri/src/module/mod.rs +++ b/src-tauri/src/module/mod.rs @@ -7,5 +7,5 @@ mod recognizer; pub mod record; mod sqlite; mod transcriber; -mod transcription; +pub mod transcription; mod writer; diff --git a/src-tauri/src/module/record.rs b/src-tauri/src/module/record.rs index 4188556..cd42ac9 100644 --- a/src-tauri/src/module/record.rs +++ b/src-tauri/src/module/record.rs @@ -139,6 +139,7 @@ impl Record { let (stop_writer_tx, stop_writer_rx) = sync_channel(1); let is_converting = Arc::new(Mutex::new(false)); let (stop_convert_tx, stop_convert_rx) = unbounded(); + let is_no_transcription = transcription_accuracy == "off"; let app_handle = self.app_handle.clone(); thread::spawn(move || loop { @@ -177,7 +178,7 @@ impl Record { .unwrap() .replace(Writer::build(&audio_path.to_str().expect("error"), spec)); - if !*is_converting.lock().unwrap() { + if !is_no_transcription && !*is_converting.lock().unwrap() { let is_converting_clone = Arc::clone(&is_converting); let app_handle_clone = app_handle.clone(); let stop_convert_rx_clone = stop_convert_rx.clone(); @@ -191,9 +192,9 @@ impl Record { app_handle_clone, transcription_accuracy_clone, speaker_language_clone, - note_id + note_id, ); - transcription.start(stop_convert_rx_clone); + transcription.start(stop_convert_rx_clone, false); let mut lock = is_converting_clone.lock().unwrap(); *lock = false; drop(lock); @@ -214,6 +215,10 @@ impl Record { .expect("failed to receive the message"); drop(stream); stop_writer_tx.send(()).unwrap(); - stop_convert_tx.send(()).unwrap(); + if !is_no_transcription { + stop_convert_tx.send(()).unwrap(); + } else { + drop(stop_convert_tx) + } } } diff --git a/src-tauri/src/module/transcription.rs b/src-tauri/src/module/transcription.rs index 3dc5bf6..e47433d 100644 --- a/src-tauri/src/module/transcription.rs +++ b/src-tauri/src/module/transcription.rs @@ -7,6 +7,9 @@ use samplerate_rs::{convert, ConverterType}; use tauri::{AppHandle, Manager}; use whisper_rs::WhisperContext; +#[derive(Debug, Clone, serde::Serialize)] +pub struct TraceCompletion {} + pub struct Transcription { app_handle: AppHandle, sqlite: Sqlite, @@ -32,9 +35,40 @@ impl Transcription { } } - pub fn start(&mut self, stop_convert_rx: Receiver<()>) { + pub fn start(&mut self, stop_convert_rx: Receiver<()>, is_continuous: bool) { while Self::convert(self).is_ok() { + if is_continuous { + let vosk_speech = self.sqlite.select_vosk(self.note_id); + if vosk_speech.is_err() { + self.app_handle + .clone() + .emit_all( + "traceCompletion", + TraceCompletion {}, + ) + .unwrap(); + break; + } + } if stop_convert_rx.try_recv().is_ok() { + let vosk_speech = self.sqlite.select_vosk(self.note_id); + if vosk_speech.is_err() { + self.app_handle + .clone() + .emit_all( + "traceCompletion", + TraceCompletion {}, + ) + .unwrap(); + } else { + self.app_handle + .clone() + .emit_all( + "traceUnCompletion", + TraceCompletion {}, + ) + .unwrap(); + } break; } } @@ -103,17 +137,7 @@ impl Transcription { .ctx .full_get_segment_text(i) .expect("failed to get segment"); - let last = converted.last().unwrap().as_str(); - if segment != last - && segment != "(音楽)" - && segment != "[音楽]" - && segment != "(音声)" - && segment != "(小声)" - && segment != "(EN)" - && segment != "(笑)" - { - converted.push(segment.to_string()); - } + converted.push(segment.to_string()); } let updated = self diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 6ed1476..8bfccaa 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "Lycoris", - "version": "0.5.0" + "version": "0.6.0" }, "tauri": { "allowlist": { diff --git a/src/App.tsx b/src/App.tsx index 2bd4dd3..227511d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,7 +8,7 @@ function App() { return (
-
+
diff --git a/src/components/SideMenu.tsx b/src/components/SideMenu.tsx index 8290f81..4b585c5 100644 --- a/src/components/SideMenu.tsx +++ b/src/components/SideMenu.tsx @@ -1,19 +1,33 @@ import { invoke } from "@tauri-apps/api" import { listen } from "@tauri-apps/api/event" -import { useEffect, useState } from "react" +import { useEffect, useRef, useState } from "react" import { useRecoilState } from "recoil" import { notesState } from "../store/atoms/notesState" import { selectedNoteState } from "../store/atoms/selectedNoteState" import { DeleteCompletionType } from "../type/DeleteCompletion.type" import { SideMenuColumn } from "./organisms/SideMenuColumn" +const KatakanaToHiragana = (katakanaValue: string | null | undefined): string => { + if (!katakanaValue) { + return ''; + } + + return katakanaValue.replace(/[\u30a1-\u30f6]/g, (substring: string): string => { + const hiraganaCharCode: number = substring.charCodeAt(0) - 0x60; + return String.fromCharCode(hiraganaCharCode); + }); +} + const SideMenu = (): JSX.Element => { + const targetRef = useRef(null); + const [searchWord, setSearchWord] = useState(""); const [notes, setNotes] = useRecoilState(notesState); const [isAdded, setAdded] = useState(false); const [selectedNote, setSelectedNote] = useRecoilState(selectedNoteState); useEffect(() => { if (!notes[notes.length - 1]?.id) { setAdded(true) + targetRef.current?.scrollIntoView({ behavior: 'smooth' }) } }, [notes]); useEffect(() => { @@ -38,7 +52,7 @@ const SideMenu = (): JSX.Element => {
- + setSearchWord(e.target.value)} />
- {notes.map((note, i) => { +
+ {notes.filter(note => { + if (searchWord === "") { + return true; + } + return KatakanaToHiragana(note.note_title.toLowerCase()).includes(KatakanaToHiragana(searchWord.toLowerCase())) + }).map((note, i) => { return ( ) diff --git a/src/components/molecules/MemoFilterButton.tsx b/src/components/molecules/MemoFilterButton.tsx index 8e58d2f..0542277 100644 --- a/src/components/molecules/MemoFilterButton.tsx +++ b/src/components/molecules/MemoFilterButton.tsx @@ -9,7 +9,10 @@ const MemoFilterButton = (): JSX.Element => { return ( ) } diff --git a/src/components/molecules/RecordStartButton.tsx b/src/components/molecules/RecordStartButton.tsx index 83bdf1d..2e7bb32 100644 --- a/src/components/molecules/RecordStartButton.tsx +++ b/src/components/molecules/RecordStartButton.tsx @@ -6,6 +6,7 @@ import { speakerLanguageState } from '../../store/atoms/speakerLanguageState'; import { transcriptionAccuracyState } from '../../store/atoms/transcriptionAccuracyState'; import { selectedNoteState } from '../../store/atoms/selectedNoteState'; import { recordingNoteState } from '../../store/atoms/recordingNoteState'; +import { tracingState } from '../../store/atoms/tracingState'; const RecordStartButton = (): JSX.Element => { const deviceLabel = useRecoilValue(audioDeviceState) @@ -14,6 +15,7 @@ const RecordStartButton = (): JSX.Element => { const [isRecording, setRecording] = useRecoilState(recordState) const selectedNote = useRecoilValue(selectedNoteState) const [recordingNote, setRecordingNote] = useRecoilState(recordingNoteState) + const isTracing = useRecoilValue(tracingState); const click = () => { setRecording(true) setRecordingNote(selectedNote!.note_id) @@ -21,7 +23,7 @@ const RecordStartButton = (): JSX.Element => { } return ( - + ) +} + +export { TraceStartButton } \ No newline at end of file diff --git a/src/components/molecules/TraceStopButton.tsx b/src/components/molecules/TraceStopButton.tsx new file mode 100644 index 0000000..5fcf7bf --- /dev/null +++ b/src/components/molecules/TraceStopButton.tsx @@ -0,0 +1,41 @@ +import { listen } from '@tauri-apps/api/event'; +import { invoke } from '@tauri-apps/api/tauri'; +import { useEffect } from 'react'; +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { traceState } from '../../store/atoms/traceState'; +import { tracingNoteState } from '../../store/atoms/tracingNoteState'; +import { tracingState } from '../../store/atoms/tracingState'; +import { transcriptionAccuracyState } from '../../store/atoms/transcriptionAccuracyState'; + +const TraceStopButton = (): JSX.Element => { + const transcriptionAccuracy = useRecoilValue(transcriptionAccuracyState); + const setTracing = useSetRecoilState(tracingState); + const [tracingNote, setTracingNote] = useRecoilState(tracingNoteState); + const setTracable = useSetRecoilState(traceState(tracingNote!)); + const click = () => { + setTracing(false) + setTracingNote(null) + invoke('stop_trace_command') + } + useEffect(() => { + const unlisten = listen('traceCompletion', () => { + setTracing(false) + setTracingNote(null) + setTracable(false) + }) + return () => { + unlisten.then(f => f()); + } + }, []) + + return ( + + ) +} + +export { TraceStopButton } \ No newline at end of file diff --git a/src/components/organisms/NoteFooter.tsx b/src/components/organisms/NoteFooter.tsx index 20622f5..bc969d6 100644 --- a/src/components/organisms/NoteFooter.tsx +++ b/src/components/organisms/NoteFooter.tsx @@ -1,4 +1,4 @@ -import { useRef, KeyboardEvent } from 'react' +import { useRef, KeyboardEvent, useEffect } from 'react' import { useRecoilValue, useSetRecoilState } from 'recoil' import { selectedNoteState } from '../../store/atoms/selectedNoteState' import { speechHistoryState } from '../../store/atoms/speechHistoryState' @@ -27,6 +27,11 @@ const NoteFooter = (): JSX.Element => { inputEl.current.value = "" } } + useEffect(() => { + if (inputEl.current) { + inputEl.current.focus(); + } + }, [selectedNote]); return (
@@ -37,7 +42,7 @@ const NoteFooter = (): JSX.Element => { - enter(e)} /> + enter(e)} />
diff --git a/src/components/organisms/NoteMain.tsx b/src/components/organisms/NoteMain.tsx index bb22f6a..c9cd972 100644 --- a/src/components/organisms/NoteMain.tsx +++ b/src/components/organisms/NoteMain.tsx @@ -14,16 +14,22 @@ import { transcriptionAccuracyState } from '../../store/atoms/transcriptionAccur import { selectedNoteState } from '../../store/atoms/selectedNoteState' import { notesState } from '../../store/atoms/notesState' import { recordingNoteState } from '../../store/atoms/recordingNoteState' +import { TraceStartButton } from '../molecules/TraceStartButton' +import { TraceStopButton } from '../molecules/TraceStopButton' +import { tracingState } from '../../store/atoms/tracingState' +import { tracingNoteState } from '../../store/atoms/tracingNoteState' const NoteMain = (): JSX.Element => { const transcriptionAccuracy = useRecoilValue(transcriptionAccuracyState) const [partialText, setPartialText] = useState(null) const [selectedNote, setSelectedNote] = useRecoilState(selectedNoteState) const recordingNote = useRecoilValue(recordingNoteState) + const tracingNote = useRecoilValue(tracingNoteState) const setNotes = useSetRecoilState(notesState) const [histories, setHistories] = useRecoilState(speechHistoryState(selectedNote!.note_id)) const isRecording = useRecoilValue(recordState); const [editTitle, setEditTitle] = useState(false); + const isTracing = useRecoilValue(tracingState); const bottomRef = useRef(null); useEffect(() => { if (recordingNote === selectedNote!.note_id) { @@ -73,14 +79,14 @@ const NoteMain = (): JSX.Element => { unlistenFinalText.then(f => f()); unlistenFinalTextConverted.then(f => f()); } - }, [recordingNote]) + }, [recordingNote, isTracing]) return (<>
-

{ e.preventDefault(); setEditTitle(true); }}> {editTitle ? - { if (e.key === "Enter" && e.keyCode === 13) { setEditTitle(false) @@ -98,19 +104,25 @@ const NoteMain = (): JSX.Element => { } })) }} /> - : selectedNote!.note_title} + :

{selectedNote!.note_title}

}

+
+ {isTracing && tracingNote === selectedNote?.note_id ? + : + } +
{(isRecording && recordingNote === selectedNote?.note_id) ? : }
+ フィルター:
-
{partialText}
+
{partialText}
) diff --git a/src/components/organisms/SettingsMain.tsx b/src/components/organisms/SettingsMain.tsx index 2ea0008..b6acd60 100644 --- a/src/components/organisms/SettingsMain.tsx +++ b/src/components/organisms/SettingsMain.tsx @@ -90,7 +90,7 @@ const SettingsMain = (): JSX.Element => {
-
+ {/*

@@ -100,7 +100,7 @@ const SettingsMain = (): JSX.Element => {

OpenAI社のAPIを利用することで、

-

高速な追っかけ文字起こし・翻訳や、要約機能及びカスタムメニューが有効となります。

+

高速な追っかけ文字起こしが選択可能となります。

(APIの利用に関しては、OpenAI社の利用規約を参照ください。)

@@ -108,7 +108,7 @@ const SettingsMain = (): JSX.Element => {
-

+
*/}
) } diff --git a/src/lib/sqlite.ts b/src/lib/sqlite.ts index 16e06a8..6a32e8d 100644 --- a/src/lib/sqlite.ts +++ b/src/lib/sqlite.ts @@ -32,7 +32,7 @@ export default class DB { } public async selectSpeechesBy(note_id: number): Promise { - return await this.db.select('SELECT * FROM speeches WHERE note_id = $1 ORDER BY created_at_unixtime DESC', [note_id]) + return await this.db.select('SELECT * FROM speeches WHERE note_id = $1 ORDER BY created_at_unixtime ASC', [note_id]) } public async loadDownloadedModels(model_type: string): Promise<{model_name: string}[]> { diff --git a/src/store/atoms/traceState.ts b/src/store/atoms/traceState.ts new file mode 100644 index 0000000..b5e49b6 --- /dev/null +++ b/src/store/atoms/traceState.ts @@ -0,0 +1,32 @@ +import { AtomEffect, atomFamily } from 'recoil' +import DB from '../../lib/sqlite'; + +const sqliteEffect: (note_id:number) => AtomEffect = + (note_id) => { + return ({setSelf, onSet, trigger}) => { + const loadPersisted = async () => { + const db = (await DB.getInstance()) + const savedValue = await db.selectSpeechesBy(note_id); + + if (savedValue.filter(v=>v.model === "vosk").length > 0) { + setSelf(true); + } + }; + + if (trigger === 'get') { + loadPersisted(); + } + + onSet(async() => { + await loadPersisted(); + }); + } + }; + +export const traceState = atomFamily({ + key: 'traceState', + default: false, + effects: (note_id:number) => [ + sqliteEffect(note_id), + ] +}) \ No newline at end of file diff --git a/src/store/atoms/tracingNoteState.ts b/src/store/atoms/tracingNoteState.ts new file mode 100644 index 0000000..c449eb4 --- /dev/null +++ b/src/store/atoms/tracingNoteState.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil' + +export const tracingNoteState = atom({ + key: 'tracingNoteState', + default: null +}) \ No newline at end of file diff --git a/src/store/atoms/tracingState.ts b/src/store/atoms/tracingState.ts new file mode 100644 index 0000000..1c88ffa --- /dev/null +++ b/src/store/atoms/tracingState.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil' + +export const tracingState = atom({ + key: 'tracingState', + default: false +}) \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index bc425ba..f27d956 100644 --- a/yarn.lock +++ b/yarn.lock @@ -430,6 +430,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@steelydylan/markdown-it-imsize@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@steelydylan/markdown-it-imsize/-/markdown-it-imsize-1.0.2.tgz#bffec33320601691162e4e903e27eb63d5488b6d" + integrity sha512-3tfhRLlv8w3GSNzjEx3y1JIyHpCuBhqXN6tILRTR4IhZcrJb6WJJo12jZ/lKiT9VITg9kHHHg6yVsDwO5nnZqw== + "@tauri-apps/api@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.1.0.tgz#2c5756f6aeecd36f7683183eaba021690711bedf" @@ -585,6 +590,11 @@ arg@^5.0.2: resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + autoprefixer@^10.4.14: version "10.4.14" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" @@ -602,6 +612,11 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -638,6 +653,31 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@1.0.0-rc.12: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.0.1" + htmlparser2 "^8.0.1" + parse5 "^7.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -700,6 +740,17 @@ convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + css-selector-tokenizer@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd" @@ -708,6 +759,11 @@ css-selector-tokenizer@^0.8.0: cssesc "^3.0.0" fastparse "^1.1.2" +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -740,6 +796,11 @@ debug@^4.1.0: dependencies: ms "2.1.2" +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" @@ -764,11 +825,51 @@ dlv@^1.1.3: resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" + integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.1" + electron-to-chromium@^1.4.284: version "1.4.340" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.340.tgz#3a6d7414c1fc2dbf84b6f7af3ec24270606c85b8" integrity sha512-zx8hqumOqltKsv/MF50yvdAlPF9S/4PXbyfzJS6ZGhbddGkRegdwImmfSVqCkEziYzrIGZ/TlrzBND4FysfkDg== +entities@^4.2.0, entities@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" + integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== + +entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + esbuild@^0.17.5: version "0.17.13" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.13.tgz#463066919a5567e8d1f4781004129da7fc8774b6" @@ -807,6 +908,11 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + fast-glob@^3.2.11: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" @@ -904,6 +1010,16 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +htmlparser2@^8.0.0, htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" @@ -940,6 +1056,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -960,6 +1081,13 @@ lilconfig@^2.0.5, lilconfig@^2.0.6: resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== +linkify-it@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" + integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== + dependencies: + uc.micro "^1.0.1" + loose-envify@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -981,6 +1109,52 @@ magic-string@^0.27.0: dependencies: "@jridgewell/sourcemap-codec" "^1.4.13" +markdown-it-anchor@^8.6.6: + version "8.6.7" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz#ee6926daf3ad1ed5e4e3968b1740eef1c6399634" + integrity sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA== + +markdown-it-container@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-2.0.0.tgz#0019b43fd02eefece2f1960a2895fba81a404695" + integrity sha512-IxPOaq2LzrGuFGyYq80zaorXReh2ZHGFOB1/Hen429EJL1XkPI3FJTpx9TsJeua+j2qTru4h3W1TiCRdeivMmA== + +markdown-it-footnote@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz#e0e4c0d67390a4c5f0c75f73be605c7c190ca4d8" + integrity sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w== + +markdown-it-inline-comments@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/markdown-it-inline-comments/-/markdown-it-inline-comments-1.0.1.tgz#176eabe631a3e08125bd739500f43c51f525896d" + integrity sha512-gObNM3NumcpsU66pO2LmV8MGBfdfFp7TcYME9iuUGs82+JYJWMmBQtAj6/qho4OhKqpR0UX2JTkuuA2HPgHUtQ== + +markdown-it-link-attributes@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz#25751f2cf74fd91f0a35ba7b3247fa45f2056d88" + integrity sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ== + +markdown-it-task-lists@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz#f68f4d2ac2bad5a2c373ba93081a1a6848417088" + integrity sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA== + +markdown-it@^12.3.2: + version "12.3.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" + integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" @@ -1024,11 +1198,38 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + object-hash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== +parse-srcset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" + integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q== + +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -1108,7 +1309,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.0.9, postcss@^8.4.21: +postcss@^8.0.9, postcss@^8.3.11, postcss@^8.4.21: version "8.4.21" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== @@ -1126,6 +1327,11 @@ postcss@^8.4.14: picocolors "^1.0.0" source-map-js "^1.0.2" +prismjs@^1.29.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -1224,6 +1430,18 @@ safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +sanitize-html@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.10.0.tgz#74d28848dfcf72c39693139131895c78900ab452" + integrity sha512-JqdovUd81dG4k87vZt6uA6YhDfWkUGruUu/aPmXLxXi45gZExnt9Bnw/qeQU8oGf82vPyaE0vO4aH0PbobB9JQ== + dependencies: + deepmerge "^4.2.2" + escape-string-regexp "^4.0.0" + htmlparser2 "^8.0.0" + is-plain-object "^5.0.0" + parse-srcset "^1.0.2" + postcss "^8.3.11" + scheduler@^0.23.0: version "0.23.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" @@ -1346,6 +1564,11 @@ typescript@^5.0.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.2.tgz#891e1a90c5189d8506af64b9ef929fca99ba1ee5" integrity sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw== +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + update-browserslist-db@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" @@ -1385,3 +1608,25 @@ yaml@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +zenn-content-css@^0.1.141: + version "0.1.141" + resolved "https://registry.yarnpkg.com/zenn-content-css/-/zenn-content-css-0.1.141.tgz#47982fd9c74cf8dcba395444a78e62636b45c7dd" + integrity sha512-mvFrU9MHg9eJyJJ07iSfzGkRxlEmQZeZUMhyTDoomlnfz6A+5I2eLDbOmH5vALh399F1lyF5HwP1ci7UrQOlYg== + +zenn-markdown-html@^0.1.141: + version "0.1.141" + resolved "https://registry.yarnpkg.com/zenn-markdown-html/-/zenn-markdown-html-0.1.141.tgz#eacbd3cc0868948dae7353f497ae4a325606372d" + integrity sha512-dFwZJRN+DprkU1zflxcVOxRppdiSQEMsCVJt9sBQGkVQq+fI7uMCiyNXPU7DyutMF0AhC/C2ODRG1lWOTXuwKA== + dependencies: + "@steelydylan/markdown-it-imsize" "^1.0.2" + cheerio "1.0.0-rc.12" + markdown-it "^12.3.2" + markdown-it-anchor "^8.6.6" + markdown-it-container "^2.0.0" + markdown-it-footnote "^3.0.3" + markdown-it-inline-comments "^1.0.1" + markdown-it-link-attributes "^4.0.1" + markdown-it-task-lists "^2.1.1" + prismjs "^1.29.0" + sanitize-html "^2.9.0"