diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 7de4fc8..abea54a 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -42,7 +42,7 @@ jobs:
- name: Build documentation with make
run: |
cd docs
- uv run make html
+ uv run make html-all
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..45b5d86
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,168 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [0.0.15a2] - Pre-Alpha
+
+### Fixed
+
+- Fix several error string missing user input logging during format
+
+ 修复遗漏的错误信息格式化 [#26](https://github.com/OwenYou/dftt_timecode/issues/26)
+
+## [0.0.15a1] - Pre-Alpha
+
+### Added
+
+- Add `DfttTimecodeInitializationError` exception class
+
+ 增加 `DfttTimecodeInitializationError`
+
+- Add GitHub Action to automatically upload releases to PyPI
+
+ 使用 GitHub Action 自动打包上传 PyPI
+
+### Changed
+
+- Modify drop frame logic to adapt to more frame rates
+
+ 修改丢帧逻辑适应更多帧率
+
+- Refactor timecode type detection logic
+
+ 重构时码类型检测逻辑
+
+- Refactor error handling during timecode initialization
+
+ 重构时码对象初始化时的错误处理
+
+- Modify error messages to enhance readability
+
+ 修改报错信息,增强可读性
+
+### Deprecated
+
+- Completely remove `InstanceMethodDispatch`
+
+ 完全移除 `InstanceMethodDispatch`
+
+### Fixed
+
+- Fix millisecond overflow issue when converting certain timecodes from SMPTE to SRT [#19](https://github.com/OwenYou/dftt_timecode/issues/19)
+
+ 修复特定时码在SMPTE转SRT时毫秒会溢出的问题
+
+## [0.0.14]
+
+### Fixed
+
+- Fix v0.0.13 import failure caused by missing dftt_timecode.core while packing
+
+ 修复v0.0.13打包后不包含core,导致库无法使用的问题
+
+## [0.0.13]
+
+### Added
+
+- Add `get_audio_sample_count` method for correctly outputting the count of audio samples at TC timestamps [#9](https://github.com/OwenYou/dftt_timecode/issues/9)
+
+ 添加 `get_audio_sample_count` 方法用于正确输出TC时间戳下的音频采样数
+
+### Changed
+
+- Use f-string for string format output
+
+ 使用 `f-string` 处理字符串格式输出
+
+- Refactor timecode output function to reduce code duplication
+
+ 重构时间码输出函数,减少代码重复
+
+### Deprecated
+
+- Use `functools.singledispatchmethod` instead of `dispatch.InstanceMethodDispatch`
+
+ 使用 `functools.singledispatchmethod` 代替 `dispatch.InstanceMethodDispatch`
+
+## [0.0.12]
+
+### Fixed
+
+- Fix DLP pattern error causing DLP ticks in range [50-99] and [150-199] to not be matched. This bug caused errors when using strings like `'00:00:27:183'` to initialize a DLP timecode object
+
+ 修复DLP正则表达式错误导致范围在50-99、150-199的DLP tick不能被匹配的问题
+
+## [0.0.11]
+
+### Added
+
+- Add `__str__` method to return timecode value for DfttTimecode object
+
+ 添加 `__str__` 方法,返回DfttTimecode对象的时间码值
+
+- Add unit tests for DfttTimecode using pytest
+
+ 添加DfttTimecode单元测试(使用pytest)
+
+### Changed
+
+- Add 23.98/23.976 FPS to drop frame detection conditions
+
+ 对丢帧的检测条件添加有关23.98/23.976的判定
+
+- `+` and `-` operators perform an OR operation on the strict property of two DfttTimecode objects being added/subtracted
+
+ `+` `-` 运算符对相加的两个DfttTimecode对象的strict属性进行或运算
+
+- Comparison operators (`==`, `>`, `>=`, etc.) now validate that both DfttTimecode objects have the same frame rate before comparison, throwing an exception if frame rates differ
+
+ 比较运算符在对两个DfttTimecode对象进行比较时会先判定帧率,若帧率不同则抛出异常
+
+- `print(self)` now outputs a formatted timecode string
+
+ `print(self)` 将会输出基于类型的时间码字符串
+
+### Fixed
+
+- Fix issue in `timecode_output(self, dest_type, output_part)` where `output_part = 3` would incorrectly return minute data
+
+ 修复 `timecode_output` 中 `output_part = 3` 时错误返回分钟数据的问题
+
+## [0.0.10]
+
+### Added
+
+- Add support for using a DfttTimecode object to initialize a new DfttTimecode object
+
+ 使用DfttTimecode对象初始化新DfttTimecode对象
+
+- Add `float()` and `int()` class methods for DfttTimecode class
+
+ 添加DfttTimecode类的float和int方法
+
+- Add `precise_timestamp` attribute for DfttTimecode class
+
+ 添加DfttTimecode类的precise_timestamp属性
+
+### Changed
+
+- DfttTimecode operators now raise errors when encountering undefined circumstances or illegal operations
+
+ DfttTimecode运算符在未定义/非法操作时将会报错
+
+- Update comparison rules for DfttTimecode operators
+
+ 修改DfttTimecode运算符的大小比较规则
+
+- When creating a timecode object using SMPTE NDF format string, if `drop_frame` is forced to `True`, the resulting object will be SMPTE DF format timecode
+
+ 使用SMPTE NDF格式字符串新建时码类对象时,若强制drop_frame为True,则新建得到的对象为SMPTE DF格式时码
+
+## [0.0.9]
+
+Initial public release.
diff --git a/ChangeLog.md b/ChangeLog.md
deleted file mode 100644
index 97459ef..0000000
--- a/ChangeLog.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Change Log
-## V0.0.9
-First Public Release.
-
-## V0.0.10
-
-添加 Add:
-
-- 使用DfttTimecode对象初始化新DfttTimecode对象
-
- Using a DfttTimecode object to instance a new DfttTimecode object.
-
-- DfttTimecode类的float和int方法
-
- class method float() and int() for DfttTimecode class
-
-- DfttTimecode类的precise_timestamp属性
-
- attribute precise_timestamp for class DfttTimecode
-
-修改 Modify:
-
-- DfttTimecode运算符在未定义/非法操作时将会报错
-
- Will raise an error when DfttTimecode operators meet undefined circumstances or illegal operations.
-
-- DfttTimecode运算符的大小比较规则
-
- Compare functions of DfttTimecode operators.
-
-- 使用SMPTE NDF格式字符串新建时码类对象时,若强制drop_frame为True,则新建得到的对象为SMPTE DF格式时码
-
-## V0.0.11
-添加 Add:
-- `__str__`方法,返回DfttTimecode对象的时间码值
-
- `__str__`method,return timecode value for DfttTimecode object
-
-- DfttTimecode单元测试(使用pytest)
-
- Unit test for DfttTimecode (Using pytest)
-
-修改 Modify:
-- 对丢帧的检测条件添加有关23.98/23.976的判定
-
- Add 23.98/23.976FPS to drop frame conditions
-
-- `+` `-`运算符对相加的两个DfttTimecode对象的strict属性进行或运算
-
- `+` `-`operators performs an or operation on the strict property of two DfttTimecode objects that are added together
-
-- 比较运算符,比如`==` `>` `>=`等,在对两个DfttTimecode对象进行比较的时候会先对两个对象的帧率进行判定,若帧率不同抛出异常
-
- Comparison operators, such as `==`, `>`, `>=`, in the comparison of two DfttTimecode objects will first compare the frame rate of the two objects, if the frame rate is different throw an exception
-
-- `print(self)` 将会输出基于类型的时间码字符串
-
- `print(self)` will output a timecode string
-
-修复 BugFix:
-- `timecode_output(self, dest_type, output_part)` 中`output_part = 3`时错误返回分钟数据的问题
-
- Addressed a problem when `output_part = 3` in `timecode_output(self, dest_type, output_part)` would return minute value in timecode value
-
- ## V0.0.12
- 修复 BugFix:
-- 修复DLP正则表达式错误导致范围在50-99 150-199的DLP tick不能被匹配的问题。
- 这一bug会导致使用形如`'00:00:27:183'`的字符串初始化dlp时间码对象时的报错。
-
- Fix DLP pattern error causing DLP ticks range [50-99] [150-199] cannot be matched.
- This bug will cause error when using strings like `'00:00:27:183'` to initilize a dlp timecode object.
-
-
-## V0.0.13
-重构 Refactor:
-- 使用`f-string`处理字符串格式输出
-
- Handling string format output using `f-string`
-
-- 重构时间码输出函数,减少代码重复
-
- Refactor the time code output function to reduce code duplication
-
-添加 Add:
-- 添加`get_audio_sample_count` 方法用于正确输出TC时间戳下的音频采样数, 解决issue [#9](https://github.com/OwenYou/dftt_timecode/issues/9)
-
- Add `get_audio_sample_count` method for correctly outputting the count of audio samples at TC timestamps,solve issue [#9](https://github.com/OwenYou/dftt_timecode/issues/9)
-
-弃用 Deprecate:
-- 使用`functools.singledispatchmethod` 代替 `dispatch.InstanceMethodDispatch`
-
- Use`functools.singledispatchmethod` instead of `dispatch.InstanceMethodDispatch`
-
-## V0.0.14
-修复 BugFix:
-- 修复v0.0.13打包后不包含core,导致库无法使用的问题。
-
- Fix v0.0.13 import failure. Caused by missing dftt_timecode.core while packing.
-
-## V0.0.15a1
-重构 Refactor:
-
-- 重构时码类型检测逻辑。
-
- Refactor timecode type detection logic
-
-- 重构时码对象初始化时的错误处理。
-
- Refactor error handling during timecode initialization
-
-- 修改报错信息,增强可读性。
-
- Modify error message to give more detail.
-
-修改 Modify:
-
-- 修改丢帧逻辑适应更多帧率。
-
- Change drop frame implementation to fit more frame rates.
-
-添加 Add:
-
-- 增加`DfttTimecodeInitializationError`
-
- Add `DfttTimecodeInitializationError`
-
-- Github Action自动打包上传PyPi。
-
- Using Github Action to automatically upload releases to PyPi.
-
-弃用 Deprecate:
-- 完全移除`InstanceMethodDispatch`
-
- Remove `InstanceMethodDispatch` at all.
-
-修复 BugFix:
-- 修复特定时码在SMPTE转SRT时毫秒会溢出的问题 Issue [#19](https://github.com/OwenYou/dftt_timecode/issues/19)。
-
- Fix certain timecode value will cause ValueError (sub-second overflow) when setting type from SMPTE to SRT.
-
-## V0.0.15a2
-修复 BugFix:
-
-- 修复遗漏的错误信息格式化 Issue [#26](https://github.com/OwenYou/dftt_timecode/issues/26)。
-
- Fix several error string missing user input logging during format.
\ No newline at end of file
diff --git a/docs/.gitignore b/docs/.gitignore
index f5967c5..598c405 100644
--- a/docs/.gitignore
+++ b/docs/.gitignore
@@ -1,10 +1,12 @@
# Sphinx build outputs
_build/
-_static/
-_templates/
# Generated files
*.pyc
__pycache__/
.DS_Store
Thumbs.db
+
+# Note: _static/ and _templates/ are NOT ignored
+# because they contain source files for the documentation
+# (custom templates and static assets like switcher.json)
diff --git a/docs/Makefile b/docs/Makefile
index 73a28c7..37a7e36 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -8,11 +8,46 @@ SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
+# i18n settings
+LANGUAGES = en zh_CN
+
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+ @echo ""
+ @echo "i18n targets:"
+ @echo " gettext to generate .pot files for translation"
+ @echo " update-po to update .po files from .pot files"
+ @echo " html-all to build HTML documentation for all languages"
+ @echo " html-zh to build HTML documentation for Chinese only"
+
+.PHONY: help Makefile gettext update-po html-all html-zh
+
+# Generate .pot files for translation
+gettext:
+ @$(SPHINXBUILD) -b gettext "$(SOURCEDIR)" "$(BUILDDIR)/gettext" $(SPHINXOPTS) $(O)
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/gettext."
+
+# Update .po files from .pot files
+update-po: gettext
+ sphinx-intl update -p "$(BUILDDIR)/gettext" -l zh_CN
+ @echo "Update finished. Translation files are in locale/zh_CN/LC_MESSAGES/."
+
+# Build HTML documentation for all languages
+html-all:
+ @echo "Building English documentation..."
+ @$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) $(O)
+ @echo "Building Chinese documentation..."
+ @$(SPHINXBUILD) -b html -D language=zh_CN "$(SOURCEDIR)" "$(BUILDDIR)/html/zh_CN" $(SPHINXOPTS) $(O)
+ @echo ""
+ @echo "Build finished. HTML documentation for all languages is in $(BUILDDIR)/html/."
-.PHONY: help Makefile
+# Build HTML documentation for Chinese only
+html-zh:
+ @echo "Building Chinese documentation..."
+ @$(SPHINXBUILD) -b html -D language=zh_CN "$(SOURCEDIR)" "$(BUILDDIR)/html/zh_CN" $(SPHINXOPTS) $(O)
+ @echo ""
+ @echo "Build finished. Chinese HTML documentation is in $(BUILDDIR)/html/zh_CN/."
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
diff --git a/docs/_static/switcher.json b/docs/_static/switcher.json
new file mode 100644
index 0000000..c0db263
--- /dev/null
+++ b/docs/_static/switcher.json
@@ -0,0 +1,12 @@
+[
+ {
+ "name": "English",
+ "version": "en",
+ "url": "https://owenyou.github.io/dftt_timecode/"
+ },
+ {
+ "name": "中文 (简体)",
+ "version": "zh_CN",
+ "url": "https://owenyou.github.io/dftt_timecode/zh_CN/"
+ }
+]
diff --git a/docs/_templates/language-switcher.html b/docs/_templates/language-switcher.html
new file mode 100644
index 0000000..d5fe6ae
--- /dev/null
+++ b/docs/_templates/language-switcher.html
@@ -0,0 +1,31 @@
+{# Language switcher dropdown for the navigation bar #}
+
+
+
+
+ {% if language == 'en' %}
+ English
+ {% else %}
+ {# From zh_CN to en: go up one level #}
+ English
+ {% endif %}
+
+
+ {% if language == 'zh-CN' or language == 'zh_CN' %}
+ 中文 (简体)
+ {% else %}
+ {# From en to zh_CN: go into zh_CN subdirectory #}
+ 中文 (简体)
+ {% endif %}
+
+
+
diff --git a/docs/changelog.rst b/docs/changelog.rst
index cfc00b6..fc0a4a8 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,50 +1,2 @@
-Changelog
-=========
-
-Version 0.0.15a1 (Pre-Alpha)
------------------------------
-
-Current development version.
-
-Features
-~~~~~~~~
-
-- Core DfttTimecode class with multiple format support
-- DfttTimeRange class for time range operations
-- High frame rate support (0.01-999.99 fps)
-- Drop-frame and non-drop-frame timecode support
-- Strict mode for 24-hour cycling
-- Comprehensive operator overloading
-- High-precision Fraction-based internal storage
-
-Supported Formats
-~~~~~~~~~~~~~~~~~
-
-- SMPTE (DF/NDF)
-- SRT (SubRip)
-- FFMPEG
-- FCPX (Final Cut Pro X)
-- DLP (Digital Cinema)
-- Frame count
-- Timestamp
-
-Version 0.0.14
---------------
-
-Previous stable release on PyPI.
-
-Earlier Versions
-----------------
-
-See the Git history for detailed changes in earlier versions.
-
-Future Plans
-------------
-
-Planned features for future releases:
-
-- Additional timecode format support
-- Enhanced time range operations
-- Performance optimizations
-- Extended validation and error handling
-- Additional utility functions for common workflows
+.. include:: ../CHANGELOG.md
+ :parser: myst_parser.sphinx_
diff --git a/docs/conf.py b/docs/conf.py
index 503052f..4e7b414 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,11 +48,28 @@
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
'sphinx.ext.autosummary',
+ 'myst_parser',
]
templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+# -- Internationalization (i18n) configuration -------------------------------
+# https://www.sphinx-doc.org/en/master/usage/advanced/intl.html
+
+# Default language (English)
+language = 'en'
+
+# Directory path for message catalogs
+locale_dirs = ['locale/']
+
+# Generate .pot files with message catalogs for each document
+gettext_compact = False
+
+# Additional languages for documentation
+# This is used by the language switcher
+gettext_additional_targets = ['index']
+
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
@@ -66,15 +83,18 @@
"show_toc_level": 2,
"navbar_align": "left",
"navigation_with_keys": False,
- "show_nav_level": 2, # Show navigation levels in sidebar
"navigation_depth": 4,
"collapse_navigation": False, # Keep navigation expanded
"logo": {
"text": "DFTT Timecode",
},
- "navbar_end": ["navbar-icon-links"],
+ "navbar_end": ["navbar-icon-links", "language-switcher"],
"primary_sidebar_end": [], # Remove primary sidebar content
"show_nav_level": 0, # Hide navigation levels
+ "switcher": {
+ "json_url": "https://owenyou.github.io/dftt_timecode/_static/switcher.json",
+ "version_match": os.environ.get("READTHEDOCS_LANGUAGE", language),
+ },
}
# Disable the left sidebar navigation
@@ -130,3 +150,12 @@
# -- Options for autosummary ------------------------------------------------
# Disable autosummary generation to avoid duplicate documentation
autosummary_generate = False
+
+# -- Options for MyST-Parser ------------------------------------------------
+# Enable markdown files to be parsed by Sphinx
+myst_enable_extensions = [
+ "colon_fence", # ::: syntax for directives
+ "deflist", # Definition lists
+ "html_image", # HTML image syntax
+]
+myst_heading_anchors = 3 # Auto-generate anchors for headings up to level 3
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 8a0f8e7..51436fa 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -14,13 +14,6 @@ Getting Started
git clone https://github.com/YOUR_USERNAME/dftt_timecode.git
cd dftt_timecode
-3. Install development dependencies:
-
- .. code-block:: bash
-
- pip install -r requirements.txt
- pip install -e .
-
Development Workflow
--------------------
@@ -31,10 +24,14 @@ Create a virtual environment and install dependencies:
.. code-block:: bash
- python3 -m venv venv
- source venv/bin/activate # On Windows: venv\Scripts\activate
- pip install -r requirements.txt
- pip install -e .
+ uv sync
+
+This command will:
+
+- Create a virtual environment (if not already present)
+- Install all dependencies from ``pyproject.toml``
+- Install the package in editable mode
+- Generate/update ``uv.lock`` for reproducible builds
Running Tests
~~~~~~~~~~~~~
@@ -43,19 +40,19 @@ Run all tests:
.. code-block:: bash
- pytest
+ uv run pytest
Run tests with verbose output:
.. code-block:: bash
- pytest -v -s
+ uv run pytest -v -s
Run specific test file:
.. code-block:: bash
- pytest test/test_dftt_timecode.py
+ uv run pytest test/test_dftt_timecode.py
Code Style
----------
@@ -92,7 +89,231 @@ Update documentation when adding new features:
.. code-block:: bash
cd docs
- sphinx-build -b html . _build
+ uv run make html
+
+Contributing Translations
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We welcome contributions to documentation translations! Currently we support:
+
+- **English** (primary language)
+- **中文 (Simplified Chinese)**
+
+How to Contribute Translations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+**Adding new translations to existing languages:**
+
+1. Navigate to the translation files:
+
+ .. code-block:: bash
+
+ cd docs/locale/zh_CN/LC_MESSAGES/
+
+2. Edit the ``.po`` files to add or improve translations:
+
+ .. code-block:: po
+
+ #: ../../quickstart.rst:2
+ msgid "Quick Start"
+ msgstr "快速开始"
+
+3. Build and preview your translations:
+
+ .. code-block:: bash
+
+ cd docs
+ uv run make html-zh # Build Chinese only
+ uv run make html-all # Build all languages
+
+4. Preview locally:
+
+ .. code-block:: bash
+
+ cd docs/_build/html
+ python -m http.server 8000
+ # Visit http://localhost:8000/zh_CN/
+
+**Adding a new language:**
+
+1. Generate translation files for your language:
+
+ .. code-block:: bash
+
+ cd docs
+ uv run sphinx-intl update -p _build/gettext -l
+ # e.g., for Japanese: -l ja
+
+2. Update ``docs/Makefile`` to include the new language in the ``LANGUAGES`` variable
+
+3. Update ``docs/_static/switcher.json`` to add your language option
+
+4. Update the language switcher template in ``docs/_templates/language-switcher.html``
+
+5. Translate the ``.po`` files in ``locale//LC_MESSAGES/``
+
+6. Build and test your translation
+
+**Translation Guidelines:**
+
+- **User documentation** (installation, quickstart, user guide): Translate everything
+- **API documentation**: Translate page titles and main descriptions, but keep technical details (class names, method names, parameters) in English
+- **Changelog**: Translate section headers, but keep technical change entries in English
+- **Code examples**: Keep code and variable names in English
+- **Technical terms**: Use consistent translations (see the translation guide in ``docs/I18N_README.md``)
+
+**Updating translations when source changes:**
+
+When documentation source files are updated, translations need to be updated:
+
+.. code-block:: bash
+
+ cd docs
+ uv run make gettext # Generate new translation templates
+ uv run make update-po # Update .po files with new strings
+ # Edit .po files to translate new or updated strings
+ uv run make html-all # Rebuild documentation
+
+**Translation System Overview**
+
+The project uses Sphinx with ``sphinx-intl`` for internationalization. The system uses gettext ``.po`` (Portable Object) files for translations, which is the industry standard for software localization.
+
+**File Structure:**
+
+::
+
+ docs/
+ ├── locale/ # Translation files directory
+ │ └── zh_CN/
+ │ └── LC_MESSAGES/
+ │ ├── index.po # Translations for index.rst
+ │ ├── quickstart.po
+ │ ├── user_guide.po
+ │ └── api/
+ │ ├── dftt_timecode.po
+ │ ├── dftt_timerange.po
+ │ └── error.po
+ ├── _build/
+ │ └── gettext/ # Generated .pot template files (don't commit)
+ └── _templates/
+ └── language-switcher.html # Language switcher dropdown widget
+
+**Detailed Translation Workflow:**
+
+1. **Generate translation templates** (when source docs change):
+
+ .. code-block:: bash
+
+ cd docs
+ uv run make gettext
+
+ This creates ``.pot`` files in ``_build/gettext/`` containing all translatable strings.
+
+2. **Update translation files**:
+
+ .. code-block:: bash
+
+ cd docs
+ uv run make update-po
+
+ This updates ``.po`` files in ``locale/zh_CN/LC_MESSAGES/`` with new strings while preserving existing translations.
+
+3. **Translate the strings**:
+
+ Open ``.po`` files and add translations:
+
+ .. code-block:: po
+
+ #: ../../index.rst:70
+ msgid "User Guide"
+ msgstr "用户指南"
+
+ #: ../../index.rst:78
+ msgid "API Reference"
+ msgstr "API 参考"
+
+ **Translation Tips:**
+
+ - Each ``msgid`` contains the original English text
+ - Add your translation in the corresponding ``msgstr`` field
+ - Preserve formatting codes like ``{0}``, ``%s``, etc.
+ - Keep technical terms (class/function names) untranslated
+ - Use tools like `Poedit `_ for easier editing
+
+4. **Build and test**:
+
+ .. code-block:: bash
+
+ cd docs
+ uv run make html-zh # Build Chinese only
+ uv run make html-all # Build all languages
+
+ Preview the result:
+
+ .. code-block:: bash
+
+ cd docs/_build/html
+ python -m http.server 8000
+ # Visit http://localhost:8000/zh_CN/
+
+5. **Commit your changes**:
+
+ .. code-block:: bash
+
+ git add locale/
+ git commit -m "Update Chinese translation for user guide"
+
+**Important Makefile Commands:**
+
+- ``make gettext``: Generate ``.pot`` template files from source ``.rst`` files
+- ``make update-po``: Update ``.po`` files from ``.pot`` templates
+- ``make html``: Build English documentation only
+- ``make html-zh``: Build Chinese documentation only
+- ``make html-all``: Build all language versions
+
+**Common Issues and Solutions:**
+
+**Translations not showing:**
+
+1. Ensure ``.po`` files have non-empty ``msgstr`` values
+2. Rebuild with ``uv run make html-all``
+3. Clear browser cache or use incognito mode
+
+**New strings not appearing in .po files:**
+
+1. Run ``uv run make gettext`` to regenerate ``.pot`` files
+2. Run ``uv run make update-po`` to update ``.po`` files
+3. Check that your source ``.rst`` files are included in the build
+
+**Language switcher not working:**
+
+1. Verify ``_templates/language-switcher.html`` exists
+2. Ensure target language HTML was built in correct subdirectory (``_build/html/zh_CN/``)
+
+**Best Practices:**
+
+- **Commit ``.po`` files**: Always commit updated ``.po`` files to version control
+- **Don't commit ``.pot`` files**: These are generated artifacts in ``_build/gettext/``
+- **Incremental translation**: It's okay to commit partially translated ``.po`` files; untranslated strings display in English
+- **Review before push**: Build and preview locally before pushing translations
+- **Consistent terminology**: Use consistent translations for technical terms across all pages
+- **Keep source in sync**: Run ``make update-po`` regularly to sync with source changes
+
+**Automated Deployment:**
+
+Documentation is automatically built and deployed via GitHub Actions when pushed to ``main``:
+
+- Workflow: ``.github/workflows/docs.yml``
+- Build command: ``uv run make html-all``
+- Deployment: GitHub Pages at https://owenyou.github.io/dftt_timecode/
+
+When you push translated ``.po`` files to the ``main`` branch (via ``dev`` merge), the multilingual documentation is automatically rebuilt and deployed.
+
+**Additional Resources:**
+
+- `Sphinx Internationalization `_
+- `sphinx-intl Documentation `_
+- `GNU gettext Documentation `_
Submitting Changes
------------------
diff --git a/docs/index.rst b/docs/index.rst
index 46d575a..ab847ca 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -14,8 +14,6 @@ dftt_timecode
Python timecode library for film and TV industry, with high frame rate support and comprehensive features.
-为影视行业设计的Python时码库,支持HFR高帧率以及其他丰富的功能。
-
DFTT stands for the Department of Film and TV Technology of Beijing Film Academy.
Features
diff --git a/docs/locale/zh_CN/LC_MESSAGES/README.mo b/docs/locale/zh_CN/LC_MESSAGES/README.mo
new file mode 100644
index 0000000..de59310
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/README.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/README.po b/docs/locale/zh_CN/LC_MESSAGES/README.po
new file mode 100644
index 0000000..8f030e2
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/README.po
@@ -0,0 +1,148 @@
+# DFTT Timecode Documentation Chinese Translation
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 12:15+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../README.md:1
+msgid "Documentation"
+msgstr "文档"
+
+#: ../../README.md:3
+msgid "This directory contains the Sphinx documentation for dftt_timecode."
+msgstr "此目录包含 dftt_timecode 的 Sphinx 文档。"
+
+#: ../../README.md:5
+msgid "Building Documentation Locally"
+msgstr "本地构建文档"
+
+#: ../../README.md:7
+msgid "Prerequisites"
+msgstr "前提条件"
+
+#: ../../README.md:9
+msgid "Install the required dependencies:"
+msgstr "安装所需的依赖:"
+
+#: ../../README.md:15
+msgid "Build HTML Documentation"
+msgstr "构建 HTML 文档"
+
+#: ../../README.md:17
+msgid "On Unix/macOS:"
+msgstr "在 Unix/macOS 上:"
+
+#: ../../README.md:24
+msgid "On Windows:"
+msgstr "在 Windows 上:"
+
+#: ../../README.md:31
+msgid "The built documentation will be available in `docs/_build/html/`."
+msgstr "构建的文档将在 `docs/_build/html/` 中提供。"
+
+#: ../../README.md:33
+msgid "View Documentation"
+msgstr "查看文档"
+
+#: ../../README.md:35
+msgid "Open `docs/_build/html/index.html` in your web browser."
+msgstr "在 Web 浏览器中打开 `docs/_build/html/index.html`。"
+
+#: ../../README.md:37
+msgid "Other Build Formats"
+msgstr "其他构建格式"
+
+#: ../../README.md:45
+msgid "Automatic Deployment"
+msgstr "自动部署"
+
+#: ../../README.md:47
+msgid ""
+"Documentation is automatically built and deployed to GitHub Pages when "
+"changes are pushed to the main branch."
+msgstr "当更改推送到主分支时,文档会自动构建并部署到 GitHub Pages。"
+
+#: ../../README.md:49
+msgid ""
+"The deployment is handled by the GitHub Actions workflow in "
+"`.github/workflows/docs.yml`."
+msgstr "部署由 `.github/workflows/docs.yml` 中的 GitHub Actions 工作流处理。"
+
+#: ../../README.md:51
+msgid "Documentation Structure"
+msgstr "文档结构"
+
+#: ../../README.md:53
+msgid "`index.rst` - Home page"
+msgstr "`index.rst` - 主页"
+
+#: ../../README.md:54
+msgid "`installation.rst` - Installation instructions"
+msgstr "`installation.rst` - 安装说明"
+
+#: ../../README.md:55
+msgid "`quickstart.rst` - Quick start guide"
+msgstr "`quickstart.rst` - 快速入门指南"
+
+#: ../../README.md:56
+msgid "`user_guide.rst` - Comprehensive user guide"
+msgstr "`user_guide.rst` - 综合用户指南"
+
+#: ../../README.md:57
+msgid "`api/` - API reference documentation"
+msgstr "`api/` - API 参考文档"
+
+#: ../../README.md:58
+msgid "`contributing.rst` - Contributing guidelines"
+msgstr "`contributing.rst` - 贡献指南"
+
+#: ../../README.md:59
+msgid "`changelog.rst` - Version history"
+msgstr "`changelog.rst` - 版本历史"
+
+#: ../../README.md:60
+msgid "`conf.py` - Sphinx configuration"
+msgstr "`conf.py` - Sphinx 配置"
+
+#: ../../README.md:61
+msgid "`_static/` - Static files (CSS, images, etc.)"
+msgstr "`_static/` - 静态文件(CSS、图片等)"
+
+#: ../../README.md:62
+msgid "`_templates/` - Custom templates"
+msgstr "`_templates/` - 自定义模板"
+
+#: ../../README.md:64
+msgid "Writing Documentation"
+msgstr "编写文档"
+
+#: ../../README.md:66
+msgid "Documentation is written in reStructuredText (RST) format"
+msgstr "文档以 reStructuredText(RST)格式编写"
+
+#: ../../README.md:67
+msgid "API documentation is auto-generated from docstrings using Sphinx autodoc"
+msgstr "API 文档使用 Sphinx autodoc 从文档字符串自动生成"
+
+#: ../../README.md:68
+msgid "Follow the existing style and structure when adding new pages"
+msgstr "添加新页面时遵循现有的风格和结构"
+
+#: ../../README.md:69
+msgid "Build and preview locally before committing changes"
+msgstr "在提交更改之前在本地构建和预览"
diff --git a/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timecode.mo b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timecode.mo
new file mode 100644
index 0000000..f7243b5
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timecode.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timecode.po b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timecode.po
new file mode 100644
index 0000000..5c86dee
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timecode.po
@@ -0,0 +1,776 @@
+# DFTT Timecode Documentation Chinese Translation - API DfttTimecode Module
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+# Note: API documentation keeps technical details in English for accuracy
+# Only translating main page titles
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 12:30+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../api/dftt_timecode.rst:2
+msgid "DfttTimecode API"
+msgstr "DfttTimecode API"
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:1 of
+msgid "Bases: :py:class:`object`"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:1 of
+msgid "High-precision timecode class for film and television production."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:3 of
+msgid ""
+"DfttTimecode provides frame-accurate timecode representation with support"
+" for multiple professional formats, high frame rates (0.01-999.99 fps), "
+"drop-frame compensation, and comprehensive arithmetic operations."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:7 of
+msgid ""
+"The class uses :class:`fractions.Fraction` internally for precise "
+"timestamp calculations, ensuring accuracy even with complex operations "
+"and format conversions."
+msgstr ""
+
+#: ../../api/dftt_timecode.rst
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ne__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__rmul__ of
+msgid "Parameters"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:10 of
+msgid ""
+"The timecode value in various supported formats: - str: Timecode string "
+"(e.g., '01:00:00:00', '01:00:00,000') - int: Frame count (with "
+"timecode_type='frame') or seconds (with timecode_type='time') - float: "
+"Timestamp in seconds - Fraction: Precise timestamp as rational number - "
+"tuple/list: Two-element [numerator, denominator] for rational time - "
+"DfttTimecode: Returns the same instance (no copy)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:17 of
+msgid ""
+"Format type of the timecode value. Use 'auto' for automatic detection. "
+"See :data:`TimecodeType` for available formats. Defaults to 'auto'."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:19 of
+msgid ""
+"Frame rate in frames per second. Supports 0.01-999.99 fps. Defaults to "
+"24.0."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:20 of
+msgid ""
+"Enable drop-frame compensation for NTSC-compatible frame rates (29.97, "
+"59.94, 119.88 fps and their multiples). Defaults to False."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:22 of
+msgid ""
+"Enable 24-hour wraparound mode. When True, timecodes automatically cycle "
+"within 0-24 hour range (e.g., 25:00:00:00 becomes 01:00:00:00). Defaults "
+"to True."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:27 of
+msgid "Current timecode format type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode of
+msgid "type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:29 of
+msgid "str"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:33 of
+msgid "Frame rate in frames per second"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:35
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:59 of
+msgid "float"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:39 of
+msgid "Whether drop-frame compensation is enabled"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:41
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:47 of
+msgid "bool"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:45 of
+msgid "Whether 24-hour strict mode is enabled"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:51 of
+msgid "Total frame count from zero"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:53 of
+msgid "int"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:57 of
+msgid "Total seconds from zero"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:63 of
+msgid "High-precision timestamp as Fraction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:65 of
+msgid "Fraction"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__ of
+msgid "Raises"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:67 of
+msgid "When initialization parameters are incompatible"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:68 of
+msgid "When timecode type doesn't match the value format"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:69 of
+msgid "When timecode value is invalid for the given parameters"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:32
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:72
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__add__:15
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__:16
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__mul__:11
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__neg__:12
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__sub__:15
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__truediv__:11
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.get_audio_sample_count:12
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_fps:12
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_strict:10
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:13
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:16 of
+msgid "Examples"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:73 of
+msgid "Create from SMPTE timecode string::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:79 of
+msgid "Create with automatic format detection::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:85 of
+msgid "Create from frame count::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:91 of
+msgid "Create with drop-frame compensation::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:97 of
+msgid "Arithmetic operations::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:107 of
+msgid "Format conversion::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:117 of
+msgid "Timecode objects are immutable. All operations return new instances."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:118 of
+msgid ""
+"The internal timestamp uses :class:`fractions.Fraction` for maximum "
+"precision."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:119 of
+msgid "Drop-frame compensation is automatically validated against frame rate."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:120 of
+msgid "Negative timecodes are supported with a leading minus sign."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:124 of
+msgid ":class:`DfttTimeRange`: For working with time intervals"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:125 of
+msgid ":mod:`dftt_timecode.pattern`: Regex patterns for format validation"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode:126 of
+msgid ":mod:`dftt_timecode.error`: Custom exception classes"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.type:1 of
+msgid "Get the current timecode format type."
+msgstr ""
+
+#: ../../api/dftt_timecode.rst
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__float__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__int__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ne__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__neg__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__repr__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__rmul__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__str__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.fps
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.framecount
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_drop_frame
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_strict
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.precise_timestamp
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timestamp
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.type of
+msgid "Returns"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.type:3 of
+msgid "The timecode format type (e.g., 'smpte', 'srt', 'ffmpeg')"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__float__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__int__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ne__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__neg__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__repr__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__rmul__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__str__
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.fps
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.framecount
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_drop_frame
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_strict
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.precise_timestamp
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timestamp
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.type of
+msgid "Return type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__float__:7
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__int__:7
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__:16
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ne__:9
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__:11
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__repr__:7
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__rmul__:9
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__str__:7
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.fps:7
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.framecount:7
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_drop_frame:12
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_strict:9
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.precise_timestamp:12
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timestamp:7
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.type:7 of
+msgid "Example"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.fps:1 of
+msgid "Get the frame rate in frames per second."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.fps:3 of
+msgid "The frame rate"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_drop_frame:1 of
+msgid "Check if drop-frame compensation is enabled."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_drop_frame:3 of
+msgid "True if drop-frame mode is enabled, False otherwise"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_drop_frame:8 of
+msgid ""
+"Drop-frame is automatically enabled for NTSC-compatible frame rates "
+"(29.97, 59.94, 119.88 and their multiples) when drop_frame=True."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_strict:1 of
+msgid "Check if 24-hour strict mode is enabled."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_strict:3 of
+msgid "True if strict mode is enabled, False otherwise"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.is_strict:6 of
+msgid "In strict mode, timecodes automatically wrap around at 24 hours."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.framecount:1 of
+msgid "Get the total frame count from zero."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.framecount:3 of
+msgid "The frame number (zero-indexed)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timestamp:1 of
+msgid "Get the timestamp in seconds from zero."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timestamp:3 of
+msgid "The timestamp in seconds (rounded to 5 decimal places)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.precise_timestamp:1 of
+msgid "Get the high-precision timestamp as a Fraction."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.precise_timestamp:3 of
+msgid "The precise timestamp for exact calculations"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.precise_timestamp:8 of
+msgid ""
+"This is the internal representation used for all calculations to maintain"
+" maximum precision."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:1 of
+msgid "Convert timecode to specified format and return as string."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:3 of
+msgid ""
+"Target timecode format. Use 'auto' to output in current format. Available"
+" formats: 'smpte', 'srt', 'dlp', 'ffmpeg', 'fcpx', 'frame', 'time'. "
+"Defaults to 'auto'."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:6 of
+msgid ""
+"For multi-part formats (SMPTE, SRT, DLP, FFMPEG), specify which part to "
+"return. 0 returns the complete timecode string, 1-4 return individual "
+"parts (hours, minutes, seconds, frames/subseconds). Defaults to 0."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:10 of
+msgid "The formatted timecode string"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:13 of
+msgid "If dest_type is not a valid timecode format"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:29 of
+msgid "For 'auto', outputs in the current timecode type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.timecode_output:30 of
+msgid "Falls back to SMPTE format if dest_type is invalid"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_fps:1 of
+msgid "Change the frame rate of the timecode."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_fps:3 of
+msgid "Target frame rate in frames per second (0.01-999.99)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_fps:4 of
+msgid ""
+"If True, rounds the internal timestamp to the nearest frame at the new "
+"frame rate. If False, preserves exact timestamp. Defaults to True."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_fps:8
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_strict:6
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:9 of
+msgid "Self reference for method chaining"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_fps:20 of
+msgid "This method modifies the object in place and returns self for chaining."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:1 of
+msgid "Change the internal timecode format type."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:3 of
+msgid ""
+"Target timecode format type. Available formats: 'smpte', 'srt', 'dlp', "
+"'ffmpeg', 'fcpx', 'frame', 'time'. Defaults to 'smpte'."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:6 of
+msgid ""
+"If True, rounds the timestamp to match the precision of the new format. "
+"If False, preserves exact timestamp. Defaults to True."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:23 of
+msgid "This changes the internal type, affecting :meth:`__str__` output"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:24 of
+msgid ""
+"Rounding adjusts precision to match format (e.g., SRT has millisecond "
+"precision)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_type:25 of
+msgid "Invalid types are ignored with a warning"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_strict:1 of
+msgid "Change the 24-hour strict mode setting."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_strict:3 of
+msgid ""
+"If True, enables 24-hour wraparound (timecodes cycle within 0-24 hours). "
+"If False, allows timecodes beyond 24 hours. Defaults to True."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.set_strict:18 of
+msgid ""
+"Changing strict mode recalculates the internal timestamp with the new "
+"mode."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.get_audio_sample_count:1 of
+msgid "Calculate the number of audio samples at the given sample rate."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.get_audio_sample_count:3 of
+msgid ""
+"Converts the timecode to audio sample count for audio synchronization. "
+"Uses high-precision rational arithmetic to avoid rounding errors."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.get_audio_sample_count:6 of
+msgid "Audio sample rate in Hz (e.g., 44100, 48000, 96000)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.get_audio_sample_count:8 of
+msgid "The number of audio samples (floored to nearest integer)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.get_audio_sample_count:20 of
+msgid ""
+"Uses floor division to ensure sample count doesn't exceed the timecode "
+"position."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__repr__:1 of
+msgid "Return detailed string representation of the timecode object."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__repr__:3 of
+msgid "Detailed representation including timecode, type, fps, and mode flags"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__str__:1 of
+msgid "Return timecode as formatted string in current type."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__str__:3 of
+msgid "Timecode string in the current format type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__add__:1 of
+msgid "Add timecode with another timecode, frame count, or timestamp."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__add__:3 of
+msgid ""
+"Value to add. Can be: - DfttTimecode: Adds timestamps (must have same fps"
+" and drop_frame) - int: Treats as frame count to add - float: Treats as "
+"seconds to add - Fraction: Treats as precise seconds to add"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__add__:9
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__:7 of
+msgid "New timecode object with the sum"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__add__:12
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__sub__:12 of
+msgid ""
+"If fps or drop_frame don't match between timecodes, or if other is an"
+" unsupported type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__add__:30 of
+msgid "Result inherits the format type of the left operand"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__add__:31 of
+msgid "If either operand has strict=True, result will have strict=True"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__:1 of
+msgid "Reflected addition (called when left operand doesn't support +)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__:3 of
+msgid "Implements commutative property: other + timecode == timecode + other"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__radd__:5 of
+msgid "Value to add (int, float, or Fraction)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__sub__:1 of
+msgid "Subtract timecode, frame count, or timestamp from this timecode."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__sub__:3 of
+msgid ""
+"Value to subtract. Can be: - DfttTimecode: Subtracts timestamps (must "
+"have same fps and drop_frame) - int: Treats as frame count to subtract - "
+"float: Treats as seconds to subtract - Fraction: Treats as precise "
+"seconds to subtract"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__sub__:9 of
+msgid "New timecode object with the difference"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__sub__:24 of
+msgid "Result can be negative, which will be displayed with a leading minus sign."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__mul__:1 of
+msgid "Multiply timecode by a numeric factor."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__mul__:3
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__rmul__:3 of
+msgid "Multiplication factor (int, float, or Fraction)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__mul__:5
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__rmul__:5 of
+msgid "New timecode with timestamp multiplied by factor"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__mul__:8 of
+msgid ""
+"If attempting to multiply two timecodes or if other is an unsupported"
+" type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__mul__:20 of
+msgid ""
+"Multiplying two timecode objects together is not allowed and will raise "
+"an error."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__rmul__:1 of
+msgid "Reflected multiplication (implements commutative property)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__truediv__:1 of
+msgid "Divide timecode by a numeric factor."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__truediv__:3 of
+msgid "Division factor (int, float, or Fraction)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__truediv__:5 of
+msgid "New timecode with timestamp divided by factor"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__truediv__:8 of
+msgid "If attempting to divide timecodes or if other is an unsupported type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__truediv__:17 of
+msgid "Dividing two timecode objects is not allowed and will raise an error."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__:1 of
+msgid "Check equality with another timecode or numeric value."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__:3
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__:3 of
+msgid ""
+"Value to compare. Can be: - DfttTimecode: Compares timestamps (must have "
+"same fps) - int: Compares as frame count - float: Compares as seconds - "
+"Fraction: Compares as precise seconds"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__:9 of
+msgid "True if values are equal (within 5 decimal places), False otherwise"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__:12
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__:12 of
+msgid "If comparing timecodes with different fps"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__eq__:13
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__:13 of
+msgid "If other is an unsupported type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ne__:1 of
+msgid "Check inequality with another timecode or numeric value."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ne__:3 of
+msgid "Value to compare (DfttTimecode, int, float, or Fraction)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ne__:5 of
+msgid "True if values are not equal, False otherwise"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__:1 of
+msgid "Check if this timecode is less than another value."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__lt__:9 of
+msgid "True if this timecode is less than other, False otherwise"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__le__:1 of
+msgid "Return self<=value."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__gt__:1 of
+msgid "Return self>value."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__ge__:1 of
+msgid "Return self>=value."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__neg__:1 of
+msgid "Return the negation of this timecode."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__neg__:3 of
+msgid "New timecode with negated timestamp"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__neg__:8 of
+msgid ""
+"In strict mode, negative timecodes wrap around within 24 hours. For "
+"example, -01:00:00:00 becomes 23:00:00:00 in strict mode."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__float__:1 of
+msgid "Convert timecode to float (seconds)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__float__:3 of
+msgid "The timestamp in seconds"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__int__:1 of
+msgid "Convert timecode to integer (frame count)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timecode.DfttTimecode.__int__:3 of
+msgid "The frame count"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:13
+msgid "Core Class"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:15
+msgid ""
+"The :class:`DfttTimecode` class is the main interface for working with "
+"timecodes in various formats."
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:18
+msgid "Supported Timecode Types"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:20
+msgid "The following timecode types are supported:"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:22
+msgid "**auto**: Automatic detection based on input format"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:23
+msgid ""
+"**smpte**: SMPTE timecode format (HH:MM:SS:FF or HH:MM:SS;FF for drop-"
+"frame)"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:24
+msgid "**srt**: SubRip subtitle format (HH:MM:SS,mmm)"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:25
+msgid "**ffmpeg**: FFmpeg format (HH:MM:SS.ff)"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:26
+msgid "**fcpx**: Final Cut Pro X format (frames/fps)"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:27
+msgid "**dlp**: DLP Cinema format (HH:MM:SS:FFF)"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:28
+msgid "**frame**: Frame count (integer)"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:29
+msgid "**time**: Timestamp in seconds (float)"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:35
+msgid "Basic Usage"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:49
+msgid "Format Conversion"
+msgstr ""
+
+#: ../../api/dftt_timecode.rst:60
+msgid "Arithmetic Operations"
+msgstr ""
+
diff --git a/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timerange.mo b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timerange.mo
new file mode 100644
index 0000000..85e41a8
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timerange.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timerange.po b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timerange.po
new file mode 100644
index 0000000..5a84cc4
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/api/dftt_timerange.po
@@ -0,0 +1,854 @@
+# DFTT Timecode Documentation Chinese Translation - API DfttTimeRange Module
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+# Note: API documentation keeps technical details in English for accuracy
+# Only translating main page titles
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 12:30+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../api/dftt_timerange.rst:2
+msgid "DfttTimeRange API"
+msgstr "DfttTimeRange API"
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:1 of
+msgid "Bases: :py:class:`object`"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:1 of
+msgid "High-precision timerange class for representing time intervals."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:3 of
+msgid ""
+"DfttTimeRange represents a time interval with a start point, duration, "
+"and direction. It provides comprehensive operations for manipulating time"
+" ranges including offset, extend, shorten, reverse, retime, intersection,"
+" and union operations."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:7 of
+msgid ""
+"The class uses :class:`fractions.Fraction` internally for precise "
+"calculations, ensuring frame-accurate operations even with complex "
+"interval manipulations."
+msgstr ""
+
+#: ../../api/dftt_timerange.rst
+msgid "Parameters"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:10 of
+msgid ""
+"Start timecode. Can be a DfttTimecode object or any value that can "
+"construct a DfttTimecode. Required if not using precise parameters."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:12 of
+msgid ""
+"End timecode. Can be a DfttTimecode object or any value that can "
+"construct a DfttTimecode. Required if not using precise parameters."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:14 of
+msgid ""
+"Direction of the timerange. True for forward (start < end), False for "
+"backward (start > end). Defaults to True."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:16 of
+msgid ""
+"Frame rate in frames per second. Used when constructing timecodes from "
+"non-timecode values. Defaults to 24.0."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:18 of
+msgid ""
+"Internal construction parameter - precise start time as Fraction. Use "
+"with precise_duration for direct construction."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:20 of
+msgid ""
+"Internal construction parameter - precise duration as Fraction. Use with "
+"start_precise_time for direct construction."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:22 of
+msgid ""
+"Enable 24-hour constraint mode. When True, the timerange duration cannot "
+"exceed 24 hours and midnight-crossing ranges are handled specially. "
+"Defaults to False."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:28
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.fps:1 of
+msgid "Frame rate of the timerange"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange of
+msgid "type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:30
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:66 of
+msgid "float"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:34
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.forward:1 of
+msgid "Direction of the timerange"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:36
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:42 of
+msgid "bool"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:40 of
+msgid "Whether 24-hour constraint is enabled"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:46 of
+msgid "Duration as high-precision Fraction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:48
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:54
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:60 of
+msgid "Fraction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:52 of
+msgid "Start time as high-precision Fraction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:58 of
+msgid "End time as high-precision Fraction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:64 of
+msgid "Duration in seconds (absolute value)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:70 of
+msgid "Duration in frames (absolute value)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:72 of
+msgid "int"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:76 of
+msgid "Start timecode object"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:78
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:84 of
+#, fuzzy
+msgid "DfttTimecode"
+msgstr "DfttTimeRange API"
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:82 of
+msgid "End timecode object"
+msgstr ""
+
+#: ../../api/dftt_timerange.rst
+msgid "Raises"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:86 of
+msgid "When creating zero-length or invalid timeranges"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:87 of
+msgid "When start and end timecodes have mismatched fps"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:88 of
+msgid ""
+"When neither (start_tc, end_tc) nor (start_precise_time, "
+"precise_duration) are provided"
+msgstr ""
+
+#: ../../api/dftt_timerange.rst:18
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:91
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:20
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.contains:16
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:19
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:16
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.offset:18
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:18
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:10
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:14
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:18
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:20
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:18 of
+msgid "Examples"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:92 of
+msgid "Create from two timecodes::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:100 of
+msgid "Create backward timerange::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:108 of
+msgid "Operations::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:118 of
+msgid "Iteration::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:128 of
+msgid "Set operations::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:141 of
+msgid "Timerange objects are immutable. All operations return new instances."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:142 of
+msgid ""
+"The internal representation uses :class:`fractions.Fraction` for "
+"precision."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:143 of
+msgid "Forward and backward timeranges behave differently in some operations."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:144 of
+msgid "Zero-length timeranges are not allowed."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:148 of
+msgid ":class:`DfttTimecode`: For working with individual timecodes"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange:149 of
+msgid ":mod:`dftt_timecode.error`: Custom exception classes"
+msgstr ""
+
+#: ../../docstring
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.TIME_24H_SECONDS:1 of
+msgid "Constant representing 24 hours in seconds (86400)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.strict_24h:1 of
+msgid "Whether timerange is constrained to 24 hours"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.precise_duration:1 of
+msgid "Precise duration as Fraction to avoid calculation errors"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.start_precise_time:1 of
+msgid "Start time as precise Fraction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.end_precise_time:1 of
+msgid "End time as precise Fraction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.duration:1 of
+msgid "Duration in seconds"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.framecount:1 of
+msgid "Duration in frames"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.start:1 of
+msgid "Start timecode"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.end:1 of
+msgid "End timecode"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.offset:1 of
+msgid "Move timerange in time while preserving duration."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.offset:3 of
+msgid ""
+"Shifts the entire timerange by the specified offset amount without "
+"changing the duration. Both start and end points move by the same amount."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.offset:6 of
+msgid ""
+"Amount to offset the timerange. Can be: - float: Seconds to shift - int: "
+"Frames to shift (converted using current fps) - DfttTimecode: Uses the "
+"timecode's timestamp - str: Timecode string to parse"
+msgstr ""
+
+#: ../../api/dftt_timerange.rst
+msgid "Returns"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.offset:12 of
+msgid "New timerange with shifted start/end points"
+msgstr ""
+
+#: ../../api/dftt_timerange.rst
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__add__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__and__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__eq__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__ge__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__gt__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__iter__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__le__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__lt__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__mul__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__ne__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__or__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__repr__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__str__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__sub__
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__truediv__ of
+msgid "Return type"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.offset:15 of
+msgid "If offset_value cannot be parsed"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.offset:26 of
+msgid "In strict_24h mode, the new start time wraps around at 24 hours."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:1 of
+msgid "Extend duration (positive value increases duration)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:3 of
+msgid ""
+"Extends or shortens the timerange by modifying the end point while "
+"keeping the start point fixed. Positive values increase duration, "
+"negative values decrease it."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:7 of
+msgid ""
+"Amount to extend the duration. Can be: - int or float: Seconds to extend "
+"(positive) or shorten (negative) - DfttTimecode: Uses the timecode's "
+"timestamp - str: Timecode string to parse"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:12 of
+msgid "New timerange with modified duration"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:15 of
+msgid ""
+"If extension results in zero-length timerange or exceeds 24 hours in "
+"strict mode"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:16 of
+msgid "If extend_value cannot be parsed"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.extend:28 of
+msgid "The direction (forward/backward) affects how extension is applied."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:1 of
+msgid "Shorten duration (positive value decreases duration)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:3 of
+msgid ""
+"This is a convenience method that calls :meth:`extend` with a negated "
+"value. Shortens the timerange by modifying the end point while keeping "
+"the start fixed."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:6 of
+msgid ""
+"Amount to shorten the duration. Can be: - int or float: Seconds to "
+"shorten (positive decreases duration) - DfttTimecode: Uses the timecode's"
+" timestamp - str: Timecode string to parse"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:11 of
+msgid "New timerange with shortened duration"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:14 of
+msgid "If shortening results in zero-length timerange"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:15 of
+msgid "If shorten_value cannot be parsed"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.shorten:26 of
+msgid "Internally calls ``extend(-shorten_value)`` for numeric values."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:1 of
+msgid "Reverse direction of timerange."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:3 of
+msgid ""
+"Creates a new timerange with swapped start/end points and inverted "
+"direction. The duration magnitude remains the same, but the direction is "
+"flipped."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:6 of
+msgid "New timerange with reversed direction"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:24 of
+msgid "The new start becomes the old end"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:25 of
+msgid "The forward flag is flipped"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:26 of
+msgid "Duration magnitude is preserved"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.reverse:27 of
+msgid "This is useful for working with timeranges that play backward"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:1 of
+msgid "Change duration by multiplication factor."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:3 of
+msgid ""
+"Scales the timerange duration by the given factor while keeping the start"
+" point fixed. This is useful for time-stretching or speed-change "
+"operations."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:6 of
+msgid ""
+"Multiplication factor for the duration. Can be: - int or float: Factor to"
+" multiply duration by - Fraction: Precise rational factor Examples: 2.0 "
+"doubles duration, 0.5 halves it, 1.5 extends by 50%"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:11 of
+msgid "New timerange with scaled duration"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:14 of
+msgid "If retime_factor is not numeric"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:15 of
+msgid ""
+"If retime_factor is 0, or if result exceeds 24 hours in strict_24h "
+"mode"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:35
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:37
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:38 of
+msgid "Start point remains unchanged"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:38 of
+msgid "Commonly used for speed ramping or time-stretching effects"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:39 of
+msgid "Factor > 1 increases duration (slow down)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:40 of
+msgid "Factor < 1 decreases duration (speed up)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.retime:41 of
+msgid "Can also use the ``*`` operator for the same effect"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:1 of
+msgid "Separate timerange into multiple equal parts."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:3 of
+msgid ""
+"Divides the timerange into a specified number of equal-duration sub-"
+"ranges. All parts have the same duration and are contiguous (adjacent "
+"with no gaps)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:6 of
+msgid "Number of parts to divide the timerange into (must be >= 2)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:8 of
+msgid "List of timerange parts, ordered from start to end"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:11 of
+msgid "If num_parts is less than 2"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:31 of
+msgid "Each part has duration = original_duration / num_parts"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:32 of
+msgid "Parts are contiguous (no gaps or overlaps)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:33 of
+msgid "All parts inherit the same fps, forward direction, and strict_24h mode"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:34 of
+msgid "For backward timeranges, parts are still ordered from start to end"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.separate:35 of
+msgid "Useful for splitting work into parallel chunks or creating segments"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.contains:1 of
+msgid "Check if timerange contains another timerange or timecode."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.contains:3 of
+msgid ""
+"Item to check for containment. Can be: - DfttTimecode: Checks if timecode"
+" is within range - DfttTimeRange: Checks if entire timerange is contained"
+" - str, int, float: Converted to timecode for checking"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.contains:7 of
+msgid ""
+"If True, requires contained timerange to have same direction. Only "
+"applies when item is a DfttTimeRange. Defaults to False."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.contains:10 of
+msgid "True if item is contained within this timerange, False otherwise"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.contains:13 of
+msgid "If item cannot be converted to timecode"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.contains:27 of
+msgid "For backward timeranges, containment is checked accordingly."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:1 of
+msgid "Calculate intersection of two timeranges (AND operation)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:3 of
+msgid ""
+"Returns the overlapping portion of two timeranges. Both timeranges must "
+"have the same direction and frame rate."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:6 of
+msgid "Another DfttTimeRange to intersect with"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:8 of
+msgid "New timerange representing the intersection, or None if no overlap"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:15
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:11
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:15
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:13 of
+msgid "If other is not a DfttTimeRange"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:12 of
+msgid "If timeranges have different directions"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:16
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:13
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:16
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:15 of
+msgid "If timeranges have different frame rates"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:29 of
+msgid "Returns None if timeranges don't overlap"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.intersect:30
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:61 of
+msgid "Strict_24h is True only if both input timeranges have it enabled"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:1 of
+msgid "Calculate union of two timeranges (OR operation)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:3 of
+msgid ""
+"Combines two overlapping or adjacent timeranges into a single continuous "
+"timerange that spans from the earliest start to the latest end. Both "
+"timeranges must have the same direction and frame rate, and must either "
+"overlap or be adjacent (touching) with no gap between them."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:8 of
+msgid "Another DfttTimeRange to union with"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:10 of
+msgid "New timerange spanning both input ranges"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:14 of
+msgid ""
+"If timeranges have different directions, or if they are non-"
+"overlapping and non-adjacent (have a gap)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:19 of
+msgid "Overlapping timeranges::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:31 of
+msgid "Adjacent (touching) timeranges::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:41 of
+msgid "Using the | operator::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:49 of
+msgid "Non-adjacent timeranges (will fail)::"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:58 of
+msgid "Timeranges must overlap or be adjacent (no gap allowed)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:59 of
+msgid "The result spans from earliest start to latest end"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:60 of
+msgid "Direction must be the same for both timeranges"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:62 of
+msgid ""
+"This is a set operation, different from :meth:`add` which combines "
+"durations"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:63 of
+msgid "Can also use the ``|`` operator as a shorthand"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:64 of
+msgid "For checking overlap, use :meth:`intersect` first"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:68 of
+msgid ":meth:`intersect`: Get the overlapping portion (AND operation)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.union:69 of
+msgid ":meth:`add`: Add durations (different from union)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:1 of
+msgid "Add durations of two timeranges (direction-sensitive)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:3 of
+msgid ""
+"Combines the durations of two timeranges to create a new timerange with "
+"extended duration. The behavior depends on whether the timeranges have "
+"the same or opposite directions."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:7 of
+#, fuzzy
+msgid "Another DfttTimeRange to add"
+msgstr "DfttTimeRange API"
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:9 of
+msgid ""
+"New timerange with combined duration, same start point and direction "
+"as the original"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:11 of
+msgid "New timerange with combined duration, same start point"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:12
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:12 of
+msgid "and direction as the original"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:17
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:17 of
+msgid "If result is zero-length"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:33 of
+msgid "Same direction: durations are added (extend)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:34 of
+msgid "Opposite direction: durations are subtracted (shorten)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.add:36 of
+msgid "This is different from :meth:`union` which combines overlapping ranges"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:1 of
+msgid "Subtract durations of two timeranges (direction-sensitive)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:3 of
+msgid ""
+"Subtracts the duration of another timerange from this one to create a new"
+" timerange with reduced duration. The behavior depends on whether the "
+"timeranges have the same or opposite directions."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:7 of
+#, fuzzy
+msgid "Another DfttTimeRange to subtract"
+msgstr "DfttTimeRange API"
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:9 of
+msgid ""
+"New timerange with reduced duration, same start point and direction "
+"as the original"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:11 of
+msgid "New timerange with reduced duration, same start point"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:36 of
+msgid "Same direction: durations are subtracted (shorten)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:37 of
+msgid "Opposite direction: durations are added (extend)"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:39 of
+msgid "This is the inverse operation of :meth:`add`"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.subtract:40 of
+msgid "Can result in zero-length error if durations are equal"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__str__:1 of
+msgid "Return str(self)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__repr__:1 of
+msgid "Return repr(self)."
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__iter__:1 of
+msgid "Iterate through timecodes in the range"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__add__:1 of
+msgid "Add operator for timeranges"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__sub__:1 of
+msgid "Subtract operator for timeranges"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__mul__:1 of
+msgid "Multiply duration by factor"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__truediv__:1 of
+msgid "Divide duration by factor"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__and__:1 of
+msgid "Intersection operator"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__or__:1 of
+msgid "Union operator"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__eq__:1 of
+msgid "Equality comparison"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__ne__:1 of
+msgid "Inequality comparison"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__lt__:1 of
+msgid "Less than comparison based on start time"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__le__:1 of
+msgid "Less than or equal comparison"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__gt__:1 of
+msgid "Greater than comparison"
+msgstr ""
+
+#: dftt_timecode.core.dftt_timerange.DfttTimeRange.__ge__:1 of
+msgid "Greater than or equal comparison"
+msgstr ""
+
+#: ../../api/dftt_timerange.rst:13
+msgid "Core Class"
+msgstr ""
+
+#: ../../api/dftt_timerange.rst:15
+msgid ""
+"The :class:`DfttTimeRange` class represents a time range with start and "
+"end points, built on top of :class:`DfttTimecode`."
+msgstr ""
+
+#: ../../api/dftt_timerange.rst:21
+msgid "Basic Usage"
+msgstr ""
+
+#: ../../api/dftt_timerange.rst:36
+msgid "Checking Containment and Intersection"
+msgstr ""
+
diff --git a/docs/locale/zh_CN/LC_MESSAGES/api/error.mo b/docs/locale/zh_CN/LC_MESSAGES/api/error.mo
new file mode 100644
index 0000000..551d300
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/api/error.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/api/error.po b/docs/locale/zh_CN/LC_MESSAGES/api/error.po
new file mode 100644
index 0000000..6c9fc13
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/api/error.po
@@ -0,0 +1,270 @@
+# DFTT Timecode Documentation Chinese Translation - API Error Module
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+# Note: API documentation keeps technical details in English for accuracy
+# Only translating main descriptions and page titles
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 12:25+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../api/error.rst:2
+msgid "Error Handling"
+msgstr "错误处理"
+
+#: ../../api/error.rst:7
+msgid "Exception Classes"
+msgstr "异常类"
+
+#: ../../api/error.rst:9
+msgid ""
+"The dftt_timecode library defines custom exception classes for different "
+"error conditions."
+msgstr "dftt_timecode 库为不同的错误情况定义了自定义异常类。"
+
+#: ../../api/error.rst:12
+msgid "DFTTError"
+msgstr ""
+
+#: dftt_timecode.error.DFTTError:1 of
+msgid "Bases: :py:class:`Exception`"
+msgstr ""
+
+#: dftt_timecode.error.DFTTError:1 of
+#, fuzzy
+msgid "Base exception class for all DFTT Timecode library errors."
+msgstr "所有 dftt_timecode 错误的基础异常类。"
+
+#: dftt_timecode.error.DFTTError:3 of
+msgid "All custom exceptions in this library inherit from this base class."
+msgstr ""
+
+#: ../../api/error.rst:18
+msgid "Base exception class for all dftt_timecode errors."
+msgstr "所有 dftt_timecode 错误的基础异常类。"
+
+#: ../../api/error.rst:21
+msgid "DFTTTimecodeValueError"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeFPSError:1
+#: dftt_timecode.error.DFTTTimeRangeMethodError:1
+#: dftt_timecode.error.DFTTTimeRangeTypeError:1
+#: dftt_timecode.error.DFTTTimeRangeValueError:1
+#: dftt_timecode.error.DFTTTimecodeInitializationError:1
+#: dftt_timecode.error.DFTTTimecodeOperatorError:1
+#: dftt_timecode.error.DFTTTimecodeTypeError:1
+#: dftt_timecode.error.DFTTTimecodeValueError:1 of
+#, fuzzy
+msgid "Bases: :py:class:`~dftt_timecode.error.DFTTError`"
+msgstr "所有 dftt_timecode 错误的基础异常类。"
+
+#: dftt_timecode.error.DFTTTimecodeValueError:1 of
+#, fuzzy
+msgid "Raised when a timecode value is invalid or out of acceptable range."
+msgstr "当提供无效的时码值时抛出。"
+
+#: dftt_timecode.error.DFTTTimeRangeFPSError:3
+#: dftt_timecode.error.DFTTTimeRangeMethodError:3
+#: dftt_timecode.error.DFTTTimeRangeTypeError:3
+#: dftt_timecode.error.DFTTTimeRangeValueError:3
+#: dftt_timecode.error.DFTTTimecodeInitializationError:3
+#: dftt_timecode.error.DFTTTimecodeOperatorError:3
+#: dftt_timecode.error.DFTTTimecodeTypeError:3
+#: dftt_timecode.error.DFTTTimecodeValueError:3 of
+msgid "Examples include:"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeValueError:4 of
+msgid "Frame number exceeding the frame rate limit"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeValueError:5 of
+msgid "Invalid drop-frame timecode values"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeValueError:6 of
+msgid "Illegal timecode values for the given parameters"
+msgstr ""
+
+#: ../../api/error.rst:27
+msgid "Raised when an invalid timecode value is provided."
+msgstr "当提供无效的时码值时抛出。"
+
+#: ../../api/error.rst:30
+msgid "DFTTTimecodeInitializationError"
+msgstr ""
+
+#: ../../api/error.rst:36 dftt_timecode.error.DFTTTimecodeInitializationError:1
+#: of
+msgid "Raised when timecode initialization fails due to incompatible parameters."
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeInitializationError:4 of
+msgid "Drop-frame status mismatch with timecode format"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeInitializationError:5 of
+msgid "Incompatible timecode value and type combinations"
+msgstr ""
+
+#: ../../api/error.rst:39
+msgid "DFTTTimecodeTypeError"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeTypeError:1 of
+#, fuzzy
+msgid "Raised when a timecode type is invalid or incompatible."
+msgstr "当提供无效的时码值时抛出。"
+
+#: dftt_timecode.error.DFTTTimecodeTypeError:4 of
+msgid "Unknown timecode format type"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeTypeError:5 of
+msgid "Type mismatch between expected and actual timecode format"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeTypeError:6 of
+msgid "Invalid data type for timecode operations"
+msgstr ""
+
+#: ../../api/error.rst:45
+#, fuzzy
+msgid "Raised when an invalid timecode type is specified or type mismatch occurs."
+msgstr "当提供无效的时码值时抛出。"
+
+#: ../../api/error.rst:48
+msgid "DFTTTimecodeOperatorError"
+msgstr ""
+
+#: ../../api/error.rst:54 dftt_timecode.error.DFTTTimecodeOperatorError:1 of
+msgid ""
+"Raised when an arithmetic or comparison operation on timecode objects "
+"fails."
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeOperatorError:4 of
+msgid "Operations between timecodes with different frame rates"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeOperatorError:5 of
+msgid "Undefined operations (e.g., dividing number by timecode)"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimecodeOperatorError:6 of
+msgid "Invalid operand types for timecode arithmetic"
+msgstr ""
+
+#: ../../api/error.rst:57
+msgid "DFTTTimeRangeMethodError"
+msgstr ""
+
+#: ../../api/error.rst:63 dftt_timecode.error.DFTTTimeRangeMethodError:1 of
+msgid ""
+"Raised when a timerange method is called with invalid parameters or "
+"conditions."
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeMethodError:4 of
+msgid "Attempting to intersect/union timeranges with different directions"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeMethodError:5 of
+msgid "Invalid offset or extend values"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeMethodError:6 of
+msgid "Operations on non-overlapping, non-adjacent timeranges"
+msgstr ""
+
+#: ../../api/error.rst:66
+msgid "DFTTTimeRangeValueError"
+msgstr ""
+
+#: ../../api/error.rst:72 dftt_timecode.error.DFTTTimeRangeValueError:1 of
+msgid "Raised when a timerange value is invalid or out of acceptable range."
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeValueError:4 of
+msgid "Zero-length timerange"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeValueError:5 of
+msgid "Duration exceeding 24 hours in strict mode"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeValueError:6 of
+msgid "Invalid timerange separation parameters"
+msgstr ""
+
+#: ../../api/error.rst:75
+msgid "DFTTTimeRangeTypeError"
+msgstr ""
+
+#: ../../api/error.rst:81 dftt_timecode.error.DFTTTimeRangeTypeError:1 of
+msgid "Raised when a timerange type or operand type is invalid."
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeTypeError:4 of
+msgid "Invalid item type for contains check"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeTypeError:5 of
+msgid "Attempting to operate on non-timerange objects"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeTypeError:6 of
+msgid "Type mismatches in timerange operations"
+msgstr ""
+
+#: ../../api/error.rst:84
+msgid "DFTTTimeRangeFPSError"
+msgstr ""
+
+#: ../../api/error.rst:90 dftt_timecode.error.DFTTTimeRangeFPSError:1 of
+msgid "Raised when timerange operations fail due to frame rate mismatches."
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeFPSError:4 of
+msgid "FPS mismatch between start and end timecodes"
+msgstr ""
+
+#: dftt_timecode.error.DFTTTimeRangeFPSError:5 of
+msgid "Operations between timeranges with different frame rates"
+msgstr ""
+
+#: ../../api/error.rst:93
+msgid "Error Examples"
+msgstr ""
+
+#: ../../api/error.rst:96
+#, fuzzy
+msgid "Invalid Timecode Value"
+msgstr "当提供无效的时码值时抛出。"
+
+#: ../../api/error.rst:109
+msgid "Timecode Initialization Error"
+msgstr ""
+
+#: ../../api/error.rst:123
+msgid "Type Error"
+msgstr ""
+
+#: ../../api/error.rst:136
+msgid "Operator Error"
+msgstr ""
+
diff --git a/docs/locale/zh_CN/LC_MESSAGES/changelog.mo b/docs/locale/zh_CN/LC_MESSAGES/changelog.mo
new file mode 100644
index 0000000..756bb8b
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/changelog.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/changelog.po b/docs/locale/zh_CN/LC_MESSAGES/changelog.po
new file mode 100644
index 0000000..a51d06e
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/changelog.po
@@ -0,0 +1,348 @@
+# DFTT Timecode Documentation Chinese Translation
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 12:20+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../../CHANGELOG.md:1
+msgid "Changelog"
+msgstr "更新日志"
+
+#: ../../../CHANGELOG.md:3
+msgid "All notable changes to this project will be documented in this file."
+msgstr "此项目的所有重要更改都将记录在此文件中。"
+
+#: ../../../CHANGELOG.md:5
+msgid ""
+"The format is based on [Keep a "
+"Changelog](https://keepachangelog.com/en/1.0.0/), and this project "
+"adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)."
+msgstr ""
+"格式基于 [Keep a "
+"Changelog](https://keepachangelog.com/en/1.0.0/),本项目遵循[语义化版本控制](https://semver.org/spec/v2.0.0.html)。"
+
+#: ../../../CHANGELOG.md:8
+msgid "[Unreleased]"
+msgstr ""
+
+#: ../../../CHANGELOG.md:10
+msgid "[0.0.15a2] - Pre-Alpha"
+msgstr ""
+
+#: ../../../CHANGELOG.md:12 ../../../CHANGELOG.md:54 ../../../CHANGELOG.md:62
+#: ../../../CHANGELOG.md:94 ../../../CHANGELOG.md:130
+msgid "Fixed"
+msgstr ""
+
+#: ../../../CHANGELOG.md:14
+msgid "Fix several error string missing user input logging during format"
+msgstr ""
+
+#: ../../../CHANGELOG.md:16
+msgid "修复遗漏的错误信息格式化 [#26](https://github.com/OwenYou/dftt_timecode/issues/26)"
+msgstr ""
+
+#: ../../../CHANGELOG.md:18
+msgid "[0.0.15a1] - Pre-Alpha"
+msgstr ""
+
+#: ../../../CHANGELOG.md:20 ../../../CHANGELOG.md:70 ../../../CHANGELOG.md:102
+#: ../../../CHANGELOG.md:138
+msgid "Added"
+msgstr ""
+
+#: ../../../CHANGELOG.md:22
+msgid "Add `DfttTimecodeInitializationError` exception class"
+msgstr ""
+
+#: ../../../CHANGELOG.md:24
+msgid "增加 `DfttTimecodeInitializationError`"
+msgstr ""
+
+#: ../../../CHANGELOG.md:26
+msgid "Add GitHub Action to automatically upload releases to PyPI"
+msgstr ""
+
+#: ../../../CHANGELOG.md:28
+msgid "使用 GitHub Action 自动打包上传 PyPI"
+msgstr ""
+
+#: ../../../CHANGELOG.md:30 ../../../CHANGELOG.md:76 ../../../CHANGELOG.md:112
+#: ../../../CHANGELOG.md:152
+#, fuzzy
+msgid "Changed"
+msgstr "更新日志"
+
+#: ../../../CHANGELOG.md:32
+msgid "Modify drop frame logic to adapt to more frame rates"
+msgstr ""
+
+#: ../../../CHANGELOG.md:34
+msgid "修改丢帧逻辑适应更多帧率"
+msgstr ""
+
+#: ../../../CHANGELOG.md:36
+msgid "Refactor timecode type detection logic"
+msgstr ""
+
+#: ../../../CHANGELOG.md:38
+msgid "重构时码类型检测逻辑"
+msgstr ""
+
+#: ../../../CHANGELOG.md:40
+msgid "Refactor error handling during timecode initialization"
+msgstr ""
+
+#: ../../../CHANGELOG.md:42
+msgid "重构时码对象初始化时的错误处理"
+msgstr ""
+
+#: ../../../CHANGELOG.md:44
+msgid "Modify error messages to enhance readability"
+msgstr ""
+
+#: ../../../CHANGELOG.md:46
+msgid "修改报错信息,增强可读性"
+msgstr ""
+
+#: ../../../CHANGELOG.md:48 ../../../CHANGELOG.md:86
+msgid "Deprecated"
+msgstr ""
+
+#: ../../../CHANGELOG.md:50
+msgid "Completely remove `InstanceMethodDispatch`"
+msgstr ""
+
+#: ../../../CHANGELOG.md:52
+msgid "完全移除 `InstanceMethodDispatch`"
+msgstr ""
+
+#: ../../../CHANGELOG.md:56
+msgid ""
+"Fix millisecond overflow issue when converting certain timecodes from "
+"SMPTE to SRT [#19](https://github.com/OwenYou/dftt_timecode/issues/19)"
+msgstr ""
+
+#: ../../../CHANGELOG.md:58
+msgid "修复特定时码在SMPTE转SRT时毫秒会溢出的问题"
+msgstr ""
+
+#: ../../../CHANGELOG.md:60
+msgid "[0.0.14]"
+msgstr ""
+
+#: ../../../CHANGELOG.md:64
+msgid ""
+"Fix v0.0.13 import failure caused by missing dftt_timecode.core while "
+"packing"
+msgstr ""
+
+#: ../../../CHANGELOG.md:66
+msgid "修复v0.0.13打包后不包含core,导致库无法使用的问题"
+msgstr ""
+
+#: ../../../CHANGELOG.md:68
+msgid "[0.0.13]"
+msgstr ""
+
+#: ../../../CHANGELOG.md:72
+msgid ""
+"Add `get_audio_sample_count` method for correctly outputting the count of"
+" audio samples at TC timestamps "
+"[#9](https://github.com/OwenYou/dftt_timecode/issues/9)"
+msgstr ""
+
+#: ../../../CHANGELOG.md:74
+msgid "添加 `get_audio_sample_count` 方法用于正确输出TC时间戳下的音频采样数"
+msgstr ""
+
+#: ../../../CHANGELOG.md:78
+msgid "Use f-string for string format output"
+msgstr ""
+
+#: ../../../CHANGELOG.md:80
+msgid "使用 `f-string` 处理字符串格式输出"
+msgstr ""
+
+#: ../../../CHANGELOG.md:82
+msgid "Refactor timecode output function to reduce code duplication"
+msgstr ""
+
+#: ../../../CHANGELOG.md:84
+msgid "重构时间码输出函数,减少代码重复"
+msgstr ""
+
+#: ../../../CHANGELOG.md:88
+msgid ""
+"Use `functools.singledispatchmethod` instead of "
+"`dispatch.InstanceMethodDispatch`"
+msgstr ""
+
+#: ../../../CHANGELOG.md:90
+msgid "使用 `functools.singledispatchmethod` 代替 `dispatch.InstanceMethodDispatch`"
+msgstr ""
+
+#: ../../../CHANGELOG.md:92
+msgid "[0.0.12]"
+msgstr ""
+
+#: ../../../CHANGELOG.md:96
+msgid ""
+"Fix DLP pattern error causing DLP ticks in range [50-99] and [150-199] to"
+" not be matched. This bug caused errors when using strings like "
+"`'00:00:27:183'` to initialize a DLP timecode object"
+msgstr ""
+
+#: ../../../CHANGELOG.md:98
+msgid "修复DLP正则表达式错误导致范围在50-99、150-199的DLP tick不能被匹配的问题"
+msgstr ""
+
+#: ../../../CHANGELOG.md:100
+msgid "[0.0.11]"
+msgstr ""
+
+#: ../../../CHANGELOG.md:104
+msgid "Add `__str__` method to return timecode value for DfttTimecode object"
+msgstr ""
+
+#: ../../../CHANGELOG.md:106
+msgid "添加 `__str__` 方法,返回DfttTimecode对象的时间码值"
+msgstr ""
+
+#: ../../../CHANGELOG.md:108
+msgid "Add unit tests for DfttTimecode using pytest"
+msgstr ""
+
+#: ../../../CHANGELOG.md:110
+msgid "添加DfttTimecode单元测试(使用pytest)"
+msgstr ""
+
+#: ../../../CHANGELOG.md:114
+msgid "Add 23.98/23.976 FPS to drop frame detection conditions"
+msgstr ""
+
+#: ../../../CHANGELOG.md:116
+msgid "对丢帧的检测条件添加有关23.98/23.976的判定"
+msgstr ""
+
+#: ../../../CHANGELOG.md:118
+msgid ""
+"`+` and `-` operators perform an OR operation on the strict property of "
+"two DfttTimecode objects being added/subtracted"
+msgstr ""
+
+#: ../../../CHANGELOG.md:120
+msgid "`+` `-` 运算符对相加的两个DfttTimecode对象的strict属性进行或运算"
+msgstr ""
+
+#: ../../../CHANGELOG.md:122
+msgid ""
+"Comparison operators (`==`, `>`, `>=`, etc.) now validate that both "
+"DfttTimecode objects have the same frame rate before comparison, throwing"
+" an exception if frame rates differ"
+msgstr ""
+
+#: ../../../CHANGELOG.md:124
+msgid "比较运算符在对两个DfttTimecode对象进行比较时会先判定帧率,若帧率不同则抛出异常"
+msgstr ""
+
+#: ../../../CHANGELOG.md:126
+msgid "`print(self)` now outputs a formatted timecode string"
+msgstr ""
+
+#: ../../../CHANGELOG.md:128
+msgid "`print(self)` 将会输出基于类型的时间码字符串"
+msgstr ""
+
+#: ../../../CHANGELOG.md:132
+msgid ""
+"Fix issue in `timecode_output(self, dest_type, output_part)` where "
+"`output_part = 3` would incorrectly return minute data"
+msgstr ""
+
+#: ../../../CHANGELOG.md:134
+msgid "修复 `timecode_output` 中 `output_part = 3` 时错误返回分钟数据的问题"
+msgstr ""
+
+#: ../../../CHANGELOG.md:136
+msgid "[0.0.10]"
+msgstr ""
+
+#: ../../../CHANGELOG.md:140
+msgid ""
+"Add support for using a DfttTimecode object to initialize a new "
+"DfttTimecode object"
+msgstr ""
+
+#: ../../../CHANGELOG.md:142
+msgid "使用DfttTimecode对象初始化新DfttTimecode对象"
+msgstr ""
+
+#: ../../../CHANGELOG.md:144
+msgid "Add `float()` and `int()` class methods for DfttTimecode class"
+msgstr ""
+
+#: ../../../CHANGELOG.md:146
+msgid "添加DfttTimecode类的float和int方法"
+msgstr ""
+
+#: ../../../CHANGELOG.md:148
+msgid "Add `precise_timestamp` attribute for DfttTimecode class"
+msgstr ""
+
+#: ../../../CHANGELOG.md:150
+msgid "添加DfttTimecode类的precise_timestamp属性"
+msgstr ""
+
+#: ../../../CHANGELOG.md:154
+msgid ""
+"DfttTimecode operators now raise errors when encountering undefined "
+"circumstances or illegal operations"
+msgstr ""
+
+#: ../../../CHANGELOG.md:156
+msgid "DfttTimecode运算符在未定义/非法操作时将会报错"
+msgstr ""
+
+#: ../../../CHANGELOG.md:158
+msgid "Update comparison rules for DfttTimecode operators"
+msgstr ""
+
+#: ../../../CHANGELOG.md:160
+msgid "修改DfttTimecode运算符的大小比较规则"
+msgstr ""
+
+#: ../../../CHANGELOG.md:162
+msgid ""
+"When creating a timecode object using SMPTE NDF format string, if "
+"`drop_frame` is forced to `True`, the resulting object will be SMPTE DF "
+"format timecode"
+msgstr ""
+
+#: ../../../CHANGELOG.md:164
+msgid "使用SMPTE NDF格式字符串新建时码类对象时,若强制drop_frame为True,则新建得到的对象为SMPTE DF格式时码"
+msgstr ""
+
+#: ../../../CHANGELOG.md:166
+msgid "[0.0.9]"
+msgstr ""
+
+#: ../../../CHANGELOG.md:168
+msgid "Initial public release."
+msgstr ""
+
diff --git a/docs/locale/zh_CN/LC_MESSAGES/contributing.mo b/docs/locale/zh_CN/LC_MESSAGES/contributing.mo
new file mode 100644
index 0000000..79f8b4b
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/contributing.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/contributing.po b/docs/locale/zh_CN/LC_MESSAGES/contributing.po
new file mode 100644
index 0000000..2c59ef4
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/contributing.po
@@ -0,0 +1,643 @@
+# DFTT Timecode Documentation Chinese Translation
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 13:18+0800\n"
+"PO-Revision-Date: 2025-10-21 12:00+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../contributing.rst:2
+msgid "Contributing"
+msgstr "贡献指南"
+
+#: ../../contributing.rst:4
+msgid ""
+"We welcome contributions to dftt_timecode! This guide will help you get "
+"started."
+msgstr "我们欢迎对 dftt_timecode 的贡献!本指南将帮助您开始贡献。"
+
+#: ../../contributing.rst:7
+msgid "Getting Started"
+msgstr "开始"
+
+#: ../../contributing.rst:9
+msgid "Fork the repository on GitHub"
+msgstr "在 GitHub 上 Fork 仓库"
+
+#: ../../contributing.rst:10
+msgid "Clone your fork locally:"
+msgstr "在本地克隆您的 Fork:"
+
+#: ../../contributing.rst:18
+msgid "Development Workflow"
+msgstr "开发工作流"
+
+#: ../../contributing.rst:21
+msgid "Setting Up Your Environment"
+msgstr "设置开发环境"
+
+#: ../../contributing.rst:23
+msgid "Create a virtual environment and install dependencies:"
+msgstr "创建虚拟环境并安装依赖:"
+
+#: ../../contributing.rst:29
+msgid "This command will:"
+msgstr "此命令将:"
+
+#: ../../contributing.rst:31
+msgid "Create a virtual environment (if not already present)"
+msgstr "创建虚拟环境(如果尚不存在)"
+
+#: ../../contributing.rst:32
+msgid "Install all dependencies from ``pyproject.toml``"
+msgstr "从 ``pyproject.toml`` 安装所有依赖"
+
+#: ../../contributing.rst:33
+msgid "Install the package in editable mode"
+msgstr "以可编辑模式安装包"
+
+#: ../../contributing.rst:34
+msgid "Generate/update ``uv.lock`` for reproducible builds"
+msgstr "生成/更新 ``uv.lock`` 以实现可重现构建"
+
+#: ../../contributing.rst:37
+msgid "Running Tests"
+msgstr "运行测试"
+
+#: ../../contributing.rst:39
+msgid "Run all tests:"
+msgstr "运行所有测试:"
+
+#: ../../contributing.rst:45
+msgid "Run tests with verbose output:"
+msgstr "以详细输出运行测试:"
+
+#: ../../contributing.rst:51
+msgid "Run specific test file:"
+msgstr "运行特定测试文件:"
+
+#: ../../contributing.rst:58
+msgid "Code Style"
+msgstr "代码风格"
+
+#: ../../contributing.rst:60
+msgid "Follow PEP 8 guidelines"
+msgstr "遵循 PEP 8 规范"
+
+#: ../../contributing.rst:61
+msgid "Use meaningful variable and function names"
+msgstr "使用有意义的变量和函数名"
+
+#: ../../contributing.rst:62
+msgid "Add docstrings to all public functions and classes"
+msgstr "为所有公共函数和类添加文档字符串"
+
+#: ../../contributing.rst:63
+msgid "Keep functions focused and concise"
+msgstr "保持函数专注和简洁"
+
+#: ../../contributing.rst:66
+msgid "Writing Tests"
+msgstr "编写测试"
+
+#: ../../contributing.rst:68
+msgid "All new features and bug fixes should include tests:"
+msgstr "所有新功能和错误修复都应包含测试:"
+
+#: ../../contributing.rst:81
+msgid "Documentation"
+msgstr "文档"
+
+#: ../../contributing.rst:83
+msgid "Update documentation when adding new features:"
+msgstr "添加新功能时更新文档:"
+
+#: ../../contributing.rst:85
+msgid "Add docstrings to your code"
+msgstr "为代码添加文档字符串"
+
+#: ../../contributing.rst:86
+msgid "Update relevant .rst files in the docs/ directory"
+msgstr "更新 docs/ 目录中的相关 .rst 文件"
+
+#: ../../contributing.rst:87
+msgid "Build documentation locally to verify:"
+msgstr "本地构建文档以验证:"
+
+#: ../../contributing.rst:95
+msgid "Contributing Translations"
+msgstr "贡献翻译"
+
+#: ../../contributing.rst:97
+msgid ""
+"We welcome contributions to documentation translations! Currently we "
+"support:"
+msgstr "我们欢迎为文档翻译做出贡献!目前我们支持:"
+
+#: ../../contributing.rst:99
+msgid "**English** (primary language)"
+msgstr "英文(主要语言)"
+
+#: ../../contributing.rst:100
+msgid "**中文 (Simplified Chinese)**"
+msgstr "中文(简体)"
+
+#: ../../contributing.rst:103
+msgid "How to Contribute Translations"
+msgstr "如何贡献翻译"
+
+#: ../../contributing.rst:105
+msgid "**Adding new translations to existing languages:**"
+msgstr "**向现有语言添加新翻译:**"
+
+#: ../../contributing.rst:107
+msgid "Navigate to the translation files:"
+msgstr "进入翻译文件目录:"
+
+#: ../../contributing.rst:113
+msgid "Edit the ``.po`` files to add or improve translations:"
+msgstr "编辑 ``.po`` 文件以添加或改进翻译:"
+
+#: ../../contributing.rst:121
+msgid "Build and preview your translations:"
+msgstr "构建并预览您的翻译:"
+
+#: ../../contributing.rst:129
+msgid "Preview locally:"
+msgstr "本地预览:"
+
+#: ../../contributing.rst:137
+msgid "**Adding a new language:**"
+msgstr "**添加新语言:**"
+
+#: ../../contributing.rst:139
+msgid "Generate translation files for your language:"
+msgstr "为您的语言生成翻译文件:"
+
+#: ../../contributing.rst:147
+msgid ""
+"Update ``docs/Makefile`` to include the new language in the ``LANGUAGES``"
+" variable"
+msgstr "更新 ``docs/Makefile``,在 ``LANGUAGES`` 变量中添加新语言"
+
+#: ../../contributing.rst:149
+msgid "Update ``docs/_static/switcher.json`` to add your language option"
+msgstr "更新 ``docs/_static/switcher.json`` 以添加您的语言选项"
+
+#: ../../contributing.rst:151
+msgid ""
+"Update the language switcher template in ``docs/_templates/language-"
+"switcher.html``"
+msgstr "更新 ``docs/_templates/language-switcher.html`` 中的语言切换器模板"
+
+#: ../../contributing.rst:153
+msgid "Translate the ``.po`` files in ``locale//LC_MESSAGES/``"
+msgstr "翻译 ``locale//LC_MESSAGES/`` 中的 ``.po`` 文件"
+
+#: ../../contributing.rst:155
+msgid "Build and test your translation"
+msgstr "构建并测试您的翻译"
+
+#: ../../contributing.rst:157
+msgid "**Translation Guidelines:**"
+msgstr "**翻译指南:**"
+
+#: ../../contributing.rst:159
+msgid ""
+"**User documentation** (installation, quickstart, user guide): Translate "
+"everything"
+msgstr "**用户文档** (安装、快速开始、用户指南):翻译所有内容"
+
+#: ../../contributing.rst:160
+msgid ""
+"**API documentation**: Translate page titles and main descriptions, but "
+"keep technical details (class names, method names, parameters) in English"
+msgstr "**API 文档**:翻译页面标题和主要描述,但保持技术细节(类名、方法名、参数)为英文"
+
+#: ../../contributing.rst:161
+msgid ""
+"**Changelog**: Translate section headers, but keep technical change "
+"entries in English"
+msgstr "**更新日志**:翻译章节标题,但保持技术变更条目为英文"
+
+#: ../../contributing.rst:162
+msgid "**Code examples**: Keep code and variable names in English"
+msgstr "**代码示例**:保持代码和变量名为英文"
+
+#: ../../contributing.rst:163
+msgid ""
+"**Technical terms**: Use consistent translations (see the translation "
+"guide in ``docs/I18N_README.md``)"
+msgstr "**技术术语**:使用一致的翻译(参见 ``docs/I18N_README.md`` 中的翻译指南)"
+
+#: ../../contributing.rst:165
+msgid "**Updating translations when source changes:**"
+msgstr "**当源文件更改时更新翻译:**"
+
+#: ../../contributing.rst:167
+msgid ""
+"When documentation source files are updated, translations need to be "
+"updated:"
+msgstr "当文档源文件更新时,需要更新翻译:"
+
+#: ../../contributing.rst:177
+msgid "**Translation System Overview**"
+msgstr "**翻译系统概述**"
+
+#: ../../contributing.rst:179
+msgid ""
+"The project uses Sphinx with ``sphinx-intl`` for internationalization. "
+"The system uses gettext ``.po`` (Portable Object) files for translations,"
+" which is the industry standard for software localization."
+msgstr ""
+"本项目使用 Sphinx 和 ``sphinx-intl`` 进行国际化。"
+"系统使用 gettext ``.po`` (Portable Object)文件进行翻译,"
+"这是软件本地化的行业标准。"
+
+#: ../../contributing.rst:181
+msgid "**File Structure:**"
+msgstr "**文件结构:**"
+
+#: ../../contributing.rst:201
+msgid "**Detailed Translation Workflow:**"
+msgstr "**详细翻译工作流:**"
+
+#: ../../contributing.rst:203
+msgid "**Generate translation templates** (when source docs change):"
+msgstr "**生成翻译模板** (当源文档更改时):"
+
+#: ../../contributing.rst:210
+msgid ""
+"This creates ``.pot`` files in ``_build/gettext/`` containing all "
+"translatable strings."
+msgstr ""
+"这将在 ``_build/gettext/`` 中创建 ``.pot`` 文件,包含所有可翻译的字符串。"
+
+#: ../../contributing.rst:212
+msgid "**Update translation files**:"
+msgstr "**更新翻译文件:**"
+
+#: ../../contributing.rst:219
+msgid ""
+"This updates ``.po`` files in ``locale/zh_CN/LC_MESSAGES/`` with new "
+"strings while preserving existing translations."
+msgstr ""
+"这将使用新字符串更新 ``locale/zh_CN/LC_MESSAGES/`` 中的 ``.po`` 文件,"
+"同时保留现有翻译。"
+
+#: ../../contributing.rst:221
+msgid "**Translate the strings**:"
+msgstr "**翻译字符串:**"
+
+#: ../../contributing.rst:223
+msgid "Open ``.po`` files and add translations:"
+msgstr "打开 ``.po`` 文件并添加翻译:"
+
+#: ../../contributing.rst:235
+msgid "**Translation Tips:**"
+msgstr "**翻译提示:**"
+
+#: ../../contributing.rst:237
+msgid "Each ``msgid`` contains the original English text"
+msgstr "每个 ``msgid`` 包含原始英文文本"
+
+#: ../../contributing.rst:238
+msgid "Add your translation in the corresponding ``msgstr`` field"
+msgstr "在相应的 ``msgstr`` 字段中添加您的翻译"
+
+#: ../../contributing.rst:239
+#, python-brace-format, python-format
+msgid "Preserve formatting codes like ``{0}``, ``%s``, etc."
+msgstr "保留格式化代码,如 ``{0}``、``%s`` 等"
+
+#: ../../contributing.rst:240
+msgid "Keep technical terms (class/function names) untranslated"
+msgstr "保持技术术语(类名/函数名)不翻译"
+
+#: ../../contributing.rst:241
+msgid "Use tools like `Poedit `_ for easier editing"
+msgstr "使用 `Poedit `_ 等工具进行更轻松的编辑"
+
+#: ../../contributing.rst:243
+msgid "**Build and test**:"
+msgstr "**构建和测试:**"
+
+#: ../../contributing.rst:251
+msgid "Preview the result:"
+msgstr "预览结果:"
+
+#: ../../contributing.rst:259
+msgid "**Commit your changes**:"
+msgstr "**提交您的更改:**"
+
+#: ../../contributing.rst:266
+msgid "**Important Makefile Commands:**"
+msgstr "**重要的 Makefile 命令:**"
+
+#: ../../contributing.rst:268
+msgid ""
+"``make gettext``: Generate ``.pot`` template files from source ``.rst`` "
+"files"
+msgstr "``make gettext``:从源 ``.rst`` 文件生成 ``.pot`` 模板文件"
+
+#: ../../contributing.rst:269
+msgid "``make update-po``: Update ``.po`` files from ``.pot`` templates"
+msgstr "``make update-po``:从 ``.pot`` 模板更新 ``.po`` 文件"
+
+#: ../../contributing.rst:270
+msgid "``make html``: Build English documentation only"
+msgstr "``make html``:仅构建英文文档"
+
+#: ../../contributing.rst:271
+msgid "``make html-zh``: Build Chinese documentation only"
+msgstr "``make html-zh``:仅构建中文文档"
+
+#: ../../contributing.rst:272
+msgid "``make html-all``: Build all language versions"
+msgstr "``make html-all``:构建所有语言版本"
+
+#: ../../contributing.rst:274
+msgid "**Common Issues and Solutions:**"
+msgstr "**常见问题和解决方案:**"
+
+#: ../../contributing.rst:276
+msgid "**Translations not showing:**"
+msgstr "**翻译未显示:**"
+
+#: ../../contributing.rst:278
+msgid "Ensure ``.po`` files have non-empty ``msgstr`` values"
+msgstr "确保 ``.po`` 文件具有非空的 ``msgstr`` 值"
+
+#: ../../contributing.rst:279
+msgid "Rebuild with ``uv run make html-all``"
+msgstr "使用 ``uv run make html-all`` 重新构建"
+
+#: ../../contributing.rst:280
+msgid "Clear browser cache or use incognito mode"
+msgstr "清除浏览器缓存或使用隐身模式"
+
+#: ../../contributing.rst:282
+msgid "**New strings not appearing in .po files:**"
+msgstr "**新字符串未出现在 .po 文件中:**"
+
+#: ../../contributing.rst:284
+msgid "Run ``uv run make gettext`` to regenerate ``.pot`` files"
+msgstr "运行 ``uv run make gettext`` 重新生成 ``.pot`` 文件"
+
+#: ../../contributing.rst:285
+msgid "Run ``uv run make update-po`` to update ``.po`` files"
+msgstr "运行 ``uv run make update-po`` 更新 ``.po`` 文件"
+
+#: ../../contributing.rst:286
+msgid "Check that your source ``.rst`` files are included in the build"
+msgstr "检查您的源 ``.rst`` 文件是否包含在构建中"
+
+#: ../../contributing.rst:288
+msgid "**Language switcher not working:**"
+msgstr "**语言切换器不工作:**"
+
+#: ../../contributing.rst:290
+msgid "Verify ``_templates/language-switcher.html`` exists"
+msgstr "验证 ``_templates/language-switcher.html`` 存在"
+
+#: ../../contributing.rst:291
+msgid ""
+"Ensure target language HTML was built in correct subdirectory "
+"(``_build/html/zh_CN/``)"
+msgstr ""
+"确保目标语言 HTML 已构建在正确的子目录中 "
+"(``_build/html/zh_CN/``)"
+
+#: ../../contributing.rst:293
+msgid "**Best Practices:**"
+msgstr "**最佳实践:**"
+
+#: ../../contributing.rst:295
+msgid ""
+"**Commit ``.po`` files**: Always commit updated ``.po`` files to version "
+"control"
+msgstr "**提交 ``.po`` 文件**:始终将更新的 ``.po`` 文件提交到版本控制"
+
+#: ../../contributing.rst:296
+msgid ""
+"**Don't commit ``.pot`` files**: These are generated artifacts in "
+"``_build/gettext/``"
+msgstr ""
+"**不要提交 ``.pot`` 文件**:这些是 ``_build/gettext/`` 中生成的构建产物"
+
+#: ../../contributing.rst:297
+msgid ""
+"**Incremental translation**: It's okay to commit partially translated "
+"``.po`` files; untranslated strings display in English"
+msgstr ""
+"**增量翻译**:可以提交部分翻译的 ``.po`` 文件;未翻译的字符串将显示为英文"
+
+#: ../../contributing.rst:298
+msgid ""
+"**Review before push**: Build and preview locally before pushing "
+"translations"
+msgstr "**推送前审查**:推送翻译前在本地构建和预览"
+
+#: ../../contributing.rst:299
+msgid ""
+"**Consistent terminology**: Use consistent translations for technical "
+"terms across all pages"
+msgstr "**一致的术语**:在所有页面上对技术术语使用一致的翻译"
+
+#: ../../contributing.rst:300
+msgid ""
+"**Keep source in sync**: Run ``make update-po`` regularly to sync with "
+"source changes"
+msgstr "**保持源同步**:定期运行 ``make update-po`` 以与源更改同步"
+
+#: ../../contributing.rst:302
+msgid "**Automated Deployment:**"
+msgstr "**自动化部署:**"
+
+#: ../../contributing.rst:304
+msgid ""
+"Documentation is automatically built and deployed via GitHub Actions when"
+" pushed to ``main``:"
+msgstr "当推送到 ``main`` 分支时,文档将通过 GitHub Actions 自动构建和部署:"
+
+#: ../../contributing.rst:306
+msgid "Workflow: ``.github/workflows/docs.yml``"
+msgstr "工作流:``.github/workflows/docs.yml``"
+
+#: ../../contributing.rst:307
+msgid "Build command: ``uv run make html-all``"
+msgstr "构建命令:``uv run make html-all``"
+
+#: ../../contributing.rst:308
+msgid "Deployment: GitHub Pages at https://owenyou.github.io/dftt_timecode/"
+msgstr "部署:GitHub Pages 位于 https://owenyou.github.io/dftt_timecode/"
+
+#: ../../contributing.rst:310
+msgid ""
+"When you push translated ``.po`` files to the ``main`` branch (via "
+"``dev`` merge), the multilingual documentation is automatically rebuilt "
+"and deployed."
+msgstr ""
+"当您将翻译的 ``.po`` 文件推送到 ``main`` 分支时(通过 ``dev`` 合并),"
+"多语言文档将自动重新构建和部署。"
+
+#: ../../contributing.rst:312
+msgid "**Additional Resources:**"
+msgstr "**附加资源:**"
+
+#: ../../contributing.rst:314
+msgid ""
+"`Sphinx Internationalization `_"
+msgstr ""
+"`Sphinx 国际化 `_"
+
+#: ../../contributing.rst:315
+msgid "`sphinx-intl Documentation `_"
+msgstr "`sphinx-intl 文档 `_"
+
+#: ../../contributing.rst:316
+msgid ""
+"`GNU gettext Documentation "
+"`_"
+msgstr ""
+"`GNU gettext 文档 "
+"`_"
+
+#: ../../contributing.rst:319
+msgid "Submitting Changes"
+msgstr "提交更改"
+
+#: ../../contributing.rst:321
+msgid "Create a new branch for your changes:"
+msgstr "为您的更改创建新分支:"
+
+#: ../../contributing.rst:327
+msgid "Make your changes and commit:"
+msgstr "进行更改并提交:"
+
+#: ../../contributing.rst:334
+msgid "Push to your fork:"
+msgstr "推送到您的 Fork:"
+
+#: ../../contributing.rst:340
+msgid "Open a Pull Request on GitHub"
+msgstr "在 GitHub 上打开 Pull Request"
+
+#: ../../contributing.rst:343
+msgid "Pull Request Guidelines"
+msgstr "Pull Request 指南"
+
+#: ../../contributing.rst:345
+msgid "Provide a clear description of the changes"
+msgstr "提供更改的清晰描述"
+
+#: ../../contributing.rst:346
+msgid "Reference any related issues"
+msgstr "引用任何相关问题"
+
+#: ../../contributing.rst:347
+msgid "Ensure all tests pass"
+msgstr "确保所有测试通过"
+
+#: ../../contributing.rst:348
+msgid "Update documentation as needed"
+msgstr "根据需要更新文档"
+
+#: ../../contributing.rst:349
+msgid "Keep changes focused and atomic"
+msgstr "保持更改集中且原子化"
+
+#: ../../contributing.rst:352
+msgid "Reporting Bugs"
+msgstr "报告错误"
+
+#: ../../contributing.rst:354
+msgid "When reporting bugs, please include:"
+msgstr "报告错误时,请包含:"
+
+#: ../../contributing.rst:356
+msgid "Python version"
+msgstr "Python 版本"
+
+#: ../../contributing.rst:357
+msgid "dftt_timecode version"
+msgstr "dftt_timecode 版本"
+
+#: ../../contributing.rst:358
+msgid "Minimal code example that reproduces the issue"
+msgstr "能重现问题的最小代码示例"
+
+#: ../../contributing.rst:359
+msgid "Expected vs actual behavior"
+msgstr "预期行为与实际行为"
+
+#: ../../contributing.rst:360
+msgid "Any error messages or stack traces"
+msgstr "任何错误消息或堆栈跟踪"
+
+#: ../../contributing.rst:363
+msgid "Feature Requests"
+msgstr "功能请求"
+
+#: ../../contributing.rst:365
+msgid "Feature requests are welcome! Please provide:"
+msgstr "欢迎功能请求!请提供:"
+
+#: ../../contributing.rst:367
+msgid "Clear description of the feature"
+msgstr "功能的清晰描述"
+
+#: ../../contributing.rst:368
+msgid "Use cases and examples"
+msgstr "使用场景和示例"
+
+#: ../../contributing.rst:369
+msgid "Why this would be valuable to other users"
+msgstr "为什么这对其他用户有价值"
+
+#: ../../contributing.rst:372
+msgid "Code of Conduct"
+msgstr "行为准则"
+
+#: ../../contributing.rst:374
+msgid "Be respectful and inclusive"
+msgstr "保持尊重和包容"
+
+#: ../../contributing.rst:375
+msgid "Focus on constructive feedback"
+msgstr "专注于建设性反馈"
+
+#: ../../contributing.rst:376
+msgid "Help create a welcoming environment for all contributors"
+msgstr "帮助为所有贡献者创建一个友好的环境"
+
+#: ../../contributing.rst:379
+msgid "License"
+msgstr "许可证"
+
+#: ../../contributing.rst:381
+msgid ""
+"By contributing, you agree that your contributions will be licensed under"
+" the GNU Lesser General Public License v2 (LGPLv2)."
+msgstr "通过贡献,您同意您的贡献将按照 GNU Lesser General Public License v2 (LGPLv2) 授权。"
+
+#~ msgid ""
+#~ "For detailed information about the "
+#~ "translation system, see ``docs/I18N_README.md``."
+#~ msgstr "有关翻译系统的详细信息,请参阅 ``docs/I18N_README.md``。"
+
diff --git a/docs/locale/zh_CN/LC_MESSAGES/index.mo b/docs/locale/zh_CN/LC_MESSAGES/index.mo
new file mode 100644
index 0000000..ebcc54d
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/index.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/index.po b/docs/locale/zh_CN/LC_MESSAGES/index.po
new file mode 100644
index 0000000..2dbfabd
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/index.po
@@ -0,0 +1,134 @@
+# DFTT Timecode Documentation Chinese Translation
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 13:28+0800\n"
+"PO-Revision-Date: 2025-10-21 11:40+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../index.rst:68
+msgid "User Guide"
+msgstr "用户指南"
+
+#: ../../index.rst:76
+msgid "API Reference"
+msgstr "API 参考"
+
+#: ../../index.rst:84
+msgid "Development"
+msgstr "开发"
+
+#: ../../index.rst:2
+msgid "dftt_timecode"
+msgstr "dftt_timecode"
+
+#: ../../index.rst:4
+msgid "PyPI"
+msgstr "PyPI"
+
+#: ../../index.rst:8
+msgid "Python 3"
+msgstr "Python 3"
+
+#: ../../index.rst:11
+msgid "License"
+msgstr "许可证"
+
+#: ../../index.rst:15
+msgid ""
+"Python timecode library for film and TV industry, with high frame rate "
+"support and comprehensive features."
+msgstr "为影视行业设计的Python时码库,支持HFR高帧率以及其他丰富的功能。"
+
+#: ../../index.rst:17
+msgid ""
+"DFTT stands for the Department of Film and TV Technology of Beijing Film "
+"Academy."
+msgstr "DFTT 代表北京电影学院电影电视技术系。"
+
+#: ../../index.rst:20
+msgid "Features"
+msgstr "特性"
+
+#: ../../index.rst:22
+msgid ""
+"**Multiple Timecode Format Support**: SMPTE (DF/NDF), SRT, DLP (Cine "
+"Canvas), FFMPEG, FCPX, frame count, timestamp"
+msgstr "**多种时码格式支持**:SMPTE (DF/NDF)、SRT、DLP (Cine Canvas)、FFMPEG、FCPX、帧计数、时间戳"
+
+#: ../../index.rst:23
+msgid "**High Frame Rate Support**: Supports frame rates from 0.01 to 999.99 fps"
+msgstr "**高帧率支持**:支持 0.01 到 999.99 fps 的帧率"
+
+#: ../../index.rst:24
+msgid "**Drop-Frame/Non-Drop-Frame**: Strictly supports SMPTE DF/NDF formats"
+msgstr "**跳帧/非跳帧**:严格支持 SMPTE DF/NDF 格式"
+
+#: ../../index.rst:25
+msgid ""
+"**Extended Time Range**: Currently supports time range from -99 to 99 "
+"hours"
+msgstr "**扩展时间范围**:目前支持 -99 到 99 小时的时间范围"
+
+#: ../../index.rst:26
+msgid ""
+"**Strict Mode**: 24-hour cycling mode that automatically converts "
+"timecodes outside the 0-24 hour range"
+msgstr "**严格模式**:24 小时循环模式,自动转换 0-24 小时范围外的时码"
+
+#: ../../index.rst:27
+msgid ""
+"**High Precision**: Internal storage using high-precision Fraction "
+"timestamps for accurate conversions"
+msgstr "**高精度**:内部使用高精度分数时间戳进行精确转换"
+
+#: ../../index.rst:28
+msgid ""
+"**Rich Operators**: Comprehensive support for arithmetic and comparison "
+"operations between timecodes and numbers"
+msgstr "**丰富的运算符**:全面支持时码与数字之间的算术和比较运算"
+
+#: ../../index.rst:31
+msgid "Installation"
+msgstr "安装"
+
+#: ../../index.rst:38
+msgid "Quick Start"
+msgstr "快速开始"
+
+#: ../../index.rst:66
+msgid "Contents"
+msgstr "目录"
+
+#: ../../index.rst:92
+msgid "Indices and tables"
+msgstr "索引和表格"
+
+#: ../../index.rst:94
+msgid ":ref:`genindex`"
+msgstr ":ref:`genindex`"
+
+#: ../../index.rst:95
+msgid ":ref:`modindex`"
+msgstr ":ref:`modindex`"
+
+#: ../../index.rst:96
+msgid ":ref:`search`"
+msgstr ":ref:`search`"
+
+#~ msgid "为影视行业设计的Python时码库,支持HFR高帧率以及其他丰富的功能。"
+#~ msgstr "为影视行业设计的 Python 时码库,支持 HFR 高帧率以及其他丰富的功能。"
+
diff --git a/docs/locale/zh_CN/LC_MESSAGES/installation.mo b/docs/locale/zh_CN/LC_MESSAGES/installation.mo
new file mode 100644
index 0000000..8cf69d4
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/installation.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/installation.po b/docs/locale/zh_CN/LC_MESSAGES/installation.po
new file mode 100644
index 0000000..66a870d
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/installation.po
@@ -0,0 +1,136 @@
+# DFTT Timecode Documentation Chinese Translation
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 11:40+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../installation.rst:2
+msgid "Installation"
+msgstr "安装"
+
+#: ../../installation.rst:5
+msgid "Requirements"
+msgstr "系统要求"
+
+#: ../../installation.rst:7
+msgid "Python >= 3.11"
+msgstr "Python >= 3.11"
+
+#: ../../installation.rst:8
+msgid "Standard library dependencies only (no external dependencies required)"
+msgstr "仅依赖标准库(无需外部依赖)"
+
+#: ../../installation.rst:10
+msgid "fractions"
+msgstr "fractions"
+
+#: ../../installation.rst:11
+msgid "logging"
+msgstr "logging"
+
+#: ../../installation.rst:12
+msgid "math"
+msgstr "math"
+
+#: ../../installation.rst:13
+msgid "functools"
+msgstr "functools"
+
+#: ../../installation.rst:14
+msgid "re"
+msgstr "re"
+
+#: ../../installation.rst:17
+msgid "Installation from PyPI"
+msgstr "从 PyPI 安装"
+
+#: ../../installation.rst:19
+msgid "The easiest way to install dftt_timecode is using pip or uv:"
+msgstr "安装 dftt_timecode 最简单的方法是使用 pip 或 uv:"
+
+#: ../../installation.rst:30
+msgid "Installation from Source"
+msgstr "从源码安装"
+
+#: ../../installation.rst:32
+msgid ""
+"For development, we recommend using **uv** for faster and more reliable "
+"dependency management:"
+msgstr "对于开发,我们建议使用 **uv** 以获得更快速和可靠的依赖管理:"
+
+#: ../../installation.rst:46
+msgid "This will:"
+msgstr "这将:"
+
+#: ../../installation.rst:48
+msgid "Create a virtual environment in ``.venv``"
+msgstr "在 ``.venv`` 中创建虚拟环境"
+
+#: ../../installation.rst:49
+msgid "Install all development dependencies (pytest, sphinx, etc.)"
+msgstr "安装所有开发依赖(pytest、sphinx 等)"
+
+#: ../../installation.rst:50
+msgid "Install the package in editable mode"
+msgstr "以可编辑模式安装包"
+
+#: ../../installation.rst:52
+msgid "Alternatively, using pip:"
+msgstr "或者,使用 pip:"
+
+#: ../../installation.rst:61
+msgid "Verifying Installation"
+msgstr "验证安装"
+
+#: ../../installation.rst:63
+msgid "You can verify the installation by importing the package:"
+msgstr "您可以通过导入包来验证安装:"
+
+#: ../../installation.rst:71
+msgid "Development Dependencies"
+msgstr "开发依赖"
+
+#: ../../installation.rst:73
+msgid ""
+"The project uses **uv** for dependency management. All dependencies are "
+"defined in ``pyproject.toml``:"
+msgstr "项目使用 **uv** 进行依赖管理。所有依赖都定义在 ``pyproject.toml`` 中:"
+
+#: ../../installation.rst:75
+msgid "**pytest** - Testing framework"
+msgstr "**pytest** - 测试框架"
+
+#: ../../installation.rst:76
+msgid "**sphinx** - Documentation generator"
+msgstr "**sphinx** - 文档生成器"
+
+#: ../../installation.rst:77
+msgid "**pydata-sphinx-theme** - Documentation theme"
+msgstr "**pydata-sphinx-theme** - 文档主题"
+
+#: ../../installation.rst:79
+msgid "To install development dependencies with uv:"
+msgstr "使用 uv 安装开发依赖:"
+
+#: ../../installation.rst:89
+msgid "To run tests:"
+msgstr "运行测试:"
+
+#: ../../installation.rst:95
+msgid "To build documentation:"
+msgstr "构建文档:"
diff --git a/docs/locale/zh_CN/LC_MESSAGES/quickstart.mo b/docs/locale/zh_CN/LC_MESSAGES/quickstart.mo
new file mode 100644
index 0000000..4b02db6
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/quickstart.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/quickstart.po b/docs/locale/zh_CN/LC_MESSAGES/quickstart.po
new file mode 100644
index 0000000..ed16f8e
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/quickstart.po
@@ -0,0 +1,108 @@
+# DFTT Timecode Documentation Chinese Translation
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 12:05+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../quickstart.rst:2
+msgid "Quick Start"
+msgstr "快速开始"
+
+#: ../../quickstart.rst:4
+msgid "This guide will help you get started with dftt_timecode quickly."
+msgstr "本指南将帮助您快速上手 dftt_timecode。"
+
+#: ../../quickstart.rst:7
+msgid "Importing the Library"
+msgstr "导入库"
+
+#: ../../quickstart.rst:14
+msgid "Creating Timecode Objects"
+msgstr "创建时码对象"
+
+#: ../../quickstart.rst:16
+msgid "There are multiple ways to create timecode objects:"
+msgstr "创建时码对象有多种方式:"
+
+#: ../../quickstart.rst:19
+msgid "SMPTE Format"
+msgstr "SMPTE 格式"
+
+#: ../../quickstart.rst:30
+msgid "Frame Count"
+msgstr "帧计数"
+
+#: ../../quickstart.rst:41
+msgid "Timestamp"
+msgstr "时间戳"
+
+#: ../../quickstart.rst:56
+msgid "Other Formats"
+msgstr "其他格式"
+
+#: ../../quickstart.rst:70
+msgid "Accessing Timecode Properties"
+msgstr "访问时码属性"
+
+#: ../../quickstart.rst:84
+msgid "Converting Between Formats"
+msgstr "格式转换"
+
+#: ../../quickstart.rst:101
+msgid "Arithmetic Operations"
+msgstr "算术运算"
+
+#: ../../quickstart.rst:104
+msgid "Adding Timecodes"
+msgstr "时码相加"
+
+#: ../../quickstart.rst:123
+msgid "Subtracting Timecodes"
+msgstr "时码相减"
+
+#: ../../quickstart.rst:134
+msgid "Multiplying and Dividing"
+msgstr "乘法和除法"
+
+#: ../../quickstart.rst:149
+msgid "Comparison Operations"
+msgstr "比较运算"
+
+#: ../../quickstart.rst:164
+msgid "Changing Timecode Properties"
+msgstr "修改时码属性"
+
+#: ../../quickstart.rst:167
+msgid "Changing Frame Rate"
+msgstr "更改帧率"
+
+#: ../../quickstart.rst:182
+msgid "Changing Strict Mode"
+msgstr "更改严格模式"
+
+#: ../../quickstart.rst:193
+msgid "Changing Timecode Type"
+msgstr "更改时码类型"
+
+#: ../../quickstart.rst:205
+msgid "Strict Mode"
+msgstr "严格模式"
+
+#: ../../quickstart.rst:207
+msgid "Strict mode ensures timecodes stay within a 24-hour range:"
+msgstr "严格模式确保时码保持在 24 小时范围内:"
diff --git a/docs/locale/zh_CN/LC_MESSAGES/user_guide.mo b/docs/locale/zh_CN/LC_MESSAGES/user_guide.mo
new file mode 100644
index 0000000..e7ad508
Binary files /dev/null and b/docs/locale/zh_CN/LC_MESSAGES/user_guide.mo differ
diff --git a/docs/locale/zh_CN/LC_MESSAGES/user_guide.po b/docs/locale/zh_CN/LC_MESSAGES/user_guide.po
new file mode 100644
index 0000000..d7ddf54
--- /dev/null
+++ b/docs/locale/zh_CN/LC_MESSAGES/user_guide.po
@@ -0,0 +1,226 @@
+# DFTT Timecode Documentation Chinese Translation
+# Copyright (C) 2025, You Ziyuan
+# This file is distributed under the same license as the DFTT Timecode
+# package.
+# You Ziyuan , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DFTT Timecode 0.0.15a2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-10-21 11:37+0800\n"
+"PO-Revision-Date: 2025-10-21 12:10+0800\n"
+"Last-Translator: You Ziyuan \n"
+"Language: zh_CN\n"
+"Language-Team: zh_CN \n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.17.0\n"
+
+#: ../../user_guide.rst:2
+msgid "User Guide"
+msgstr "用户指南"
+
+#: ../../user_guide.rst:4
+msgid "This comprehensive guide covers all aspects of using dftt_timecode."
+msgstr "本综合指南涵盖了使用 dftt_timecode 的各个方面。"
+
+#: ../../user_guide.rst:7
+msgid "Overview"
+msgstr "概述"
+
+#: ../../user_guide.rst:9
+msgid ""
+"dftt_timecode is a comprehensive Python library designed for the film and"
+" TV industry to handle timecodes in various formats with high precision. "
+"It supports high frame rates (HFR) up to 999.99 fps and provides a rich "
+"set of operations for timecode manipulation."
+msgstr "dftt_timecode 是一个为影视行业设计的综合性 Python 库,用于高精度处理各种格式的时码。它支持高达 999.99 fps 的高帧率(HFR),并提供丰富的时码操作功能。"
+
+#: ../../user_guide.rst:14
+msgid "Key Concepts"
+msgstr "核心概念"
+
+#: ../../user_guide.rst:17
+msgid "Timecode Types"
+msgstr "时码类型"
+
+#: ../../user_guide.rst:19
+msgid "The library supports multiple timecode formats used in different contexts:"
+msgstr "该库支持在不同场景下使用的多种时码格式:"
+
+#: ../../user_guide.rst:21
+msgid "**SMPTE**: Industry-standard format (HH:MM:SS:FF)"
+msgstr "**SMPTE**:行业标准格式(HH:MM:SS:FF)"
+
+#: ../../user_guide.rst:22
+msgid "**SRT**: SubRip subtitle format (HH:MM:SS,mmm)"
+msgstr "**SRT**:SubRip 字幕格式(HH:MM:SS,mmm)"
+
+#: ../../user_guide.rst:23
+msgid "**FFMPEG**: FFmpeg timestamp format (HH:MM:SS.ff)"
+msgstr "**FFMPEG**:FFmpeg 时间戳格式(HH:MM:SS.ff)"
+
+#: ../../user_guide.rst:24
+msgid "**FCPX**: Final Cut Pro X format (frames/fps)"
+msgstr "**FCPX**:Final Cut Pro X 格式(frames/fps)"
+
+#: ../../user_guide.rst:25
+msgid "**DLP**: Digital cinema format (HH:MM:SS:FFF)"
+msgstr "**DLP**:数字电影格式(HH:MM:SS:FFF)"
+
+#: ../../user_guide.rst:26
+msgid "**Frame**: Simple frame count"
+msgstr "**Frame**:简单的帧计数"
+
+#: ../../user_guide.rst:27
+msgid "**Time**: Seconds-based timestamp"
+msgstr "**Time**:基于秒的时间戳"
+
+#: ../../user_guide.rst:30
+msgid "Frame Rates"
+msgstr "帧率"
+
+#: ../../user_guide.rst:32
+msgid "The library supports:"
+msgstr "该库支持:"
+
+#: ../../user_guide.rst:34
+msgid "Standard frame rates (23.976, 24, 25, 29.97, 30, 50, 59.94, 60, etc.)"
+msgstr "标准帧率(23.976、24、25、29.97、30、50、59.94、60 等)"
+
+#: ../../user_guide.rst:35
+msgid "High frame rates (96, 100, 120, 144, 240, etc.)"
+msgstr "高帧率(96、100、120、144、240 等)"
+
+#: ../../user_guide.rst:36
+msgid "Custom frame rates from 0.01 to 999.99 fps"
+msgstr "0.01 到 999.99 fps 的自定义帧率"
+
+#: ../../user_guide.rst:37
+msgid "Precise fractional frame rates using Python's Fraction type"
+msgstr "使用 Python 的 Fraction 类型的精确分数帧率"
+
+#: ../../user_guide.rst:40
+msgid "Drop-Frame vs Non-Drop-Frame"
+msgstr "跳帧 vs 非跳帧"
+
+#: ../../user_guide.rst:42
+msgid ""
+"For NTSC video standards (29.97 fps, 59.94 fps), the library correctly "
+"handles:"
+msgstr "对于 NTSC 视频标准(29.97 fps、59.94 fps),该库正确处理:"
+
+#: ../../user_guide.rst:44
+msgid "Non-drop-frame (NDF): Uses colon separator (HH:MM:SS:FF)"
+msgstr "非跳帧(NDF):使用冒号分隔符(HH:MM:SS:FF)"
+
+#: ../../user_guide.rst:45
+msgid "Drop-frame (DF): Uses semicolon separator (HH:MM:SS;FF)"
+msgstr "跳帧(DF):使用分号分隔符(HH:MM:SS;FF)"
+
+#: ../../user_guide.rst:47
+msgid ""
+"Drop-frame timecode compensates for the slight discrepancy between "
+"nominal and actual frame rates by periodically skipping frame numbers."
+msgstr "跳帧时码通过定期跳过帧编号来补偿名义帧率和实际帧率之间的微小差异。"
+
+#: ../../user_guide.rst:51
+msgid "Strict Mode"
+msgstr "严格模式"
+
+#: ../../user_guide.rst:53
+msgid "Strict mode ensures timecodes remain within a 24-hour cycle:"
+msgstr "严格模式确保时码保持在 24 小时周期内:"
+
+#: ../../user_guide.rst:55
+msgid ""
+"Enabled: Timecodes wrap around at 24 hours (25:00:00:00 becomes "
+"01:00:00:00)"
+msgstr "启用:时码在 24 小时处循环(25:00:00:00 变为 01:00:00:00)"
+
+#: ../../user_guide.rst:56
+msgid "Disabled: Timecodes can exceed 24 hours (useful for long-form content)"
+msgstr "禁用:时码可以超过 24 小时(适用于长篇内容)"
+
+#: ../../user_guide.rst:59
+msgid "Common Use Cases"
+msgstr "常见使用场景"
+
+#: ../../user_guide.rst:62
+msgid "Video Editing"
+msgstr "视频编辑"
+
+#: ../../user_guide.rst:77
+msgid "Subtitle Timing"
+msgstr "字幕时间轴"
+
+#: ../../user_guide.rst:90
+msgid "Frame Rate Conversion"
+msgstr "帧率转换"
+
+#: ../../user_guide.rst:100
+msgid "High Frame Rate Workflows"
+msgstr "高帧率工作流"
+
+#: ../../user_guide.rst:112
+msgid "Best Practices"
+msgstr "最佳实践"
+
+#: ../../user_guide.rst:114
+msgid ""
+"**Use Strict Mode for Standard Workflows**: Enable strict mode for "
+"typical video editing to prevent timecode values from exceeding 24 hours."
+msgstr "**标准工作流使用严格模式**:为典型的视频编辑启用严格模式,以防止时码值超过 24 小时。"
+
+#: ../../user_guide.rst:117
+msgid ""
+"**Specify Frame Rates Explicitly**: Always specify the correct frame rate"
+" when creating timecode objects to ensure accurate conversions."
+msgstr "**明确指定帧率**:创建时码对象时始终指定正确的帧率,以确保准确转换。"
+
+#: ../../user_guide.rst:120
+msgid ""
+"**Use Fraction for Precise Frame Rates**: For frame rates like 23.976 or "
+"29.97, use Fraction for maximum precision:"
+msgstr "**使用 Fraction 获得精确帧率**:对于 23.976 或 29.97 等帧率,使用 Fraction 以获得最大精度:"
+
+#: ../../user_guide.rst:128
+msgid ""
+"**Handle Drop-Frame Correctly**: When working with NTSC frame rates "
+"(29.97, 59.94), ensure drop-frame is set correctly based on your workflow"
+" requirements."
+msgstr "**正确处理跳帧**:使用 NTSC 帧率(29.97、59.94)时,根据工作流要求确保正确设置跳帧。"
+
+#: ../../user_guide.rst:131
+msgid ""
+"**Validate User Input**: Use try-except blocks to catch and handle "
+"timecode errors gracefully:"
+msgstr "**验证用户输入**:使用 try-except 块优雅地捕获和处理时码错误:"
+
+#: ../../user_guide.rst:143
+msgid "Performance Considerations"
+msgstr "性能考虑"
+
+#: ../../user_guide.rst:145
+msgid ""
+"The library uses high-precision Fraction internally for timestamp "
+"storage, which ensures accuracy but may be slower than floating-point "
+"arithmetic. For performance-critical applications:"
+msgstr "该库在内部使用高精度 Fraction 存储时间戳,这确保了准确性,但可能比浮点运算慢。对于性能关键型应用:"
+
+#: ../../user_guide.rst:148
+msgid "Create timecode objects once and reuse them"
+msgstr "创建一次时码对象并重复使用"
+
+#: ../../user_guide.rst:149
+msgid "Use frame count operations when possible (integer arithmetic is faster)"
+msgstr "尽可能使用帧计数操作(整数运算更快)"
+
+#: ../../user_guide.rst:150
+msgid ""
+"Consider caching converted values if the same conversions are needed "
+"repeatedly"
+msgstr "如果需要重复进行相同的转换,请考虑缓存转换后的值"
diff --git a/pyproject.toml b/pyproject.toml
index 230911e..d5ddd13 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -43,4 +43,6 @@ dev = [
"pytest>=8.3.4",
"sphinx>=7.0.0",
"pydata-sphinx-theme>=0.15.0",
+ "myst-parser>=4.0.0",
+ "sphinx-intl>=2.0.0",
]
diff --git a/uv.lock b/uv.lock
index 469cf3a..8323050 100644
--- a/uv.lock
+++ b/uv.lock
@@ -127,6 +127,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
]
+[[package]]
+name = "click"
+version = "8.3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "colorama", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" },
+]
+
[[package]]
name = "colorama"
version = "0.4.6"
@@ -143,18 +155,22 @@ source = { editable = "." }
[package.dev-dependencies]
dev = [
+ { name = "myst-parser" },
{ name = "pydata-sphinx-theme" },
{ name = "pytest" },
{ name = "sphinx" },
+ { name = "sphinx-intl" },
]
[package.metadata]
[package.metadata.requires-dev]
dev = [
+ { name = "myst-parser", specifier = ">=4.0.0" },
{ name = "pydata-sphinx-theme", specifier = ">=0.15.0" },
{ name = "pytest", specifier = ">=8.3.4" },
{ name = "sphinx", specifier = ">=7.0.0" },
+ { name = "sphinx-intl", specifier = ">=2.0.0" },
]
[[package]]
@@ -205,6 +221,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
]
+[[package]]
+name = "markdown-it-py"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "mdurl" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" },
+]
+
[[package]]
name = "markupsafe"
version = "3.0.3"
@@ -279,6 +307,44 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
]
+[[package]]
+name = "mdit-py-plugins"
+version = "0.5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "markdown-it-py" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205, upload-time = "2025-08-11T07:25:47.597Z" },
+]
+
+[[package]]
+name = "mdurl"
+version = "0.1.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
+]
+
+[[package]]
+name = "myst-parser"
+version = "4.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "docutils" },
+ { name = "jinja2" },
+ { name = "markdown-it-py" },
+ { name = "mdit-py-plugins" },
+ { name = "pyyaml" },
+ { name = "sphinx" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5f/df/76d0321c3797b54b60fef9ec3bd6f4cfd124b9e422182156a1dd418722cf/myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d", size = 84579, upload-time = "2025-02-12T10:53:02.078Z" },
+]
+
[[package]]
name = "packaging"
version = "25.0"
@@ -340,6 +406,61 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
]
+[[package]]
+name = "pyyaml"
+version = "6.0.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" },
+ { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" },
+ { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" },
+ { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" },
+ { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" },
+ { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" },
+ { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" },
+ { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" },
+ { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" },
+ { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" },
+ { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" },
+ { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" },
+ { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" },
+ { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" },
+ { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" },
+ { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" },
+ { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" },
+ { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" },
+ { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" },
+ { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" },
+ { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" },
+ { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" },
+ { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
+]
+
[[package]]
name = "requests"
version = "2.32.5"
@@ -410,6 +531,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" },
]
+[[package]]
+name = "sphinx-intl"
+version = "2.3.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "babel" },
+ { name = "click" },
+ { name = "sphinx" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/7a/21/eb12016ecb0b52861762b0d227dff75622988f238776a5ee4c75bade507e/sphinx_intl-2.3.2.tar.gz", hash = "sha256:04b0d8ea04d111a7ba278b17b7b3fe9625c58b6f8ffb78bb8a1dd1288d88c1c7", size = 27921, upload-time = "2025-08-02T04:53:01.891Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f7/3b/156032fa29a87e9eba9182b8e893a7e88c1d98907a078a371d69be432e52/sphinx_intl-2.3.2-py3-none-any.whl", hash = "sha256:f0082f9383066bab8406129a2ed531d21c38706d08467bf5ca3714e8914bb2be", size = 12899, upload-time = "2025-08-02T04:53:00.353Z" },
+]
+
[[package]]
name = "sphinxcontrib-applehelp"
version = "2.0.0"