"""Raw-text convenience layer; no Torch import, jobs, installs, or downloads. Supply a G2P callable returning (full_phonemes, tokens), or an explicit FULL phoneme_override. No per-word dictionary, chunking, truncation, cached fallback, or phoneme cleanup is performed. Optional offline Misaki uses preinstalled American small-model assets; those external assets are NOT in the TTS budget. This optional module is not yet part of the frozen export manifest. """ from contextlib import contextmanager import hashlib import importlib import importlib.metadata import importlib.util from pathlib import Path import socket import threading VERSIONS = {"misaki":"0.9.4", "spacy":"3.8.16", "en_core_web_sm":"3.8.0"} _OFFLINE_LOCK = threading.RLock() class FrontendUnavailable(RuntimeError): pass def _require(ok, message): if not ok: raise ValueError(message) def prepare_phonemes(text, vocab, g2p=None, phoneme_override=None, max_phonemes=510): """Same full-override semantics as native27_phoneme_frontend; no fallback. Automatic source is user-g2p unless produced by our qualified Misaki wrapper. Display text is returned unchanged, including whitespace/punctuation. """ _require(isinstance(text,str) and bool(text.strip()) and len(text)<=20000, "Nonempty display text required, at most20000 characters") _require(type(max_phonemes) is int and 1<=max_phonemes<=510, "Phoneme cap must be1..510") _require(isinstance(vocab,dict) and bool(vocab) and all(isinstance(c,str) and len(c)==1 and type(i) is int and 0