#2037: complete the Traditional Chinese effect-name catalog

Add 308 Traditional Chinese effect names and 21 category labels, written from the English source with Taiwan creative-software terms. Update the completeness tests to require the zh-hant table and recount the localization docs.
This commit is contained in:
SHXJ committed 2026-11-03 22:34:55 +08:00
1 parent d025b59e6d
commit b77db389af
3 files changed
+437 -46

No files matched your search

+422 -33
View File
@@ -30,6 +30,13 @@
//! `Face Measurements` / `Face Track Points` are EffectCraft's own effects, so their wording is
//! ours.
//!
//! The Traditional Chinese names for Taiwan are written from the meaning of the English ones, with
//! the terms Taiwan's creative software uses (`圖層`, `遮罩`, `筆刷`, `雜訊`, `發光`, `漸層`); they
//! are not converted from the Simplified table. Brand and coined names (`Cryptomatte`,
//! `EXtractoR`, `IDentifier`, `Key Light`, `Unmult`, `Lumetri Color`, `Colorama`, `Minimax`,
//! `Vegas`, `Mocha`) stay in English; the `CC` series keeps its prefix and translates the
//! descriptive tail, and the `VR` and `OCIO` sets keep their prefix in Chinese word order.
//!
//! The French names are written from the meaning of the English ones, with the vocabulary of the
//! French menus; they come from no other application's interface. Brand and coined names
//! (`Cryptomatte`, `EXtractoR`, `IDentifier`, `Key Light`, `Unmult`, `Lumetri Color`, `Colorama`,
@@ -70,9 +77,9 @@ impl Catalog {
///
/// **Adding a language** is two tables and one arm: write its rows (one per effect, ids from
/// [`SIMPLIFIED_CHINESE`]) and its category labels, name them in the `static` below and in this
/// `match`. Nothing else changes — not the lookups, not one panel. `zh-hant` and `ja` are listed
/// with empty tables, so a translator fills rows in without touching this function, and until
/// then those languages draw the registry's English name.
/// `match`. Nothing else changes — not the lookups, not one panel. `zh-hant` now covers every
/// effect and category; `ja` ships a table that a translator fills in without touching this
/// function. An effect with no row draws the registry's English name until its row arrives.
fn catalog(language: &str) -> Option<&'static Catalog> {
static SIMPLIFIED: Catalog = Catalog { rows: SIMPLIFIED_CHINESE, categories: SIMPLIFIED_CHINESE_CATEGORIES, index: OnceLock::new() };
static TRADITIONAL: Catalog = Catalog { rows: TRADITIONAL_CHINESE, categories: TRADITIONAL_CHINESE_CATEGORIES, index: OnceLock::new() };
@@ -462,10 +469,323 @@ const SIMPLIFIED_CHINESE: &[Row] = &[
("ec.vr.sharpen", "VR Sharpen", "VR 锐化"),
("ec.vr.spheretoplane", "VR Sphere to Plane", "VR 球面到平面"),
];
/// Traditional Chinese (`zh-hant`): no rows yet. A translator fills one row per effect, ids from
/// [`SIMPLIFIED_CHINESE`]; a row may repeat the English name, which is what the language draws
/// for that effect.
const TRADITIONAL_CHINESE: &[Row] = &[];
/// Traditional Chinese (`zh-hant`): one row per effect in the registry, ids from
/// [`SIMPLIFIED_CHINESE`]. Written from the meaning of the English names with the vocabulary
/// Taiwan's creative software uses (圖層, 遮罩, 筆刷, 雜訊, 發光, 漸層), not converted from the
/// Simplified table. Brand and coined names (`Cryptomatte`, `EXtractoR`, `IDentifier`, `Key Light`,
/// `Unmult`, `Lumetri Color`, `Colorama`, `Minimax`, `Vegas`, `Mocha`) stay in English; the `CC`
/// series keeps its prefix and translates the descriptive tail, and the `VR` and `OCIO` sets keep
/// their prefix in Chinese word order.
const TRADITIONAL_CHINESE: &[Row] = &[
("ec.3d.channelextract", "3D Channel Extract", "3D 通道擷取"),
("ec.3d.cryptomatte", "Cryptomatte", "Cryptomatte"),
("ec.3d.depthmatte", "Depth Matte", "深度遮罩"),
("ec.3d.depthoffield", "Depth of Field", "景深"),
("ec.3d.extractor", "EXtractoR", "EXtractoR"),
("ec.3d.fog3d", "Fog 3D", "3D 霧"),
("ec.3d.identifier", "IDentifier", "IDentifier"),
("ec.3d.idmatte", "ID Matte", "ID 遮罩"),
("ec.3d.instance3d", "3D Layer Instance", "3D 圖層實體"),
("ec.audio.backwards", "Backwards", "倒轉"),
("ec.audio.basstreble", "Bass & Treble", "低音與高音"),
("ec.audio.compressor", "Compressor", "壓縮器"),
("ec.audio.delay", "Delay", "延遲"),
("ec.audio.distortion", "Distortion", "失真"),
("ec.audio.flangechorus", "Flange & Chorus", "鑲邊與合聲"),
("ec.audio.gate", "Gate", "雜訊閘"),
("ec.audio.highlowpass", "High-Low Pass", "高通/低通"),
("ec.audio.modulator", "Modulator", "調變器"),
("ec.audio.parametriceq", "Parametric EQ", "參數等化器"),
("ec.audio.reverb", "Reverb", "殘響"),
("ec.audio.stereomixer", "Stereo Mixer", "立體聲混音器"),
("ec.audio.tone", "Tone", "音調"),
("ec.blur.bilateral", "Bilateral Blur", "雙邊模糊"),
("ec.blur.cameralens", "Camera Lens Blur", "相機鏡頭模糊"),
("ec.blur.camerashakedeblur", "Camera-Shake Deblur", "相機晃動去模糊"),
("ec.blur.cccross", "CC Cross Blur", "CC 十字模糊"),
("ec.blur.ccradial", "CC Radial Blur", "CC 徑向模糊"),
("ec.blur.ccradialfast", "CC Radial Fast Blur", "CC 徑向快速模糊"),
("ec.blur.ccvector", "CC Vector Blur", "CC 向量模糊"),
("ec.blur.channel", "Channel Blur", "通道模糊"),
("ec.blur.compound", "Compound Blur", "複合模糊"),
("ec.blur.directional", "Directional Blur", "方向模糊"),
("ec.blur.fastbox", "Fast Box Blur", "快速方框模糊"),
("ec.blur.gaussian", "Gaussian Blur", "高斯模糊"),
("ec.blur.radial", "Radial Blur", "徑向模糊"),
("ec.blur.reduceflicker", "Reduce Interlace Flicker", "減少交錯閃爍"),
("ec.blur.sharpen", "Sharpen", "銳利化"),
("ec.blur.smart", "Smart Blur", "智慧型模糊"),
("ec.blur.unsharp", "Unsharp Mask", "遮色片銳利化"),
("ec.channel.arithmetic", "Arithmetic", "算術"),
("ec.channel.blend", "Blend", "混合"),
("ec.channel.calculations", "Calculations", "運算"),
("ec.channel.cccomposite", "CC Composite", "CC 合成"),
("ec.channel.combiner", "Channel Combiner", "通道合成器"),
("ec.channel.compoundarithmetic", "Compound Arithmetic", "複合算術"),
("ec.channel.invert", "Invert", "反轉"),
("ec.channel.minimax", "Minimax", "Minimax"),
("ec.channel.removecolormatting", "Remove Color Matting", "移除色彩殘邊"),
("ec.channel.setchannels", "Set Channels", "設定通道"),
("ec.channel.setmatte", "Set Matte", "設定遮罩"),
("ec.channel.shiftchannels", "Shift Channels", "轉移通道"),
("ec.channel.solidcomposite", "Solid Composite", "實色合成"),
("ec.color.autocolor", "Auto Color", "自動色彩"),
("ec.color.autocontrast", "Auto Contrast", "自動對比"),
("ec.color.autolevels", "Auto Levels", "自動色階"),
("ec.color.blackwhite", "Black & White", "黑白"),
("ec.color.brightnesscontrast", "Brightness & Contrast", "亮度與對比"),
("ec.color.broadcast", "Broadcast Colors", "廣播色彩"),
("ec.color.cccolorneutralizer", "CC Color Neutralizer", "CC 色彩中和器"),
("ec.color.cccoloroffset", "CC Color Offset", "CC 色彩偏移"),
("ec.color.cckernel", "CC Kernel", "CC 核心"),
("ec.color.cctoner", "CC Toner", "CC 色調"),
("ec.color.changecolor", "Change Color", "變更色彩"),
("ec.color.changetocolor", "Change to Color", "變更為色彩"),
("ec.color.channelmixer", "Channel Mixer", "通道混合器"),
("ec.color.colorama", "Colorama", "Colorama"),
("ec.color.colorbalance", "Color Balance", "色彩平衡"),
("ec.color.colorbalancehls", "Color Balance (HLS)", "色彩平衡(HLS)"),
("ec.color.colorlink", "Color Link", "色彩連結"),
("ec.color.colorstabilizer", "Color Stabilizer", "色彩穩定器"),
("ec.color.curves", "Curves", "曲線"),
("ec.color.equalize", "Equalize", "等化"),
("ec.color.exposure", "Exposure", "曝光"),
("ec.color.gammapedestalgain", "Gamma/Pedestal/Gain", "伽瑪/基準/增益"),
("ec.color.huesaturation", "Hue/Saturation", "色相/飽和度"),
("ec.color.leavecolor", "Leave Color", "保留色彩"),
("ec.color.levels", "Levels", "色階"),
("ec.color.levelsic", "Levels (Individual Controls)", "色階(個別控制項)"),
("ec.color.lumetri", "Lumetri Color", "Lumetri Color"),
("ec.color.ociocdl", "OCIO CDL Transform", "OCIO CDL 轉換"),
("ec.color.ociocolorspace", "OCIO Color Space Transform", "OCIO 色彩空間轉換"),
("ec.color.ociodisplay", "OCIO Display Transform", "OCIO 顯示轉換"),
("ec.color.ociofile", "OCIO File Transform", "OCIO 檔案轉換"),
("ec.color.ociolook", "OCIO Look Transform", "OCIO 外觀轉換"),
("ec.color.photofilter", "Photo Filter", "相片濾鏡"),
("ec.color.psarbitrarymap", "PS Arbitrary Map", "PS 任意映射"),
("ec.color.selectivecolor", "Selective Color", "選擇性色彩"),
("ec.color.shadowhighlight", "Shadow/Highlight", "陰影/亮部"),
("ec.color.tint", "Tint", "染色"),
("ec.color.tritone", "Tritone", "三色調"),
("ec.color.vibrance", "Vibrance", "自然飽和度"),
("ec.color.videolimiter", "Video Limiter", "視訊限制器"),
("ec.control.angle", "Angle Control", "角度控制"),
("ec.control.checkbox", "Checkbox Control", "核取方塊控制"),
("ec.control.color", "Color Control", "色彩控制"),
("ec.control.dropdown", "Dropdown Menu Control", "下拉式選單控制"),
("ec.control.layer", "Layer Control", "圖層控制"),
("ec.control.point", "Point Control", "點控制"),
("ec.control.point3d", "3D Point Control", "3D 點控制"),
("ec.control.slider", "Slider Control", "滑桿控制"),
("ec.control.stereo3d", "Stereo 3D Controls", "立體 3D 控制"),
("ec.distort.bezierwarp", "Bezier Warp", "貝茲彎曲"),
("ec.distort.bulge", "Bulge", "凸出"),
("ec.distort.ccbender", "CC Bender", "CC 彎曲"),
("ec.distort.ccbendit", "CC Bend It", "CC 彎折"),
("ec.distort.ccblobbylize", "CC Blobbylize", "CC 團塊化"),
("ec.distort.ccflomotion", "CC Flo Motion", "CC 流動"),
("ec.distort.ccgriddler", "CC Griddler", "CC 格線"),
("ec.distort.cclens", "CC Lens", "CC 鏡頭"),
("ec.distort.ccpageturn", "CC Page Turn", "CC 翻頁"),
("ec.distort.ccpowerpin", "CC Power Pin", "CC 強力釘選"),
("ec.distort.ccripplepulse", "CC Ripple Pulse", "CC 漣漪脈衝"),
("ec.distort.ccslant", "CC Slant", "CC 傾斜"),
("ec.distort.ccsmear", "CC Smear", "CC 塗抹"),
("ec.distort.ccsplit", "CC Split", "CC 分割"),
("ec.distort.ccsplit2", "CC Split 2", "CC 分割 2"),
("ec.distort.cctiler", "CC Tiler", "CC 並排"),
("ec.distort.cornerpin", "Corner Pin", "邊角釘選"),
("ec.distort.displacementmap", "Displacement Map", "位移映射"),
("ec.distort.liquify", "Liquify", "液化"),
("ec.distort.magnify", "Magnify", "放大"),
("ec.distort.meshwarp", "Mesh Warp", "網格彎曲"),
("ec.distort.mirror", "Mirror", "鏡像"),
("ec.distort.offset", "Offset", "位移"),
("ec.distort.opticscompensation", "Optics Compensation", "光學補償"),
("ec.distort.polar", "Polar Coordinates", "極座標"),
("ec.distort.puppet", "Puppet", "木偶"),
("ec.distort.reshape", "Reshape", "重塑"),
("ec.distort.ripple", "Ripple", "漣漪"),
("ec.distort.rollingshutterrepair", "Rolling Shutter Repair", "滾動快門修正"),
("ec.distort.smear", "Smear", "塗抹"),
("ec.distort.spherize", "Spherize", "球面化"),
("ec.distort.transform", "Transform", "變形"),
("ec.distort.turbulentdisplace", "Turbulent Displace", "擾流位移"),
("ec.distort.twirl", "Twirl", "扭轉"),
("ec.distort.twirllegacy", "Twirl (Legacy)", "扭轉(舊版)"),
("ec.distort.upscale", "Detail-preserving Upscale", "保留細節放大"),
("ec.distort.warp", "Warp", "彎曲"),
("ec.distort.warpstabilizer", "Warp Stabilizer", "彎曲穩定器"),
("ec.distort.wavewarp", "Wave Warp", "波浪彎曲"),
("ec.generate.advancedlightning", "Advanced Lightning", "進階閃電"),
("ec.generate.audiospectrum", "Audio Spectrum", "音訊頻譜"),
("ec.generate.audiowaveform", "Audio Waveform", "音訊波形"),
("ec.generate.beam", "Beam", "光束"),
("ec.generate.ccgluegun", "CC Glue Gun", "CC 膠水槍"),
("ec.generate.cclightburst", "CC Light Burst 2.5", "CC 光爆 2.5"),
("ec.generate.cclightrays", "CC Light Rays", "CC 光線"),
("ec.generate.cclightsweep", "CC Light Sweep", "CC 光線掃掠"),
("ec.generate.ccthreads", "CC Threads", "CC 絲線"),
("ec.generate.cellpattern", "Cell Pattern", "細胞圖樣"),
("ec.generate.checkerboard", "Checkerboard", "棋盤格"),
("ec.generate.circle", "Circle", "圓形"),
("ec.generate.ellipse", "Ellipse", "橢圓"),
("ec.generate.eyedropperfill", "Eyedropper Fill", "滴管填色"),
("ec.generate.fill", "Fill", "填色"),
("ec.generate.fourcolor", "4-Color Gradient", "四色漸層"),
("ec.generate.fractal", "Fractal", "碎形"),
("ec.generate.gradientramp", "Gradient Ramp", "漸層色帶"),
("ec.generate.grid", "Grid", "格線"),
("ec.generate.lensflare", "Lens Flare", "鏡頭光暈"),
("ec.generate.paintbucket", "Paint Bucket", "油漆桶"),
("ec.generate.radiowaves", "Radio Waves", "無線電波"),
("ec.generate.scribble", "Scribble", "塗鴉"),
("ec.generate.stroke", "Stroke", "筆畫"),
("ec.generate.vegas", "Vegas", "Vegas"),
("ec.generate.writeon", "Write-on", "書寫"),
("ec.key.advancedspill", "Advanced Spill Suppressor", "進階溢色抑制"),
("ec.key.ccsimplewireremoval", "CC Simple Wire Removal", "CC 簡易鋼絲移除"),
("ec.key.colordifference", "Color Difference Key", "色彩差異去背"),
("ec.key.colorkey", "Color Key", "色彩去背"),
("ec.key.colorrange", "Color Range", "色彩範圍"),
("ec.key.differencematte", "Difference Matte", "差異遮罩"),
("ec.key.extract", "Extract", "擷取"),
("ec.key.innerouter", "Inner/Outer Key", "內/外去背"),
("ec.key.keycleaner", "Key Cleaner", "去背淨化"),
("ec.key.linearcolor", "Linear Color Key", "線性色彩去背"),
("ec.key.luma", "Luma Key", "亮度去背"),
("ec.key.screen", "Screen Key", "螢幕去背"),
("ec.key.spill", "Spill Suppressor", "溢色抑制"),
("ec.key.unmult", "Unmult", "Unmult"),
("ec.keying.keylight", "Key Light", "Key Light"),
("ec.matte.mattechoker", "Matte Choker", "遮罩收縮器"),
("ec.matte.objectmatte", "Object Matte", "物件遮罩"),
("ec.matte.refinehard", "Refine Hard Matte", "調整硬邊遮罩"),
("ec.matte.refinesoft", "Refine Soft Matte", "調整柔邊遮罩"),
("ec.matte.rotobrush", "Roto Brush & Refine Edge", "Roto 筆刷與邊緣調整"),
("ec.matte.simplechoker", "Simple Choker", "簡單收縮器"),
("ec.noise.addgrain", "Add Grain", "新增顆粒"),
("ec.noise.curlnoise", "Curl Noise", "捲曲雜訊"),
("ec.noise.dustscratches", "Dust & Scratches", "汙點與刮痕"),
("ec.noise.fractal", "Fractal Noise", "碎形雜訊"),
("ec.noise.matchgrain", "Match Grain", "符合顆粒"),
("ec.noise.median", "Median", "中值"),
("ec.noise.medianlegacy", "Median (Legacy)", "中值(舊版)"),
("ec.noise.noise", "Noise", "雜訊"),
("ec.noise.noisealpha", "Noise Alpha", "雜訊 Alpha"),
("ec.noise.noisehls", "Noise HLS", "雜訊 HLS"),
("ec.noise.noisehlsauto", "Noise HLS Auto", "雜訊 HLS 自動"),
("ec.noise.removegrain", "Remove Grain", "移除顆粒"),
("ec.noise.turbulent", "Turbulent Noise", "擾流雜訊"),
("ec.obsolete.basic3d", "Basic 3D", "基礎 3D"),
("ec.obsolete.basictext", "Basic Text", "基礎文字"),
("ec.obsolete.gaussianlegacy", "Gaussian Blur (Legacy)", "高斯模糊(舊版)"),
("ec.obsolete.lightning", "Lightning", "閃電"),
("ec.obsolete.mochashape", "Mocha shape", "Mocha 形狀"),
("ec.obsolete.pathtext", "Path Text", "路徑文字"),
("ec.paint.paint", "Paint", "繪畫"),
("ec.perspective.3dglasses", "3D Glasses", "3D 眼鏡"),
("ec.perspective.bevelalpha", "Bevel Alpha", "Alpha 斜角"),
("ec.perspective.beveledges", "Bevel Edges", "邊緣斜角"),
("ec.perspective.cameratracker", "3D Camera Tracker", "3D 攝影機追蹤"),
("ec.perspective.cccylinder", "CC Cylinder", "CC 圓柱"),
("ec.perspective.ccenvironment", "CC Environment", "CC 環境"),
("ec.perspective.ccsphere", "CC Sphere", "CC 球體"),
("ec.perspective.ccspotlight", "CC Spotlight", "CC 聚光燈"),
("ec.perspective.dropshadow", "Drop Shadow", "陰影"),
("ec.perspective.radialshadow", "Radial Shadow", "徑向陰影"),
("ec.sim.carddance", "Card Dance", "卡片舞蹈"),
("ec.sim.caustics", "Caustics", "焦散"),
("ec.sim.ccballaction", "CC Ball Action", "CC 球狀動作"),
("ec.sim.ccbubbles", "CC Bubbles", "CC 泡泡"),
("ec.sim.ccdrizzle", "CC Drizzle", "CC 細雨"),
("ec.sim.cchair", "CC Hair", "CC 毛髮"),
("ec.sim.ccmrmercury", "CC Mr. Mercury", "CC 水銀先生"),
("ec.sim.ccparticlesystems2", "CC Particle Systems II", "CC 粒子系統 II"),
("ec.sim.ccparticleworld", "CC Particle World", "CC 粒子世界"),
("ec.sim.ccpixelpolly", "CC Pixel Polly", "CC 像素破碎"),
("ec.sim.ccrainfall", "CC Rainfall", "CC 下雨"),
("ec.sim.ccscatterize", "CC Scatterize", "CC 散開"),
("ec.sim.ccsnowfall", "CC Snowfall", "CC 下雪"),
("ec.sim.ccstarburst", "CC Star Burst", "CC 星爆"),
("ec.sim.foam", "Foam", "泡沫"),
("ec.sim.particleplayground", "Particle Playground", "粒子遊樂場"),
("ec.sim.shatter", "Shatter", "粉碎"),
("ec.sim.waveworld", "Wave World", "波浪世界"),
("ec.stylize.brushstrokes", "Brush Strokes", "筆觸"),
("ec.stylize.cartoon", "Cartoon", "卡通"),
("ec.stylize.ccblockload", "CC Block Load", "CC 區塊載入"),
("ec.stylize.ccburnfilm", "CC Burn Film", "CC 燒灼底片"),
("ec.stylize.ccglass", "CC Glass", "CC 玻璃"),
("ec.stylize.cchextile", "CC HexTile", "CC 六角並排"),
("ec.stylize.cckaleida", "CC Kaleida", "CC 萬花筒"),
("ec.stylize.ccmrsmoothie", "CC Mr. Smoothie", "CC 平滑先生"),
("ec.stylize.ccplastic", "CC Plastic", "CC 塑膠"),
("ec.stylize.ccrepetile", "CC RepeTile", "CC 重複並排"),
("ec.stylize.ccthreshold", "CC Threshold", "CC 臨界值"),
("ec.stylize.ccthresholdrgb", "CC Threshold RGB", "CC 臨界值 RGB"),
("ec.stylize.ccvignette", "CC Vignette", "CC 暗角"),
("ec.stylize.coloremboss", "Color Emboss", "彩色浮雕"),
("ec.stylize.emboss", "Emboss", "浮雕"),
("ec.stylize.findedges", "Find Edges", "尋找邊緣"),
("ec.stylize.glow", "Glow", "發光"),
("ec.stylize.mosaic", "Mosaic", "馬賽克"),
("ec.stylize.motiontile", "Motion Tile", "動態並排"),
("ec.stylize.posterize", "Posterize", "色調分離"),
("ec.stylize.roughenedges", "Roughen Edges", "粗糙邊緣"),
("ec.stylize.scatter", "Scatter", "散佈"),
("ec.stylize.strobe", "Strobe Light", "頻閃光"),
("ec.stylize.texturize", "Texturize", "材質化"),
("ec.stylize.threshold", "Threshold", "臨界值"),
("ec.text.numbers", "Numbers", "數字"),
("ec.text.timecode", "Timecode", "時間碼"),
("ec.time.ccforcemotionblur", "CC Force Motion Blur", "CC 強制動態模糊"),
("ec.time.ccwidetime", "CC Wide Time", "CC 寬廣時間"),
("ec.time.echo", "Echo", "回音"),
("ec.time.pixelmotionblur", "Pixel Motion Blur", "像素動態模糊"),
("ec.time.posterizetime", "Posterize Time", "色調分離時間"),
("ec.time.timedifference", "Time Difference", "時間差異"),
("ec.time.timedisplacement", "Time Displacement", "時間位移"),
("ec.time.timewarp", "Timewarp", "時間扭曲"),
("ec.transition.blockdissolve", "Block Dissolve", "區塊溶解"),
("ec.transition.cardwipe", "Card Wipe", "卡片擦拭"),
("ec.transition.ccglasswipe", "CC Glass Wipe", "CC 玻璃擦拭"),
("ec.transition.ccgridwipe", "CC Grid Wipe", "CC 格線擦拭"),
("ec.transition.ccimagewipe", "CC Image Wipe", "CC 影像擦拭"),
("ec.transition.ccjaws", "CC Jaws", "CC 巨顎"),
("ec.transition.cclightwipe", "CC Light Wipe", "CC 光線擦拭"),
("ec.transition.cclinesweep", "CC Line Sweep", "CC 線條掃掠"),
("ec.transition.ccradialscalewipe", "CC Radial ScaleWipe", "CC 徑向縮放擦拭"),
("ec.transition.ccscalewipe", "CC Scale Wipe", "CC 縮放擦拭"),
("ec.transition.cctwister", "CC Twister", "CC 扭轉"),
("ec.transition.ccwarpomatic", "CC WarpoMatic", "CC 自動彎曲"),
("ec.transition.gradientwipe", "Gradient Wipe", "漸層擦拭"),
("ec.transition.iriswipe", "Iris Wipe", "光圈擦拭"),
("ec.transition.linearwipe", "Linear Wipe", "線性擦拭"),
("ec.transition.radialwipe", "Radial Wipe", "徑向擦拭"),
("ec.transition.venetian", "Venetian Blinds", "百葉窗"),
("ec.utility.applylut", "Apply Color LUT", "套用色彩 LUT"),
("ec.utility.ccoverbrights", "CC Overbrights", "CC 過亮"),
("ec.utility.cineon", "Cineon Converter", "Cineon 轉換器"),
("ec.utility.colorprofileconverter", "Color Profile Converter", "色彩設定檔轉換器"),
("ec.utility.facemeasurements", "Face Measurements", "臉部測量"),
("ec.utility.facetrackpoints", "Face Track Points", "臉部追蹤點"),
("ec.utility.growbounds", "Grow Bounds", "擴展範圍"),
("ec.utility.hdrcompander", "HDR Compander", "HDR 壓縮擴展器"),
("ec.utility.hdrcompression", "HDR Highlight Compression", "HDR 亮部壓縮"),
("ec.vr.blur", "VR Blur", "VR 模糊"),
("ec.vr.chromaticaberrations", "VR Chromatic Aberrations", "VR 色差"),
("ec.vr.colorgradients", "VR Color Gradients", "VR 色彩漸層"),
("ec.vr.converter", "VR Converter", "VR 轉換器"),
("ec.vr.denoise", "VR De-Noise", "VR 降噪"),
("ec.vr.digitalglitch", "VR Digital Glitch", "VR 數位故障"),
("ec.vr.fractalnoise", "VR Fractal Noise", "VR 碎形雜訊"),
("ec.vr.glow", "VR Glow", "VR 發光"),
("ec.vr.planetosphere", "VR Plane to Sphere", "VR 平面轉球體"),
("ec.vr.rotatesphere", "VR Rotate Sphere", "VR 旋轉球體"),
("ec.vr.sharpen", "VR Sharpen", "VR 銳利化"),
("ec.vr.spheretoplane", "VR Sphere to Plane", "VR 球體轉平面"),
];
/// Japanese (`ja`): reserved for the Japanese data point on #821, so both languages share this
/// one catalog instead of inventing a second mechanism. A translator fills one row per effect,
@@ -795,8 +1115,32 @@ const JAPANESE_EFFECTS: &[Row] = &[
("ec.vr.spheretoplane", "VR Sphere to Plane", "VR 球体から平面"),
];
/// Traditional Chinese (`zh-hant`) category labels, keyed by the registry's English category.
const TRADITIONAL_CHINESE_CATEGORIES: &[(&str, &str)] = &[];
/// The 21 category folder names in Traditional Chinese, written from the English source with the
/// vocabulary Taiwan's creative software uses; the labels stay distinct so the Effect menu shows
/// one folder per category.
const TRADITIONAL_CHINESE_CATEGORIES: &[(&str, &str)] = &[
("3D Channel", "3D 通道"),
("Audio", "音訊"),
("Blur & Sharpen", "模糊與銳利化"),
("Channel", "通道"),
("Color Correction", "色彩校正"),
("Distort", "扭曲"),
("Expression Controls", "表示式控制"),
("Generate", "產生"),
("Immersive Video", "沉浸式影片"),
("Keying", "去背"),
("Matte", "遮罩"),
("Noise & Grain", "雜訊與顆粒"),
("Obsolete", "過時"),
("Paint", "繪畫"),
("Perspective", "透視"),
("Simulation", "模擬"),
("Stylize", "風格化"),
("Text", "文字"),
("Time", "時間"),
("Transition", "轉場"),
("Utility", "公用程式"),
];
/// Japanese (`ja`) category labels, keyed by the registry's English category.
const JAPANESE_CATEGORIES: &[(&str, &str)] = &[
@@ -1880,38 +2224,42 @@ mod tests {
#[test]
fn every_row_names_a_registry_effect() {
let registry = effects::registry();
for (id, english, translated) in SIMPLIFIED_CHINESE {
let Some(spec) = registry.iter().find(|spec| spec.id == *id) else {
panic!("{id} ({english}) is not an effect in the registry");
};
assert_eq!(*english, spec.name, "{id}: the catalog says {english:?}, the registry {:?}", spec.name);
assert!(!translated.is_empty(), "{id}: empty translation");
for (language, rows) in COMPLETE {
for (id, english, translated) in *rows {
let Some(spec) = registry.iter().find(|spec| spec.id == *id) else {
panic!("{language} row {id} ({english}) is not an effect in the registry");
};
assert_eq!(*english, spec.name, "{language} row {id}: the catalog says {english:?}, the registry {:?}", spec.name);
assert!(!translated.is_empty(), "{language} row {id}: empty translation");
}
}
}
/// Rows are keyed by id, so a repeated id would shadow a translation.
#[test]
fn ids_are_unique() {
let mut ids: Vec<&str> = SIMPLIFIED_CHINESE.iter().map(|(id, _, _)| *id).collect();
let listed = ids.len();
ids.sort_unstable();
ids.dedup();
assert_eq!(listed, ids.len(), "an effect id is listed twice");
for (language, rows) in COMPLETE.iter().chain(PARTIAL) {
let mut ids: Vec<&str> = rows.iter().map(|(id, _, _)| *id).collect();
let listed = ids.len();
ids.sort_unstable();
ids.dedup();
assert_eq!(listed, ids.len(), "{language} lists an effect id twice");
}
}
/// The languages that have no rows yet, with the table a translator fills in for each. A new
/// language is added here and to [`catalog`]; the test then guards its rows as they arrive.
const PENDING: &[(&str, &[Row])] = &[("zh-hant", TRADITIONAL_CHINESE)];
/// The languages whose tables are complete: one row per effect in the registry and one row
/// per category. A translator moves a language here from [`PARTIAL`] when its table is done;
/// the completeness tests then fail if a new effect or category arrives without a row.
const COMPLETE: &[(&str, &[Row])] = &[("zh-hans", SIMPLIFIED_CHINESE), ("zh-hant", TRADITIONAL_CHINESE)];
/// The languages whose tables are being filled in: guarded like [`PENDING`] row by row.
/// The languages whose tables are being filled in: guarded row by row.
const PARTIAL: &[(&str, &[Row])] = &[("ja", JAPANESE_EFFECTS), ("ka", GEORGIAN), ("sv", SWEDISH), ("fr", FRENCH)];
/// A pending language may lag Simplified Chinese but may not invent ids or disagree about
/// which effect an id names: a translator fills these tables row by row. While they are
/// empty the test is a no-op, which is why the slot ships before the data does.
/// A partial language may lag Simplified Chinese but may not invent ids or disagree about
/// which effect an id names: a translator fills these tables row by row.
#[test]
fn a_pending_language_only_uses_known_ids() {
for (language, rows) in PENDING.iter().chain(PARTIAL) {
fn a_partial_language_only_uses_known_ids() {
for (language, rows) in PARTIAL {
let mut ids: Vec<&str> = vec![];
for (id, english, translated) in *rows {
let Some((_, hans_english, _)) = SIMPLIFIED_CHINESE.iter().find(|(hans_id, _, _)| hans_id == id) else {
@@ -1928,6 +2276,35 @@ mod tests {
}
}
/// A complete language translates every effect the registry has and labels every category, so
/// a new effect or category cannot ship in English to a Chinese interface.
#[test]
fn a_complete_language_covers_the_registry() {
let registry = effects::registry();
let categories = effects::categories();
for (language, rows) in COMPLETE {
for spec in registry {
assert!(
rows.iter().any(|(id, _, _)| *id == spec.id),
"{language} has no row for {} ({}): a complete table covers every effect",
spec.name,
spec.id
);
}
let labels = match *language {
"zh-hans" => SIMPLIFIED_CHINESE_CATEGORIES,
"zh-hant" => TRADITIONAL_CHINESE_CATEGORIES,
other => panic!("{other} is complete but has no category table in this test"),
};
for source in &categories {
assert!(
labels.iter().any(|(english, _)| english == source),
"{language} has no category label for {source}: a complete table covers every category"
);
}
}
}
/// Every category row of every language names a category that exists, else the generated
/// Effect menu and Effects & Presets would carry a label no folder has.
#[test]
@@ -1966,13 +2343,13 @@ mod tests {
/// English, and a language with no catalog or no row for an effect, draws the registry's
/// name rather than an empty label; a language with a row draws the row. Every table in
/// [`PENDING`] and [`PARTIAL`] has an arm in [`catalog`]: an arm-less table's rows would be dead.
/// [`COMPLETE`] and [`PARTIAL`] has an arm in [`catalog`]: an arm-less table's rows would be dead.
#[test]
fn languages_without_rows_draw_the_registry_name() {
for (language, _) in PENDING.iter().chain(PARTIAL) {
for (language, _) in COMPLETE.iter().chain(PARTIAL) {
assert!(catalog(language).is_some(), "{language} has a table but no arm in `catalog`: its rows would be dead");
}
let tables = PENDING.iter().chain(PARTIAL).copied().chain([("zh-hans", SIMPLIFIED_CHINESE)]);
let tables = COMPLETE.iter().chain(PARTIAL).map(|(language, rows)| (*language, *rows));
for (language, rows) in [("en", &[][..]), ("uk", &[][..]), ("cs", &[][..])].into_iter().chain(tables) {
set_current(language);
let expected = rows.iter().find(|(id, _, _)| *id == "ec.blur.gaussian").map_or("Gaussian Blur", |(_, _, translated)| *translated);
@@ -2027,7 +2404,7 @@ mod tests {
}
#[cfg(test)]
mod japanese_category_tests {
mod category_name_tests {
use super::*;
use std::collections::HashMap;
@@ -2042,4 +2419,16 @@ mod japanese_category_tests {
}
}
}
/// The same for Traditional Chinese: one repeated label would hide a category behind another
/// in the Effect menu.
#[test]
fn no_two_categories_share_a_traditional_chinese_name() {
let mut seen: HashMap<&str, &str> = HashMap::new();
for (english, traditional) in TRADITIONAL_CHINESE_CATEGORIES {
if let Some(other) = seen.insert(traditional, english) {
panic!("`{english}` and `{other}` both draw as `{traditional}`");
}
}
}
}
+1 -1
View File
@@ -72,7 +72,7 @@ are grouped by area; the issue tracker has the rest.
| 13 | **3D model formats and materials** | After Effects 26 imports FBX, USD/USDZ, STL besides glTF and OBJ (`usd_plugins`), and Substance 3D materials with mesh displacement (26.0–26.2); we read glTF, OBJ, STL (binary and ASCII, with facet colours) and FBX 7.x (binary and ASCII: meshes, hierarchy, Lambert/Phong materials and textures; no FBX animation or skinning yet) | Product shots and 3D scenes come as FBX/USDZ | 25–45 h | — · [file-format-parity.md](file-format-parity.md) |
| 14 | **Object Matte** (26.2, disk cache in 26.5) | First slice (#783): the Object Matte effect (Effect ▸ Matte) and `objectMatte.apply` turn a point (and optional box) on a reference frame into a matte and follow the object up to 600 frames each way, or segment every frame on its own; Roto Brush's engine, cache and model (MobileSAM from Settings ▸ Roto Brush, classical graph cut without it). Since then: the Object Matte tool in the viewer (click / drag a box, hover crosshair), the box as the model's box prompt, background tracking with progress and cancel, Freeze, and segmentations kept in the disk cache (26.5). Missing: a comparison with After Effects ([plan](fidelity/object-matte.md)) | The new one-click roto | 10–20 h | G7 · [target-app-parity.md](target-app-parity.md) |
| 15 | **Hardware video decode and encode** | No VideoToolbox, NVENC, Quick Sync or VA-API; #498 asks for it (answered: CUDA / NVENC need Nvidia's proprietary SDK through FFI, which the no-`unsafe` rule forbids); open PR #819 adds hardware decoding via `filmcraft-platform`; FilmCraft has VideoToolbox / NVENC / VA-API paths to borrow | 4K playback and export speed | 25–45 h | G5/G6 · [hardware-parity.md](hardware-parity.md) |
| 16 | **Localization depth** | Menus in 11 languages (ja, zh-hans, zh-hant, uk, es, pt-br, ru, fr, de, cs, ka: 630 rows each, 629 in Georgian); panels in 7 (ja 996 rows, zh-hans 998, zh-hant 951, uk 524, pt-br 695, cs 518, ka 885); effect names translated in Simplified Chinese (307), Japanese (297) and Georgian (307, plus the generated Effect menu), their ~1,650 parameter names untranslated; Korean and Italian (After Effects ships them) absent; Hangul probe added (#599 closed) | After Effects is used heavily in Japan, China, Korea, Brazil, Europe | 60–110 h + native review | G9 · [localization-parity.md](localization-parity.md) |
| 16 | **Localization depth** | Menus in 11 languages (ja, zh-hans, zh-hant, uk, es, pt-br, ru, fr, de, cs, ka: 630 rows each, 629 in Georgian); panels in 7 (ja 996 rows, zh-hans 998, zh-hant 951, uk 524, pt-br 695, cs 518, ka 885); effect names translated in Simplified Chinese (308), Traditional Chinese (308, plus 21 categories), Japanese (297) and Georgian (308, plus the generated Effect menu), their ~1,650 parameter names untranslated; Korean and Italian (After Effects ships them) absent; Hangul probe added (#599 closed) | After Effects is used heavily in Japan, China, Korea, Brazil, Europe | 60–110 h + native review | G9 · [localization-parity.md](localization-parity.md) |
| 17 | **Media Browser lists files import refuses** | The Media Browser, the import and proxy dialogs and `media::is_importable` share one movie list since #1701, AVI included (Targa and Radiance HDR import since #745; DPX and Cineon since #756, log shown as stored unless Interpret Footage ▸ Cineon Settings converts it; MXF OP1a / OP-Atom since #767; AVI since #1701, without DV, MPEG-4 Part 2 or other legacy codecs yet); #431 and #324 closed | Confusing failures on common VFX formats | 15–30 h | G6 · [file-format-parity.md](file-format-parity.md) |
| 18 | **Relative paths and relinking** | Projects store absolute footage paths; no relink when a project moves | Moving or sharing a project breaks it | 6–12 h | G4 · [file-format-parity.md](file-format-parity.md) |
| 19 | **Plug-in ecosystem** | No After Effects SDK hosting (#600, #327 OpenFX, #334, #376 plug-in manager); our WebAssembly API has no third-party plug-ins | Many pro projects depend on Trapcode, Element, Saber… | 40–80 h for API growth; SDK hosting needs an owner decision | G8 · [scripting-parity.md](scripting-parity.md) |
+14 -12
View File
@@ -1,6 +1,6 @@
# Localization parity
> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-30 · **Change:** minor (Polish (`pl`): menus 630, panels 695; recounted at this tree after #1774: Japanese 1,923 of ≈ 4,200 interface strings (46%, with 297 effect names), Simplified Chinese 1,935 (46%, with 307 effect names), Traditional Chinese 1,581 (38%, its panel catalog 951 rows after #2244); overall ≈ 24%; previously: minor, the panel/dialog catalogs grow by 303 rows in Japanese, Simplified Chinese and Traditional Chinese: panel tabs, form and dialog labels, context menus, tracker/graph/text-panel labels, credits and File-panel footers; previously: minor, catalogs recounted at `upstream/main` 470ea7a3: menus in 10 languages, panels in 6, Hangul probe (#599)) · **Target:** Adobe After Effects 2026
> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-11-03 · **Change:** Traditional Chinese (`zh-hant`) effect names are complete: 308 names and 21 categories (#2037). Previously: minor (Polish (`pl`): menus 630, panels 695; recounted at this tree after #1774: Japanese 1,923 of ≈ 4,200 interface strings (46%, with 297 effect names), Simplified Chinese 1,935 (46%, with 307 effect names), Traditional Chinese 1,581 (38%, its panel catalog 951 rows after #2244); overall ≈ 24%; previously: minor, the panel/dialog catalogs grow by 303 rows in Japanese, Simplified Chinese and Traditional Chinese: panel tabs, form and dialog labels, context menus, tracker/graph/text-panel labels, credits and File-panel footers; previously: minor, catalogs recounted at `upstream/main` 470ea7a3: menus in 10 languages, panels in 6, Hangul probe (#599)) · **Target:** Adobe After Effects 2026
How much of EffectCraft's interface is translated, language by language, compared with After
Effects. [gaps.md](gaps.md) gap 16 and workstream G9 hold the work;
@@ -29,18 +29,19 @@ interface; Arabic and Hebrew text *in layers* is supported through its Middle Ea
the Simplified Chinese catalog's 694 rows, plus 191 for panels converted to the catalog since
(885 in all). Swedish (added later) also has one.
- **Effect names:** `crates/ui-egui/src/i18n/effects.rs`, keyed by **effect id**, in Simplified
Chinese (307 rows, one per effect in the registry), Japanese (297 of the 307 ids), Georgian
(307 rows, plus its 21 categories) and Swedish (307 rows, plus its 21 categories). The registry's
Chinese (308 rows, one per effect in the registry), Traditional Chinese (308 rows, plus its 21
categories), Japanese (297 of the 308 ids), Georgian (308 rows, plus its 21 categories) and
Swedish (308 rows, plus its 21 categories). The registry's
English name stays the effect's identity: `effect.list`, `effect.apply {"effect": …}`, scripts
and expressions match on it, and the property tree stores it as the effect group's name. Only
the drawing — the Effect menu, Effect Controls, the Timeline and Effects & Presets — goes
through the catalog, so a project file is identical whichever interface language opens it.
A repeat (`Gaussian Blur 2`) keeps the index the engine appends, and a group the user renamed
in Effect Controls stays verbatim. Adding a language there is two tables and one arm, and no
panel changes: Traditional Chinese has its table in place and empty, and Japanese fills 297 of
the 307 ids, so the rest draw English until a translator completes them. Each language decides
for itself which names stay English — Adobe's Japanese interface leaves the `CC`, `VR` and
`OCIO` sets in English while its Chinese one translates them — so a row repeating the English
panel changes: Traditional Chinese now covers all 308 ids and 21 categories, and Japanese fills
297 of the 308 ids, so the rest draw English until a translator completes them. Each language
decides for itself which names stay English — Adobe's Japanese interface leaves the `CC`, `VR`
and `OCIO` sets in English while its Chinese one translates them — so a row repeating the English
name is a choice, not a missing row.
- **Missing strings:** a string with no row in the interface language shows in English, and no
test, build or release fails on a missing translation. The `missing_translations_report` test
@@ -76,14 +77,14 @@ counted, so the true percentages are slightly lower.
| Language | Code | UI strings translated | Dialogs / tooltips / help | Script support | Native review | Status | To `full` |
|---|---|---|---|---|---|---|---|
| English | `en` | ≈ 4,200 (100%, source) | All; docs in English | — | yes | full | — |
| Simplified Chinese | `zh-hans` | 1,935 (≈ 46%): menus 630 rows, panels 998, effect names 307 | Panels and dialogs partly; no help, effect names translated and their parameter names not; Home screen literals unwrapped (#574, closed) | System CJK fallback; Han follows the UI language; CJK text in comps renders wrongly (#453); IME in text layers | no | partial | 6–9 h + review |
| Simplified Chinese | `zh-hans` | 1,936 (≈ 46%): menus 630 rows, panels 998, effect names 308 | Panels and dialogs partly; no help, effect names translated and their parameter names not; Home screen literals unwrapped (#574, closed) | System CJK fallback; Han follows the UI language; CJK text in comps renders wrongly (#453); IME in text layers | no | partial | 6–9 h + review |
| Spanish | `es` | 1,142 (≈ 29%): menus 629 rows, panels 513 | Menus only; the panel catalog from #996 | Latin, fine | no | partial | 9–12 h + review |
| Hindi | `hi` | 0 | — | UI: Devanagari fallback font but no shaping; text layers shape Devanagari | no | none (After Effects: none) | 9–13 h + shaping in the UI |
| Arabic | `ar` | 0 | — | UI: Arabic fallback font but no shaping and no RTL layout; text layers: bidi + shaping | no | none (After Effects: none) | 9–13 h + 15–25 h RTL UI |
| French | `fr` | 2,124 (≈ 51%): menus 632 rows, panels 1,184, effect names 308 | Panels and dialogs at the source list of the other panel catalogs; effect names and their 21 categories; no help; machine-translated from the English, not yet native-speaker proofread | Latin, fine | no | partial | 2–4 h + review |
| Portuguese (Brazil) | `pt-br` | 1,324 (≈ 34%): menus 629 rows, panels 695 | Panels and dialogs at the Chinese catalogs' source list; the six keys main added after that count are translated too; AI-assisted, not yet native-speaker proofread | Latin, fine | no | partial | independent native review |
| Indonesian | `id` | 0 | — | Latin, fine | no | none (After Effects: none) | 8–12 h + review |
| Japanese | `ja` | 1,923 (≈ 46%): menus 630 rows, panels 996, effect names 297 | Panels and dialogs partly; no help, effect names translated for 297 of the 307 ids and their parameter names not; Home screen literals unwrapped (#574, closed) | Japanese system fallback; vertical text and Tate-Chu-Yoko in text layers; IME | no | partial | 6–9 h + review |
| Japanese | `ja` | 1,923 (≈ 46%): menus 630 rows, panels 996, effect names 297 | Panels and dialogs partly; no help, effect names translated for 297 of the 308 ids and their parameter names not; Home screen literals unwrapped (#574, closed) | Japanese system fallback; vertical text and Tate-Chu-Yoko in text layers; IME | no | partial | 6–9 h + review |
| German | `de` | 624 (≈ 16%) | Menus only (open PR #666 adds interface translations) | Latin, fine | no | menus only | 7–10 h + review |
| Korean | `ko` | 0 | — | Hangul fallback probe added (#599, closed); not checked on macOS here | no | none | 9–13 h + review |
| Vietnamese | `vi` | 0 | — | Latin with stacked diacritics; untested | no | none (After Effects: none) | 8–12 h + review |
@@ -92,12 +93,12 @@ Other languages EffectCraft ships (6):
| Language | Code | UI strings translated | Status | To `full` |
|---|---|---|---|---|
| Traditional Chinese | `zh-hant` | 1,581 (≈ 38%): menus 630 rows, panels 951 | partial | 6–9 h + review |
| Traditional Chinese | `zh-hant` | 1,910 (≈ 45%): menus 630 rows, panels 951, effect names 308 + 21 categories | partial; effect names complete, parameter names and engine text still in English | 3–5 h + review |
| Ukrainian | `uk` | 1,153 (≈ 29%): menus 629 rows, panels 524 | partial | 6–9 h + review |
| Polish | `pl` | 1,325 (≈ 34%): menus 630 rows, panels 695 | partial; unwrapped UI, effects and engine text still in English; AI-drafted, native review welcome | Remaining strings + native review |
| Czech | `cs` | 1,147 (≈ 29%): menus 629 rows, panels 518 | Existing catalog entries covered; unwrapped UI, effects and engine text still in English; AI-assisted, not yet native-speaker proofread | Remaining strings + independent native review |
| Georgian | `ka` | 1,514 (≈ 39%): menus 629 rows, panels 885 (the Simplified Chinese catalog's 694 plus 191 Georgian-only rows: form dialogs, context menus, column headers), effect names 307 + 21 categories; native-speaker reviewed | partial | 5–8 h |
| Swedish | `sv` | menus 630 rows, panels 723, effect names 307 and categories 21; added after the measurement above | Settings, Edit menu and Match System (`sv-*` locales) offer it; parameter and engine text still in English; not yet native-speaker reviewed | Remaining strings + native review |
| Georgian | `ka` | 1,514 (≈ 39%): menus 629 rows, panels 885 (the Simplified Chinese catalog's 694 plus 191 Georgian-only rows: form dialogs, context menus, column headers), effect names 308 + 21 categories; native-speaker reviewed | partial | 5–8 h |
| Swedish | `sv` | menus 630 rows, panels 723, effect names 308 and categories 21; added after the measurement above | Settings, Edit menu and Match System (`sv-*` locales) offer it; parameter and engine text still in English; not yet native-speaker reviewed | Remaining strings + native review |
Russian (`ru`) has a menu catalog (630 rows, ≈ 15%); After Effects also ships Italian, which EffectCraft does not (8–12 h).
@@ -119,6 +120,7 @@ can give; only Georgian, contributed by a native speaker (#1843), has had it.
| Date | Change | Summary |
|---|---|---|
| 2026-11-03 | minor | Traditional Chinese (`zh-hant`): effect names complete — 308 names and 21 categories (#2037); the menu and panel catalogs stay at 630 and 951 rows |
| 2026-10-30 | minor | Recounted on the merged tree after #1774: Japanese 1,923 (46%, 297 effect names), Simplified Chinese 1,935 (46%, 307 effect names), Traditional Chinese 1,581 (38%, 951 panel rows after #2244's prune); overall ≈ 24% |
| 2026-10-22 | minor | Panel/dialog second step: 300 more catalog rows in Japanese, Simplified Chinese and Traditional Chinese, plus the three rows the review found missing (Basic, Advanced and Play/Stop) — panel tabs, form and dialog labels, panel context menus, the tracker and graph controls, text-panel options, File-panel footers and credits; the panel tables are now 996 Japanese and 998 Simplified Chinese rows, all drawn through `tr`/`tr_args`, with the tests keeping the three catalogs listing the same sources; the 30 October recount above carries the share |
| 2026-10-18 | minor | Brazilian Portuguese completes its panel catalog (278 new rows, 417 → 695, the Chinese catalogs' source list); the doc recount closes the drift the batch merges left in every language's panel count; AI-assisted, not yet native-speaker proofread |