41 Commits
Author SHA1 Message Date
forklessandGitHub 3bd853ba21 Update README to remove low-literacy audience reference
Removed mention of low-literacy audiences from the benefits list.
2026-06-11 09:19:05 +02:00
Forkless a59c4c8ef0 fix(build): update build.sh paths to use PROJECT_DIR after moving to tools/ 2026-05-12 01:48:57 +02:00
Forkless c61205cf9b chore: move build.sh to tools/ directory 2026-05-12 01:46:24 +02:00
Forkless c0596cde7c chore: remove release zip from repo tracking 2026-05-12 01:31:44 +02:00
Forkless 0ac8bc93ad chore: add 1.1.4 release zip 2026-05-12 01:30:49 +02:00
Forkless ca1e44c408 chore: bump version to 1.1.4 2026-05-12 01:29:09 +02:00
Forkless 72b0829218 docs: update changelog and readme for 1.1.4 dashboard widget and about icons 2026-05-12 01:26:29 +02:00
Forkless 7c24206d11 style(dashboard): reorder audio type cards to Opus, MP3, WAV 2026-05-12 01:19:17 +02:00
Forkless 539816b800 style(dashboard): remove unicode icons from info rows for cleaner look 2026-05-12 01:17:08 +02:00
Forkless afe006fde7 feat(dashboard): add horizontal storage usage bar with percentage 2026-05-12 01:12:31 +02:00
Forkless 8e6582dd33 fix(dashboard): change human_size param from int to float to match disk_free_space return type 2026-05-12 01:06:49 +02:00
Forkless 257befe9a7 feat(dashboard): add storage stats dashboard widget toggleable via Screen Options 2026-05-12 01:00:08 +02:00
Forkless bd45b5c47d feat(about): add SVG icons before GitHub and Buy Me a Coffee links 2026-05-12 00:43:23 +02:00
Forkless bf57b04ccb v1.1.3 2026-05-11 23:44:30 +02:00
Forkless 3e9984b208 v1.1.3 — Bump version, 120/120 translations, SVG icons, About tab cleanup 2026-05-11 23:42:12 +02:00
Forkless 4efd81750e Use official SVG icons for GitHub and Buy Me a Coffee links 2026-05-11 23:36:59 +02:00
Forkless fea62ff082 Add GitHub and Buy Me a Coffee links to About tab 2026-05-11 23:18:11 +02:00
Forkless 6fb65a5279 Remove Help tab, add GitHub and Buy Me a Coffee links to About tab 2026-05-11 23:11:28 +02:00
Forkless e3cfdd996f Fix translation count (102→118) and add Opus to features 2026-05-11 22:59:28 +02:00
Forkless fa172f78f9 Fix doc: v1.1.2 in nav, 118-string translation count 2026-05-11 22:36:01 +02:00
Forkless fdf79a13c3 AUDIT.md version bumped to v1.1.2 2026-05-11 22:33:42 +02:00
Forkless d7bfbd9eea Update docs: v1.1.2 version, 118/118 translations 2026-05-11 22:33:08 +02:00
Forkless 7278b522a7 Document Makefile targets in README and developer docs 2026-05-11 22:22:33 +02:00
Forkless 198a05d559 Remove .gitignore from repository (self-ignored) 2026-05-11 22:17:03 +02:00
Forkless fe66723905 Audio Player Styles rename 2026-05-11 22:03:27 +02:00
Forkless cbc2092494 v1.1.2 — Style rename and cleanup 2026-05-11 22:00:32 +02:00
Forkless 4abb9f4fdc Audio Player Styles rename 2026-05-11 22:00:32 +02:00
Forkless 688cc81dae Remove horizontal rule separators from AUDIT.md 2026-05-11 21:57:24 +02:00
Forkless c3c240e9d0 Remove horizontal rule separators from README — cleaner rendering 2026-05-11 21:57:24 +02:00
Forkless 89cd772f8b v1.1.1: Player fix for logged-out users, field reorder, changelog 2026-05-11 21:57:24 +02:00
Forkless d5bd564ae2 Fix: player not rendering for logged-out users — removed in_the_loop() guard 2026-05-11 21:57:24 +02:00
Forkless 42542267de Update README and docs with AUDIT.md link and v1.1.0 version 2026-05-11 21:57:24 +02:00
Forkless fc85ad2d02 Add security audit document (29 categories, 1 finding fixed, zero open) 2026-05-11 21:57:24 +02:00
Forkless 3ae3490de5 Remove .deepseek and AGENTS.md from repository; add to .gitignore 2026-05-11 21:57:24 +02:00
Forkless 36b4618d2d v1.1.0 security audit: 29/29 cleared (1 finding fixed — settings data loss on Logs tab save) 2026-05-11 21:57:24 +02:00
Forkless 61fe8b626d Critical fix: sanitize_settings now merges with existing settings to prevent data loss from standalone forms (Logs tab) 2026-05-11 21:57:24 +02:00
forklessandForkless 66f8f75bf4 Update README.md 2026-05-11 21:57:24 +02:00
Forkless 8f151daa25 Revert FFmpeg path to full binary only; add separate FFprobe Binary Path field 2026-05-11 21:57:24 +02:00
Forkless 47e2407b38 Fix: FFmpeg path detection uses is_executable instead of is_dir to work under open_basedir 2026-05-11 21:57:24 +02:00
Forkless 7470ddd832 Fix: FFmpeg Binaries Path now accepts directory-only paths (auto-appends /ffmpeg) 2026-05-11 21:57:24 +02:00
Forkless fac0699997 Initial public commit 2026-05-11 21:57:24 +02:00
44 changed files with 1226 additions and 150 deletions
-9
View File
@@ -1,9 +0,0 @@
# Build artifacts
build/
*.zip
# OS files
.DS_Store
Thumbs.db
.deepseek/
AGENTS.md
+2 -7
View File
@@ -1,17 +1,15 @@
# Security Audit — Piperless v1.1.0
# Security Audit — Piperless v1.1.3
**Audit date:** 2026-05-10
**Scope:** All 8 PHP classes (`includes/*.php`), plus `uninstall.php`
**Findings:** 1 (fixed). Open: 0
**Auditor:** DeepSeek V4 Pro (systematic automated review)
---
## Summary
29 categories reviewed. One logic-level bug found and fixed mid-session (settings data loss on partial form save). Zero outstanding security vulnerabilities — critical, high, medium, or low.
---
## Results
@@ -47,7 +45,6 @@
| 28 | File permissions | ✅ Pass | Cache directory created with proper permissions. Log `chmod 0600`. |
| 29 | HTTP security headers | ✅ Pass | `Content-Range`, `Accept-Ranges: bytes`, `Cache-Control: public, max-age=86400`. |
---
## Legend
@@ -56,7 +53,6 @@
| ✅ Pass | No vulnerability found |
| 🔧 Fixed | Bug found and resolved |
---
## Defense-in-Depth Layers
@@ -66,9 +62,8 @@ Piperless shells out to the Piper TTS engine and ffmpeg — both system binaries
2. **Authorization layer:** Every admin action checks capabilities. Every post-specific action checks ownership. Public endpoints (audio proxy) use rate limiting instead.
3. **Shell boundary:** `escapeshellarg()` wraps every argument passed to `exec()`, `proc_open()`, and `proc_close()`. No string concatenation into shell commands anywhere.
4. **Output layer:** All HTML output goes through WordPress escaping functions. REST responses use `sanitize_text_field()`. Player attributes use `esc_attr()` and `esc_url()`.
5. **Failure safety:** Every execution path has a fallback. Failed MP3 conversion stores WAV. Failed ffprobe reads the WAV header. Failed temp writes clean up. Mutexes release in all branches.
5. **Failure safety:** Every execution path has a fallback. Failed MP3 or Opus conversion stores WAV. Failed ffprobe reads the WAV header. Failed temp writes clean up. Mutexes release in all branches.
---
## Audit Methodology
+22 -1
View File
@@ -2,6 +2,27 @@
All notable changes to the Piperless WordPress plugin.
## [1.1.4] — 2026-05-12
### Added
- **Dashboard widget** — new "Piperless — Audio Storage" widget on the WordPress admin dashboard (togglable via Screen Options). Shows Opus/MP3/WAV file counts and total sizes in a card grid, published posts without audio transcripts with a quick "View posts" link, and server disk usage with a horizontal usage bar and percentage indicator.
### Changed
- **About tab** — SVG icons now appear inline before the GitHub Repository and Buy Me a Coffee links for a polished look.
### Fixed
- **Dashboard TypeError** — `human_size()` parameter changed from `int` to `float` to handle `disk_free_space()` return type.
## [1.1.3] — 2026-05-11
### Changed
- **About tab** — removed Help tab, added GitHub Repository and Buy Me a Coffee links with official SVG icons
- **Style descriptions** — cleaned hex color codes from all player theme descriptions
## [1.1.1] — 2026-05-10
### Fixed
@@ -28,7 +49,7 @@ All notable changes to the Piperless WordPress plugin.
- **FFmpeg Binaries Path** — field renamed from "FFmpeg Binary Path" to reflect that the directory is used for the full toolchain (ffmpeg, ffprobe). Description updated to mention MP3/Opus.
- **Cache scanning includes `.opus`** — all cache methods (`get_entries`, `clear`, `delete`, `stats`, `clear_orphans`) now handle `.opus` alongside `.mp3` and `.wav`.
- **Opus cache badge** — blue badge (#1565c0) in the cache browser Format column.
- **Translations** — all 8 locales at 117/117 strings.
- **Translations** — all 8 locales at 118/118 strings.
## [1.0.0] — 2026-05-09
+2 -1
View File
@@ -11,7 +11,7 @@ all: translations
# ── Build ────────────────────────────────────────────────────────────────────
build:
@echo "=== Building Piperless ==="
./build.sh
./tools/build.sh
# ── Translations ─────────────────────────────────────────────────────────────
translations:
@@ -85,5 +85,6 @@ help:
@echo " make check-translations Validate translation integrity & lock state"
@echo " make json2po Convert all locale JSON files → .po files"
@echo " make build Create distribution ZIP via build.sh"
@echo " make release Build, tag, push, and upload a GitHub release"
@echo " make clean Remove build artifacts"
@echo ""
+35 -30
View File
@@ -11,27 +11,25 @@ Piperless converts every published post into a natural-sounding audio transcript
- **Visually impaired** readers can listen instead of read
- **Dyslexic** readers get an alternative format
- **Low-literacy** audiences can access your content
- **Commuting** readers can consume posts as audio
- **Non-native speakers** benefit from hearing correct pronunciation
---
## Features
- **Automatic generation** — optionally generate audio when a post is published. No per-post action required.
- **6 player themes** — Classic, Minimal, Modern Dark, NewsViews, NewsViews Classic, and Custom CSS. Match your brand.
- **6 player themes** — Classic, Minimal, Modern Dark, Ron Burgundy, Dan Rather Blue, and Custom CSS. Match your brand.
- **Per-post overrides** — customize voice, language, quality, player style, and placement for individual posts via the Gutenberg sidebar.
- **Content-addressed caching** — identical text + voice + language always produces the same audio file. Never regenerate the same content twice.
- **Multi-language** — Piper supports 20+ languages. Install the voice models you need and Piperless auto-discovers them.
- **Voice aliases** — rename technical model names like `en_US-lessac-low` to "American Female" in your admin panel.
- **MP3 conversion** — auto-converts Piper's WAV output to compact MP3 using ffmpeg (optional, falls back to WAV).
- **MP3 & Opus encoding** — auto-converts Piper's WAV output to MP3 or Opus using ffmpeg. Opus offers better quality at lower bitrates. Falls back to WAV if ffmpeg is unavailable.
- **Smart text extraction** — uses the post excerpt when available to avoid reading embedded content (YouTube, Twitter, third-party embeds), decimal numbers, and other artifacts that produce garbled speech. Falls back to the full post body when no excerpt is set.
- **No external services** — Piper runs on your server. Text never leaves your infrastructure. GDPR-compliant by architecture.
- **Production-hardened** — 29/29 security audit clearance. Rate limiting, authorization layering, process timeout guards, open_basedir aware.
- **Dashboard widget** — at-a-glance storage stats on the WordPress dashboard (togglable via Screen Options). File counts and sizes by audio format, posts awaiting transcription, and disk usage bar.
- **8 admin languages** — Dutch, German, French, Spanish, Chinese (Simplified), Japanese, Brazilian Portuguese, and Italian translations included.
---
## Why the Excerpt Matters
@@ -45,7 +43,6 @@ Piperless solves this by **using the WordPress excerpt field first**. Write a cl
**Pro tip:** Think of the excerpt as your "audio script." It doesn't replace the post — it's the version that sounds natural when read aloud.
---
## Requirements
@@ -60,7 +57,6 @@ Piperless solves this by **using the WordPress excerpt field first**. Write a cl
**Piperless will not work on shared hosting.** It requires shell access to install Piper and the ability to run system binaries via `proc_open`.
---
## Quick Start
@@ -107,7 +103,6 @@ Go to **Settings → Piperless** and set:
Open any post in the block editor. In the Piperless sidebar panel, click **Generate Audio**. The audio player will appear in your post automatically based on your placement settings.
---
## Admin Panel
@@ -121,10 +116,9 @@ Piperless adds a settings page under **Settings → Piperless** with 8 tabs:
| **Performance** | Piper process timeout (303600s), audio endpoint rate limiting |
| **Cache Management** | Stats, cache browser, clear orphaned files, flush entire cache |
| **Logs** | Logging level configuration, live log viewer, clear log |
| **Help** | Usage instructions and ffmpeg notes |
| **About** | Version and contact information |
| **About** | Version, GitHub repository, and support links |
| **Dashboard** | WordPress admin dashboard widget with audio storage stats and disk usage |
---
## Player Themes
@@ -133,15 +127,14 @@ Six built-in themes plus unlimited custom CSS:
| Theme | Description |
|-------|-------------|
| **Classic** | Blue accent, clean borders |
| **Minimal** | Dark text, no border decoration |
| **Modern Dark** | Blue accent on dark background |
| **NewsViews** | Burgundy accent (#B31942) |
| **NewsViews Classic** | Navy accent (#233452) |
| **Minimal** | Clean, understated |
| **Modern Dark** | Dark background |
| **Ron Burgundy** | Bold burgundy |
| **Dan Rather Blue** | Classic navy |
| **Custom CSS** | Full control — base theme with your own styles |
Each theme is a standalone CSS file. Switch themes instantly from the Styling tab.
---
## Accessibility
@@ -152,7 +145,6 @@ Piperless was built with accessibility in mind:
- **Keyboard navigation** — player is a navigable region
- **Content-as-transcript** — since the audio is generated from the post text, the text itself serves as the transcript for WCAG compliance
---
## Security
@@ -169,7 +161,6 @@ Piperless shells out to system binaries. It was built with defense-in-depth from
Comprehensive review: **29/29 categories cleared. 1 logic bug found and fixed. Zero open findings.** [See full audit →](AUDIT.md)
---
## Translation
@@ -177,18 +168,17 @@ Piperless ships with complete translations for:
| Language | Locale | Coverage |
|----------|--------|----------|
| Dutch | nl_NL | 102/102 |
| German | de_DE | 102/102 |
| French | fr_FR | 102/102 |
| Spanish | es_ES | 102/102 |
| Chinese (Simplified) | zh_CN | 102/102 |
| Japanese | ja | 102/102 |
| Portuguese (Brazil) | pt_BR | 102/102 |
| Italian | it_IT | 102/102 |
| Dutch | nl_NL | 120/120 |
| German | de_DE | 120/120 |
| French | fr_FR | 120/120 |
| Spanish | es_ES | 120/120 |
| Chinese (Simplified) | zh_CN | 120/120 |
| Japanese | ja | 120/120 |
| Portuguese (Brazil) | pt_BR | 120/120 |
| Italian | it_IT | 120/120 |
The admin panel, Gutenberg sidebar, and frontend player are fully translated. See `languages/` for `.po` and `.mo` files.
---
## Filters & Hooks
@@ -204,7 +194,6 @@ The admin panel, Gutenberg sidebar, and frontend player are fully translated. Se
- `[piperless_player]` — render the audio player for the current post
- `[piperless_player post_id="123"]` — render the player for a specific post
---
## Development
@@ -218,19 +207,35 @@ includes/
├── class-cache-manager.php # Content-addressed file cache, MP3 conversion
├── class-gutenberg.php # Block editor sidebar, REST API endpoints
├── class-settings.php # Admin panel (8 tabs), AJAX handlers
├── class-dashboard.php # Dashboard widget with file stats and disk usage
├── class-player.php # Frontend HTML5 player (6 themes)
└── class-logger.php # PSR-3 logger with dual-channel fallback
```
### Build & Tooling
The `Makefile` wraps the build and translation toolchain:
```
make build → Create piperless-X.Y.Z.zip
make translations → Extract .pot → JSON, sync to all locales
make json2po → Convert JSON translations back to .po/.mo
make check-translations → Validate translation integrity
make lock-translations → Lock all locales for translation work
make unlock-translations → Release all translation locks
make translation-status → Show lock/completion for each locale
make clean → Remove build artifacts
```
All tools run as standalone shell scripts in `tools/` — the Makefile is a convenience wrapper.
See `doc/index.html` for full developer documentation with architecture diagram, method tables, and security model.
---
## License
MIT-licensed. Piperless is free and open-source. Piper TTS is also MIT-licensed. Voice models vary — check individual model licenses.
---
## Links
+12
View File
@@ -236,6 +236,18 @@
color: #757575;
}
.piperless-about-link {
display: inline-flex;
align-items: center;
gap: 6px;
}
.piperless-about-link-icon {
width: 18px;
height: 18px;
flex-shrink: 0;
}
/* Cache browser badges */
.piperless-cache-badge {
display: inline-block;
+132
View File
@@ -0,0 +1,132 @@
/**
* Piperless Dashboard Widget Styles
*
* Card-based layout for the WordPress admin dashboard widget
* showing audio storage stats at a glance.
*
* @package Piperless
*/
/* ── Dashboard container ───────────────────────────────────────────────── */
.piperless-dashboard {
font-size: 13px;
line-height: 1.5;
}
.piperless-dash-empty {
color: #757575;
font-style: italic;
margin: 0;
}
/* ── Stat cards grid ───────────────────────────────────────────────────── */
.piperless-dash-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-bottom: 14px;
}
.piperless-dash-card {
background: #f8f9fa;
border: 1px solid #e5e7eb;
border-left: 4px solid var(--card-accent);
border-radius: 6px;
padding: 12px;
text-align: center;
}
.piperless-dash-card-value {
font-size: 26px;
font-weight: 700;
line-height: 1.2;
color: #1d2327;
}
.piperless-dash-card-label {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: #646970;
margin: 2px 0;
}
.piperless-dash-card-sub {
font-size: 12px;
color: #757575;
margin-top: 2px;
}
/* ── Info rows ─────────────────────────────────────────────────────────── */
.piperless-dash-info {
display: flex;
flex-direction: column;
gap: 8px;
}
.piperless-dash-info-item {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 12px;
background: #f8f9fa;
border: 1px solid #e5e7eb;
border-radius: 6px;
}
.piperless-dash-info-text {
flex: 1;
color: #1d2327;
}
.piperless-dash-info-link {
margin-left: auto;
font-size: 12px;
text-decoration: none;
color: #2271b1;
white-space: nowrap;
}
.piperless-dash-info-link:hover {
color: #135e96;
text-decoration: underline;
}
/* ── Color highlights per info row ─────────────────────────────────────── */
.piperless-dash-info-posts {
border-left: 4px solid #dba617;
}
.piperless-dash-info-storage {
border-left: 4px solid #2271b1;
}
/* ── Storage usage bar ─────────────────────────────────────────────────── */
.piperless-dash-info-body {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 6px;
}
.piperless-dash-bar {
width: 100%;
height: 6px;
background: #dcdcde;
border-radius: 3px;
overflow: hidden;
}
.piperless-dash-bar-fill {
height: 100%;
background: #2271b1;
border-radius: 3px;
transition: width 0.3s ease;
}
.piperless-dash-bar-label {
font-size: 11px;
color: #757575;
}
+2 -2
View File
@@ -1,7 +1,7 @@
/**
* Piperless Player — NewsViews Classic Theme
* Piperless Player — Dan Rather Blue Theme
*
* Based on the NewsViews style with #233452 replacing the burgundy accent.
* Based on the Ron Burgundy style with #233452 replacing the burgundy accent.
*/
.piperless-player--newsviews-classic {
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Piperless Player — NewsViews Theme
* Piperless Player — Ron Burgundy Theme
*
* Based on the Classic style with #B31942 replacing the blue accent.
*/
+2 -2
View File
@@ -260,8 +260,8 @@
{ value: 'classic', label: 'Classic' },
{ value: 'minimal', label: 'Minimal' },
{ value: 'dark', label: 'Modern Dark' },
{ value: 'newsviews', label: 'NewsViews' },
{ value: 'newsviews-classic', label: 'NewsViews Classic' },
{ value: 'newsviews', label: 'Ron Burgundy' },
{ value: 'newsviews-classic', label: 'Dan Rather Blue' },
],
onChange: function ( val ) { updateMeta( '_piperless_style', val ); },
} ),
+501
View File
@@ -0,0 +1,501 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g id="watermark_1_">
<g>
<g id="watermark" style="opacity:0.61;">
<g>
<g>
<g>
<g>
<polygon style="fill:#FFFFFF;" points="213.765,461.172 208.204,474.017 205.268,474.017 199.726,461.172 202.938,461.172
206.846,470.347 210.81,461.172 "/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M223.507,469.741h-7.469c0.275,1.23,1.321,1.982,2.826,1.982c1.046,0,1.798-0.312,2.477-0.954
l1.523,1.651c-0.917,1.046-2.294,1.597-4.074,1.597c-3.413,0-5.634-2.147-5.634-5.083c0-2.954,2.257-5.083,5.267-5.083
c2.899,0,5.138,1.945,5.138,5.12C223.562,469.191,223.526,469.503,223.507,469.741 M216.002,468.071h4.863
c-0.202-1.248-1.138-2.055-2.422-2.055C217.139,466.016,216.204,466.805,216.002,468.071"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M224.735,468.934c0-2.973,2.294-5.083,5.505-5.083c2.074,0,3.707,0.899,4.423,2.514
l-2.22,1.193c-0.532-0.936-1.321-1.358-2.221-1.358c-1.45,0-2.587,1.009-2.587,2.734c0,1.725,1.138,2.734,2.587,2.734
c0.899,0,1.688-0.404,2.221-1.358l2.22,1.211c-0.716,1.578-2.349,2.495-4.423,2.495
C227.029,474.017,224.735,471.907,224.735,468.934"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M242.828,473.393c-0.587,0.422-1.45,0.624-2.331,0.624c-2.33,0-3.688-1.193-3.688-3.542
v-4.055h-1.523v-2.202h1.523v-2.404h2.863v2.404h2.459v2.202h-2.459v4.019c0,0.844,0.458,1.303,1.229,1.303
c0.422,0,0.844-0.128,1.156-0.367L242.828,473.393z"/>
</g>
</g>
<g>
<path style="fill:#FFFFFF;" d="M262.474,463.997v2.643c-0.238-0.018-0.422-0.037-0.642-0.037
c-1.578,0-2.624,0.862-2.624,2.753v4.661h-2.863v-9.873h2.734v1.303C259.776,464.493,260.951,463.997,262.474,463.997"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M263.299,472.53l1.009-2.239c1.083,0.789,2.697,1.339,4.239,1.339
c1.762,0,2.477-0.587,2.477-1.376c0-2.404-7.469-0.752-7.469-5.524c0-2.184,1.762-4,5.413-4c1.615,0,3.267,0.385,4.459,1.138
l-0.918,2.257c-1.193-0.679-2.422-1.009-3.56-1.009c-1.761,0-2.44,0.66-2.44,1.468c0,2.367,7.468,0.734,7.468,5.45
c0,2.147-1.78,3.982-5.45,3.982C266.492,474.017,264.437,473.411,263.299,472.53"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M285.428,469.741h-7.469c0.275,1.23,1.321,1.982,2.826,1.982c1.046,0,1.798-0.312,2.477-0.954
l1.523,1.651c-0.918,1.046-2.294,1.597-4.074,1.597c-3.413,0-5.634-2.147-5.634-5.083c0-2.954,2.257-5.083,5.267-5.083
c2.9,0,5.138,1.945,5.138,5.12C285.484,469.191,285.447,469.503,285.428,469.741 M277.923,468.071h4.863
c-0.202-1.248-1.138-2.055-2.422-2.055C279.061,466.016,278.125,466.805,277.923,468.071"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M297.007,469.741h-7.469c0.275,1.23,1.321,1.982,2.826,1.982c1.046,0,1.798-0.312,2.477-0.954
l1.523,1.651c-0.918,1.046-2.294,1.597-4.074,1.597c-3.413,0-5.634-2.147-5.634-5.083c0-2.954,2.257-5.083,5.267-5.083
c2.899,0,5.138,1.945,5.138,5.12C297.062,469.191,297.025,469.503,297.007,469.741 M289.501,468.071h4.863
c-0.202-1.248-1.138-2.055-2.422-2.055C290.639,466.016,289.703,466.805,289.501,468.071"/>
</g>
<g>
<polygon style="fill:#FFFFFF;" points="303.208,470.145 301.831,471.503 301.831,474.017 298.969,474.017 298.969,460.401
301.831,460.401 301.831,468.108 306.016,464.144 309.429,464.144 305.318,468.328 309.796,474.017 306.327,474.017 "/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M256.601,475.359L256.601,475.359l-2.86-2.86c-0.435,0.508-0.953,0.943-1.534,1.284
c-0.092,0.069-0.186,0.136-0.283,0.199l3.027,3.027c0.456,0.456,1.195,0.456,1.65,0
C257.057,476.554,257.057,475.815,256.601,475.359"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M249.984,463.244c0.221-0.173,0.495-0.281,0.797-0.281c0.042,0,0.083,0.002,0.124,0.006
c-0.214-0.156-0.478-0.249-0.764-0.249c-0.395,0-0.744,0.18-0.981,0.458c-0.051,0-0.1,0.006-0.151,0.008
c0.039-0.077,0.064-0.162,0.064-0.255c0-0.234-0.143-0.434-0.346-0.519c0.087,0.126,0.138,0.279,0.138,0.445
c0,0.122-0.031,0.237-0.081,0.341c-2.811,0.201-5.03,2.539-5.03,5.4c0,2.993,2.426,5.42,5.42,5.42
c2.993,0,5.42-2.426,5.42-5.42C254.595,465.879,252.593,463.635,249.984,463.244 M247.983,464.656
c0.435,0,0.844,0.112,1.199,0.309c0.374-0.245,0.82-0.387,1.299-0.387c0.711,0,1.348,0.312,1.784,0.806
c-0.435-0.379-1.004-0.61-1.627-0.61c-0.449,0-0.87,0.12-1.234,0.329c-0.079,0.046-0.156,0.096-0.229,0.15
c-0.065-0.048-0.133-0.093-0.204-0.134c-0.369-0.219-0.8-0.344-1.26-0.344c-0.3,0-0.588,0.054-0.854,0.152
C247.196,464.754,247.578,464.656,247.983,464.656 M251.772,469.098c0.115,0.305,0.181,0.634,0.181,0.979
c0,1.534-1.244,2.777-2.778,2.777c-1.534,0-2.777-1.243-2.777-2.777c0-0.345,0.066-0.674,0.181-0.979
c-0.62-0.382-1.035-1.064-1.035-1.846c0-1.197,0.971-2.168,2.168-2.168c0.565,0,1.078,0.218,1.463,0.572
c0.386-0.354,0.899-0.572,1.464-0.572c1.197,0,2.168,0.971,2.168,2.168C252.807,468.034,252.392,468.716,251.772,469.098"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M251.666,467.061c0,0.497-0.404,0.901-0.901,0.901c-0.497,0-0.901-0.404-0.901-0.901
s0.404-0.901,0.901-0.901c0.101,0,0.197,0.017,0.287,0.047c-0.03,0.062-0.045,0.132-0.045,0.204
c0,0.273,0.221,0.494,0.494,0.494c0.05,0,0.099-0.008,0.146-0.022C251.66,466.941,251.666,467,251.666,467.061"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M248.255,467.061c0,0.376-0.305,0.681-0.681,0.681c-0.376,0-0.681-0.305-0.681-0.681
s0.305-0.681,0.681-0.681c0.076,0,0.149,0.013,0.217,0.035c-0.023,0.047-0.034,0.1-0.034,0.155
c0,0.206,0.167,0.374,0.374,0.374c0.038,0,0.075-0.006,0.11-0.017C248.25,466.97,248.255,467.015,248.255,467.061"/>
</g>
<g>
<g>
<g>
<rect x="242.908" y="467.83" style="fill:#FFFFFF;" width="0.616" height="0.616"/>
</g>
<g>
<rect x="254.827" y="467.83" style="fill:#FFFFFF;" width="0.616" height="0.616"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M255.205,468.082h-0.14c0-3.248-2.642-5.89-5.89-5.89c-3.248,0-5.89,2.642-5.89,5.89h-0.14
c0-1.611,0.627-3.125,1.766-4.264c1.139-1.139,2.653-1.766,4.264-1.766c1.611,0,3.125,0.627,4.264,1.766
C254.578,464.957,255.205,466.471,255.205,468.082"/>
</g>
</g>
<g>
<rect x="248.868" y="461.814" style="fill:#FFFFFF;" width="0.616" height="0.616"/>
</g>
<g>
<rect x="244.95" y="462.052" style="fill:#FFFFFF;" width="8.45" height="0.14"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M245.174,462.15c0,0.108-0.088,0.196-0.196,0.196c-0.108,0-0.196-0.088-0.196-0.196
c0-0.108,0.088-0.196,0.196-0.196C245.086,461.954,245.174,462.042,245.174,462.15"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M253.596,462.15c0,0.108-0.088,0.196-0.196,0.196c-0.108,0-0.196-0.088-0.196-0.196
c0-0.108,0.088-0.196,0.196-0.196C253.509,461.954,253.596,462.042,253.596,462.15"/>
</g>
</g>
</g>
<g>
<path style="fill:#FFFFFF;" d="M314.356,473.409c0,1.559-2.364,1.559-2.364,0C311.993,471.851,314.356,471.851,314.356,473.409
z"/>
</g>
<g>
<g>
<g>
<path style="fill:#FFFFFF;" d="M161.739,466.549l1.772,6.088l1.855-6.088h2.215l-2.823,8.14h-2.33l-0.837-2.396l-0.722-2.708
l-0.722,2.708l-0.837,2.396h-2.33l-2.839-8.14h2.231l1.855,6.088l1.756-6.088H161.739z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M176.713,466.549l1.772,6.088l1.855-6.088h2.215l-2.823,8.14h-2.33l-0.837-2.396l-0.722-2.708
l-0.722,2.708l-0.837,2.396h-2.33l-2.839-8.14h2.231l1.855,6.088l1.756-6.088H176.713z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M191.687,466.549l1.772,6.088l1.855-6.088h2.215l-2.823,8.14h-2.33l-0.837-2.396l-0.722-2.708
l-0.722,2.708l-0.837,2.396h-2.33l-2.839-8.14h2.231l1.855,6.088l1.756-6.088H191.687z"/>
</g>
</g>
<g>
<path style="fill:#FFFFFF;" d="M200.908,473.52c0,1.559-2.364,1.559-2.364,0C198.545,471.962,200.908,471.962,200.908,473.52z
"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M322.71,473.409c-0.935,0.919-1.919,1.28-3.117,1.28c-2.346,0-4.3-1.411-4.3-4.282
s1.953-4.284,4.3-4.284c1.149,0,2.035,0.329,2.921,1.199l-1.264,1.329c-0.476-0.428-1.066-0.64-1.623-0.64
c-1.346,0-2.33,0.985-2.33,2.396c0,1.542,1.05,2.362,2.297,2.362c0.64,0,1.28-0.18,1.772-0.672L322.71,473.409z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M331.805,470.472c0,2.33-1.591,4.217-4.217,4.217c-2.626,0-4.201-1.887-4.201-4.217
c0-2.314,1.609-4.217,4.185-4.217C330.149,466.255,331.805,468.158,331.805,470.472z M325.389,470.472
c0,1.231,0.739,2.38,2.199,2.38c1.46,0,2.199-1.149,2.199-2.38c0-1.215-0.854-2.396-2.199-2.396
C326.144,468.077,325.389,469.258,325.389,470.472z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M338.572,474.689v-4.332c0-1.068-0.559-2.035-1.658-2.035c-1.082,0-1.722,0.967-1.722,2.035
v4.332h-2.003v-8.107h1.855l0.148,0.985c0.426-0.82,1.362-1.116,2.133-1.116c0.969,0,1.937,0.394,2.396,1.51
c0.723-1.149,1.658-1.478,2.708-1.478c2.297,0,3.43,1.412,3.43,3.84v4.365h-2.003v-4.365c0-1.066-0.442-1.97-1.526-1.97
c-1.082,0-1.756,0.935-1.756,2.003v4.332H338.572z"/>
</g>
</g>
</g>
</g>
<g style="opacity:0.61;">
<g>
<g>
<path style="fill:#FFFFFF;" d="M345.988,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C346.003,438.696,346.005,434.997,345.988,431.299z
M317.537,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
C316.987,417.166,316.991,417.162,317.537,417.162z M340.822,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
C341.375,451.574,341.37,451.579,340.822,451.579z"/>
</g>
<g>
<g>
<rect x="327.418" y="417.053" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="325.662" y="418.107" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="327.418" y="419.161" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="325.662" y="420.215" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="327.418" y="421.269" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="325.662" y="422.323" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="327.418" y="423.378" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="325.662" y="424.432" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="327.418" y="425.486" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="325.662" y="426.54" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="327.418" y="427.594" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
<g>
<rect x="325.662" y="428.648" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
</g>
</g>
</g>
<g>
<path style="fill:#FFFFFF;" d="M187.637,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C187.652,438.696,187.655,434.997,187.637,431.299z
M159.187,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
C158.636,417.166,158.64,417.162,159.187,417.162z M182.472,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
C183.024,451.574,183.019,451.579,182.472,451.579z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M159.779,440.669v-7.897h2.779c0.375,0,0.726,0.061,1.053,0.182
c0.327,0.121,0.612,0.292,0.855,0.513c0.242,0.221,0.434,0.483,0.573,0.789c0.14,0.305,0.21,0.642,0.21,1.009
c0,0.375-0.07,0.715-0.21,1.02c-0.14,0.305-0.331,0.568-0.573,0.789c-0.243,0.221-0.528,0.392-0.855,0.513
c-0.327,0.121-0.678,0.182-1.053,0.182h-1.29v2.901H159.779z M162.58,436.356c0.39,0,0.684-0.111,0.882-0.331
c0.199-0.22,0.298-0.474,0.298-0.761c0-0.14-0.024-0.276-0.072-0.408c-0.048-0.132-0.121-0.248-0.221-0.347
c-0.099-0.099-0.223-0.178-0.37-0.237c-0.147-0.059-0.32-0.089-0.518-0.089h-1.312v2.173H162.58z"/>
<path style="fill:#FFFFFF;" d="M166.308,432.771h1.731l3.177,5.294h0.088l-0.088-1.522v-3.772h1.478v7.897h-1.566l-3.353-5.592
h-0.088l0.088,1.522v4.07h-1.467V432.771z"/>
<path style="fill:#FFFFFF;" d="M177.922,436.334h3.872c0.022,0.089,0.04,0.195,0.055,0.32c0.014,0.125,0.022,0.25,0.022,0.375
c0,0.507-0.077,0.985-0.231,1.434c-0.154,0.449-0.397,0.849-0.728,1.202c-0.353,0.375-0.776,0.666-1.268,0.871
c-0.493,0.206-1.055,0.309-1.688,0.309c-0.574,0-1.114-0.103-1.622-0.309c-0.507-0.206-0.948-0.492-1.323-0.86
c-0.375-0.367-0.673-0.803-0.894-1.307c-0.221-0.504-0.331-1.053-0.331-1.649c0-0.595,0.11-1.145,0.331-1.649
c0.221-0.504,0.518-0.939,0.894-1.307c0.375-0.367,0.816-0.654,1.323-0.86c0.507-0.206,1.048-0.309,1.622-0.309
c0.64,0,1.211,0.11,1.715,0.331c0.504,0.221,0.935,0.526,1.296,0.915l-1.025,1.004c-0.258-0.272-0.544-0.48-0.861-0.623
c-0.316-0.143-0.695-0.215-1.136-0.215c-0.361,0-0.703,0.065-1.026,0.193c-0.324,0.129-0.607,0.311-0.85,0.546
c-0.242,0.235-0.436,0.52-0.579,0.855c-0.143,0.335-0.215,0.708-0.215,1.119c0,0.412,0.072,0.785,0.215,1.12
c0.143,0.335,0.338,0.62,0.584,0.855c0.246,0.235,0.531,0.418,0.855,0.546c0.323,0.129,0.669,0.193,1.037,0.193
c0.419,0,0.773-0.061,1.064-0.182c0.29-0.121,0.538-0.278,0.744-0.469c0.148-0.132,0.275-0.3,0.381-0.502
c0.106-0.202,0.189-0.428,0.248-0.678h-2.482V436.334z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M224.019,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
c0.271-0.002,0.541,0.008,0.809-0.058c0.997-0.246,1.69-1.044,1.694-2.069C224.034,438.696,224.036,434.997,224.019,431.299z
M195.568,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
C195.018,417.166,195.022,417.162,195.568,417.162z M218.854,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
C219.406,451.574,219.401,451.579,218.854,451.579z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M205.111,432.771h1.699l2.967,7.897h-1.644l-0.651-1.886h-3.044l-0.651,1.886h-1.643
L205.111,432.771z M206.997,437.415l-0.706-1.974l-0.287-0.96h-0.088l-0.287,0.96l-0.706,1.974H206.997z"/>
<path style="fill:#FFFFFF;" d="M211.331,434.536c-0.125,0-0.245-0.024-0.359-0.072c-0.114-0.048-0.213-0.114-0.298-0.199
c-0.084-0.084-0.151-0.182-0.198-0.292c-0.048-0.11-0.072-0.232-0.072-0.364s0.024-0.254,0.072-0.364
c0.048-0.11,0.114-0.208,0.198-0.292c0.084-0.084,0.184-0.151,0.298-0.198c0.114-0.048,0.233-0.072,0.359-0.072
c0.257,0,0.478,0.09,0.662,0.27c0.184,0.181,0.276,0.399,0.276,0.656s-0.092,0.476-0.276,0.656
C211.809,434.446,211.589,434.536,211.331,434.536z M210.615,440.669v-5.404h1.445v5.404H210.615z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M261.044,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C261.059,438.696,261.061,434.997,261.044,431.299z
M232.593,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
C232.042,417.166,232.047,417.162,232.593,417.162z M255.878,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
C256.431,451.574,256.426,451.579,255.878,451.579z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M236.361,440.845c-0.338,0-0.662-0.048-0.971-0.143c-0.309-0.095-0.592-0.239-0.849-0.43
c-0.257-0.191-0.481-0.425-0.673-0.7c-0.191-0.276-0.342-0.597-0.452-0.965l1.401-0.551c0.103,0.397,0.283,0.726,0.54,0.987
c0.257,0.261,0.596,0.392,1.015,0.392c0.154,0,0.303-0.02,0.447-0.061c0.143-0.04,0.272-0.099,0.386-0.176
s0.204-0.175,0.27-0.292c0.066-0.118,0.099-0.254,0.099-0.408c0-0.147-0.026-0.279-0.077-0.397
c-0.051-0.117-0.138-0.227-0.259-0.331c-0.121-0.103-0.28-0.202-0.475-0.298c-0.195-0.095-0.435-0.195-0.722-0.298l-0.485-0.176
c-0.213-0.073-0.429-0.173-0.645-0.298c-0.217-0.125-0.413-0.276-0.59-0.452c-0.177-0.176-0.322-0.384-0.436-0.623
c-0.114-0.239-0.171-0.509-0.171-0.81c0-0.309,0.06-0.597,0.182-0.866c0.121-0.268,0.294-0.503,0.518-0.706
c0.224-0.202,0.492-0.36,0.805-0.474s0.66-0.171,1.042-0.171c0.397,0,0.74,0.053,1.031,0.16
c0.291,0.107,0.537,0.243,0.739,0.408c0.202,0.165,0.366,0.348,0.491,0.546c0.125,0.199,0.217,0.386,0.276,0.563l-1.312,0.551
c-0.074-0.221-0.208-0.419-0.402-0.596c-0.195-0.176-0.462-0.265-0.8-0.265c-0.324,0-0.592,0.075-0.805,0.226
c-0.213,0.151-0.32,0.348-0.32,0.59c0,0.235,0.103,0.436,0.309,0.601c0.206,0.165,0.533,0.325,0.982,0.48l0.497,0.165
c0.316,0.111,0.605,0.237,0.866,0.381c0.261,0.143,0.485,0.314,0.673,0.513c0.187,0.199,0.331,0.425,0.43,0.678
c0.1,0.254,0.149,0.546,0.149,0.877c0,0.412-0.083,0.767-0.248,1.064c-0.165,0.298-0.377,0.542-0.634,0.734
c-0.258,0.191-0.548,0.335-0.872,0.43C236.986,440.797,236.67,440.845,236.361,440.845z"/>
<path style="fill:#FFFFFF;" d="M239.516,432.771h1.61l1.633,4.754l0.287,1.015h0.088l0.309-1.015l1.699-4.754h1.61l-2.879,7.897
h-1.566L239.516,432.771z"/>
<path style="fill:#FFFFFF;" d="M251.097,436.334h3.871c0.022,0.089,0.04,0.195,0.055,0.32c0.015,0.125,0.023,0.25,0.023,0.375
c0,0.507-0.078,0.985-0.232,1.434c-0.154,0.449-0.397,0.849-0.728,1.202c-0.353,0.375-0.775,0.666-1.268,0.871
c-0.493,0.206-1.055,0.309-1.688,0.309c-0.574,0-1.114-0.103-1.621-0.309c-0.507-0.206-0.949-0.492-1.324-0.86
c-0.375-0.367-0.673-0.803-0.894-1.307c-0.22-0.504-0.331-1.053-0.331-1.649c0-0.595,0.11-1.145,0.331-1.649
c0.221-0.504,0.518-0.939,0.894-1.307c0.375-0.367,0.816-0.654,1.324-0.86c0.507-0.206,1.047-0.309,1.621-0.309
c0.64,0,1.211,0.11,1.715,0.331c0.504,0.221,0.936,0.526,1.296,0.915l-1.026,1.004c-0.257-0.272-0.544-0.48-0.861-0.623
c-0.316-0.143-0.694-0.215-1.136-0.215c-0.36,0-0.702,0.065-1.026,0.193c-0.323,0.129-0.607,0.311-0.849,0.546
c-0.243,0.235-0.436,0.52-0.579,0.855c-0.143,0.335-0.215,0.708-0.215,1.119c0,0.412,0.072,0.785,0.215,1.12
c0.143,0.335,0.338,0.62,0.585,0.855c0.246,0.235,0.531,0.418,0.854,0.546c0.324,0.129,0.669,0.193,1.037,0.193
c0.419,0,0.774-0.061,1.064-0.182c0.29-0.121,0.539-0.278,0.745-0.469c0.147-0.132,0.274-0.3,0.38-0.502
c0.107-0.202,0.189-0.428,0.248-0.678h-2.482V436.334z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M297.3,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C297.315,438.696,297.318,434.997,297.3,431.299z
M268.85,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
C268.299,417.166,268.303,417.162,268.85,417.162z M292.135,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.001,1.997,0.001,3.994,0,5.991
C292.687,451.574,292.682,451.579,292.135,451.579z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M272.966,434.183v1.831h3.165v1.412h-3.165v1.831h3.518v1.412h-5.007v-7.897h5.007v1.412H272.966
z"/>
<path style="fill:#FFFFFF;" d="M277.852,440.669v-7.897h2.779c0.375,0,0.726,0.061,1.053,0.182
c0.327,0.121,0.612,0.292,0.855,0.513c0.243,0.221,0.434,0.483,0.574,0.789c0.14,0.305,0.209,0.642,0.209,1.009
c0,0.375-0.07,0.715-0.209,1.02c-0.14,0.305-0.331,0.568-0.574,0.789c-0.243,0.221-0.528,0.392-0.855,0.513
c-0.327,0.121-0.678,0.182-1.053,0.182h-1.29v2.901H277.852z M280.653,436.356c0.389,0,0.684-0.111,0.882-0.331
c0.199-0.22,0.298-0.474,0.298-0.761c0-0.14-0.024-0.276-0.072-0.408c-0.048-0.132-0.121-0.248-0.221-0.347
c-0.099-0.099-0.222-0.178-0.37-0.237c-0.147-0.059-0.32-0.089-0.518-0.089h-1.312v2.173H280.653z"/>
<path style="fill:#FFFFFF;" d="M286.797,440.845c-0.338,0-0.662-0.048-0.971-0.143c-0.309-0.095-0.592-0.239-0.849-0.43
c-0.257-0.191-0.482-0.425-0.673-0.7c-0.191-0.276-0.342-0.597-0.452-0.965l1.401-0.551c0.103,0.397,0.283,0.726,0.541,0.987
c0.257,0.261,0.595,0.392,1.015,0.392c0.154,0,0.303-0.02,0.447-0.061c0.143-0.04,0.272-0.099,0.386-0.176
c0.114-0.077,0.204-0.175,0.27-0.292c0.066-0.118,0.1-0.254,0.1-0.408c0-0.147-0.026-0.279-0.077-0.397
c-0.051-0.117-0.138-0.227-0.259-0.331c-0.121-0.103-0.279-0.202-0.474-0.298c-0.195-0.095-0.436-0.195-0.723-0.298
l-0.485-0.176c-0.213-0.073-0.428-0.173-0.645-0.298c-0.217-0.125-0.414-0.276-0.59-0.452c-0.176-0.176-0.322-0.384-0.436-0.623
c-0.114-0.239-0.171-0.509-0.171-0.81c0-0.309,0.061-0.597,0.182-0.866c0.121-0.268,0.294-0.503,0.518-0.706
c0.224-0.202,0.493-0.36,0.805-0.474c0.312-0.114,0.66-0.171,1.042-0.171c0.397,0,0.741,0.053,1.031,0.16
c0.29,0.107,0.537,0.243,0.739,0.408c0.202,0.165,0.365,0.348,0.491,0.546c0.125,0.199,0.217,0.386,0.276,0.563l-1.312,0.551
c-0.074-0.221-0.208-0.419-0.403-0.596c-0.195-0.176-0.462-0.265-0.799-0.265c-0.324,0-0.592,0.075-0.805,0.226
c-0.213,0.151-0.32,0.348-0.32,0.59c0,0.235,0.103,0.436,0.309,0.601c0.206,0.165,0.533,0.325,0.982,0.48l0.496,0.165
c0.316,0.111,0.605,0.237,0.866,0.381c0.261,0.143,0.485,0.314,0.673,0.513c0.187,0.199,0.331,0.425,0.43,0.678
c0.099,0.254,0.149,0.546,0.149,0.877c0,0.412-0.083,0.767-0.248,1.064c-0.165,0.298-0.377,0.542-0.634,0.734
c-0.258,0.191-0.548,0.335-0.872,0.43C287.422,440.797,287.105,440.845,286.797,440.845z"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M321.394,439.168l4.004-4.985h-3.827v-1.412h5.559v1.5l-3.96,4.985h4.004v1.412h-5.779V439.168z"
/>
<path style="fill:#FFFFFF;" d="M328.409,432.771h1.489v7.897h-1.489V432.771z"/>
<path style="fill:#FFFFFF;" d="M331.486,440.669v-7.897h2.779c0.375,0,0.726,0.061,1.053,0.182
c0.327,0.121,0.612,0.292,0.855,0.513s0.434,0.483,0.574,0.789c0.14,0.305,0.209,0.642,0.209,1.009
c0,0.375-0.07,0.715-0.209,1.02c-0.14,0.305-0.331,0.568-0.574,0.789c-0.243,0.221-0.528,0.392-0.855,0.513
c-0.327,0.121-0.678,0.182-1.053,0.182h-1.29v2.901H331.486z M334.288,436.356c0.389,0,0.684-0.111,0.882-0.331
c0.199-0.22,0.298-0.474,0.298-0.761c0-0.14-0.024-0.276-0.072-0.408c-0.048-0.132-0.121-0.248-0.221-0.347
c-0.099-0.099-0.222-0.178-0.37-0.237c-0.147-0.059-0.32-0.089-0.518-0.089h-1.312v2.173H334.288z"/>
</g>
</g>
<g style="opacity:0.61;">
<path style="fill:#FFFFFF;" d="M300.133,433.27h9.067v2.242h-9.067V433.27z M300.133,437.136h9.067v2.243h-9.067V437.136z"/>
</g>
</g>
<g style="opacity:0.61;">
<path style="fill:#FFFFFF;" d="M156.756,478.878h1.607c1.263,0,2.114,0.812,2.114,1.974c0,1.161-0.851,1.973-2.114,1.973h-1.607
V478.878z M158.34,482.464c1.049,0,1.725-0.665,1.725-1.612c0-0.947-0.677-1.613-1.725-1.613h-1.167v3.225H158.34z"/>
<path style="fill:#FFFFFF;" d="M165.139,480.851c0-1.15,0.879-2.007,2.075-2.007c1.184,0,2.069,0.851,2.069,2.007
c0,1.156-0.885,2.007-2.069,2.007C166.019,482.858,165.139,482.002,165.139,480.851z M168.866,480.851
c0-0.942-0.705-1.635-1.652-1.635c-0.953,0-1.663,0.693-1.663,1.635c0,0.941,0.71,1.635,1.663,1.635
C168.162,482.486,168.866,481.793,168.866,480.851z"/>
<path style="fill:#FFFFFF;" d="M179.596,478.878l-1.331,3.947h-0.44l-1.156-3.366l-1.161,3.366h-0.434l-1.331-3.947h0.429
l1.139,3.394l1.178-3.394h0.389l1.161,3.411l1.156-3.411H179.596z"/>
<path style="fill:#FFFFFF;" d="M187.731,478.878v3.947h-0.344l-2.537-3.202v3.202h-0.417v-3.947h0.344l2.543,3.203v-3.203H187.731
z"/>
<path style="fill:#FFFFFF;" d="M193.093,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
<path style="fill:#FFFFFF;" d="M200.061,480.851c0-1.15,0.879-2.007,2.075-2.007c1.184,0,2.069,0.851,2.069,2.007
c0,1.156-0.885,2.007-2.069,2.007C200.941,482.858,200.061,482.002,200.061,480.851z M203.788,480.851
c0-0.942-0.705-1.635-1.652-1.635c-0.953,0-1.663,0.693-1.663,1.635c0,0.941,0.71,1.635,1.663,1.635
C203.083,482.486,203.788,481.793,203.788,480.851z"/>
<path style="fill:#FFFFFF;" d="M211.636,481.77h-2.199l-0.474,1.054h-0.434l1.804-3.947h0.412l1.804,3.947h-0.44L211.636,481.77z
M211.484,481.432l-0.947-2.12l-0.947,2.12H211.484z"/>
<path style="fill:#FFFFFF;" d="M217.28,478.878h1.607c1.263,0,2.114,0.812,2.114,1.974c0,1.161-0.851,1.973-2.114,1.973h-1.607
V478.878z M218.864,482.464c1.049,0,1.725-0.665,1.725-1.612c0-0.947-0.677-1.613-1.725-1.613h-1.167v3.225H218.864z"/>
<path style="fill:#FFFFFF;" d="M234.041,481.77h-2.199l-0.474,1.054h-0.434l1.804-3.947h0.412l1.804,3.947h-0.44L234.041,481.77z
M233.889,481.432l-0.947-2.12l-0.947,2.12H233.889z"/>
<path style="fill:#FFFFFF;" d="M239.685,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
<path style="fill:#FFFFFF;" d="M247.082,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
<path style="fill:#FFFFFF;" d="M260.449,479.239v1.551h2.041v0.361h-2.041v1.675h-0.417v-3.947h2.706v0.361H260.449z"/>
<path style="fill:#FFFFFF;" d="M267.678,478.878h0.417v3.947h-0.417V478.878z"/>
<path style="fill:#FFFFFF;" d="M273.456,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
<path style="fill:#FFFFFF;" d="M283.644,482.464v0.361h-2.791v-3.947h2.706v0.361h-2.289v1.404h2.041v0.355h-2.041v1.466H283.644z
"/>
<path style="fill:#FFFFFF;" d="M294.672,479.239v1.551h2.041v0.361h-2.041v1.675h-0.417v-3.947h2.706v0.361H294.672z"/>
<path style="fill:#FFFFFF;" d="M301.5,480.851c0-1.15,0.879-2.007,2.075-2.007c1.184,0,2.069,0.851,2.069,2.007
c0,1.156-0.885,2.007-2.069,2.007C302.379,482.858,301.5,482.002,301.5,480.851z M305.226,480.851
c0-0.942-0.705-1.635-1.652-1.635c-0.953,0-1.663,0.693-1.663,1.635c0,0.941,0.71,1.635,1.663,1.635
C304.522,482.486,305.226,481.793,305.226,480.851z"/>
<path style="fill:#FFFFFF;" d="M313.351,482.825l-0.902-1.269c-0.102,0.011-0.203,0.017-0.316,0.017h-1.06v1.252h-0.417v-3.947
h1.477c1.004,0,1.613,0.507,1.613,1.353c0,0.62-0.327,1.054-0.902,1.24l0.964,1.353H313.351z M313.328,480.231
c0-0.632-0.417-0.992-1.207-0.992h-1.048v1.979h1.048C312.911,481.218,313.328,480.851,313.328,480.231z"/>
<path style="fill:#FFFFFF;" d="M322.907,478.878v3.947h-0.4v-3.158l-1.551,2.656h-0.197l-1.551-2.639v3.14h-0.4v-3.947h0.344
l1.714,2.926l1.697-2.926H322.907z"/>
<path style="fill:#FFFFFF;" d="M330.744,481.77h-2.199l-0.473,1.054h-0.434l1.804-3.947h0.411l1.804,3.947h-0.44L330.744,481.77z
M330.592,481.432l-0.947-2.12l-0.947,2.12H330.592z"/>
<path style="fill:#FFFFFF;" d="M336.957,479.239h-1.387v-0.361h3.192v0.361h-1.387v3.586h-0.417V479.239z"/>
<path style="fill:#FFFFFF;" d="M343.063,482.346l0.164-0.321c0.282,0.276,0.784,0.479,1.302,0.479c0.739,0,1.06-0.31,1.06-0.699
c0-1.083-2.43-0.417-2.43-1.877c0-0.581,0.451-1.083,1.455-1.083c0.446,0,0.908,0.13,1.224,0.35l-0.141,0.333
c-0.338-0.22-0.733-0.327-1.083-0.327c-0.722,0-1.043,0.321-1.043,0.716c0,1.083,2.43,0.429,2.43,1.866
c0,0.581-0.462,1.077-1.472,1.077C343.937,482.858,343.356,482.65,343.063,482.346z"/>
</g>
</g>
<g>
</g>
<g>
<path d="M372.927,129.733l-0.308-0.182l-0.714-0.218C372.192,129.576,372.552,129.717,372.927,129.733z"/>
<path d="M377.441,161.889l-0.345,0.097L377.441,161.889z"/>
<path d="M373.01,129.512c-0.035-0.005-0.071-0.013-0.105-0.025c-0.001,0.023-0.001,0.047,0,0.07
C372.944,129.552,372.98,129.537,373.01,129.512z"/>
<path d="M377.134,161.713l0.521-0.297l0.193-0.109l0.176-0.188C377.693,161.263,377.392,161.464,377.134,161.713z"/>
<path d="M373.796,130.364l-0.508-0.484l-0.345-0.188C373.128,130.02,373.434,130.261,373.796,130.364z"/>
<path d="M245.83,442.334c-0.407,0.176-0.763,0.45-1.036,0.799l0.32-0.206C245.333,442.728,245.642,442.491,245.83,442.334z"/>
<path d="M320.198,427.707c0-0.461-0.224-0.375-0.169,1.259c0-0.133,0.054-0.266,0.079-0.392
C320.137,428.282,320.161,427.997,320.198,427.707z"/>
<path d="M312.48,442.334c-0.407,0.176-0.763,0.45-1.036,0.799l0.322-0.206C311.984,442.728,312.292,442.491,312.48,442.334z"/>
<path d="M193.525,445.867c-0.308-0.268-0.686-0.444-1.09-0.508c0.327,0.158,0.654,0.315,0.872,0.436L193.525,445.867z"/>
<path d="M181.804,434.564c-0.048-0.476-0.195-0.938-0.43-1.356c0.167,0.434,0.306,0.879,0.418,1.332L181.804,434.564z"/>
<path style="fill:#FCDB2B;" d="M260.848,232.808c-16.163,6.92-34.507,14.766-58.281,14.766c-9.945-0.021-19.842-1.385-29.422-4.057
l16.442,168.812c0.582,7.056,3.796,13.634,9.005,18.43c5.208,4.796,12.03,7.458,19.11,7.456c0,0,23.313,1.21,31.092,1.21
c8.374,0,33.478-1.21,33.478-1.21c7.08,0,13.899-2.663,19.106-7.458c5.207-4.796,8.421-11.374,9.002-18.429l17.611-186.544
c-7.87-2.688-15.813-4.473-24.767-4.473C287.739,221.305,275.261,226.639,260.848,232.808z"/>
<path d="M122.222,160.915l0.279,0.26l0.182,0.109C122.542,161.146,122.388,161.022,122.222,160.915z"/>
<path d="M404.039,145.275l-2.475-12.489c-2.222-11.206-7.265-21.794-18.767-25.844c-3.687-1.295-7.87-1.852-10.697-4.534
c-2.827-2.682-3.663-6.847-4.317-10.709c-1.21-7.089-2.348-14.184-3.59-21.261c-1.071-6.084-1.919-12.919-4.711-18.501
c-3.632-7.495-11.169-11.878-18.664-14.777c-3.84-1.434-7.759-2.646-11.738-3.632c-18.725-4.94-38.412-6.756-57.675-7.791
c-23.122-1.276-46.305-0.891-69.372,1.15c-17.169,1.562-35.252,3.451-51.567,9.39c-5.963,2.173-12.108,4.782-16.642,9.389
c-5.564,5.66-7.38,14.414-3.317,21.473c2.888,5.013,7.779,8.554,12.967,10.897c6.758,3.019,13.815,5.316,21.055,6.853
c20.159,4.456,41.039,6.205,61.635,6.95c22.827,0.921,45.691,0.175,68.409-2.234c5.617-0.617,11.226-1.358,16.824-2.222
c6.593-1.011,10.824-9.632,8.88-15.637c-2.324-7.18-8.572-9.965-15.637-8.881c-1.041,0.164-2.076,0.315-3.117,0.466l-0.751,0.109
c-2.394,0.303-4.787,0.585-7.181,0.848c-4.943,0.533-9.9,0.969-14.868,1.308c-11.127,0.775-22.284,1.132-33.436,1.15
c-10.957,0-21.92-0.309-32.854-1.029c-4.988-0.327-9.965-0.743-14.929-1.247c-2.258-0.236-4.51-0.484-6.762-0.763l-2.143-0.272
l-0.466-0.067l-2.222-0.321c-4.54-0.684-9.081-1.471-13.573-2.422c-0.453-0.101-0.859-0.353-1.149-0.715s-0.449-0.813-0.449-1.277
c0-0.464,0.158-0.915,0.449-1.277c0.291-0.362,0.696-0.614,1.149-0.715h0.085c3.893-0.829,7.816-1.538,11.751-2.155
c1.312-0.206,2.627-0.408,3.947-0.605h0.036c2.464-0.163,4.94-0.605,7.392-0.896c21.332-2.219,42.791-2.975,64.225-2.264
c10.407,0.303,20.807,0.914,31.165,1.968c2.227,0.23,4.444,0.472,6.66,0.745c0.848,0.103,1.701,0.224,2.554,0.327l1.719,0.248
c5.012,0.747,9.999,1.653,14.96,2.718c7.349,1.598,16.787,2.119,20.056,10.171c1.041,2.555,1.513,5.394,2.088,8.076l0.732,3.42
c0.02,0.061,0.033,0.124,0.042,0.188c1.732,8.072,3.465,16.144,5.201,24.215c0.126,0.596,0.13,1.212,0.008,1.81
c-0.121,0.597-0.365,1.164-0.714,1.663c-0.35,0.499-0.799,0.921-1.319,1.239c-0.521,0.318-1.101,0.526-1.705,0.609h-0.049
l-1.059,0.145l-1.047,0.139c-3.317,0.432-6.639,0.835-9.964,1.211c-6.551,0.747-13.111,1.392-19.681,1.937
c-13.057,1.086-26.138,1.798-39.248,2.137c-6.679,0.177-13.356,0.26-20.031,0.248c-26.572-0.021-53.118-1.565-79.512-4.625
c-2.857-0.339-5.715-0.702-8.572-1.072c2.216,0.285-1.61-0.218-2.385-0.327c-1.816-0.254-3.632-0.519-5.449-0.793
c-6.096-0.914-12.156-2.04-18.24-3.027c-7.356-1.211-14.39-0.605-21.043,3.027c-5.461,2.989-9.881,7.571-12.671,13.137
c-2.87,5.933-3.723,12.392-5.007,18.767c-1.283,6.375-3.281,13.234-2.524,19.778c1.628,14.124,11.502,25.602,25.705,28.169
c13.361,2.422,26.794,4.382,40.264,6.053c52.913,6.481,106.368,7.255,159.447,2.313c4.322-0.403,8.639-0.844,12.949-1.319
c1.347-0.148,2.709,0.007,3.987,0.454c1.278,0.446,2.441,1.173,3.402,2.128c0.961,0.954,1.697,2.112,2.152,3.386
c0.457,1.276,0.621,2.637,0.483,3.985l-1.344,13.063c-2.708,26.4-5.415,52.797-8.124,79.191c-2.824,27.719-5.669,55.435-8.53,83.15
c-0.807,7.805-1.614,15.61-2.422,23.411c-0.774,7.682-0.883,15.607-2.343,23.198c-2.299,11.939-10.382,19.269-22.175,21.952
c-10.805,2.458-21.841,3.749-32.921,3.85c-12.284,0.067-24.561-0.478-36.843-0.412c-13.113,0.074-29.174-1.138-39.296-10.896
c-8.893-8.572-10.122-21.994-11.333-33.599c-1.614-15.365-3.215-30.728-4.801-46.088l-8.899-85.414l-5.757-55.267
c-0.097-0.913-0.194-1.815-0.285-2.735c-0.69-6.593-5.358-13.046-12.713-12.714c-6.296,0.28-13.452,5.631-12.713,12.714
l4.268,40.972l8.827,84.753c2.514,24.075,5.023,48.153,7.525,72.235c0.484,4.613,0.938,9.239,1.447,13.852
c2.767,25.208,22.018,38.792,45.858,42.62c13.924,2.239,28.187,2.7,42.316,2.929c18.114,0.29,36.407,0.987,54.225-2.294
c26.401-4.843,46.209-22.473,49.036-49.817c0.807-7.895,1.614-15.791,2.422-23.689c2.684-26.12,5.364-52.243,8.039-78.367
l8.754-85.36l4.014-39.12c0.199-1.94,1.02-3.763,2.336-5.201c1.316-1.438,3.062-2.414,4.977-2.784
c7.549-1.471,14.766-3.983,20.135-9.728C405.359,169.225,407.06,157.298,404.039,145.275z M120.058,153.714
c0.115-0.054-0.097,0.933-0.188,1.392C119.852,154.411,119.889,153.793,120.058,153.714z M120.791,159.381
c0.061-0.043,0.242,0.199,0.43,0.49c-0.285-0.266-0.466-0.466-0.436-0.49H120.791z M121.511,160.331
C121.771,160.774,121.911,161.052,121.511,160.331L121.511,160.331z M122.958,161.506h0.036c0,0.042,0.067,0.084,0.091,0.127
c-0.04-0.047-0.085-0.089-0.133-0.127H122.958z M376.324,159.75c-2.712,2.579-6.797,3.777-10.836,4.377
c-45.283,6.72-91.225,10.122-137.005,8.62c-32.763-1.12-65.182-4.758-97.618-9.341c-3.178-0.448-6.623-1.029-8.808-3.372
c-4.117-4.419-2.095-13.319-1.023-18.658c0.981-4.892,2.857-11.412,8.675-12.108c9.081-1.065,19.627,2.767,28.611,4.129
c10.816,1.651,21.673,2.972,32.57,3.965c46.506,4.238,93.793,3.578,140.093-2.621c8.439-1.134,16.847-2.452,25.226-3.953
c7.464-1.338,15.741-3.85,20.251,3.881c3.094,5.267,3.506,12.313,3.027,18.264c-0.147,2.593-1.28,5.032-3.166,6.817H376.324z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 39 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" transform="scale(64)" fill="#1B1F23"/>
</svg>

After

Width:  |  Height:  |  Size: 968 B

+27 -9
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Piperless v1.1.0 — Developer Documentation</title>
<title>Piperless v1.1.4 — Developer Documentation</title>
<style>
:root {
--bg: #ffffff;
@@ -55,7 +55,7 @@ td:first-child { font-family: "SF Mono", Monaco, monospace; font-size: 13px; }
<body>
<nav>
<h2>Piperless 1.1.0</h2>
<h2>Piperless 1.1.4</h2>
<a href="#overview">Overview</a>
<a href="#architecture">Architecture</a>
<a href="#plugin">Plugin (Orchestrator)</a>
@@ -74,7 +74,7 @@ td:first-child { font-family: "SF Mono", Monaco, monospace; font-size: 13px; }
<main>
<h1>Piperless</h1>
<p>WordPress Plugin — Audio Transcripts via Piper TTS &middot; v1.1.0 &middot; Generated 2026-05-09</p>
<p>WordPress Plugin — Audio Transcripts via Piper TTS &middot; v1.1.4 &middot; Generated 2026-05-11</p>
<h2 id="overview">Overview</h2>
<p>
@@ -90,7 +90,7 @@ HTML5 audio player on the frontend.
<li>8 PHP classes, ~4,000 lines</li>
<li>7 admin panel tabs, 4 REST API endpoints</li>
<li>6 player themes + Custom CSS</li>
<li>Full nl_NL translation (98 strings)</li>
<li>8 complete translations — DE, FR, ES, IT, JA, NL, PT, ZH (118 strings each)</li>
</ul>
<h2 id="architecture">Architecture</h2>
@@ -324,11 +324,11 @@ based on the <code>?tab=</code> query parameter. Custom field types (<code>mode
<h4>Themes</h4>
<table>
<tr><th>CSS Class</th><th>Name</th><th>Accent</th></tr>
<tr><td>piperless-player--classic</td><td>Classic</td><td>#2271b1 (blue)</td></tr>
<tr><td>piperless-player--minimal</td><td>Minimal</td><td>#333333 (dark gray), no border</td></tr>
<tr><td>piperless-player--dark</td><td>Modern Dark</td><td>#2271b1 on dark bg</td></tr>
<tr><td>piperless-player--newsviews</td><td>NewsViews</td><td>#B31942 (burgundy)</td></tr>
<tr><td>piperless-player--newsviews-classic</td><td>NewsViews Classic</td><td>#233452 (navy)</td></tr>
<tr><td>piperless-player--classic</td><td>Classic</td><td>Blue accent, clean borders</td></tr>
<tr><td>piperless-player--minimal</td><td>Minimal</td><td>Clean, understated</td></tr>
<tr><td>piperless-player--dark</td><td>Modern Dark</td><td>Dark background</td></tr>
<tr><td>piperless-player--newsviews</td><td>Ron Burgundy</td><td>Bold burgundy</td></tr>
<tr><td>piperless-player--newsviews-classic</td><td>Dan Rather Blue</td><td>Classic navy</td></tr>
<tr><td></td><td>Custom CSS</td><td>User-defined via textarea (sanitized)</td></tr>
</table>
@@ -438,6 +438,24 @@ for deterministic attribution.
<li>@ suppression on filesystem calls with error_clear_last() + log_last_error() for diagnostics</li>
</ul>
<h2 id="build">Build &amp; Tooling</h2>
<p>The <code>Makefile</code> wraps the build and translation toolchain:</p>
<table>
<tr><th>Command</th><th>Action</th></tr>
<tr><td><code>make build</code></td><td>Create piperless-X.Y.Z.zip</td></tr>
<tr><td><code>make translations</code></td><td>Extract .pot → JSON, sync to all locales</td></tr>
<tr><td><code>make json2po</code></td><td>Convert JSON translations back to .po/.mo</td></tr>
<tr><td><code>make check-translations</code></td><td>Validate translation integrity</td></tr>
<tr><td><code>make lock-translations</code></td><td>Lock all locales for translation work</td></tr>
<tr><td><code>make unlock-translations</code></td><td>Release all translation locks</td></tr>
<tr><td><code>make translation-status</code></td><td>Show lock/completion for each locale</td></tr>
<tr><td><code>make clean</code></td><td>Remove build artifacts</td></tr>
</table>
<p>All tools run as standalone shell scripts in <code>tools/</code> — the Makefile is a convenience wrapper.</p>
</main>
</body>
</html>
+319
View File
@@ -0,0 +1,319 @@
<?php
/**
* Dashboard widget — audio storage at a glance.
*
* @package Piperless
*/
declare(strict_types=1);
namespace Piperless;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Dashboard widget.
*
* Registers a WordPress dashboard widget (togglable via Screen Options)
* that shows:
*
* - Counts and total size of WAV, MP3, and Opus files in the cache
* - Number of published posts without an audio transcript
* - Available disk space on the server
*
* @since 1.1.4
*/
class Dashboard {
/** @var Logger */
private Logger $logger;
/** @var Cache_Manager */
private Cache_Manager $cache;
/** @var string Widget slug. */
private string $widget_id = 'piperless_dashboard';
/**
* Constructor.
*
* @param Logger $logger Logger.
* @param Cache_Manager $cache Cache manager.
*/
public function __construct( Logger $logger, Cache_Manager $cache ) {
$this->logger = $logger;
$this->cache = $cache;
}
/**
* Register hooks.
*/
public function init(): void {
add_action( 'wp_dashboard_setup', [ $this, 'register_widget' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_styles' ] );
}
/**
* Register the dashboard widget.
*/
public function register_widget(): void {
wp_add_dashboard_widget(
$this->widget_id,
__( 'Piperless — Audio Storage', 'piperless' ),
[ $this, 'render' ]
);
}
/**
* Render the dashboard widget.
*/
public function render(): void {
$file_stats = $this->get_file_stats();
$without = $this->get_posts_without_audio();
$disk = $this->get_disk_usage();
$total_files = ( $file_stats['mp3']['count'] ?? 0 )
+ ( $file_stats['wav']['count'] ?? 0 )
+ ( $file_stats['opus']['count'] ?? 0 );
?>
<div class="piperless-dashboard">
<?php if ( 0 === $total_files ) : ?>
<p class="piperless-dash-empty"><?php esc_html_e( 'No audio files generated yet. Publish a post or generate audio from the editor sidebar.', 'piperless' ); ?></p>
<?php else : ?>
<div class="piperless-dash-grid">
<?php $this->render_file_card(
__( 'Opus', 'piperless' ),
$file_stats['opus'] ?? [ 'count' => 0, 'bytes' => 0 ],
'#1565c0'
); ?>
<?php $this->render_file_card(
__( 'MP3', 'piperless' ),
$file_stats['mp3'] ?? [ 'count' => 0, 'bytes' => 0 ],
'#008a20'
); ?>
<?php $this->render_file_card(
__( 'WAV', 'piperless' ),
$file_stats['wav'] ?? [ 'count' => 0, 'bytes' => 0 ],
'#f56e28'
); ?>
</div>
<?php endif; ?>
<div class="piperless-dash-info">
<div class="piperless-dash-info-item piperless-dash-info-posts">
<span class="piperless-dash-info-text">
<?php
printf(
/* translators: %d: number of posts without audio */
esc_html( _n(
'%d post without an audio transcript.',
'%d posts without an audio transcript.',
$without,
'piperless'
) ),
$without
);
?>
</span>
<?php if ( $without > 0 ) : ?>
<a href="<?php echo esc_url( admin_url( 'edit.php?post_type=post' ) ); ?>" class="piperless-dash-info-link">
<?php esc_html_e( 'View posts', 'piperless' ); ?>
</a>
<?php endif; ?>
</div>
<div class="piperless-dash-info-item piperless-dash-info-storage">
<div class="piperless-dash-info-body">
<span class="piperless-dash-info-text">
<?php
printf(
/* translators: 1: free space, 2: total space */
esc_html__( 'Server storage: %1$s free of %2$s', 'piperless' ),
esc_html( $this->human_size( $disk['free'] ) ),
esc_html( $this->human_size( $disk['total'] ) )
);
?>
</span>
<div class="piperless-dash-bar">
<div class="piperless-dash-bar-fill" style="width:<?php echo esc_attr( (string) round( $disk['pct'] ) ); ?>%;"></div>
</div>
<span class="piperless-dash-bar-label">
<?php
printf(
/* translators: %s: percentage used */
esc_html__( '%s%% used', 'piperless' ),
esc_html( (string) round( $disk['pct'] ) )
);
?>
</span>
</div>
</div>
</div>
</div>
<?php
}
/**
* Render a single file-type stat card.
*
* @param string $label e.g. "MP3".
* @param array $stats ['count' => int, 'bytes' => int].
* @param string $color Accent color hex.
*/
private function render_file_card( string $label, array $stats, string $color ): void {
$count = $stats['count'] ?? 0;
$size = $this->human_size( $stats['bytes'] ?? 0 );
?>
<div class="piperless-dash-card" style="--card-accent: <?php echo esc_attr( $color ); ?>;">
<div class="piperless-dash-card-value"><?php echo esc_html( (string) $count ); ?></div>
<div class="piperless-dash-card-label"><?php echo esc_html( $label ); ?></div>
<div class="piperless-dash-card-sub"><?php echo esc_html( $size ); ?></div>
</div>
<?php
}
/**
* Scan the cache directory and return per-format file counts and byte totals.
*
* @return array<string,array{count:int,bytes:int}>
*/
private function get_file_stats(): array {
$cache_dir = $this->cache->dir();
$stats = [
'mp3' => [ 'count' => 0, 'bytes' => 0 ],
'wav' => [ 'count' => 0, 'bytes' => 0 ],
'opus' => [ 'count' => 0, 'bytes' => 0 ],
];
if ( ! is_dir( $cache_dir ) ) {
return $stats;
}
foreach ( [ 'mp3', 'wav', 'opus' ] as $ext ) {
$files = (array) glob( $cache_dir . '/*.' . $ext );
foreach ( $files as $file ) {
$size = @filesize( $file );
if ( false !== $size ) {
$stats[ $ext ]['count']++;
$stats[ $ext ]['bytes'] += $size;
}
}
}
return $stats;
}
/**
* Count published posts / pages without an audio transcript.
*
* @return int
*/
private function get_posts_without_audio(): int {
global $wpdb;
$types = $this->supported_post_types();
$placeholders = implode( ',', array_fill( 0, count( $types ), '%s' ) );
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$count = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*)
FROM {$wpdb->posts} p
WHERE p.post_type IN ( {$placeholders} )
AND p.post_status = 'publish'
AND NOT EXISTS (
SELECT 1 FROM {$wpdb->postmeta} pm
WHERE pm.post_id = p.ID
AND pm.meta_key = '_piperless_audio_url'
AND pm.meta_value != ''
)",
...$types
)
);
return (int) $count;
}
/**
* Get disk usage stats for the uploads directory volume.
*
* @return array{total:float,free:float,used:float,pct:float}
*/
private function get_disk_usage(): array {
$dir = $this->cache->dir();
// Walk up until we find a directory that exists.
while ( ! is_dir( $dir ) && '/' !== $dir ) {
$dir = dirname( $dir );
}
$total = @disk_total_space( $dir );
$free = @disk_free_space( $dir );
$fallback = [ 'total' => 0.0, 'free' => 0.0, 'used' => 0.0, 'pct' => 0.0 ];
if ( false === $total || null === $total || false === $free || null === $free || $total <= 0.0 ) {
return $fallback;
}
$used = $total - $free;
$pct = ( $used / $total ) * 100.0;
return [
'total' => (float) $total,
'free' => (float) $free,
'used' => (float) $used,
'pct' => (float) $pct,
];
}
/**
* Format bytes as a human-readable string.
*
* @param float $bytes Raw byte count.
* @return string e.g. "24.5 MB"
*/
private function human_size( float $bytes ): string {
if ( $bytes <= 0.0 ) {
return '0 B';
}
$units = [ 'B', 'KB', 'MB', 'GB', 'TB' ];
$exp = (int) floor( log( $bytes, 1024 ) );
$exp = min( $exp, count( $units ) - 1 );
$val = $bytes / ( 1024 ** $exp );
return round( $val, 1 ) . ' ' . $units[ $exp ];
}
/**
* Enqueue dashboard-specific styles on the dashboard page only.
*
* @param string $hook_suffix Current admin page hook.
*/
public function enqueue_styles( string $hook_suffix ): void {
if ( 'index.php' !== $hook_suffix ) {
return;
}
wp_enqueue_style(
'piperless-dashboard',
PIPERLESS_PLUGIN_URL . 'assets/css/dashboard.css',
[],
PIPERLESS_VERSION
);
}
/**
* Supported post types for audio transcripts.
*
* @return string[]
*/
private function supported_post_types(): array {
$types = apply_filters( 'piperless_post_types', [ 'post', 'page' ] );
return is_array( $types ) ? $types : [ 'post' ];
}
}
+2 -2
View File
@@ -29,8 +29,8 @@ if ( ! defined( 'ABSPATH' ) ) {
*
* ## Player style
*
* Six themes are available (Classic, Minimal, Modern Dark, NewsViews,
* NewsViews Classic, Custom CSS). The theme class is applied as
* Six themes are available (Classic, Minimal, Modern Dark, Ron Burgundy,
* Dan Rather Blue, Custom CSS). The theme class is applied as
* piperless-player--<style> on the container div. Per-post override
* via _piperless_style meta.
*
+5
View File
@@ -57,6 +57,9 @@ class Plugin {
/** @var Gutenberg */
private Gutenberg $gutenberg;
/** @var Dashboard */
private Dashboard $dashboard;
/**
* Private constructor — use ::instance().
*/
@@ -68,6 +71,7 @@ class Plugin {
$this->transcriber = new Transcriber( $this->logger, $this->piper, $this->cache_manager );
$this->player = new Player( $this->logger );
$this->gutenberg = new Gutenberg( $this->logger, $this->transcriber, $this->cache_manager );
$this->dashboard = new Dashboard( $this->logger, $this->cache_manager );
}
/**
@@ -89,6 +93,7 @@ class Plugin {
$this->settings->init();
$this->gutenberg->init();
$this->player->init();
$this->dashboard->init();
// Auto-generate on publish.
add_action( 'transition_post_status', [ $this, 'maybe_auto_generate' ], 10, 3 );
+14 -6
View File
@@ -282,8 +282,8 @@ class Settings {
'classic' => __( 'Classic', 'piperless' ),
'minimal' => __( 'Minimal', 'piperless' ),
'dark' => __( 'Modern Dark', 'piperless' ),
'newsviews' => __( 'NewsViews', 'piperless' ),
'newsviews-classic' => __( 'NewsViews Classic', 'piperless' ),
'newsviews' => __( 'Ron Burgundy', 'piperless' ),
'newsviews-classic' => __( 'Dan Rather Blue', 'piperless' ),
'---' => '──────────',
'custom' => __( 'Custom CSS', 'piperless' ),
],
@@ -569,10 +569,6 @@ class Settings {
class="nav-tab <?php echo 'logs' === $active_tab ? 'nav-tab-active' : ''; ?>">
<?php esc_html_e( 'Logs', 'piperless' ); ?>
</a>
<a href="?page=<?php echo esc_attr( $this->page_slug ); ?>&tab=help"
class="nav-tab <?php echo 'help' === $active_tab ? 'nav-tab-active' : ''; ?>">
<?php esc_html_e( 'Help', 'piperless' ); ?>
</a>
<a href="?page=<?php echo esc_attr( $this->page_slug ); ?>&tab=about"
class="nav-tab <?php echo 'about' === $active_tab ? 'nav-tab-active' : ''; ?>">
<?php esc_html_e( 'About', 'piperless' ); ?>
@@ -637,6 +633,18 @@ class Settings {
<p class="piperless-about-blurb">
<?php esc_html_e( 'Piperless turns your WordPress posts into audio transcripts. Developed by Forkless, it makes your content accessible, engaging, and easy to listen to. Quick setup, high-quality speech, and seamless integration.', 'piperless' ); ?>
</p>
<p>
<a href="https://github.com/forkless/Piperless" target="_blank" class="piperless-about-link">
<img src="<?php echo esc_url( PIPERLESS_PLUGIN_URL . 'assets/svg/github.svg' ); ?>" class="piperless-about-link-icon" alt="" aria-hidden="true" width="18" height="18">
<?php esc_html_e( 'GitHub Repository', 'piperless' ); ?>
</a>
</p>
<p>
<a href="https://buymeacoffee.com/forkless" target="_blank" class="piperless-about-link">
<img src="<?php echo esc_url( PIPERLESS_PLUGIN_URL . 'assets/svg/coffee.svg' ); ?>" class="piperless-about-link-icon" alt="" aria-hidden="true" width="18" height="18">
<?php esc_html_e( 'Buy me a coffee', 'piperless' ); ?>
</a>
</p>
<p class="piperless-about-contact">
<?php esc_html_e( 'Questions? Contact the developers at', 'piperless' ); ?>
<a href="mailto:devs@forkless.com">devs@forkless.com</a>
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "de_DE",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "Minimaler Schweregrad für die Protokollierung.",
"Models Directory": "Modelle-Verzeichnis",
"Modern Dark": "Modern Dunkel",
"NewsViews Classic": "NewsViews Classic",
"No suitable Piper voice model found. Check your models directory.": "Kein passendes Piper-Stimmenmodell gefunden. Überprüfe dein Modelle-Verzeichnis.",
"No text content available for this post.": "Kein Textinhalt für diesen Beitrag verfügbar.",
"Orphaned files cleared.": "Verwaiste Dateien gelöscht.",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps (Minimal)",
"FFprobe Binary Path": "FFprobe-Binärpfad",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Absoluter Pfad zur ffprobe-Binärdatei für die Erkennung der Audiodauer. Automatische Erkennung aus dem ffmpeg-Verzeichnis, wenn leer.",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Absoluter Pfad zur ffmpeg-Binärdatei für MP3/Opus-Konvertierung. Automatische Erkennung aus üblichen Pfaden, wenn leer."
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Absoluter Pfad zur ffmpeg-Binärdatei für MP3/Opus-Konvertierung. Automatische Erkennung aus üblichen Pfaden, wenn leer.",
"Dan Rather Blue": "Dan Rather Blue",
"GitHub Repository": "GitHub-Repository",
"Buy me a coffee": "Kauf mir einen Kaffee"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: German <LL@li.org>\n"
"Language: de_DE\n"
@@ -236,10 +236,6 @@ msgstr "Modelle-Verzeichnis"
msgid "Modern Dark"
msgstr "Modern Dunkel"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "NewsViews Classic"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "Kein passendes Piper-Stimmenmodell gefunden. Überprüfe dein Modelle-Verzeichnis."
@@ -478,3 +474,13 @@ msgstr "Absoluter Pfad zur ffprobe-Binärdatei für die Erkennung der Audiodauer
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "Absoluter Pfad zur ffmpeg-Binärdatei für MP3/Opus-Konvertierung. Automatische Erkennung aus üblichen Pfaden, wenn leer."
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "Dan Rather Blue"
msgid "GitHub Repository"
msgstr "GitHub-Repository"
msgid "Buy me a coffee"
msgstr "Kauf mir einen Kaffee"
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "es_ES",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "Gravedad mínima para registrar en el log.",
"Models Directory": "Directorio de modelos",
"Modern Dark": "Oscuro moderno",
"NewsViews Classic": "NewsViews Classic",
"No suitable Piper voice model found. Check your models directory.": "No se encontró un modelo de voz Piper adecuado. Revisa tu directorio de modelos.",
"No text content available for this post.": "No hay contenido de texto disponible para esta entrada.",
"Orphaned files cleared.": "Archivos huérfanos eliminados.",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps (mínimo)",
"FFprobe Binary Path": "Ruta del binario FFprobe",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Ruta absoluta al binario ffprobe para la detección de la duración del audio. Se detecta automáticamente desde el directorio ffmpeg si se deja vacío.",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Ruta absoluta al binario ffmpeg para la conversión MP3/Opus. Se detecta automáticamente si se deja vacío."
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Ruta absoluta al binario ffmpeg para la conversión MP3/Opus. Se detecta automáticamente si se deja vacío.",
"Dan Rather Blue": "Dan Rather Blue",
"GitHub Repository": "Repositorio GitHub",
"Buy me a coffee": "Invítame a un café"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish <LL@li.org>\n"
"Language: es_ES\n"
@@ -236,10 +236,6 @@ msgstr "Directorio de modelos"
msgid "Modern Dark"
msgstr "Oscuro moderno"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "NewsViews Classic"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "No se encontró un modelo de voz Piper adecuado. Revisa tu directorio de modelos."
@@ -478,3 +474,13 @@ msgstr "Ruta absoluta al binario ffprobe para la detección de la duración del
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "Ruta absoluta al binario ffmpeg para la conversión MP3/Opus. Se detecta automáticamente si se deja vacío."
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "Dan Rather Blue"
msgid "GitHub Repository"
msgstr "Repositorio GitHub"
msgid "Buy me a coffee"
msgstr "Invítame a un café"
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "fr_FR",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "Sévérité minimale à enregistrer dans le journal.",
"Models Directory": "Répertoire des modèles",
"Modern Dark": "Sombre moderne",
"NewsViews Classic": "NewsViews Classic",
"No suitable Piper voice model found. Check your models directory.": "Aucun modèle de voix Piper approprié trouvé. Vérifiez votre répertoire de modèles.",
"No text content available for this post.": "Aucun contenu texte disponible pour cet article.",
"Orphaned files cleared.": "Fichiers orphelins supprimés.",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps (minimal)",
"FFprobe Binary Path": "Chemin du binaire FFprobe",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Chemin absolu vers le binaire ffprobe pour la détection de la durée audio. Auto-détecté depuis le répertoire ffmpeg si laissé vide.",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Chemin absolu vers le binaire ffmpeg pour la conversion MP3/Opus. Auto-détecté depuis les chemins courants si laissé vide."
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Chemin absolu vers le binaire ffmpeg pour la conversion MP3/Opus. Auto-détecté depuis les chemins courants si laissé vide.",
"Dan Rather Blue": "Dan Rather Blue",
"GitHub Repository": "Dépôt GitHub",
"Buy me a coffee": "Offrez-moi un café"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: French <LL@li.org>\n"
"Language: fr_FR\n"
@@ -236,10 +236,6 @@ msgstr "Répertoire des modèles"
msgid "Modern Dark"
msgstr "Sombre moderne"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "NewsViews Classic"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "Aucun modèle de voix Piper approprié trouvé. Vérifiez votre répertoire de modèles."
@@ -478,3 +474,13 @@ msgstr "Chemin absolu vers le binaire ffprobe pour la détection de la durée au
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "Chemin absolu vers le binaire ffmpeg pour la conversion MP3/Opus. Auto-détecté depuis les chemins courants si laissé vide."
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "Dan Rather Blue"
msgid "GitHub Repository"
msgstr "Dépôt GitHub"
msgid "Buy me a coffee"
msgstr "Offrez-moi un café"
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "it_IT",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "Livello di gravità minimo da registrare nel log.",
"Models Directory": "Directory dei modelli",
"Modern Dark": "Modern Dark",
"NewsViews Classic": "NewsViews Classic",
"No suitable Piper voice model found. Check your models directory.": "Nessun modello vocale Piper adatto trovato. Controlla la directory dei modelli.",
"No text content available for this post.": "Nessun contenuto testuale disponibile per questo post.",
"Orphaned files cleared.": "File orfani eliminati.",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps (minimo)",
"FFprobe Binary Path": "Percorso binario FFprobe",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Percorso assoluto al binario ffprobe per il rilevamento della durata audio. Rilevato automaticamente dalla directory ffmpeg se lasciato vuoto.",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Percorso assoluto al binario ffmpeg per la conversione MP3/Opus. Rilevato automaticamente se lasciato vuoto."
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Percorso assoluto al binario ffmpeg per la conversione MP3/Opus. Rilevato automaticamente se lasciato vuoto.",
"Dan Rather Blue": "Dan Rather Blue",
"GitHub Repository": "Repository GitHub",
"Buy me a coffee": "Offrimi un caffè"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: it <LL@li.org>\n"
"Language: it_IT\n"
@@ -236,10 +236,6 @@ msgstr "Directory dei modelli"
msgid "Modern Dark"
msgstr "Modern Dark"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "NewsViews Classic"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "Nessun modello vocale Piper adatto trovato. Controlla la directory dei modelli."
@@ -478,3 +474,13 @@ msgstr "Percorso assoluto al binario ffprobe per il rilevamento della durata aud
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "Percorso assoluto al binario ffmpeg per la conversione MP3/Opus. Rilevato automaticamente se lasciato vuoto."
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "Dan Rather Blue"
msgid "GitHub Repository"
msgstr "Repository GitHub"
msgid "Buy me a coffee"
msgstr "Offrimi un caffè"
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "ja",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "ログに記録する最小の重要度。",
"Models Directory": "モデルディレクトリ",
"Modern Dark": "モダンダーク",
"NewsViews Classic": "ニュースビュークラシック",
"No suitable Piper voice model found. Check your models directory.": "適切なPiper音声モデルが見つかりません。モデルディレクトリを確認してください。",
"No text content available for this post.": "この投稿にはテキストコンテンツがありません。",
"Orphaned files cleared.": "孤立ファイルをクリアしました。",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps(最小)",
"FFprobe Binary Path": "FFprobeバイナリパス",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "音声の長さ検出用ffprobeバイナリへの絶対パス。空の場合はffmpegディレクトリから自動検出されます。",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "MP3/Opus変換用ffmpegバイナリへの絶対パス。空の場合は自動検出されます。"
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "MP3/Opus変換用ffmpegバイナリへの絶対パス。空の場合は自動検出されます。",
"Dan Rather Blue": "ダン・ラザー・ブルー",
"GitHub Repository": "GitHubリポジトリ",
"Buy me a coffee": "コーヒーを奢ってください"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Japanese <LL@li.org>\n"
"Language: ja\n"
@@ -236,10 +236,6 @@ msgstr "モデルディレクトリ"
msgid "Modern Dark"
msgstr "モダンダーク"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "ニュースビュークラシック"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "適切なPiper音声モデルが見つかりません。モデルディレクトリを確認してください。"
@@ -478,3 +474,13 @@ msgstr "音声の長さ検出用ffprobeバイナリへの絶対パス。空の
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "MP3/Opus変換用ffmpegバイナリへの絶対パス。空の場合は自動検出されます。"
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "ダン・ラザー・ブルー"
msgid "GitHub Repository"
msgstr "GitHubリポジトリ"
msgid "Buy me a coffee"
msgstr "コーヒーを奢ってください"
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "nl_NL",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "Minimale ernst om in het log vast te leggen.",
"Models Directory": "Modellenmap",
"Modern Dark": "Modern Donker",
"NewsViews Classic": "NewsViews Classic",
"No suitable Piper voice model found. Check your models directory.": "Geen geschikt Piper stemmodel gevonden. Controleer je modellenmap.",
"No text content available for this post.": "Geen tekstinhoud beschikbaar voor dit bericht.",
"Orphaned files cleared.": "Verweesde bestanden gewist.",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps (minimaal)",
"FFprobe Binary Path": "FFprobe-binair pad",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Absoluut pad naar de ffprobe binary voor audioduurdetectie. Automatisch gedetecteerd vanuit de ffmpeg-directory, indien leeg gelaten.",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Absoluut pad naar de ffmpeg binary voor MP3/Opus-conversie. Automatisch gedetecteerd als leeg gelaten."
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Absoluut pad naar de ffmpeg binary voor MP3/Opus-conversie. Automatisch gedetecteerd als leeg gelaten.",
"Dan Rather Blue": "Dan Rather Blue",
"GitHub Repository": "GitHub-repository",
"Buy me a coffee": "Koop een kop koffie voor me"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Dutch <LL@li.org>\n"
"Language: nl_NL\n"
@@ -236,10 +236,6 @@ msgstr "Modellenmap"
msgid "Modern Dark"
msgstr "Modern Donker"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "NewsViews Classic"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "Geen geschikt Piper stemmodel gevonden. Controleer je modellenmap."
@@ -478,3 +474,13 @@ msgstr "Absoluut pad naar de ffprobe binary voor audioduurdetectie. Automatisch
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "Absoluut pad naar de ffmpeg binary voor MP3/Opus-conversie. Automatisch gedetecteerd als leeg gelaten."
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "Dan Rather Blue"
msgid "GitHub Repository"
msgstr "GitHub-repository"
msgid "Buy me a coffee"
msgstr "Koop een kop koffie voor me"
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "pt_BR",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "Severidade mínima para registrar no log.",
"Models Directory": "Diretório de Modelos",
"Modern Dark": "Modern Dark",
"NewsViews Classic": "NewsViews Classic",
"No suitable Piper voice model found. Check your models directory.": "Nenhum modelo de voz Piper adequado encontrado. Verifique seu diretório de modelos.",
"No text content available for this post.": "Nenhum conteúdo de texto disponível para esta publicação.",
"Orphaned files cleared.": "Arquivos órfãos limpos.",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps (mínimo)",
"FFprobe Binary Path": "Caminho do binário FFprobe",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Caminho absoluto para o binário ffprobe para detecção de duração do áudio. Detectado automaticamente do diretório ffmpeg se deixado vazio.",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Caminho absoluto para o binário ffmpeg para conversão MP3/Opus. Detectado automaticamente se deixado vazio."
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Caminho absoluto para o binário ffmpeg para conversão MP3/Opus. Detectado automaticamente se deixado vazio.",
"Dan Rather Blue": "Dan Rather Blue",
"GitHub Repository": "Repositório GitHub",
"Buy me a coffee": "Me pague um café"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: pt <LL@li.org>\n"
"Language: pt_BR\n"
@@ -236,10 +236,6 @@ msgstr "Diretório de Modelos"
msgid "Modern Dark"
msgstr "Modern Dark"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "NewsViews Classic"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "Nenhum modelo de voz Piper adequado encontrado. Verifique seu diretório de modelos."
@@ -478,3 +474,13 @@ msgstr "Caminho absoluto para o binário ffprobe para detecção de duração do
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "Caminho absoluto para o binário ffmpeg para conversão MP3/Opus. Detectado automaticamente se deixado vazio."
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "Dan Rather Blue"
msgid "GitHub Repository"
msgstr "Repositório GitHub"
msgid "Buy me a coffee"
msgstr "Me pague um café"
+6 -4
View File
@@ -3,8 +3,8 @@
"locale": "zh_CN",
"source": "translations.json",
"generated": "2026-05-10",
"total_strings": 118,
"translated": 118,
"total_strings": 120,
"translated": 120,
"locked": false
},
"strings": {
@@ -63,7 +63,6 @@
"Minimum severity to record in the log.": "记录到日志的最低严重程度。",
"Models Directory": "模型目录",
"Modern Dark": "现代深色",
"NewsViews Classic": "NewsViews Classic",
"No suitable Piper voice model found. Check your models directory.": "未找到合适的 Piper 声音模型。请检查您的模型目录。",
"No text content available for this post.": "此文章没有可用的文本内容。",
"Orphaned files cleared.": "孤立文件已清除。",
@@ -125,6 +124,9 @@
"12 kbps (minimal)": "12 kbps(最小)",
"FFprobe Binary Path": "FFprobe 二进制文件路径",
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "ffprobe 二进制文件的绝对路径,用于音频时长检测。留空则从 ffmpeg 目录自动检测。",
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "ffmpeg 二进制文件的绝对路径,用于 MP3/Opus 转换。留空则自动检测。"
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "ffmpeg 二进制文件的绝对路径,用于 MP3/Opus 转换。留空则自动检测。",
"Dan Rather Blue": "丹·拉瑟蓝",
"GitHub Repository": "GitHub 仓库",
"Buy me a coffee": "请我喝杯咖啡"
}
}
Binary file not shown.
+11 -5
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: Piperless 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: zh <LL@li.org>\n"
"Language: zh_CN\n"
@@ -236,10 +236,6 @@ msgstr "模型目录"
msgid "Modern Dark"
msgstr "现代深色"
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgstr "NewsViews Classic"
#: includes/class-transcriber.php:83
msgid "No suitable Piper voice model found. Check your models directory."
msgstr "未找到合适的 Piper 声音模型。请检查您的模型目录。"
@@ -478,3 +474,13 @@ msgstr "ffprobe 二进制文件的绝对路径,用于音频时长检测。留
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
msgstr "ffmpeg 二进制文件的绝对路径,用于 MP3/Opus 转换。留空则自动检测。"
#: includes/class-settings.php:now
msgid "Dan Rather Blue"
msgstr "丹·拉瑟蓝"
msgid "GitHub Repository"
msgstr "GitHub 仓库"
msgid "Buy me a coffee"
msgstr "请我喝杯咖啡"
+1 -1
View File
@@ -242,7 +242,7 @@ msgid "Above & below content"
msgstr ""
#: includes/class-settings.php:now
msgid "NewsViews Classic"
msgid "Dan Rather Blue"
msgstr ""
#: assets/js/gutenberg.js
+2 -2
View File
@@ -3,7 +3,7 @@
* Plugin Name: Piperless — Audio Transcripts
* Plugin URI: https://forkless.com
* Description: Generate audio transcripts of WordPress posts using Piper TTS. Customizable players, caching, and full Gutenberg integration.
* Version: 1.1.1
* Version: 1.1.4
* Requires at least: 6.0
* Requires PHP: 8.0
* Author: Forkless
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
}
// ── Constants ────────────────────────────────────────────────────────────────
define( 'PIPERLESS_VERSION', '1.1.1' );
define( 'PIPERLESS_VERSION', '1.1.4' );
define( 'PIPERLESS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'PIPERLESS_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'PIPERLESS_PLUGIN_FILE', __FILE__ );
+6 -5
View File
@@ -13,18 +13,19 @@ set -euo pipefail
PLUGIN_SLUG="piperless"
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
# ── Read version from plugin header ───────────────────────────────────────
VERSION=$( grep -oP '^\s*\*\s*Version:\s*\K[0-9.]+' "${SCRIPT_DIR}/${PLUGIN_SLUG}.php" | head -1 )
VERSION=$( grep -oP '^\s*\*\s*Version:\s*\K[0-9.]+' "${PROJECT_DIR}/${PLUGIN_SLUG}.php" | head -1 )
if [[ -z "${VERSION}" ]]; then
echo "Error: could not determine plugin version from ${PLUGIN_SLUG}.php"
exit 1
fi
BUILD_DIR="${SCRIPT_DIR}/build"
BUILD_DIR="${PROJECT_DIR}/build"
STAGING="${BUILD_DIR}/${PLUGIN_SLUG}"
ZIP_FILE="${SCRIPT_DIR}/${PLUGIN_SLUG}-${VERSION}.zip"
ZIP_FILE="${PROJECT_DIR}/${PLUGIN_SLUG}-${VERSION}.zip"
echo "=== Piperless Build Script ==="
echo "Version: ${VERSION}"
@@ -49,7 +50,7 @@ INCLUDE=(
)
for item in "${INCLUDE[@]}"; do
src="${SCRIPT_DIR}/${item}"
src="${PROJECT_DIR}/${item}"
if [[ -e "${src}" ]]; then
cp -r "${src}" "${STAGING}/"
else
@@ -67,7 +68,7 @@ find "${STAGING}" -name '*.map' -delete
echo "Creating ZIP archive…"
cd "${BUILD_DIR}"
zip -r "${ZIP_FILE}" "${PLUGIN_SLUG}" > /dev/null
cd "${SCRIPT_DIR}"
cd "${PROJECT_DIR}"
# ── Verify ────────────────────────────────────────────────────────────────
ZIP_SIZE=$( du -h "${ZIP_FILE}" | cut -f1 )