From 2cc7a4c0d471b24de0414f189aa0b9406388996f Mon Sep 17 00:00:00 2001 From: Kirill Zhumarin Date: Mon, 17 Aug 2026 22:07:35 +0300 Subject: [PATCH] Add Siemens software catalog --- .gitattributes | 14 + .gitignore | 2 + AGENTS.md | 138 +++++ README.md | 182 ++++++ .../armdebugger/files/ArmDebugger-079.rar | 3 + development/debuggers/armdebugger/index.yaml | 29 + development/debuggers/index.yaml | 4 + development/index.yaml | 4 + development/java-tools/index.yaml | 4 + .../java-tools/midletsigner/files/JRE131L.rar | 3 + .../midletsigner/files/MidletSigner5.rar | 3 + .../java-tools/midletsigner/index.yaml | 30 + .../patch-tools/ffpatch/files/ffpatch.rar | 3 + development/patch-tools/ffpatch/index.yaml | 23 + .../filescomparer/files/fc_v1.2.rar | 3 + .../patch-tools/filescomparer/index.yaml | 21 + .../patch-tools/hex2vkp/files/hex2vkp.zip | 3 + development/patch-tools/hex2vkp/index.yaml | 20 + development/patch-tools/index.yaml | 4 + .../patch-tools/slfc/files/slfc-chaos.exe | Bin 0 -> 58880 bytes .../patch-tools/slfc/files/slfc-vi-soft.exe | Bin 0 -> 58880 bytes development/patch-tools/slfc/index.yaml | 23 + index.yaml | 4 + multimedia/audio-tools/index.yaml | 4 + .../audio-tools/vmo2wav/files/vmo2wav.zip | 3 + multimedia/audio-tools/vmo2wav/index.yaml | 17 + multimedia/index.yaml | 4 + package.json | 18 + pnpm-lock.yaml | 540 ++++++++++++++++++ pnpm-workspace.yaml | 2 + schema/index.schema.json | 189 ++++++ scripts/fillSha256.ts | 272 +++++++++ scripts/printTree.ts | 222 +++++++ service/drivers/index.yaml | 4 + .../drivers/pl-2303/files/PL-2303_patched.rar | 3 + service/drivers/pl-2303/index.yaml | 16 + service/firmware-tools/index.yaml | 6 + .../firmware-tools/winswup/files/WSMPlus2.rar | 3 + .../winswup/files/winswup-0.91-pre1.7z | 3 + .../winswup/files/winswup-0.91-pre2.7z | 3 + .../winswup/files/winswup-0.91.7z | 3 + .../winswup/files/winswup-0.95-amd32.7z | 3 + .../winswup/files/winswup-0.95.7z | 3 + .../winswup/files/winswup-0.97.7z | 3 + .../winswup/files/winswup-0.98-pre.7z | 3 + .../winswup/files/winswup-0.98.7z | 3 + .../winswup/files/winswup-1.04.7z | 3 + .../winswup/files/winswup-1.23.7z | 3 + .../winswup/files/winswup-1.27.7z | 3 + .../winswup/files/winswup-1.28.7z | 3 + .../winswup/files/winswup-1.30.7z | 3 + .../winswup/files/winswup-1.34.7z | 3 + .../winswup/files/winswup-1.35.7z | 3 + .../winswup/files/winswup-1.40.7z | 3 + .../winswup/files/winswup-1.44.7z | 3 + .../winswup/files/winswup-3.002.7z | 3 + .../winswup/files/winswup-3.05.7z | 3 + .../winswup/files/winswup-3.17.7z | 3 + .../winswup/files/winswup-3.19.7z | 3 + .../winswup/files/winswup-3.20.rar | 3 + .../winswup/files/winswup-4.07.7z | 3 + .../winswup/files/winswup-4.14p3.7z | 3 + .../winswup/files/winswup-4.20.7z | 3 + service/firmware-tools/winswup/index.yaml | 186 ++++++ service/firmware-tools/wsff/files/WSFF4.rar | 3 + service/firmware-tools/wsff/index.yaml | 16 + service/flashers/index.yaml | 4 + .../flashers/v-klay/files/v_klay_setup.zip | 3 + .../v-klay/files/v_klay_setup_v2152.rar | 3 + .../v-klay/files/v_klay_setup_v25.zip | 3 + .../v-klay/files/v_klay_setup_v272.zip | 3 + .../v-klay/files/v_klay_update_v2112.rar | 3 + service/flashers/v-klay/index.yaml | 54 ++ .../flashers/x65flasher/files/bsReader.zip | 3 + service/flashers/x65flasher/files/px75v1.rar | 3 + .../x65flasher/files/x65flasher-2103.rar | 3 + service/flashers/x65flasher/index.yaml | 32 ++ service/index.yaml | 4 + service/repair-tools/index.yaml | 6 + .../joker/files/JokerSorceV0341.rar | 3 + .../repair-tools/joker/files/JokerV0295.rar | 3 + service/repair-tools/joker/index.yaml | 38 ++ .../files/SiemensEEPROMtool315plus.rar | 3 + .../siemens-eeprom-tool/index.yaml | 20 + .../x65-papua-utils/files/AllBugSGold.rar | 3 + .../x65-papua-utils/files/SWP2.rar | 3 + .../x65-papua-utils/files/SWP3.rar | 3 + .../x65-papua-utils/files/SWPEXE.rar | 3 + .../files/x65PapuaUtilsV036.rar | 3 + .../files/x65PapuaUtilsV038.rar | 3 + .../files/x65PapuaUtilsV041.rar | 3 + .../files/x65PapuaUtilsV043.rar | 3 + .../files/x65PapuaUtilsV044.rar | 3 + .../files/x65PapuaUtilsV045.rar | 3 + .../files/x65PapuaUtilsV046.rar | 3 + .../files/x65PapuaUtilsV047.rar | 3 + .../files/x65PapuaUtilsV048.rar | 3 + .../files/x65PapuaUtilsV050.rar | 3 + .../files/x65PapuaUtilsV051.rar | 3 + .../files/x65PapuaUtilsV054.rar | 3 + .../files/x65PapuaUtilsV055.rar | 3 + .../files/x65PapuaUtilsV056.rar | 3 + .../files/x65PapuaUtilsV060.rar | 3 + .../files/x65PapuaUtilsV062.rar | 3 + .../files/x65PapuaUtilsV064.rar | 3 + .../files/x65PapuaUtilsV065.rar | 3 + .../files/x65PapuaUtilsV066.rar | 3 + .../files/x65PapuaUtilsV067c.rar | 3 + .../files/x65PapuaUtilsV068.rar | 3 + .../files/x65PapuaUtilsV069.rar | 3 + .../files/x65PapuaUtilsV070.rar | 3 + .../files/x65PapuaUtilsV074.rar | 3 + .../files/x65PapuaUtilsV075.rar | 3 + .../files/x65PapuaUtilsV076b.rar | 3 + .../files/x65PapuaUtilsV077.rar | 3 + .../files/x65PapuaUtilsV078.rar | 3 + .../files/x65PapuaUtilsV079d.rar | 3 + .../files/x65PapuaUtilsV111b.rar | 3 + .../files/x65PapuaUtilsV111c_rus.rar | 3 + .../repair-tools/x65-papua-utils/index.yaml | 259 +++++++++ tsconfig.json | 12 + 121 files changed, 2670 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 development/debuggers/armdebugger/files/ArmDebugger-079.rar create mode 100644 development/debuggers/armdebugger/index.yaml create mode 100644 development/debuggers/index.yaml create mode 100644 development/index.yaml create mode 100644 development/java-tools/index.yaml create mode 100644 development/java-tools/midletsigner/files/JRE131L.rar create mode 100644 development/java-tools/midletsigner/files/MidletSigner5.rar create mode 100644 development/java-tools/midletsigner/index.yaml create mode 100644 development/patch-tools/ffpatch/files/ffpatch.rar create mode 100644 development/patch-tools/ffpatch/index.yaml create mode 100644 development/patch-tools/filescomparer/files/fc_v1.2.rar create mode 100644 development/patch-tools/filescomparer/index.yaml create mode 100644 development/patch-tools/hex2vkp/files/hex2vkp.zip create mode 100644 development/patch-tools/hex2vkp/index.yaml create mode 100644 development/patch-tools/index.yaml create mode 100644 development/patch-tools/slfc/files/slfc-chaos.exe create mode 100644 development/patch-tools/slfc/files/slfc-vi-soft.exe create mode 100644 development/patch-tools/slfc/index.yaml create mode 100644 index.yaml create mode 100644 multimedia/audio-tools/index.yaml create mode 100644 multimedia/audio-tools/vmo2wav/files/vmo2wav.zip create mode 100644 multimedia/audio-tools/vmo2wav/index.yaml create mode 100644 multimedia/index.yaml create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 schema/index.schema.json create mode 100644 scripts/fillSha256.ts create mode 100644 scripts/printTree.ts create mode 100644 service/drivers/index.yaml create mode 100644 service/drivers/pl-2303/files/PL-2303_patched.rar create mode 100644 service/drivers/pl-2303/index.yaml create mode 100644 service/firmware-tools/index.yaml create mode 100644 service/firmware-tools/winswup/files/WSMPlus2.rar create mode 100644 service/firmware-tools/winswup/files/winswup-0.91-pre1.7z create mode 100644 service/firmware-tools/winswup/files/winswup-0.91-pre2.7z create mode 100644 service/firmware-tools/winswup/files/winswup-0.91.7z create mode 100644 service/firmware-tools/winswup/files/winswup-0.95-amd32.7z create mode 100644 service/firmware-tools/winswup/files/winswup-0.95.7z create mode 100644 service/firmware-tools/winswup/files/winswup-0.97.7z create mode 100644 service/firmware-tools/winswup/files/winswup-0.98-pre.7z create mode 100644 service/firmware-tools/winswup/files/winswup-0.98.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.04.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.23.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.27.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.28.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.30.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.34.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.35.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.40.7z create mode 100644 service/firmware-tools/winswup/files/winswup-1.44.7z create mode 100644 service/firmware-tools/winswup/files/winswup-3.002.7z create mode 100644 service/firmware-tools/winswup/files/winswup-3.05.7z create mode 100644 service/firmware-tools/winswup/files/winswup-3.17.7z create mode 100644 service/firmware-tools/winswup/files/winswup-3.19.7z create mode 100644 service/firmware-tools/winswup/files/winswup-3.20.rar create mode 100644 service/firmware-tools/winswup/files/winswup-4.07.7z create mode 100644 service/firmware-tools/winswup/files/winswup-4.14p3.7z create mode 100644 service/firmware-tools/winswup/files/winswup-4.20.7z create mode 100644 service/firmware-tools/winswup/index.yaml create mode 100644 service/firmware-tools/wsff/files/WSFF4.rar create mode 100644 service/firmware-tools/wsff/index.yaml create mode 100644 service/flashers/index.yaml create mode 100644 service/flashers/v-klay/files/v_klay_setup.zip create mode 100644 service/flashers/v-klay/files/v_klay_setup_v2152.rar create mode 100644 service/flashers/v-klay/files/v_klay_setup_v25.zip create mode 100644 service/flashers/v-klay/files/v_klay_setup_v272.zip create mode 100644 service/flashers/v-klay/files/v_klay_update_v2112.rar create mode 100644 service/flashers/v-klay/index.yaml create mode 100644 service/flashers/x65flasher/files/bsReader.zip create mode 100644 service/flashers/x65flasher/files/px75v1.rar create mode 100644 service/flashers/x65flasher/files/x65flasher-2103.rar create mode 100644 service/flashers/x65flasher/index.yaml create mode 100644 service/index.yaml create mode 100644 service/repair-tools/index.yaml create mode 100644 service/repair-tools/joker/files/JokerSorceV0341.rar create mode 100644 service/repair-tools/joker/files/JokerV0295.rar create mode 100644 service/repair-tools/joker/index.yaml create mode 100644 service/repair-tools/siemens-eeprom-tool/files/SiemensEEPROMtool315plus.rar create mode 100644 service/repair-tools/siemens-eeprom-tool/index.yaml create mode 100644 service/repair-tools/x65-papua-utils/files/AllBugSGold.rar create mode 100644 service/repair-tools/x65-papua-utils/files/SWP2.rar create mode 100644 service/repair-tools/x65-papua-utils/files/SWP3.rar create mode 100644 service/repair-tools/x65-papua-utils/files/SWPEXE.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV036.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV038.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV041.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV043.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV044.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV045.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV046.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV047.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV048.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV050.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV051.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV054.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV055.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV056.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV060.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV062.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV064.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV065.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV066.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV067c.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV068.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV069.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV070.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV074.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV075.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV076b.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV077.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV078.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV079d.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111b.rar create mode 100644 service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111c_rus.rar create mode 100644 service/repair-tools/x65-papua-utils/index.yaml create mode 100644 tsconfig.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8479566 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Store archives in Git LFS. +*.7z filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.cab filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..380f475 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +.pnpm-store/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..946361d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,138 @@ +# Правила ведения каталога + +Эти правила действуют для всего репозитория. Перед изменением метаданных сверяйся +с `schema/index.schema.json`. Не добавляй поля, которых нет в схеме. + +## Структура + +- Корень репозитория является корнем каталога; папку `catalog` создавать не + нужно. +- Каждая категория и каждая программа находятся в собственной папке и содержат + ровно один файл `index.yaml`. +- Вложенность категорий не ограничена. Дочерние категории и программы + определяются по файловой структуре и не перечисляются в индексе категории. +- Имя папки — стабильный идентификатор. Используй строчные латинские буквы, + цифры, дефис и подчёркивание. +- В папке программы все загружаемые файлы находятся в `files`, а скриншоты — в + `img`. +- Не создавай отдельные YAML-файлы или папки метаданных для версий. Все версии + описываются в `versions` единственного `index.yaml` программы. +- Папки без `index.yaml`, например `schema`, `files` и `img`, не являются + категориями. + +## YAML категории + +Используй только следующие обязательные поля и сохраняй их порядок: + +```yaml +format: 1 +type: category +name: Русское название категории +description: Описание категории на русском языке. +``` + +## YAML программы + +Поля программы располагай в следующем порядке: + +1. `format: 1` — обязательное поле. +2. `type: program` — обязательное поле. +3. `name` — обязательное официальное название программы. +4. `description` — обязательное подробное описание на русском языке в формате + Markdown. +5. `homepage` — необязательный URL домашней страницы. +6. `source` — необязательный URL исходного кода. +7. `screenshots` — обязательный массив путей; используй `[]`, если изображений + нет. +8. `versions` — обязательный непустой массив версий. +9. `additional_files` — необязательный массив файлов, не привязанных к версии. + +Новые версии добавляй в начало `versions`, от новых к старым. Каждая версия +имеет такой вид: + +```yaml +- version: "1.2.0" + status: current + released: "2007-08-14" + files: + - path: files/program-1.2.0.zip + description: Назначение файла на русском языке + platform: win32 + sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef +``` + +Поля версии располагай в порядке `version`, `status`, `released`, `description`, +`files`. Обязательны только `version` и непустой массив `files`. Необязательный +`status` принимает `current` для актуальной версии и `archived` для устаревшей, +сохранённой ради архива. Если статусы используются у программы, указывай их у +всех её версий. Поле `released` добавляй только при наличии достоверной даты. +Не переноси changelog в `description` версии и не добавляй это поле для полноты. +Оно допустимо только в особом случае, когда нужно зафиксировать существенное +ограничение, которое нельзя выразить номером версии или описанием конкретного +файла. + +Необязательное поле файла `platform` принимает одно из значений: `win32`, +`win64`, `dos`, `java` или `j2me`. Для Windows разрядность входит в название +платформы; отдельное поле `architecture` не используется. + +Файлы, которые подходят ко всем версиям или существуют отдельно от релиза, +помещай в `additional_files`, а не внутрь случайной версии: + +```yaml +additional_files: + - path: files/manual.pdf + description: Руководство пользователя +``` + +## Текст и достоверность + +- Названия категорий, описания программ, версий и файлов пиши на русском языке. + Официальные названия продуктов и технологий не переводи. +- Сохраняй полноту исходного описания. Не сокращай перечень возможностей до + общего пересказа и не удаляй значимые технические подробности. +- Содержимое каждого `description` интерпретируется как Markdown. Для длинного + описания со списком используй литеральный блок `|-` и Markdown-списки; для + обычного абзаца, перенесённого на несколько строк, используй `>-`. Не вставляй + HTML-разметку. +- Не выдумывай даты, ссылки, возможности или платформы. Неизвестное + необязательное поле лучше не добавлять. +- Сначала пытайся определить версию по странице, имени файла, README и + метаданным бинарника. Если номер версии нигде не указан и достоверно получить + его невозможно, используй каталоговое значение `version: "1.0"`. Не выводи + номер версии из даты сборки. +- Если источник содержит только текущую версию, добавляй только её. Не ищи + более ранние архивы в Wayback Machine без отдельного указания пользователя. + +## Пути и файлы + +- Все пути относительны папке программы и используют `/`. +- Путь загружаемого файла начинается с `files/`; путь скриншота — с `img/`. +- Абсолютные пути, `..` и обратная косая черта запрещены. +- Каждый путь из YAML должен указывать на существующий файл. +- Один файл нельзя одновременно указывать в `versions` и `additional_files`. +- Для каждого добавленного файла вычисляй и указывай SHA-256 в нижнем регистре. +- Архивы должны проходить через Git LFS согласно `.gitattributes`. Остальные + файлы хранятся в обычном Git. + +## Стиль YAML + +- Кодировка — UTF-8, окончания строк — LF, отступ — два пробела, табуляция + запрещена. +- Версии и даты всегда заключай в двойные кавычки. +- Дата имеет формат `YYYY-MM-DD`, SHA-256 — ровно 64 шестнадцатеричных символа. +- Не используй YAML-теги, anchors, aliases и merge keys. +- Не допускай неизвестных полей и дубликатов в массивах. + +## Проверка + +Перед завершением изменения: + +1. Проверь синтаксис всех затронутых `index.yaml` безопасным YAML-парсером. +2. Проверь их по `schema/index.schema.json` валидатором JSON Schema Draft 2020-12, + если он доступен. +3. Убедись, что все пути существуют и их SHA-256 совпадает с метаданными. + Для заполнения и обновления сумм используй `pnpm sha256 [путь]`, для проверки + без изменения файлов — `pnpm sha256:check [путь]`. +4. Для каждого нового архива выполни `git check-attr filter -- <путь>` и + убедись, что значение равно `lfs`. +5. Выполни `git diff --check`. diff --git a/README.md b/README.md index e69de29..b6054a3 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,182 @@ +# Каталог программ + +Репозиторий хранит дистрибутивы программ и их метаданные. Все пользовательские +названия и описания пишутся на русском языке. Официальные названия программ, +версии, имена платформ и другие технические значения переводить не нужно. + +## Структура + +Корень репозитория одновременно является корнем каталога программ. Вложенность +категорий не ограничена. Имя папки служит стабильным машиночитаемым +идентификатором: используйте строчные латинские буквы, цифры, дефис и +подчёркивание. + +```text +./ +├── index.yaml +├── schema/ +│ └── index.schema.json +└── system/ + ├── index.yaml + └── file-managers/ + ├── index.yaml + └── example-program/ + ├── index.yaml + ├── img/ + │ └── screenshot.png + └── files/ + ├── example-program-1.0.0.zip + ├── example-program-1.1.0.zip + └── manual.pdf +``` + +Каждая категория и каждая программа содержит ровно один `index.yaml`: + +- `type: category` означает категорию; рядом могут находиться подкатегории и + программы; +- `type: program` означает программу; все её версии описываются в этом же + файле; +- `img` и `files` — зарезервированные папки внутри программы. + +Папки без `index.yaml`, например корневая `schema`, не входят в дерево +категорий. + +Список дочерних элементов категории не дублируется в YAML: он определяется по +вложенным папкам. Благодаря этому перемещение программы не требует правки +родительских индексов. + +## Категория + +```yaml +format: 1 +type: category +name: Системные программы +description: Утилиты для настройки и обслуживания устройства. +``` + +## Программа + +```yaml +format: 1 +type: program +name: Пример программы +description: |- + Краткое описание назначения и возможностей программы. + + Возможности: + - первая возможность; + - вторая возможность. +homepage: https://example.org/program +source: https://github.com/example/program +screenshots: + - img/screenshot.png +versions: + - version: "1.1.0" + status: current + released: "2007-08-14" + files: + - path: files/example-program-1.1.0.zip + description: Дистрибутив программы + platform: win32 + sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + - version: "1.0.0" + files: + - path: files/example-program-1.0.0.zip +additional_files: + - path: files/manual.pdf + description: Руководство пользователя +``` + +Обязательные поля программы: `format`, `type`, `name`, `description`, +`screenshots`, `versions`. Поля `homepage`, `source` и `additional_files` +необязательны. + +Поле `description` содержит Markdown. Для содержательного описания используйте +абзацы и списки внутри литерального YAML-блока `|-`. + +Все файлы программы хранятся в её папке `files`. Версионные файлы перечислены +в `versions[].files`, а не зависящие от версии — в `additional_files`. Один и +тот же файл не следует указывать в обоих местах. Новые версии добавляются в +начало массива `versions`, от новых к старым. + +Необязательное поле файла `platform` использует короткие машиночитаемые +значения: `win32`, `win64`, `dos`, `java` или `j2me`. Отдельного поля +архитектуры нет: разрядность Windows уже включена в `win32` или `win64`. + +Необязательное поле `status` принимает значение `current` для актуальной версии +или `archived` для версии, оставленной в каталоге как архивная. Если программа +использует статусы, они указываются у всех её версий. + +`description` версии используется только для существенных исключений, которые +нельзя выразить номером версии или описанием файла. Обычный список изменений в +индекс не переносится. + +Скриншоты хранятся в `img`; пути всегда начинаются с `img/`. Если скриншотов +нет, указывается пустой массив: `screenshots: []`. + +## Правила формата + +- Кодировка всех YAML-файлов — UTF-8, окончания строк — LF. +- `format` — версия формата метаданных. Текущее значение: `1`. +- Неизвестные поля запрещены: расширение формата требует изменения схемы. +- Все пути задаются относительно папки программы. Абсолютные пути, `..` и + обратная косая черта запрещены. +- Даты записываются строкой `YYYY-MM-DD` и берутся в кавычки. +- URL используют только `http` или `https`. +- `sha256`, если указан, содержит 64 шестнадцатеричных символа в нижнем + регистре. +- Массивы не должны содержать дубликаты. +- Описания программы, версии и файла пишутся на русском языке. + +Архивы хранятся через Git LFS, остальные файлы — как обычные объекты Git. + +## Заполнение SHA-256 + +Для установки зависимостей используется pnpm: + +```shell +pnpm install +``` + +Команда вычисляет контрольные суммы всех файлов из `versions` и +`additional_files`, после чего добавляет или обновляет поля `sha256`: + +```shell +pnpm sha256 +``` + +Можно ограничить обход одной программой, категорией или конкретным индексом: + +```shell +pnpm sha256 service/repair-tools/joker +pnpm sha256 service/repair-tools/joker/index.yaml +``` + +Для проверки без изменения YAML используется отдельная команда: + +```shell +pnpm sha256:check +``` + +## Дерево каталога + +Дерево категорий и программ строится по файловой структуре и названиям из +`index.yaml`: + +```shell +pnpm tree +``` + +Можно вывести только выбранную ветку, добавить пути каталогов или версии +программ: + +```shell +pnpm tree service/repair-tools +pnpm tree --paths +pnpm tree --versions +``` + +Формальная JSON Schema находится в +[`schema/index.schema.json`](schema/index.schema.json). Она проверяет структуру +и значения `index.yaml`; соответствие русского текста проверяется при ревью, +поскольку название продукта может состоять из латинских символов. diff --git a/development/debuggers/armdebugger/files/ArmDebugger-079.rar b/development/debuggers/armdebugger/files/ArmDebugger-079.rar new file mode 100644 index 0000000..f238229 --- /dev/null +++ b/development/debuggers/armdebugger/files/ArmDebugger-079.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94e089e35a4733c97890c34c14d065007332057f5b11693a7f94cca7245251ad +size 439518 diff --git a/development/debuggers/armdebugger/index.yaml b/development/debuggers/armdebugger/index.yaml new file mode 100644 index 0000000..ee05b45 --- /dev/null +++ b/development/debuggers/armdebugger/index.yaml @@ -0,0 +1,29 @@ +format: 1 +type: program +name: ArmDebugger +description: |- + Отладчик для телефонов Siemens 65/70/75-й серии. + + Возможности: + - автоматическая генерация CGSN-патча по слитому фулфлешу; + - просмотр содержимого памяти телефона в HEX-дампе; + - ARM/Thumb-дизассемблер с inline-ассемблером; + - пошаговая трассировка программы или процесса; + - установка точек мониторинга на любой адрес флеш-памяти и на запись в + диапазон RAM; + - редактирование памяти, в том числе флеш-области, с использованием замещения + flash-страниц; + - поиск байтов, строк и ссылок в памяти; + - интеграция с Keil ARM Tools; + - дамп памяти в файл, вызов функций flash с параметрами и hex/bin/dec + калькулятор. +homepage: https://web.archive.org/web/20130813164842/http://chaos.allsiemens.com/software.html +screenshots: [] +versions: + - version: "0.7.9" + released: "2006-12-28" + files: + - path: files/ArmDebugger-079.rar + description: Отладчик, краткое руководство и примеры для Keil ARM Tools + platform: win32 + sha256: 94e089e35a4733c97890c34c14d065007332057f5b11693a7f94cca7245251ad diff --git a/development/debuggers/index.yaml b/development/debuggers/index.yaml new file mode 100644 index 0000000..b333795 --- /dev/null +++ b/development/debuggers/index.yaml @@ -0,0 +1,4 @@ +format: 1 +type: category +name: Отладчики +description: Программы для анализа памяти, машинного кода и выполнения программ. diff --git a/development/index.yaml b/development/index.yaml new file mode 100644 index 0000000..f6aadd2 --- /dev/null +++ b/development/index.yaml @@ -0,0 +1,4 @@ +format: 1 +type: category +name: Средства разработки +description: Инструменты для исследования и разработки программного обеспечения телефонов. diff --git a/development/java-tools/index.yaml b/development/java-tools/index.yaml new file mode 100644 index 0000000..d696630 --- /dev/null +++ b/development/java-tools/index.yaml @@ -0,0 +1,4 @@ +format: 1 +type: category +name: Инструменты Java ME +description: Программы для разработки, настройки и подготовки приложений Java ME. diff --git a/development/java-tools/midletsigner/files/JRE131L.rar b/development/java-tools/midletsigner/files/JRE131L.rar new file mode 100644 index 0000000..39b2346 --- /dev/null +++ b/development/java-tools/midletsigner/files/JRE131L.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0236f9e6fd71537d878792b7aa4cf6b20c2a729ae9672c81d6e69289f1afcf89 +size 624754 diff --git a/development/java-tools/midletsigner/files/MidletSigner5.rar b/development/java-tools/midletsigner/files/MidletSigner5.rar new file mode 100644 index 0000000..568e881 --- /dev/null +++ b/development/java-tools/midletsigner/files/MidletSigner5.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad81aebd58ddf45a57c42123d708214aa2cd1297cf1c871c95b8808f70939046 +size 19259 diff --git a/development/java-tools/midletsigner/index.yaml b/development/java-tools/midletsigner/index.yaml new file mode 100644 index 0000000..1a245cb --- /dev/null +++ b/development/java-tools/midletsigner/index.yaml @@ -0,0 +1,30 @@ +format: 1 +type: program +name: MidletSigner +description: |- + Программа для самостоятельного создания сертификата и подписывания + Java-мидлетов на телефонах Siemens 65-й и 75-й серий. + + Подписанный мидлет может работать без постоянных запросов подтверждения при + чтении и записи файлов, выходе в интернет, отправке SMS и MMS, доступе к + COM-порту, Bluetooth, адресной книге, органайзеру и мультимедийным функциям. + Подпись также позволяет автоматически запускать мидлет по времени или + событию. + + Программа работает из командной строки с JAD- и JAR-файлами. Для работы + требуется JRE версии 1.3 или новее. Для телефонов 65-й серии нужен OpenDisc + 2.0, а для телефонов 75-й серии в телефон должен быть введён SKEY. +homepage: https://web.archive.org/web/20130813164842/http://chaos.allsiemens.com/software.html +screenshots: [] +versions: + - version: "5" + files: + - path: files/MidletSigner5.rar + description: MidletSigner 5 с русским и английским руководствами + platform: java + sha256: ad81aebd58ddf45a57c42123d708214aa2cd1297cf1c871c95b8808f70939046 +additional_files: + - path: files/JRE131L.rar + description: Минимальный JRE 1.3.1 только для запуска MidletSigner + platform: win32 + sha256: 0236f9e6fd71537d878792b7aa4cf6b20c2a729ae9672c81d6e69289f1afcf89 diff --git a/development/patch-tools/ffpatch/files/ffpatch.rar b/development/patch-tools/ffpatch/files/ffpatch.rar new file mode 100644 index 0000000..7487a56 --- /dev/null +++ b/development/patch-tools/ffpatch/files/ffpatch.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fef324ef0e22d97dc550e6bb20acd1a5edb4c6d773784f1edb2ad3ad854aac6 +size 79635 diff --git a/development/patch-tools/ffpatch/index.yaml b/development/patch-tools/ffpatch/index.yaml new file mode 100644 index 0000000..fd9ff32 --- /dev/null +++ b/development/patch-tools/ffpatch/index.yaml @@ -0,0 +1,23 @@ +format: 1 +type: program +name: FFPatch +description: |- + Программа для сравнения двух файлов fullflash, сохранения найденных отличий + в виде патча VKP и поиска уже установленных патчей в образе flash-памяти. + + Возможности: + - сравнение оригинального и текущего fullflash; + - формирование файла различий в формате VKP; + - поиск одного или нескольких патчей VKP в fullflash; + - добавление патчей отдельными файлами или целым каталогом; + - исключение заданных диапазонов адресов из поиска и сравнения; + - сохранение настроек фильтрации адресов. +homepage: https://web.archive.org/web/20130813164842/http://vi-soft.com.ua/ +screenshots: [] +versions: + - version: "0.4.2" + files: + - path: files/ffpatch.rar + description: Программа FFPatch и руководство пользователя + platform: win32 + sha256: 6fef324ef0e22d97dc550e6bb20acd1a5edb4c6d773784f1edb2ad3ad854aac6 diff --git a/development/patch-tools/filescomparer/files/fc_v1.2.rar b/development/patch-tools/filescomparer/files/fc_v1.2.rar new file mode 100644 index 0000000..aadea80 --- /dev/null +++ b/development/patch-tools/filescomparer/files/fc_v1.2.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e2416941803cf80c9a56a859b0cc2e714388e5f907d89403c0d3f05c7520cc4 +size 7415 diff --git a/development/patch-tools/filescomparer/index.yaml b/development/patch-tools/filescomparer/index.yaml new file mode 100644 index 0000000..2ddbab4 --- /dev/null +++ b/development/patch-tools/filescomparer/index.yaml @@ -0,0 +1,21 @@ +format: 1 +type: program +name: FilesComparer +description: |- + Программа для сравнения файлов и образов flash-памяти. + + Возможности: + - сравнение файлов одинакового и разного размера; + - ограничение сравнения начальным и конечным адресами; + - передача параметров через командную строку; + - выравнивание результатов по байтам; + - работа под DOS и Windows. +homepage: https://web.archive.org/web/20130813164842/http://vi-soft.com.ua/ +screenshots: [] +versions: + - version: "1.2" + files: + - path: files/fc_v1.2.rar + description: Программа FilesComparer 1.2 + platform: win32 + sha256: 1e2416941803cf80c9a56a859b0cc2e714388e5f907d89403c0d3f05c7520cc4 diff --git a/development/patch-tools/hex2vkp/files/hex2vkp.zip b/development/patch-tools/hex2vkp/files/hex2vkp.zip new file mode 100644 index 0000000..6ad3426 --- /dev/null +++ b/development/patch-tools/hex2vkp/files/hex2vkp.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10149c6770337551f18f5ff948acf9e3fbd025fca3e97a1f0f1cab9702301786 +size 50300 diff --git a/development/patch-tools/hex2vkp/index.yaml b/development/patch-tools/hex2vkp/index.yaml new file mode 100644 index 0000000..d1d8883 --- /dev/null +++ b/development/patch-tools/hex2vkp/index.yaml @@ -0,0 +1,20 @@ +format: 1 +type: program +name: Hex2VKP +description: |- + Консольный конвертер из формата Intel HEX в формат патчей VKP программы + V_KLay. + + Intel HEX применяется для загрузки данных в микроконтроллеры и может быть + создан компиляторами для C166, включая Keil и Tasking C. Hex2VKP преобразует + результат компиляции в патч VKP для последующей записи через V_KLay. Ключ + `-F` создаёт секцию отмены патча `UNDO PATCH`. +homepage: https://web.archive.org/web/20130813164842/http://vi-soft.com.ua/ +screenshots: [] +versions: + - version: "0.1a" + files: + - path: files/hex2vkp.zip + description: Программа Hex2VKP, исходный код, настройки и руководство + platform: win32 + sha256: 10149c6770337551f18f5ff948acf9e3fbd025fca3e97a1f0f1cab9702301786 diff --git a/development/patch-tools/index.yaml b/development/patch-tools/index.yaml new file mode 100644 index 0000000..436a8c8 --- /dev/null +++ b/development/patch-tools/index.yaml @@ -0,0 +1,4 @@ +format: 1 +type: category +name: Средства создания патчей +description: Программы для сравнения прошивок, поиска изменений и создания патчей VKP. diff --git a/development/patch-tools/slfc/files/slfc-chaos.exe b/development/patch-tools/slfc/files/slfc-chaos.exe new file mode 100644 index 0000000000000000000000000000000000000000..73519ab9d342da7958bff102131ac01428997d5c GIT binary patch literal 58880 zcmeFa4SZD9wKsg`D;bgrGe80X0|pE=8qnCFA_F=Q1`rHPGA0-$ezY)7Q?*FW!7l<6 z53xDfPNh{_Thz+M_S$NDX|JsTErujb0Ii0PY7hkcsGjjqjgn3Rj5+Ur?Q>=l{OIlT z{NDRM@BRHAG-vkNA8W6@_S$Q&z4qGslwBVXtb!oe1-GEj3<-mPnHxjp}OsZPxQ)~ft9(jEEI9V=I@$zT4R zJ4(Kpl~Hi{KLh)J)BeAsK)^2u*I1mw{J(b2P1br`7-`G2I0WG-#Q2QZZ65s6-!^*p z8DaFlonG-T`6~o0f{E^RNe?7&LV{Qi$(Z=3Kyds;C<(sNTCJ)gUSo~!T1(^4Fv=QbHno7jk_ zwYQnVEf3-;s(lM3wBP)q5ZLxoF#MZLL1^FpI55cEBbLc? zs6wGGqh$~=>YKW*^R)6>r~1|t7`o~po|&yuM$6}v;g84=2+c#CR6U^@ngtwvMaKUzSxzxa)^*9s&P113l(IzWJfHXEh7S-Y zPTle};QPdhTb{!&>t?M?Z#eM9Cj)zdLX1!Wwcn@JVWl-0v<#zir zS+}guK=EczZ!{NRC*d)*H5TI0c1mgfpYbj znKIDWy5X5x!Ay!qscbp(_XSkH0g}VHq?l+!<<6&2Nvlb2;{RY3lbr7VkX%)2Gc=KE zhRQ@&Rjm+IKh8F)Z@=*dV;s;}QANr%?EQTVG4p-P?jA5`rBlhFKyvK#v^)YLVDv=m z6RgIm>ge*u!&2}?3wl?(MxH~N1<|SVQkpmF@7d9V5`kJsD*R^&FB(fiYx@aAhPwQ! zQ&7g~{yxQx$MSG*4k-L{nNTeVs+~}~zy@f;zq3wO*|So~K`nyWV4yD81keEg?!q4` z;o;2>nAPXZ-^m<&GmQE!5fhXdbXU z;S_i)Ff^1=7%8sm5vZy@hNnF2a6XCTe|C=VA_L!5cYk};YVkYYyCap22Y}<2ga669h5CKVk)bf}*8q)}p+2+!9&Nc6 z#EVw;Y^UzP_5o|HHB1@Rz$mKH$tpo% z-tPu^H<9Q*#Xghggi%V6zQJ-@kNX7qv{iJ-r!A7J%fS<%_GuZ(FzU^rSoW5!XUXFJ z{pY;}P89M5A&B|2?k9qvq&2om_L5dDT{*XfdI3y^zNETNvz}Uen6${{%!aXu+^knA zX^gucZIzE(ct*9Nq~)NavItRV#CMuY>Z2< z3{@HiX9yJm_1zx}!XnXD(%R0`+PP$^#iYFF3kjPxZ3^Fp#;Gfi;B~wY;)$7IiDDwP z7(r+U=u9ZqyC5GL<6=gmE~d%#9)UNxI{XXD`^KYaSPup>k-;DSE#iXeUl6IJg}eAm zE4`$L-{mj=N!cqsidDW+z;t;P20bhD$X6IJ9m)38w4(vZxmnN21*3v7fe-Pio|8T7 z-33AEtk84v5QmPZv4ni;OOQz*;5WM*lv&L830)2X^ZsNCQRdm-pin+SiSsDrL5TVg zRcv)3%|@LQ5@U#u7LKOTx7!VmH5jrgy?3#e`Ca@fs!+BeB_C@hF+dJdt{PU$;b zKtUVJ+H9>h$0Eeat$m8muK1jCo86l;12OB~-9kSl`-f#I*`oyP$|5Jx$n3L9Cu=K- zH|WGGbxvq6v9|!a%jcv!LGDdzk(KUaJ-HJ%BgP_#8S+{M!Er-*ftxrp1IoA=e#dc+hT?sld z=PT7t<$8M*4bKL{V@MgY3-ei}3)4))yF#z7vrM+j)-JauynEdbYytSVV0CYN7=a>R zf_+-_8S|iS`6HM2v$dQ`l;?tC9?SO1yX=a~!(Y1QdpLT`DZi8OW^o+XvVff}aw?0R z^engYj5ZLIxBJ>r1E8-NmuiU;KxVr#*LhZEW&WrE?R@l-R=_?hDq(NPAK5J)URTL} zbAA39j9q*i|4R6ipE%Y(W;8N? z(b9}a^{G=_)^P4QkIH|sokMNe!YS~nExn=BfcHg$E;c#>lg($1huNTeBbI4Kci0Yi zD--U<2;SxUocZ8AbDb)g!2ZHK}1SgBek$Zq(y~+HE zqBqnHM&^szn?-LJL}W{xdZ`ns%6#U+>cJAU+q^}C%Y*8_8$cl87ZQig8zRuRFq}C= z^+cHZDF`t4Y;J&M^>HRuU&|U~|T~%*%Oh zt&?TV^Eo)vDhK@$`JQrG85Ps_L=RZ+?nupO82qTMW@h& z_j%1u?Mi)#lcAL*>{{7{K+yq6fcXf%p>7}0^$QHrArEMvzKj?KQFG11uA)~+>}1kg zm#y79|6%9aKY;vi(wn-0@?{piegVf>@$zX*^9+%x7Gz3FDBfnwC*a_7Ss(%7({P&j za!m$=lzI(7)wBmx(g#glEXXsvH~s@r$ikfQT~@IK;}eD7NkBqbGQa>_I(plr5hNkA zxTri^Hfc85X)$C@H|CPK)goTVGE4|gFE2m5^z}}HRPAIHkZ*<*ldpjY94`OdY~OGh zJ;IdH6?S&LUAfLqq7Kher!vnTEr*zf%!5n?((9adt91T9>uK-4wdn!%ZBiIbxn3TG zP{+LEPc*dKFc=%&BheMbTKs^j#JNbwlKlz0tl7bAN;TH#i5pBBauSk`Qqw+%6MIBJ z{S{5rU!*myg`imxf4xj1VbE2V{vw}~)1o)puY>YSjuxt5 z4n5o(|4d_rW;0BKC*?s;-KA&YYRqwKM$l~aC5AGQ-%KD5$RFDknnl@bHe#)4wMCf_ zt+p$98Rk5Bm2HoW&x!J`K86Hv2c}FsgEVWJxQ#&T6l0SA0_Wx$vn!uwK{Mh!vds>@@>LZ&a|c)tG?x6?G~L>`EHzQk(if z>n`=D_$iay6ODhbKfq=bfP4OMeGMu2(8bD08H1gu66#xGNW{sfz*gH0wvu<*s0${5 zx4f@NkiX8@--xQk@&^{uy4g(m!-U*rw;l7o;{N__B$eomaiu;XUQKxtUaoYlNn@*> zij+vvaAFJDwOq}|)I=7G!{X@W z&;tGf1ql;OmHHSBP1ddjwQ^p-kg;_|ypV>;z$lc%{H_4XJ(?_cvssR~YPp@Y+d7L5 zkX(NJGt68NES<`Y2}9H5a-8?CMA|00Ju|3Irs9|OzhqtUHh)Ft3rI_I|pCrf1%NRl((|-9S31K8yLb znsph}9GYJYc}G(QADnG8-_ja`{=x-?WKn?-`xy)oAXy;%>iK3&lNqCC@_>`_qmO9K z9>G{qeU7u&>_f|T6|2bYuObhklq`B{A;ZCr7DR15fmbDmp2O@PWc)B;KSHqI$Hb?X z4dDM;AxwGI8%YdzI8%`XRlVAXJbRf>b7s<3au>p1XWMB-)6cT)eEXI<5&6H)w)3yT zUH3(};ytTZeP`v@!Zq9dIND89o2sHe!N}+E#s}3^KnV?x`&||>J*cifL7kkkYjA66 zs$ZT?!g%^@7?aP2G3)DK@cB{9HmolmqsoAqN!j`Mq`trQc@Ta+;CJ~4Kz>24cM9Sq zrlE`5wz#2-dJfMsl?=fE;(k*>a|Q4@xYUxvLG76vi`yf?Dh?@E03TPZENP``;R z0NN?uJ~BZ->tYyYWgfO~Uu<72aq<_WN7zn2ebbE`KO>Ks!#lWUvN-+os5nxOu5;@= zAKOdivl)2DMoM@q9F@EKDZDM9q`ruyC5mM%l(~VdI7hn;Bj6%y3CqvH~DVV?P z&)B5t7}n61_cnZF!M}!gBlst3wB{23wsF5yxG^qG?Qg?y5~NAmL}ZQo61q4l?)zL9 zU2)%_E~YOkNNC#^En38`DX=dp+GVysh)TDk+4?tI(I2QfdJ_>5tLpc%nypQ?jjiHU z^GdIlP9kYn%=+HNX5@v<^DIrJ79{64&$Bj_S`ixCJkN$1q^Z;fLjm5?u9o(}LW_pn z01Bk~7n>t-}tn#a!SmZmk&wKP{*5Sr3F*Vt&32i5!fhkYc(R*grg;m50)Ub|$OTQI(|c&` zs1Pd-Dc_tcw^>ohd+4rDkQVB)Ux(St@8oOuAbZ=!RpaRV0;f{y>MFIrJdKRorO<5g z9F1XCnuk#)th{v#%rdr>w<@p#-q61C)~(pay70nzrKNX=FJT?}rD2TA;PR@e03utg)cJ+!`-+I;9nI zeKyRCSZ~S4ZSsIkgw;uN>;M3PCcEY8qmZ$Xb?5~TS0gg`5-Rp%WQZ?t*&!391lqP7 zx*f=kjS}QcHP4z;AUWPiyXuq*cRl*&G(tXHmg3E~LI0<(LTK@x}mMC5;n$bWGK z?>^q{5v(#hK96@|fO5qt*KW!+BAF{s5c64CUVJXkRZh7s{v&c(@KE0?H(?>yJkC{l z>PeX9j2;>nuB7ZMDf=wS{=AW$GhUv$Hb}!TBD+ zxy^tBIm0=OiZ4TP*uQ9h(Pglei+LNdLrPXmVl8)L96Tb|7kn*yoxqBY`3r4zcEzuv zh#flWWlFue90;islh{aC#TUBl?v2j?nl7ojbV8T%btzAma*bgH*83J`hJwac_r?Zf zgZ;&y&pb-y39U-2Bg44p@=6{l3`O-P9I0GEoGsVq2^cKh)YMjL>L0184FOJJ+D<_| z#t+qnS`u6Wp%(F6xxN=xa<9~f7F3=XQ8}QwbbqfR^|7)OO4$HdG4?Ux1jSn#t<$D7 zh;$tWfh+a~;t9RV0qE`Zy%x~{6LDD|HU=TsXio&3%azyqY|saWc;J`=y)JBh0XTk6 zIKI7%&~}gH395gk_VV$IsWZU`rZP^uJYH(IiqqUL zlzMDndT|O2X%)y%`w{C>;~0~hS;DP3ey&&JmGY|R8Ly`PN;(#r;%pHyR$)^J$@irRQg-c>a1$cJ^)!NGOL?1t zahk0?WlvsCx(6>jF6;o~g?~Z?9;N~z1tL#!5%k++f9BkFr@VLw>d%P{eBW`iOa9^73jDg>{@FW8JCj$FB0=poI;*Dvx zqak@c+AuDBF6B8$d3IBtDQ2FX>F%9lN*8*&IouJDJ100Q#^jb{0k|^o_6=dG0aGAh zcfY_p936Dt>+xM4G2HMW?R++@O3;rNYtRLNc_oyy$^^{qh?~k2+F)ApCwREO`@F7r zhfSo>{0P7{yv`w%r63Rq)^n`b4NkV!8I!;nfOp=T@lLx~$dtw8qV+U!uS@%iE)3zB94ofVkQ|?Yr%jkF;WkkZTEC zKax8-S{?*Gq`OEiwT+k>syD0gNHe1TBVX7l@41v#aZ2UE?X>8M`VT5)2LoYR?WyZl z5_7{qAzlnp5N^75e$m>5ydDepap5OHtMGj^Ra{F`#nC0k@L%7j!KHzrabyTOGa_6h#JTbr%w$3Qp5-wl#3qY^G&LMeMy zfgW7n(Lz*amEE)<-p%|S%3S-7rzondTN%at-K=sqSq>=eRb?&&OE+ZLVh^k7hIy+7 zu{}y&BjLc>hbGY>@x}?mseoQpJW6tJkmv|it%v$eS|r~GxsCk^kG242bwNsRc>t}~ zt{_YAy$9WYyga(V5>O8vrpW`cB=HXH$DU4mF)ZyKZG^tsuKtA9?5VLu z`XP{YQD;dGRH@x;NWv)ALU6ALsCUC!VCXVDc`lMi+uDs}R9by@@{}D}AP($*0`j(C`@~r>cVde zg1Yz`Oy#LHsmVT@)B}gmH&4;h|MM2A!t0>QXs?!j)nX*jyb|8jLgP(+ZLNR~J&5Pl z1ZE<64m~;A6d*sn6ppPZK{%cQ6REciRl{<4$yrv+<(CrHwU%1D>Z;*=tGh=ZerXT@KQ(ixf-M~WOb(wK0r(E}xfLA#7K+fj)!Be!&X=@a;Ip3L zvVbu?3V&Hq?B=K!p!wCTCJ`pDz@Yle9$jx}MG!PtOq-7#E_EKH@eO>F$Lwo0!gJB0 zW~&`E=(1g1x8{B^$NxiJP@#*>;2&L-$!!G{GS1W+2*`<`je4j zI(`s65_8Z2brZy^`Y0-H@O}VZ!(sB|`leoW#u?=Rz#bT z$tOREFeB2t3mZjPm~Iu|B_W^E#Zy;UV7(lnon(Sy(X?2;2ydoM>^&CKkAu}~g^F;U zm)ew$1Pn1~pD}%m+0VpeC9U3xPyfj$tjVlRQx~CL8vSwm6Te0rNXyv*8i0poKhcf0 zRj76dwnftTl0DcEay{`3vUS;c5*neSta>Ye;Me3m6S||M6>%vb763u7851rNQf&{Y zAFLUcgcO2WpIuf)|FJnf9KM{ysSnZ;+RD8q)~XD|b-Uaeo%tzeU`Me)mAvY88YL zSSb0kB2s!onG1p$Qq0xxj*t!=>y&^AVnd!dtszE>O!1rM?GCH~B%)0=0zNI*2()T$P-`J}MqpBj^&$^1 zyINK~;wXBIp~pCSz(P+eLwLHH_DIcx0H=650)#N+Jnga2%BMG42IbB*HG+4H)^qmv zzlCKrrk>?+mK@;DmM}q;tG{23DtigCxghz>9nxq{fb0(yMXNC^2V0#c=3 zOcj#l$#7cZeNX-!pr{Srv{>N55PA%nby0huHY=#U{E?xC^kQh(n3Q0hMeW`*uo#FV zvGA+F7Qvs)9A$~Cv3rmKXEFjcpgE&AT5RP4-Gp~zwtGqdUG-lPFR(D|H zsgBvu0+{>e%BQS#q{^Q}0JfAm)vdp>C_63YX;>;2rc;)->jmBq?e054HoFS3>B z(dcN0^8Wx&HQBUqONVgEB04YmPq zO`;BllfL*oOTLstMj^=!x@OvX3BUVqhFsxWEW`Tdf8e-u-T?~z?~cp=0N4H>8khOE z6XO`;GC<+~YFye3T#a%04ceCbSH|Tih`V9qawmi-#^q0LLxpFJ%Z82t40ReV&`tbK zuOl^F7!`?q%z5844-Te$xE$s0$>HJ@J+)TIe-b!bPZ?tvW>Ke>X14WhC42I{ySc`wa zgyp_}EsYBQK#`v|MNP93=mApOIw5%BZh<)!WGd0wr9`3^`!Ho_Sc#9ei6d#fB|3xZ zL!I^|CC+C0t&8aGi55tlTBi!f!8xPresEJ-ACU@WX)_C`_)0_xW9lJl!m z{Vrw0Jnv87Y3ef`v=Ui~s2(iSK-8i6-ZfRfOxLr72=rG@i%G_E#F+OZ(B%j4|sUT>?&8aoq zmR9d1a)_5f*XP?AlY{P^(7He5vyaoq7cn@qgq`lhLTdn_F;TPM7( zSf`~#yF$JX`vy6Dtf5r#uu_w%mK$AAWDE!lchTlkQ?iw{e4=>RLQljO;SBq;k3lzIoiN}n*Ubinb; z?(M#dc#Bl^DAfz2M}|C`>kBZ}@RU?Np0n#Qhh*Id3=9L6WWQoPxrJD$v6Y;>pnlK` zoX}CVa}nHgAb3t`3B5p=#8j192y-I(2<94N@dy5vJD%sb z1=Ri!O>PEN>(UgyD(Z5m;6!zykM=^YEwD$gDS#NOLr(V#^9yD%v0yfBO8ks?XRMN4 zKn~Wff~ZTu4ykvyyRiWYUDz~+oE1tAzsy^ZS5QB@dF+Cc)_7aK=*SYl%JDWIh4Lu` ztv*Zek)F%NB6F8w2RL)L;)W-ZH?Lq_2g@sn+WBfmbC&Ec#V$ju-CP^>qViquSj($; zd(|4)&d^+W9roO$Rkd-obrmcCM2gyfsLxaQAcgzXXDHl*aLM7Fgkw;>5?(jlr%Rqw z{2H(k$2E*3{F1LD@rnhGme%kM{g|$o(su9}>-tW);~EIDq4iv2>$K5oty5)u*Z~^-4B9?TYW=Etkg^ zLS#&goXHR!kuzD+nB}T$sx91k_jv%oZgzX@Sp-6C;pk^JN%m)~QdUS_#^q(~N0iX8 zY_wpJH(<=KkT+m{^(-J7x*=FBjko4FPT-q+u8}liCC^5-a(X&n2;Eu?8~c zlqlv^+WDfnHSF3BVPjVqiLN#_PEM!LB;X9(xC8X?5zfQ*-yZn7bSf#R8DLVnD zBdo;(dZm*#^s#x@czE5IhBFalsE2P>`3%gw7~DO4p{tkWx|_zMFpdXG6ZxW7K2wA? zo|z8kf-}<%qd=2i*PfAet5nNZ!19@5sT8Y9suN~(2b?CQlC!GiVB3%^pShcWT_mheeurjQ&diy`N`BlYF z!6Ls}vcEqLaj@|q<^T}Rin=28x*(=+r;z5@jygABsjN9-ze5(ezRxP=5k-S~B^)Nn z1&im0HrPwcXKYEI5TvY9V=;x<8Yf3tWj@X`DjCe52kD3t4E|nIGlU+A9RJ6{@sh)~1L$&%4vZhRgU z-cB?@;XUQhFiUe`ax==`&~D()Rj_lgcZBF_u8DEHBO-EUs^n~*L_aezCpEXnBTqmM+r``n4vLM5K1$V91l930EIN>LL9~&gaKa(Y zh|+!s0S3sG@Yf;M+^cu``ym+MJ&`Ec^Kw3#sFb~rf{`=%?g!_hPWR3O^63rkhb~2! zy%O1Vykvj#KKKkZU)JFh?-qpBiPiA zw8_&?de%;_T!+F4;XJ?gpFoUwi38k#N{ye$9Td2o5j_&>*n4IL-tvJtv zO*(Ar)A)>$>y$iTcQ?|xA|&`g0DiyiqO6=Od@Y^1##us0Mz&DC3IcuAQc zJfOu^BNaQ#wmnc(5M|p76)Sc_68g^xdfCA6)PdL>N`2j9G>ueQ>?UIn@OSycPht~| zC{&Y*%0N`)%FCp4BkL_Qr15g6)hN^O;U`#X8IV3eC~{?ql!rXul*S?tDrxvo$2!8u z@MoUk5)S0DBoNdBAOLUV*~0V8bT>YRzyhSCN`D^_UH;u*Go0*0fD8UC1U!g|24hW? z?-8%!4EhK&^>>#3E^3&VEBo`{y^_ZQ;Nu<~7f~vY#5SQ=e-{-NFGRW>=^OX(w1Xn7 z5eI*Y4O-;WzKbvhgYj}BAOd6YqEv|xiiDKP*TgLM%l_Arg)Vcy;D0SusxXzC!|x{e z-N~$(2q$w!8?OeZVUm*TkHD!yuI~{rjgk>9lU1snRzaI2ziw~#zZbxgeK*$OYPl{Q z(WM^sgHho2j$F#?esDZcME(jj7xzkF>$pSlx8glAYr5pn%R01d@Vx-PPJgRjrUFQ_ zzrTspaBpRY`v;4uaM?gnSqCPu*lfI+*hiy_fE;guidDNBP#q+ZI-H%20VD|Whi9UX zQWi|9u^)r(pe{;FHn4$7=*u~%vOFVSh|LA*8mUOAt8p>GfU)^~lE(nijHaTq ziZ#!LC~D%xIyt>4H>6Usfbx}9pJ%qhz~8J!u2%)A5J%w)A*{4>&1&GPI5&Y#P%7W& z8DI!k^N~TWe_s%15Q*1er+Gkgv;gG|AS|tGaC~_Y2nz25T11e4ONiD)TI@6$@wH_f zRAwHPIDl*s6!p{0})*!pyyh`oGnfX}N? z$GA~p2Uh9W#sC`Vsyv*8;*q#_A+NuSV2T&hih2D7oJ~F@vj*`OhtaQ@i}V6sP4yNV$tZxf?CN?vrm%SmoP$t@k+i%mdBKQr2q7TdBar27JS3 zu-bgJ3JNe+rr^_-@Rqf1c)!2PM>S10r?lE)^_xbX)U-Fnc;|@Tj0!HGX7*ly4FNtj zM7YnQ{rNadO|2`EE-_0YTKB8X@Fh5IxI%$GusLX>lIRqxT}A?c%Kl!mjev8&EUN*D z#`a4}<@2npRVjN;D`ozdWdBRn5c5<-%YI$1K85K9Em8d25NGnLlc34;E9?B^6^%x%UH=F^)BQu$T(DA!ax zv3rrpl#8Q5s}SQVOh~cBZbk}-%c4AIMl67L6RCjuFxLt}Y%DoWGz%MBrT0x-)M85d z6RAT&wXtAIGk}^}aImT*ZWuvFL79YGR8W0_yzCdiI_2di(lsB_$`v-3Ej{21C{pri z&jy!xp8U~B(Y;vA)-I7h3W)G8pRAqF7LjfVGl?&k!BWKnxojTXTzE9>n-uNykSl%C z1`;M40PL2qGa!J@Gi_H5_09-*(ETHFJu>6MGzNLzSI){?o6jTvn2H3hwU~qe^xuZZ zg&#?lXQ^mvSFM%jU7LzTT=-xz?@g&_o)_H(xQkPfR33y!++}CQkt=;boiaQwOfBNk znW<=k$!UOD?u#%eYR+&fP+p>ekvAg+gmB0=BL9IZI29=l?s5e5ondjD21fMWWVAs8 zBk~W)NUDoyU__I--{>5I>oFpgWF*DG+nMSjAAwZ;79;MKVR4)WM)cxjG}RBa9Gul~ z8uOMw_P&~S&TaDDa8*i^@5UVuZuiUk-7nZHe}?Jfyj{dgK;zng^}M|dZv>+}2(F=- z4{Hu?F`LbDh-Kw_VRjggG@>20&R!;uaC;dC)UJ(#=_6X^tf;k=W2g7UAaC;EdF}k9 zreTk*q%9S!T1G@>3L*|X5^yl_o@Qsf!B`bc!@kP8bGY$o%Gov1P-Ha<0R-dWQceLiTuDFp)R~(2Xr%j zhBX*wL+o(wY0eBOhIXyhV?8k@e!qe7TzSyCZYt&3PSx=>W`NVY)*1v-o(lC)1;^b( zInyHdS>QAV^OJTNZ-#a;l^t5#nq@6i7Pi1AjIz9dVd5I{AEbQ>qDe_B?K=#0(K(@p zdY3M&O+zh6X|8lNdH5O>FD3hQ1L^55QdHuWy_)_CeBfqbq>A;le;Jqfv4d+e{sRVsH` zk-Fwxy#JX>ReD$!@ma<4TD=O*$L#iGIpXOI2b}8{#eR-lY7wI3fqO-6JBym-IyLuj zHnRA9I7ZZlSr4;0PIkP9vz_Ec?FlT0_P~1wj(RvWU7^l4YcTr6hm(4%;$ z)vJ)>+EmVN9KjTNdcZ)>C~O0chEdF*RgeZ_jWb$~jcPjTYh5g+@q;FPumOzWp{%0z zeFOK{wWCm(;^&(my*N$Jk}7U*MZU$<=$xANst8ddJ z1ATI%(dfh2=d167iJf{zML+Pj43#Y#)<4~dC#>!U+-TWpx@gD>@nF!G_TNw!SS}MF zX-R5u9H1J#`y<}F3A!M`vzE|pKm^WV_+jMFjrvb}r9^#Bv$H7!-nDeba+Pnvyi!E2 z)2NZutR}=R8`hiHtiah)fp_TTQCPKjBe}H_sGZ%;wP*-GfQpd-jQ9|wE;jZ@adV7uwqR{zQZmu)w*7x2Ko>gqP9PzfUnY?>!8Tv{vpZP)2@Sz9}6`{{v!cK2_(51bxKGt0G=>_4FLw2x>HoBV3{Wcv~nz52|< z(_j6zPl%C9({OtJ80<;7T7JLBCmb$}kxGN<4q19A%lUX^ZH@cuaR9r&hwYZ%N#8YK zd&UBL3Ck->?Dh#tO&>x6O2e@*grFV4kW!Nn-G`@NLqKouJG$p^ec$GNaFTIvYzH$u zW1+#(uyj5wiP7$nKAaVfRNK zEf<@B+3uaMus540+4e`Xe`MPyw{0uMNG3WTE;X zmbx?>qTcAL!ME!N55EgFY>+z-@wmk1L%0kNe&}Vc_Z(Xv+)G+k|Gv%c7jW`nUuIhf za_-RW37%h{`V!i&Pi^JT4*uMYXZTe-)cuptjP`Ipg*%P#3_w$N7~z{J{97JA{9af; z7nZq8sWx>jFof!8=snR@BrfB=^oW#ptdMGDPNghPS3i`UhNto1mA=Eb$2m6e>x3X< z*A_TK4fi^)^oePQFFZDLb34mW_>Ccp?4$!wp2LNQ{#Meu`PlKddp4VTf!y&DNgeWM z@L*fT{osS>9a+cDhfDz+af1ySlUChi&00S(QjZf<<2uu(FCaoyx*!SnV*+r}=7TF* z^AhX&Dda0pQa{C#tI0Mjrc^zL)|YVo$7FU|koMzVQRy$*xFyZD*%|e)bQd?JEzq1+ ztP$e~MJr$Oz9qfenT92U2YqR_m5<-|31@yUNJeP;dSB?p+N(5YX!~Gk=*7R_vO*Uu zX-;-Jgu^kBkW!DpyZVL@lu7*em zR-!piP~U;65S@a~592aG+z^e2`l=BLWz++3hiXo2KIA{~c1`bQEuDk!-OTerWvNif zf8=d{FJNfbhL|&yxi^%#$cjHZ{?a7Z5I)+B5UvcFO1n0_K%~n-`<+t=8@c{8rVKzi zbX;@eN6Q#0m81-(%Msp}@OYq`8_=EW%FvY?7B$A}T@gC)nbv8WUfO>&T6TnWV)LoL zY1CXJK#nMqrj5J0*^=xFTPgKLF8Tt_OO;2wd(jtkPS};Kk?ZHRw}4F8Trxd!3?9x- zjXQa!U2?;05y({nd8RM9Jkxc_>pp+kNC&PnAZOeoH>b+({M}R z0y|#2=nbXXQfJVUgeAqWcBK08Cy*wQGYdsegy+iExHuHOUp$}qrM^Ca1PFZ4b3mv7wT9Lz&00!B^T?2a&k}&sDI~%x@@?2 z)_58Q^$jqf&g80EdP^QC2BYI-{IG$NR(X%kPJZ^={(VKK*uL-g;|w|LN*%@L_wF4WoR~zf^t$`kL2kC-wuz3&bKk7rGmNhgQpjpSvG?h5{sP%!6VuL1O>f{m>?! zq0s%%_Yr7}Zy48UD=uxWj5m!b#dhxqdRu^D*bnbj|88w0qL)hPM*2cuvj?Z{PuS`Q zy!Ed7JjnH;*V!ps|MJ>m?8UuIL$r3hst(@ z(6nYhjVsg?c{e|@*H4JwX!^XlNzC0Etn`5Ea;N@BP!S3broH3j++M6+%-psgTKF_#gDSoi?$;^yz zCb=6I3fQI#aywRO_3;JbH2MLL??-2G9^XTOui$ZG5P-*N5P-+e1Ds+G2hPtS+{D;! z1+Ql%V~O8S62CvLjWbf0N|~Wl)`fH{0*DW_^&OM-C!NjuzkbPJeVv#;Uz@a4JO`+P z`?EQ}0up(9rcBD=@X-_^Ub3xF#t0y z*gaZ*gicdLXisVY3k-pF7d!oNOQ-)I`0c~rNvKgLc7o{Gm{e(Q#D1Ytc^un;@8ftT zM%_9%*Yi1}ot#O~MQ{OuSB(!h<@!|=(_=fpvGMi@-FnpTF*NCe-225%9D1fmN<(!P z4elz_rAfcHG*$kisj{DE_!#vORDU*nbqH#tK5mh6BlZ6f#L@DZtKAzTfGwX{>fZP_ z1b{jA>izBB9x1N@OMkS>-S{7X(HO^NR&S862P{?E({Pt@Kll^G!)3<(&<`k}6@z^@ zOvCxn#={{cSIppUSTU|Pyrw6CZ46O^u=#u=e&oRs8$2xC)*7`(a5YwXj5e*j(t!IR z9|CM#6nm1D9c&pC{VEl4->@5U7|u@QKGaTQ@Ri0d3_ zax&|cY;X@PftSxJauo7Q*LV3}qOJgq?p|>gedPL=;KGS{^UQSY$Pi)sELsn_D;*#o zp~>VUl*isQ7AbGZ?cMB5!x_G`{7-bXMf(kr8csZP`-EP0BEszy{m0@p@OP{qMdV9% ze(V=OAX0x)5dC;saHVV6tDzQ%PGv5f0A3B@0x#po%71Wh_tj9>T<72h4epGJ|A^uT z5Bag7siNZq?RpSyJ+1^BfK+}1TVdeOqPB9|fU3Z=tNL*Lkim^&=18e&q1&-A7MRRt?H4f5U?I$Y#EqHv%z-j?*h#7;q^9ZbGCx4^)NU zCj)e_EpQyiiZQ_7M-!Z}F(5Ft7u(di!n%==`f#a9(q(uHw4a~F_tYm{;7F>FF%0zWw|!0RZAeT?9#e0`nIkAB z#-#wy*u|;(rH?_}=$Af%X9zCI6?&arFM;{~DBX(Ik^AHk{<+zbA;|6dBYtN2lO+K&0Z0`7l7 zz&-Qv*9y28-GcT%RlqfWjfmj_F7h=Z=KnPT_vF{q&IQ~fUsL;80*>1){$=?#h|9tL zOZi5v{#yC=k^y0ue47R#`V6F6m!lY=-n&xr4QnLk(V^;CX}6A!U0HFTm~qz_)~9-M zuO8c3#5p4APVAF`7DS(}W4Z(De9EN>|ee)35Y^8ueE6WC|L_75C( zLhL#xJ78GR;3FIFiWoN#V7p1NAQ$%gFoZ%=g@x6jIXHVd1C(eyyusFgxKutaadY){X5;BGLR4sZ_VZDw*4^ip%S(?n!PWYT^`N;A-2mAhe%r++r8_Q=T{Vl zQ@UuQslDC>Bg#ltf1-#&?gzA zg6bbWi_y1n5Ui81n)yJTKVJ7_7x%#)s0{@#_eaBan|5v#B zd&9ZD1!%o#{TklBhq(ol*==-*+000{aEd@VQBb|J}1m zhEHBYImGg0pXPT=z(kETD$aPO7h~A;Y7<~b!rSjI=5H=}Fd?NIPHDvuR%p!$+-UVv zq++fa6MhcUpgJB@sK%TTYsa|8Nx#S8#1H3R-@G{%$kcUx80Q;*PD8%_gvI^9qXX6(YU6)_;QZU!Rq3HPW9o)0In~ItCQrsIrv; zbfJ>D5445eVW3pEUPNcV_Mkt9-Ic=8F#M=+ZPOv7nfn7+NWr-S*B$IfgL31t;S4l2 zayQyC!Uu25BG#>)Piec}bGrYy+LCz`mw;p5_h}gvYrMdTa^qp?PuNf3jvweRwzp`-N)?Mwe4e_OO@lI^Z{0qqFzqeJuvBGd{R2h@K|1E-Q3(B*0bNV8sOKe%VBO5OVmu%>&yUk5hE z;qm3_A9&>Qpt=K*LG|}2Y>)=^fFRrfA1pu)6Pq@b!#H3sP)8x_E)|||-E`bDy+z2! zM;6=J!HRJ9{lNJ#zzC?Tkx8CifIT#xj*Soc*2nea3((N9j;J}uhi2juD2zCFO8IFUDcVZ}Ub*8>t9pg(xD zGx`MO)hwmzZ2V?<;E@*y;_5N=06=j!863O31Yy==kgC=io)1KDqZ8G|PuW+g5B|GJ zy&oEp*zrNWg*@MSL}^|VeO%GP+o6jWROva?qUtTwQuIi!(PmwAlT%+tRX`^h z#%Yc&?4f}L=1IQqrgvBx3W&21A8hEj4NVDO1F&j!5n&##=9pZEmvESZI$b!2FM81z zzEDiimf-sTM-aGHT}~z7kYn6MGis4IK`Ssaf@cM7iV=2Fc&rhovn=#UFakz-8afCP zKerVY35joT3~lQDh^}t09jlJWq(N{DSb}HqKedIFfl);9KogyLv7`PWgTj%kxd+$59ou85(j)x*^`8ZX6a* z5$N|jji~lb{N1A7l6*JlO~T5f$$Gvj4!LNb^l4y> zuRs#sxU$=ytzA({o1wp;#>e64L=UI<3 z@l`~Iiyy$3PN@{^m^lO<4Ms0#a{}B7(u0-sEP|qW=;mAlmcnDUQ1n(64}3ZkPh3Ke z=MC*T$55U_ad5xiLKOwnA3sd>@{AR#LN9=pMR}5a$(;c>P_KiKmuATP*TZt?b=SMr z3dReRtJNqE%(hZ-jML0;3s6_j#Tc!oeir>z>P1iE#TQUV@_K1BXNKRUT&EILHx8>0 zV!zbfEj{`DezuQwVaGJJUwR{!iAT3k1uTbCF>jOZpa6s!KYMT7>l3X>L?xV$btyJ< z9FE)?W>3wk+gK*H;q%4#>=EK;Y)oX<6zN>umP(i++Tq}CCX7YG=u`Jj*Y)pk3 z+G@08!H@8(q;2iyO?EfFh|USS(4}f2HHaTy#vNHyudP`aUN2k~e~Qd(BrdAe=FgrY zO+{@PxTEJ;qknmR1D%hC@H~g3f1zlfeU;?k+tes=&#)3W7GdJ~92*N|L{Ed!c??Zn z^qEYZb36J-!>odBEt4)RGjatk2OuONu-yEN57#}+mBJRId7?X@uKFSM(|#p~qEb8p zN`uPG8M$JGn6o?l{u|#h%v!IFT2PURdDO-NBofncL z?Z7a$c;M{9XEoz7Ha0}p#mZ?=;)nAGiNUYnj}X3ED7uL#HuBMRH(mf)I-Er|Z7~Qy zJTmtolSe2j$sj}XsTREEyf2Wxv$WJt=TYdn1NVt-$#axpazM1;x0qkZ~ zhe@a2LJ6dFd~zP2?TmNz9x6xpZ#lv{m+lf=MR8ktQty@YZpdKDq-0SNm4T(GvRs}+ zuYy!3&l%u>@oE@VY^4`2`yzzM=QwUtUGjGr4JJ|o?kihpSzuFbJwbKwNhGlW@&unBwR{5CL*P6C^#uY0AeN;#dShoc1V4)2 zXs@*^6OSWHX;6KqiOcRrQv5j72%sj>FCsQGG4)^y-0_X*ecSe1}&+&H@e}BN=r}*>#z$cu8zZb2@gKcXWKiml= zwhf_V>_&Rc4gBFD^f^#~#$aH9TR+&hJ9u3S%0KbGs* zLB$TPtN+c(cjs$kqLsbmf}cv{_N)POdgA>HKT6b2bj1=R2R{Mzc08-Okg933V_8G_ zf{{7hfG8X5~Q>E4>i<$%}H%rjnsihcwQ{~QH`D5#v%kdDuNe`=*u0Ga>^-DpmO+D`) zs9BqUdDZ|AJM6;+uK`n`qDt>Z<7u(Z^&Qew)i^v}Nl~Tm$eQ1hHSW>mYF7@fzksxc z^8+@UA+<^3(e;siv|cbzd6u-YUR=HJ-uNIAX=``@^LZ5Cvno5GVL#b$(SW}{zODrg z44!UK=Nv2m7bkAk=C|Za=dfdRui(Y3b5^MZ$5Vq=xjhXrYd+S_!S%Uv`)Ti)yG9L5 z)zZ9Y)_#J+^RoX0w%VPz0-|hS!zP==acLBRZL*6=p2~A(fChqeLzjaB#JK3Xym!!b z8ORDQqE8mnD?j+(;Z*6sI!RBluolAeZ+Jtdl6dqcyEd8u^=zEX(gV4OB$4F3eBDQ= z&y*MZen>cbF7V)#;8t3ss?Qt%xT^dLwluF?J@5vH#ugOfF1F{1Q>x}ysK25RzPSr5 z2tVc0e1xzyp=8m0wCcUED5$F-Kll`&E~5}B`fNdQfK^SaP;WVDKwau9XA5Q{ZYFA* zQLaXLyhk0MY|$(>u512J?9`*R!g6(l*)|+;?xW^qo6Qr9=HWBdB>3Ilvc3&}gB5`j z?XO@`G(En+V-as<6A2Hjp5ZZ^FP?%D`HzTqisbnHlv2&{`+S}N%an5#uGgPELi&^v z?WM_RJIee6WjMWS~_^`4(EI7+LTs z`W(uV>~J{wT&v=95<+}_!8Cjmii{}57~152DtF9pS9c)|JdZKW$3P2SX_zP9e>?o$ z^q_r;$KenPJHaJF@|VU;*#0_=FZHu?NOTO~xpf+P%)I@WuH>dyez&!8)i2FDw9*Z# za~}ZS7}S><*YDglQkB>1dOSj_Y24?l{uSd+U5zNYiASj`5oQsRz8J*DI3`HyHHh~< zM)8tcy^0DvMFj?tC8%nRsKv-^95|zoHsLcQwF0i!p7e9-N;|-+S7nZ{>BjJAG zMti(HUtB<$E&5t~5$KaAli5xARLj=l+#=#GAIk%%!buSq+$=;O*f{sG1E_&04Bv7dGI4 zf_81Pj_f5c@t}@8Z88UmL8M(?wVc2e;{&lA?)f}L%ir+;LER7JYY6J21oc6J`dtGm z$YBWbN?b;Wd>NX>*PJmAr?&4mj@Ja;lTR0En7WDJbq3Zja!9r|cxp814Kp%y{eciZ3oJ-H_{!S_aOkX8T z|3H{NPMGfch__$%uYrJ;M=%XxED|57`SL) z7$F3B^{(MDJ3a*v-U(A|fGczZZa=~OAjX?!bb;K_+Oh(29*n784Vuu9+k$MWa=YGU}gDAlZ)OSpts5bWfQ4zN=*-aTg12_ftAq57hEWb zD-((-)qfBdAK|W(#W;Y{6J3CB+W!*gIB>~BxA6f8xOjEr+p>7U_lt0k61}eW;5DS& zn~RS{U~WDLU#|%~LyxjJ8yQHo1xjEh z|LR1xGB=+m;l3u^@X=cU6?D*TDdQ!C*3$1>d>i*TT!V$v+fS z@Bb-rSPv_kq2Gz`Ue3^0XS2!~`Wg?90s4r6(F`&8Z0!vF64Vp9dp@o9EAj2k3S7Q} z4`7u0u#Sn5{UiWS)tCg|DZ)&MOQ50TQKt>Aj2N&&vZQ0u`0)o zWfekL!?}~b8{ouOhjRIMjfi}5D~P-vM5ZK~N<5lJT?X+W;h7 zmrc~kxV0fl7f}@Ao)#dhRPHXv*s+A^=6iJ%bZ6{f@k`>(35>mp`v}V`tCm*;1J~+z z=HuH(cP8{Z^FSB<&TRcokAA01ztgGTY1c1NH}IMG8j^}!w*N)m1+Os)k{zX$RSEWI zhA(bRCuAN2F0_bss6T^fj@$?0IijT%P{c}oa5*DWCv_JMhB}vCSD@GB>vgbZ*4fqZ zyq4mW0G2zp!3K(b8Qjye?Hd5w<$oTnhyE8W+os@>l&kI5mirK~gB}=FY@d1#E&`-o zB48@xGl`pw;euhSj)N%-c#R9w4ME|2>XLEPB{JVLaTz_qzefY@z`#(wVpu=qq93}R zNc97?lfLnAs{-1ZH02TxqmsA!qIl^9t60EFv)QH8SJ5E0TNX_#*H;$?D%2HRq+7ff-D?H-5;`ockdpCa|DKZKjD+yb02caIAfrUCrb1pYDtA2GnIw;_|! zf$A+39HVTa0<08FmB7~qEcGf4;ym_STozzT**W|9m{X2zK_AyHl$Q0O4V zXK6)?N-4KRrCzMGqD7?m0IgP~TuPNv>KzQ#Xj4cnHQ#^jb7m3(T5iAJ_xsx4oTJqT=Zyd{1|9f+LU4XR-vNUTA2w-uEx%r_6LcQZldJj zV+ykRN!AVl=Z;w9-OdqeVsCbN2%acq}*smN=?D)>zydL)Tjdt-6G%sVNz?@ zwN6{IWgZs+CCOKy!>2MGT*D3qBrP5C>^SX4rkj(pR=fz8Ekf3cpVBWck3U&afK&L} z?;w%~iR9lA$y;$!KH{loGWI&RWTW8d@Ur&&w-II(jMyqA3?YE$gXC!@&#TCDq2h@% zoM@Zu0P0z8?Dhu;DIH*N9rh7pcM!P_Mh0TvThCIXaaqlPwWd$TcTN37`s{mfo)Bec zSCoY~-VaA4h@;{}{V>Ks`%zR3g#K^t&oZWj9bPnb|Mj^Mi3LL(C zHU>!8BW9x{X!J>)Fuqd7IYa3aX-6}7joNcl_VHqHnyy`9o6erI(LI;2 zWIdOQFEqO8Lyew~l0t<&AEjj7`8P0KuAh;$f~N70zd=Tf%7Mj=PEAgILV&EoHuAAa zTs?Y+pOI*Np2^pmf#=CD_Qu0B?45TrxY_!Ob1X1yMwr-?(BL4X7AXyVz1h*mVl*>c zM0JaRD_7BUaiEh1!sEZOS>Yn=H?j&~+|Qtaw7*Dg9L*5{RH9=eNfQclxh^ z`;UbC5f%3bP>@Dj=VfNC-1kLd^bYZ%3jDj_hzhP~wvgm>Y-Lz+i{jSLCx#STWkYt) z%jvxnaP}lx1RZ8D9!=@cI`oLpsylpQ)qdAnUDSZ?Mi2 zvNin3I{*=nnHri2 z&sO@i*o^NC4l0+Ova!_h4NU0aV#9A{uf%DQtH}Ci94I5A<>RD2R5=lcKH?4g|9k$5 z$wn(e;N-^lA9HfrO{iE;IJp-ACsjMS5d*UC_=sH~ly-aqq0AI<5F5@9W_#3+#iB|H zumkO4T-FL2W}QpH!-e83_qg&0$Kio%?Ao8paLFO58yH>EwEvGwqMc z58o}}!;4y6^>`vBl0O*fAB-GhIf2lL#cElnhWpt3h|9*$e~(_mhC$}!NI8pRV+EEP zdl!@UP*!nreq0GXttz3X6(!V-GK3P^xF8LaasgJL1xzDiEta)ioUAYpt*<}!;V1Y` zXg}I#f-_kwULY&>kk%j(>|8laQU;};anFqhS6Af{2W}{crixGKe~(ee2x-v&Jh{ex zff_>6081Y@!^px)(F>fIdqlrco{Q)>93F?5P;Di397mntj5!PnvN4XIg~nk;P^{|C zD4>(FalvZk5#(7f9$$}A-;sqD%-Zwd#c0oSsXgmq#NIeeoW~cr1E_~9yHNRuulA_g z-!WDDV_&#qzg8>&6pVr%JDj0t-g3WUFN9o04@F)yDH@xmx?>=a5BCu|J<~t&adQEwK}*tm zOCg!?Ju^n&a&nZ5=HMn*Yy=*RjAPfFk{S;22>}iTqfmFUr#I6&FE_jo{g0|Y$4ERy zFlNIww~T4eP%ew!K`#GJxvcsvD+Ky{hek-5(Qon?A)x}zp?eKet?w_wHL5%t-NbJ~ zR<3Q$JzfdMz(2p8E(L0r2<0RgvA-Nr%JqGqfx0+0g}#gKgCfNeaiQmk(tfu&P=)E* zdcY<%Q3oZuj1q07M9YUII$KF}rkW_WzeEVd zuteu5iBfj5R!B%WP9KSJNQyp{I66=j8@-Mfs>BUs9uGpxXY_SXPFa$~*oRx>2h2vRC7spYIV2d(F!XxNb}p@qhNXpHW5bb1|=9fMk^iP$#vkAPi(BgR+m$!;u`Sj&abggjPu*y zr^qc7*-DXf)if#xPJL2RnT_j=!ujnVP?%*DW&wri`;9{9jRRRv=cIf_3CV&oNk9YC zY-lBov2UKHK!v^e6LoPfj2z%mrg%UR$9)HMh~)d=5nXPeiU(YhgJpxS({;ee+t^Ey z^hQehE=oG0CS8F`!fJa4YN5L9?Zv&E=sxMq!7_a@K08Y}5Iq#V5)y4*_QdeO#G6m| z+>WEi^4m>>Z$IJtA>k{Ed&vEL^lb2IMXx^vUl5{X2wy?*WxlSerpm8phmCAxbI4Xc)0gY6wy?ph2H3 zV+FsM0xhCIdJ44c%s|mHp3#6VD=kU3P;Zum^pnwhp*0{OhT~g=<2}N$lyF#w<0v0@ z{Js=427DpA42Pou}bGQgB~WWNQ$;X-;?IwbM&F=%k8#o2O6 zG=Cp05=v z)MyleQeb1T6Ql|v|1miw+J%pwVeL6ug^x&kK6ggIg&5`#K?XQJfguLRuRgVxW?gAW zdE*K6L$O#JYpqN=*ThKcrK6Wu?nEG@gj~ush}%l1K+5=l=S0?Xw`Hd+Il;uzy+q@7 zqVXq0@b3Q?}QNEl>U5IZ;U<`j^v7ceMMbi5U z#e*cxX%r#z`_n1%D^y9s=R?^i%lIVR+F6;syo<+1QaYYBIqDpU4uA`TzoB#MQ+hs6 ziQLxnVO7r;RbWTQF@+sS+LT~F4HLSdo?HnRboW=_Eb0?92^l#SyGNNS?KP3*sx~OP z&}XpH+l8}iu4J5;QGiWjCoqLeA#PEFk0#3ptq4w^7N3sp>v_4~igEJYyU@F^)g5(u zkXE#M{x*mcHkBoFTm^oIWw0nR21*kRptGYHJueMJUqaO)hk*s@?azbFwXp+>8K0q* zs!{18VW>>&)(sZ*WtZV>sD5S+F!MAsxiRFP%FJ|TW->FInYqj?U}hmRd1j7dW-&7- zF;ifso|z_Q+L-BN=2T`@F|(SPwajc_<{W0uW#)Wlx|!L|Odm6Y%#@kg#mvRbT+YlD z%v{CHHOySc%mSQ(x2;{~ zwSu7K6P|%kFc5Od-hiJW%yx1<6}I3v{;bQv1;uSnt{*^8@I@y_TWM(n*^#@PoM{#O z0dv2F@BVgBnC<(W++z4v#G1R8bZ9sMVs`UELBfWxWhH&pcIF!b4nrsL|kK)F0&8TaBcSi>% ztKHsEQ}g5&3tt^@xvRa+Ay=rIzuL}sbhv#!J|2*7b)l5pLlK=+BMF7GzB~L4k6h#F z7O3wVia6oxWdy>&Hh{!ac!iVG1F8W&0LKwPIY2MO z4EBrB6i@b{2O+rX|3o|$;y(MYbF$YM_(T`c({tiWc;-f2dg44A{u_@={)>T!$~TUi z+;*vMG2lqv?&R_TS^z!%0Pjb;aPyw77Eh2`GB3A>&|tV`*OxdlPMsaTG877gxX_}o z?Dm90g!>=W&8aF46qfR1LmRkiKAE_KMknV^g7>LRDfEx{npUe}yy)t+h9oI8^C zT+Y+$o9Y|tZmcM7c7;6@pvDzmSTY=6A_Q{NdCm}Vj|!hF9G)x(Tc-J3ZDD>qUoowz zs;s`LysW;memKhF;)p-&ZS#ZMO--$?5I>=$Q+74`JhgJDULoh~gJ79!fFcbVM8Y!PLd6~L z3ix6)AgV*Ev&Sz(V6_G!es>9X^)>%o#A}A9O^pK&wGUo&vUf7N@cyoG$eyVmdMAH+ zP7e#OxD1(!{7B(;KIeoZN&SD_X9GxUYHF&et#x~vBW+cIz`_KvyG_o-`^cAg9yjiw zFiIZlWfwZ~S)HCxt1qzVYOb~dUlOtYa%60>kES`pb37SvC#gR2NrwBEL>U?Mg8c#q zE^y!i2mUWOpryF;A&FEV>%Z;eRK|r|PI7W;+NkvO^xVsGaxP6y%S*nhWKuCb>?bX) zBtQSs;ZN42Ym+BsO+bL0D+`m8)3TEDiznnvP=j21XZnUqk7WFgFDMw5lNJw|gMgZZ1uyVHD7X#{N=hrqW4 z+@3@bw@Y?0y3`qlM3&v2PH&5cE0bkUM^MJVK@RXC(9;QpGZF&D@-S`?&0%QX$S8{i zz9DBGmf3J3Emx>5!ssgtwPBtD8m$brHGA8*$}Ud}I7!s<7{XyRR}l(?!=(y3n$uW# zP8K7bmUget%?CpP${V;o-R}y*77Te^vWK5OWft-a)i~gzqETmzD7gq5|0u=b_4ARi zhnq%4LnQe?sfTeQ=xXusK2IxVP^c7H=BE36o;J+aggu^x9ER`i(tzIw)th36yTjnu z5UoUcm@5wj7GnM-=nZc4`l_-6%)qo$D8kAwQMX$#jD`;;j;5&dM+(d1kyWOny2tAT zs0>6x-~`nLOuL1=$Zy2&>cnISjUu^nHc6#M40&#ipq;qE8#P*UB;3vFwQE?NnU0~% zFe^7T-nLktsM2*OrqC1uF~gR@amD_K&sTz9&d)_SAO2wBxV*fiy!<>o$y{DaYToFy z_(N{&8Jm}Nc~<%rd3hJ*6_7&?8JCcuJlPppSy|~Bd3mGqaxcC#FKDi7J2U(pNke~0=lKlBaA(rcUvkp<{l(++#O43h&$@NV z=NMxheg*f(0zLp70sJ0t6z~VY9|0c$dI5g|d<^&mkPJS4ir+s2{sQ;{aM7zy?lM3D zVB~Wp+^zvk0O$dBz*ImDpaC!kFc&Z%;0Ck0ZVG4NimEI{HI|}!uBc;5k$Xx}H&;|Pi7zVWi`@9Ri7Tt&YHPTf zfZy%v<{BcNF#XQL+qu-6>4ec%Fu)OAg#N(84ubO^zb`hyj*!p{l#lnuGKpqeKt68%agx+#Or)-^REV{ zf4yt>JI*6(jxT@h8$Z8)OWE4@|N6+^dYAs_hKg72y>#3prK z=8yC2zno`{K6>9bAN~&it>n7-dx|0~6^>gzxNN7}$q~G&0(j_`TX_qQDGw~x_}lnk z04{1*A7+xCx=0jD7%LU$7ZS<63;YB}RQP|Djy8w#wtShA!#?$wa*E4Z0rY&bjQzl% zlL~hw!VI;Ec)Y$rhNo{p3DY;A+ExEP)n7@B%;oXd_!?H}^qJGRiDZ<{ESt$qB%_p@ z&dubeA?U=!TPa-10OS^bQ*nXz#M_`sIdR|euNN4u?y|Nby_iZS5t_*5hh$-F5+6sF4Ns2OsU$&Zs zH8w#Dp`aLgH&1VtgfY2D(7Ab)Smo!E3=aPsx6l*vdwe?WWUS$ESe>bbnpmbRrE#=A zgLOt7jb+Q4{iJ;QNRMp8Y8@0Es8s%;^+kl4zXI}Ag^_EAlq#uDOkIQ?3s!VsIN(<3 zk868;CmTGRM@Yg)&j_4Bj4xWxz#2NjA zFONe=uKo)DILv`~aK9-&Ln2ttXnT!F=r5q^Ree(Gut zTf7?SZyMphsNE$?STSI~v;e?jo!hn8eFh!E`Qa+=X!Q>ff1Z(ATI3Kl)i^+Z!VfIL0vy1*w8G zD^oDEyXA8RDGRmH?u9c8V+e!Fk%pQkEU48s)SX#s9ZF#*e9xv}Wc;&3DC=O9{!psr zSTTx+R0uD1R82jL*$GzELr4>bFn;6lx)>j6DNucb{{*~N*Ve{^GzXw5v5~i@i{w34 z)iLaBiuf0K{qAB~p!x?P5*6{Ra7~r*_2Mc>Sf3|!Zgl4emcZHR3K4H;5%J5GP^UJ` zs*7jlT*0S~sE)--MJaWlYPC#9|29=_;T?AV%i=x+j` zc?JW|wYJ+TlY}~BL0wIVBt)shEz9x3ES}m>(KwCTePdbmV#QKd*#JwTh!8p+Yj_c& z3piUUoE;QV!O|eL_jv5{sq2Y+e@W^k)a=m>oJHDKAs?2d&a)z(R|WYh?D68HLjIp* zbwtS~`1)m)^bA5#aPf4T6CKQi3FQ?PUF|fpeBrskfeRe?r#R5(nrPKR#s!)WomUbZd0$UQ(tjs zy)O{FSd>vBC_LIgjE3OI$;%>7lYZ7@IK1HSAAr~;A%Hs;En6Z^CBu9e8 z1U1j~vOB?4qEwl-AzI_KH+n*}6s=-VZIxXtzAw=1^3|}#W}ucM#Bh$%E2FK+>O1XW zCih|cqZ$1*Sitm_WBYkSV7Axosc6THH^*rIgsp-eup7Y$ymzJxVO# z4+ngn3OVFc$8?H21+S$EV=TohE{eCJ^uwjW7mkxi?<$FS0}C2mKFs*DFi0Y9yV2jy zMvd+SZAe7L-{=KbUA_cH)vjWVXRaZT$T6_b4tbRdjQ2_`>npWxHb%LDMa0G$l$@*0 zQyyTPUKCblsu|lUnG53G1=4Q z!2}v=fKtQ|L0*y;Bj?l*;llGT%7Hr)Q;q zhMNp`8NO}!uHlDshDBPGx4T$^WRNbW~+IYd9K-O{(<>f^K0f0&3)$2&8e27=42sVxKzj$ zt`K-(yf6uK`zFC5OciDbwL+sXS7;X61-~E*w+YLIyM#5ueZqR-QDKwtqVTe?Pxwsu zLKvgT*XT71G!f0WH9ycirP-%BsQFOyspb;xv)Z?{Svrqyp>ByTUE8h=YP+;|Y46c) z&~DN`t$jhePx}Wg$8+3PsuA`yJ8v(tJMESBD#tGzdmMjseB`)T%9bpWB;6_9Ej2pE z2(yIOh2IDnn#(k1O{Jz*vrMy6bC2dhjZQmNTc=&6U8j9S`*ZDX?NRMV+E2A7wO`W} z>s(0xF5SJlpX*Zed-O&_x#8FP-|6QV{%X8ftQV_9m)I&!5u@Tvajv*fyj6Ted`9dS zGfmYdx2ebU3V1isTxE{hUbb-%2FE~Zt0`={$F$z`l<7~V0n=#nBJ&FK@6E@}qQz-> z(DD~^8fw#c%MQy+me(x@EJrMFS`Jx`S^i{6vU;si>-VjDtg z)b0m|^YuT}zpQ^-|6Bck>$44)8I~B<8SI9D;U&Xi!|x3_#wU%>8+W0uREhJ&r%^Y4 zEIuo~DDD=2B_0-!ihW{{X`)GIDl^raZZb8SI48bsLLRGx_k=3#t=hHPg}R{b2f9~u zW%?HVA^rRMt%jc%E;4@2XfpoL^kb7%tPt-I*NX3opNLV@cTJC(W|?mh_lkbgE#_|X zO7p$u31Wj7LAp$1U+h|O>m-aRteRpoejbq)X({X8#UA?1W`x3gvF?(D}+_3 zr@6vQ`lI@YX{~94DZ_d-+V2AEHfyu(lzlfi@3bwo{oMAMZGwHN{W*J~LvqYPZL5&J zFLCoB*OBfeNcAq%r9IkTX@9F7&}Qnc(V28Jb#C2lx^=qEI$8T2?Tfm*^_%ru_0Q;c z=wHykrhiZWd;MSZ7mJfkdQ+>p!@Sx2r1>`M3hPqqDr?BrZF|`Exa}#&4#zW&oenOD z^L3HVb-GgBEUi!b25M}J?mpcH-9x&Kx{FMgm;|v#dis_r88MVGm>@saMdCk{a=9=eOf|l=F zIO}NZ<&cAmt*fn%TYqQ0&$`=YwobR+Vs%@?)_vAbt+_U>&2ID9?ze5Vy=i;Lw$_m) zb=YsUN9^79C6Iz16BY|HqAEmno7<8W$CvJT31SsNng|bNdL5cuYRBY>xNQ; z)(|oD7*-idjauVv##P39jN6RQ8b3FtiALyjYk4;?2QpE(8`UpP{w3`op8sZhE` zDwZZodPq;FG!3<&PMRa#BDtjnQc&uY7DJ-0lGaKONZ*q-N}Hvv(lgQy=|yRe^t$wx zbO8B2q@}H2H<50^;5}dYj+pyCG`HqQOO#4kSlkC_eZ2_Izr0t+|r?d;SzAEhpweLy? zrNhz@>6jFgPDp)Hzce77mg3SvkrX54#8Tl-^kyqGTQr+AuWI%~wjS0T(VWoqX$rLc z8XJ0(T;zDJHdj}mE7bA2T3v%~4%&WD=hJne{cqLn(Cx%UM*DSd>E6{HMEyLXo2qx~ z9}qW+o5XG69+8Oe2mNy)b=_jS=o5qBMVGi(TrREai!di2^9V~e;8arTRE zL5?02cba#Z_n2QbkFyk8CRqeaF0_#Kwhgw8woSGzXkpuI4bU^DI=UQN9s3>ajt!1J z$7u%=6H?KeXQGwm3I#$Tdh~xRJGU9P8+RCYqKDW6iLl@JmhoNVLE~ZL5o64F0y;*& zaR7Y>C+3O;Vxh>32o_2?vp>NdZ-M!}9cdWVX&b&LNdNJ?otMk@KcjZZUty;Y%uj(6j z6@4`$E&u9&1onT^{=cI@z%K|lSe(MzUwBON;iG(OOn{V6Fx%Xl%)$dcK?q#_jS=}g$Va&C|6D%b<*P^J z15J6oeP57oP5qkNDVpj{(E80U%D4Jk-=>U|540E3@O$WU`2y$1{O{ZUTng+S?-PW) z1N_r{#DfJ-;R6X)A2T z)B4L+3X6~8DfE30&%DfR3inQ+@G+{(^8O48-^FWug6a}_sV-X^hj5HTI7LtMpXRCk z`kdl|g2l_1FWne@YO7D!%<$NC#Jc4%{Fc`Vs{V{1uwHddmLS}uIw3pMZz70<-b)0b zIy4j6@Ny8jwmiaVvtSe%)7!-f0aQ4ZSGXKcGjRxsoyj5|^(8|iv4S0EerF)`6I2{>Z3BvbED{8{%T;GlSF8cOYIvTeuDb!J zs6AL&#Uv+da4G({JZx)74?RcCqBd5u!y(sieF7`72h^z(2#B+}T}toq$00@pxzoN( z9=12wi}q_{>pXP=Tk0xPf4iDj#(I^Cfsgns{L!8w()sk#MXzrJSFB0QvH^}oSvmiQk zUP|*u{C(ToQ6f+WNr3+>q35zlC~P}`$l4yi>J*f0-G54P<53j~AW=Ol6RP<^wHs

}ZPXnQ-sg1(Z;;s?rSV8boVvtM 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'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@types/node@26.2.0': + resolution: {integrity: sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==} + + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + tsx@4.23.12: + resolution: {integrity: sha512-FDf4L4sYzKtzWYhU/Xm0AQFdTjdIxNo9ElTf2mxXM6k8YMHXzYUe4yODVaXP4V9uMFbVg8c0qyBccK2OOxb45Q==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + +snapshots: + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@types/node@26.2.0': + dependencies: + undici-types: 8.3.0 + + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + fsevents@2.3.3: + optional: true + + tsx@4.23.12: + dependencies: + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 + + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + undici-types@8.3.0: {} + + yaml@2.9.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..5ed0b5a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +allowBuilds: + esbuild: true diff --git a/schema/index.schema.json b/schema/index.schema.json new file mode 100644 index 0000000..da8bc35 --- /dev/null +++ b/schema/index.schema.json @@ -0,0 +1,189 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Индекс каталога программ", + "description": "Схема index.yaml для категории или программы.", + "oneOf": [ + { + "$ref": "#/$defs/category" + }, + { + "$ref": "#/$defs/program" + } + ], + "$defs": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": "string", + "minLength": 1, + "maxLength": 4000, + "contentMediaType": "text/markdown" + }, + "url": { + "type": "string", + "format": "uri", + "pattern": "^https?://" + }, + "filePath": { + "type": "string", + "pattern": "^(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\)files/.+$" + }, + "screenshotPath": { + "type": "string", + "pattern": "^(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\)img/.+\\.(?:png|jpe?g|webp|gif)$" + }, + "file": { + "title": "Файл программы", + "type": "object", + "additionalProperties": false, + "required": [ + "path" + ], + "properties": { + "path": { + "$ref": "#/$defs/filePath" + }, + "description": { + "$ref": "#/$defs/description" + }, + "platform": { + "type": "string", + "enum": [ + "win32", + "win64", + "dos", + "java", + "j2me" + ] + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$" + } + } + }, + "version": { + "title": "Версия программы", + "type": "object", + "additionalProperties": false, + "required": [ + "version", + "files" + ], + "properties": { + "version": { + "type": "string", + "minLength": 1, + "maxLength": 80, + "pattern": "^[^/\\\\]+$" + }, + "status": { + "type": "string", + "enum": [ + "current", + "archived" + ] + }, + "released": { + "type": "string", + "format": "date" + }, + "description": { + "$ref": "#/$defs/description" + }, + "files": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/$defs/file" + } + } + } + }, + "category": { + "title": "Категория", + "type": "object", + "additionalProperties": false, + "required": [ + "format", + "type", + "name", + "description" + ], + "properties": { + "format": { + "const": 1 + }, + "type": { + "const": "category" + }, + "name": { + "$ref": "#/$defs/name" + }, + "description": { + "$ref": "#/$defs/description" + } + } + }, + "program": { + "title": "Программа", + "type": "object", + "additionalProperties": false, + "required": [ + "format", + "type", + "name", + "description", + "screenshots", + "versions" + ], + "properties": { + "format": { + "const": 1 + }, + "type": { + "const": "program" + }, + "name": { + "$ref": "#/$defs/name" + }, + "description": { + "$ref": "#/$defs/description" + }, + "homepage": { + "$ref": "#/$defs/url" + }, + "source": { + "$ref": "#/$defs/url" + }, + "screenshots": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/screenshotPath" + } + }, + "versions": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/$defs/version" + } + }, + "additional_files": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/$defs/file" + } + } + } + } + } +} diff --git a/scripts/fillSha256.ts b/scripts/fillSha256.ts new file mode 100644 index 0000000..0fd1f07 --- /dev/null +++ b/scripts/fillSha256.ts @@ -0,0 +1,272 @@ +#!/usr/bin/env node + +import { createHash } from "node:crypto"; +import { createReadStream } from "node:fs"; +import { + lstat, + mkdir, + readdir, + readFile, + realpath, + rename, + rm, + stat, + writeFile, +} from "node:fs/promises"; +import path from "node:path"; +import process from "node:process"; +import { parseDocument } from "yaml"; + +type CatalogFile = { + path?: unknown; + sha256?: unknown; +}; + +type ProgramIndex = { + type?: unknown; + versions?: Array<{ files?: CatalogFile[] }>; + additional_files?: CatalogFile[]; +}; + +type Options = { + check: boolean; + targets: string[]; +}; + +type FileReference = { + data: CatalogFile; + yamlPath: Array; +}; + +const ignoredDirectories = new Set([".git", "node_modules", "files", "img"]); + +function usage(): void { + console.log(`Использование: pnpm sha256 [--check] [путь ...] + +Без путей скрипт обходит текущий каталог. Путь может указывать на index.yaml +или на папку, внутри которой нужно найти index.yaml. + + --check только проверить суммы, не изменяя YAML + --help показать эту справку`); +} + +function parseArguments(args: string[]): Options { + const targets: string[] = []; + let check = false; + + for (const argument of args) { + if (argument === "--check") { + check = true; + } else if (argument === "--help" || argument === "-h") { + usage(); + process.exit(0); + } else if (argument.startsWith("-")) { + throw new Error(`Неизвестный параметр: ${argument}`); + } else { + targets.push(argument); + } + } + + return { check, targets: targets.length > 0 ? targets : ["."] }; +} + +async function findIndexes(target: string, result: Set): Promise { + const absoluteTarget = path.resolve(target); + const targetStat = await lstat(absoluteTarget); + + if (targetStat.isFile()) { + if (path.basename(absoluteTarget) !== "index.yaml") { + throw new Error(`Ожидался index.yaml: ${target}`); + } + result.add(absoluteTarget); + return; + } + + if (!targetStat.isDirectory()) { + throw new Error(`Путь не является файлом или каталогом: ${target}`); + } + + const entries = await readdir(absoluteTarget, { withFileTypes: true }); + for (const entry of entries) { + const entryPath = path.join(absoluteTarget, entry.name); + if (entry.isFile() && entry.name === "index.yaml") { + result.add(entryPath); + } else if (entry.isDirectory() && !ignoredDirectories.has(entry.name)) { + await findIndexes(entryPath, result); + } + } +} + +function collectFileReferences(data: ProgramIndex): FileReference[] { + const references: FileReference[] = []; + + for (const [versionIndex, version] of (data.versions ?? []).entries()) { + for (const [fileIndex, file] of (version.files ?? []).entries()) { + references.push({ + data: file, + yamlPath: ["versions", versionIndex, "files", fileIndex], + }); + } + } + + for (const [fileIndex, file] of (data.additional_files ?? []).entries()) { + references.push({ + data: file, + yamlPath: ["additional_files", fileIndex], + }); + } + + return references; +} + +async function resolveCatalogFile(indexPath: string, value: unknown): Promise { + if (typeof value !== "string" || value.length === 0) { + throw new Error("поле path отсутствует или не является строкой"); + } + if (path.isAbsolute(value) || value.includes("\\")) { + throw new Error(`недопустимый путь: ${value}`); + } + + const parts = value.split("/"); + if (parts[0] !== "files" || parts.some((part) => part === ".." || part === "")) { + throw new Error(`путь должен находиться внутри files/: ${value}`); + } + + const programDirectory = path.dirname(indexPath); + const filesDirectory = path.resolve(programDirectory, "files"); + const filePath = path.resolve(programDirectory, ...parts); + const relativePath = path.relative(filesDirectory, filePath); + if (relativePath.startsWith("..") || path.isAbsolute(relativePath)) { + throw new Error(`путь выходит за пределы files/: ${value}`); + } + + const [realFilesDirectory, realFilePath] = await Promise.all([ + realpath(filesDirectory), + realpath(filePath), + ]); + const realRelativePath = path.relative(realFilesDirectory, realFilePath); + if (realRelativePath.startsWith("..") || path.isAbsolute(realRelativePath)) { + throw new Error(`символическая ссылка выходит за пределы files/: ${value}`); + } + if (!(await stat(realFilePath)).isFile()) { + throw new Error(`путь не указывает на обычный файл: ${value}`); + } + + return realFilePath; +} + +async function calculateSha256(filePath: string): Promise { + const hash = createHash("sha256"); + for await (const chunk of createReadStream(filePath)) { + hash.update(chunk); + } + return hash.digest("hex"); +} + +async function writeAtomically(filePath: string, contents: string): Promise { + const directory = path.dirname(filePath); + const temporaryPath = path.join( + directory, + `.${path.basename(filePath)}.${process.pid}.tmp`, + ); + + await mkdir(directory, { recursive: true }); + try { + await writeFile(temporaryPath, contents, "utf8"); + await rename(temporaryPath, filePath); + } finally { + await rm(temporaryPath, { force: true }); + } +} + +async function processIndex(indexPath: string, check: boolean): Promise { + const source = await readFile(indexPath, "utf8"); + const document = parseDocument(source, { prettyErrors: true }); + if (document.errors.length > 0) { + throw new Error(document.errors.map((error) => error.message).join("; ")); + } + + const data = document.toJS() as ProgramIndex; + if (data.type !== "program") { + return 0; + } + + let changed = 0; + const errors: string[] = []; + const references = collectFileReferences(data); + + const results = await Promise.all( + references.map(async (reference) => { + try { + const filePath = await resolveCatalogFile(indexPath, reference.data.path); + return { reference, digest: await calculateSha256(filePath) }; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + errors.push(`${String(reference.data.path)}: ${message}`); + return undefined; + } + }), + ); + + if (errors.length > 0) { + throw new Error(errors.join("; ")); + } + + for (const result of results) { + if (result === undefined || result.reference.data.sha256 === result.digest) { + continue; + } + changed += 1; + if (!check) { + document.setIn([...result.reference.yamlPath, "sha256"], result.digest); + } + } + + const displayPath = path.relative(process.cwd(), indexPath) || indexPath; + if (changed > 0 && check) { + console.error(`${displayPath}: требуется обновить SHA-256 (${changed})`); + } else if (changed > 0) { + await writeAtomically(indexPath, document.toString()); + console.log(`${displayPath}: обновлено SHA-256 (${changed})`); + } + + return changed; +} + +async function main(): Promise { + const options = parseArguments(process.argv.slice(2)); + const indexes = new Set(); + + for (const target of options.targets) { + await findIndexes(target, indexes); + } + + let changed = 0; + let failed = 0; + for (const indexPath of [...indexes].sort()) { + try { + changed += await processIndex(indexPath, options.check); + } catch (error) { + failed += 1; + const displayPath = path.relative(process.cwd(), indexPath) || indexPath; + const message = error instanceof Error ? error.message : String(error); + console.error(`${displayPath}: ${message}`); + } + } + + if (failed > 0) { + console.error(`Ошибок: ${failed}`); + process.exitCode = 1; + } else if (options.check && changed > 0) { + console.error(`Файлов с несовпадениями: ${changed}`); + process.exitCode = 1; + } else { + console.log( + changed > 0 + ? `Готово, обновлено полей: ${changed}` + : `Готово, все SHA-256 актуальны. Проверено index.yaml: ${indexes.size}`, + ); + } +} + +await main(); diff --git a/scripts/printTree.ts b/scripts/printTree.ts new file mode 100644 index 0000000..913a49e --- /dev/null +++ b/scripts/printTree.ts @@ -0,0 +1,222 @@ +#!/usr/bin/env node + +import { lstat, readdir, readFile } from "node:fs/promises"; +import path from "node:path"; +import process from "node:process"; +import { parseDocument } from "yaml"; + +type CatalogType = "category" | "program"; + +type CatalogIndex = { + type?: unknown; + name?: unknown; + versions?: Array<{ version?: unknown; status?: unknown }>; +}; + +type CatalogVersion = { + version: string; + status?: "current" | "archived"; +}; + +type CatalogNode = { + type: CatalogType; + name: string; + directory: string; + versions: CatalogVersion[]; + children: CatalogNode[]; +}; + +type Options = { + showPaths: boolean; + showVersions: boolean; + target: string; +}; + +const collator = new Intl.Collator("ru", { + numeric: true, + sensitivity: "base", +}); + +function usage(): void { + console.log(`Использование: pnpm tree [параметры] [путь] + +Без пути выводится всё дерево каталога. Путь может указывать на папку категории, +программы или на её index.yaml. + + --versions вывести версии под каждой программой + --paths вывести относительные пути каталогов + --help показать эту справку`); +} + +function parseArguments(args: string[]): Options { + const targets: string[] = []; + let showPaths = false; + let showVersions = false; + + for (const argument of args) { + if (argument === "--paths") { + showPaths = true; + } else if (argument === "--versions") { + showVersions = true; + } else if (argument === "--help" || argument === "-h") { + usage(); + process.exit(0); + } else if (argument.startsWith("-")) { + throw new Error(`Неизвестный параметр: ${argument}`); + } else { + targets.push(argument); + } + } + + if (targets.length > 1) { + throw new Error("Можно указать только один путь"); + } + + return { + showPaths, + showVersions, + target: targets[0] ?? ".", + }; +} + +function compareNodes(left: CatalogNode, right: CatalogNode): number { + if (left.type !== right.type) { + return left.type === "category" ? -1 : 1; + } + return collator.compare(left.name, right.name); +} + +async function resolveDirectory(target: string): Promise { + const absoluteTarget = path.resolve(target); + const targetStat = await lstat(absoluteTarget); + + if (targetStat.isDirectory()) { + return absoluteTarget; + } + if (targetStat.isFile() && path.basename(absoluteTarget) === "index.yaml") { + return path.dirname(absoluteTarget); + } + throw new Error(`Ожидалась папка каталога или index.yaml: ${target}`); +} + +async function readCatalogNode(directory: string): Promise { + const indexPath = path.join(directory, "index.yaml"); + let source: string; + + try { + source = await readFile(indexPath, "utf8"); + } catch (error) { + const reason = error instanceof Error ? error.message : String(error); + throw new Error(`${indexPath}: не удалось прочитать index.yaml: ${reason}`); + } + + const document = parseDocument(source, { prettyErrors: true }); + if (document.errors.length > 0) { + const errors = document.errors.map((error) => error.message).join("; "); + throw new Error(`${indexPath}: ${errors}`); + } + + const data = document.toJS() as CatalogIndex; + if (data.type !== "category" && data.type !== "program") { + throw new Error(`${indexPath}: неизвестный type`); + } + if (typeof data.name !== "string" || data.name.length === 0) { + throw new Error(`${indexPath}: отсутствует название`); + } + + const versions = + data.type === "program" + ? (data.versions ?? []).map((entry, index) => { + if (typeof entry.version !== "string" || entry.version.length === 0) { + throw new Error(`${indexPath}: некорректная версия с индексом ${index}`); + } + if ( + entry.status !== undefined && + entry.status !== "current" && + entry.status !== "archived" + ) { + throw new Error(`${indexPath}: неизвестный статус версии ${entry.version}`); + } + return { version: entry.version, status: entry.status } as CatalogVersion; + }) + : []; + + const children: CatalogNode[] = []; + if (data.type === "category") { + const entries = await readdir(directory, { withFileTypes: true }); + for (const entry of entries) { + if (!entry.isDirectory()) { + continue; + } + + const childDirectory = path.join(directory, entry.name); + try { + const childIndexStat = await lstat(path.join(childDirectory, "index.yaml")); + if (childIndexStat.isFile()) { + children.push(await readCatalogNode(childDirectory)); + } + } catch (error) { + const code = (error as NodeJS.ErrnoException).code; + if (code !== "ENOENT") { + throw error; + } + } + } + } + + children.sort(compareNodes); + return { type: data.type, name: data.name, directory, versions, children }; +} + +function formatNode(node: CatalogNode, showPaths: boolean): string { + const categorySuffix = node.type === "category" ? "/" : ""; + if (!showPaths) { + return `${node.name}${categorySuffix}`; + } + + const relativePath = path.relative(process.cwd(), node.directory) || "."; + return `${node.name}${categorySuffix} [${relativePath}]`; +} + +function printChildren( + node: CatalogNode, + prefix: string, + options: Pick, +): void { + const entries: Array<{ label: string; node?: CatalogNode }> = node.children.map( + (child) => ({ label: formatNode(child, options.showPaths), node: child }), + ); + + if (options.showVersions && node.type === "program") { + entries.push( + ...node.versions.map(({ version, status }) => ({ + label: `версия ${version}${status === undefined ? "" : ` [${status}]`}`, + })), + ); + } + + entries.forEach((entry, index) => { + const last = index === entries.length - 1; + console.log(`${prefix}${last ? "└── " : "├── "}${entry.label}`); + if (entry.node !== undefined) { + printChildren(entry.node, `${prefix}${last ? " " : "│ "}`, options); + } + }); +} + +async function main(): Promise { + const options = parseArguments(process.argv.slice(2)); + const directory = await resolveDirectory(options.target); + const root = await readCatalogNode(directory); + + console.log(formatNode(root, options.showPaths)); + printChildren(root, "", options); +} + +try { + await main(); +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + console.error(`Ошибка: ${message}`); + process.exitCode = 1; +} diff --git a/service/drivers/index.yaml b/service/drivers/index.yaml new file mode 100644 index 0000000..c81937e --- /dev/null +++ b/service/drivers/index.yaml @@ -0,0 +1,4 @@ +format: 1 +type: category +name: Драйверы +description: Драйверы устройств и кабелей для работы с мобильными телефонами. diff --git a/service/drivers/pl-2303/files/PL-2303_patched.rar b/service/drivers/pl-2303/files/PL-2303_patched.rar new file mode 100644 index 0000000..9862bed --- /dev/null +++ b/service/drivers/pl-2303/files/PL-2303_patched.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce4c19231e2e051a80267487c37062df0161569edc0f43013df7f6d1fa0565e6 +size 231854 diff --git a/service/drivers/pl-2303/index.yaml b/service/drivers/pl-2303/index.yaml new file mode 100644 index 0000000..da09f65 --- /dev/null +++ b/service/drivers/pl-2303/index.yaml @@ -0,0 +1,16 @@ +format: 1 +type: program +name: PL-2303 Driver +description: >- + Модифицированный Chaos драйвер для дата-кабелей на чипсете Prolific PL-2303. + В отличие от штатного драйвера он позволяет флешерам обмениваться данными с + телефоном на скорости до 1625000 бит/с. +homepage: https://web.archive.org/web/20130813164842/http://chaos.allsiemens.com/software.html +screenshots: [] +versions: + - version: "2.0.5.26" + files: + - path: files/PL-2303_patched.rar + description: Драйвер PL-2303 с поддержкой скорости до 1625000 бит/с + platform: win32 + sha256: ce4c19231e2e051a80267487c37062df0161569edc0f43013df7f6d1fa0565e6 diff --git a/service/firmware-tools/index.yaml b/service/firmware-tools/index.yaml new file mode 100644 index 0000000..b9228a1 --- /dev/null +++ b/service/firmware-tools/index.yaml @@ -0,0 +1,6 @@ +format: 1 +type: category +name: Инструменты прошивок +description: >- + Вспомогательные программы для анализа, распаковки и изменения файлов прошивок + и сервисных обновлений. diff --git a/service/firmware-tools/winswup/files/WSMPlus2.rar b/service/firmware-tools/winswup/files/WSMPlus2.rar new file mode 100644 index 0000000..93918c4 --- /dev/null +++ b/service/firmware-tools/winswup/files/WSMPlus2.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1eb247567a4b5b66b8f796e6e3012481d819c825f400693fb26eae8b79f785f +size 137632 diff --git a/service/firmware-tools/winswup/files/winswup-0.91-pre1.7z b/service/firmware-tools/winswup/files/winswup-0.91-pre1.7z new file mode 100644 index 0000000..80c77a3 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.91-pre1.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9254f44bc15d6e1027d96112860eb2b392d83de20b15a680037534704e460a9e +size 190868 diff --git a/service/firmware-tools/winswup/files/winswup-0.91-pre2.7z b/service/firmware-tools/winswup/files/winswup-0.91-pre2.7z new file mode 100644 index 0000000..ced6ce3 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.91-pre2.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0c19ca1f49ab76f2c544adf0291d82172f1024c44606a1443bb365c588eced1 +size 177805 diff --git a/service/firmware-tools/winswup/files/winswup-0.91.7z b/service/firmware-tools/winswup/files/winswup-0.91.7z new file mode 100644 index 0000000..06e1acd --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.91.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ae4a7be7abc7f17fc6f0dd55d601da56226571aa8634dae38ba16f5f65b47ad +size 180291 diff --git a/service/firmware-tools/winswup/files/winswup-0.95-amd32.7z b/service/firmware-tools/winswup/files/winswup-0.95-amd32.7z new file mode 100644 index 0000000..166a556 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.95-amd32.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5df6de4c09f872f2175dd7fe26d456ce7cb1dba254bfe6e2b41bd47e6acc9482 +size 201184 diff --git a/service/firmware-tools/winswup/files/winswup-0.95.7z b/service/firmware-tools/winswup/files/winswup-0.95.7z new file mode 100644 index 0000000..b200ea2 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.95.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1792894d1a1efa7e95de3f747a86c1e5eefc00c8914a7e78859dabeac57c2a3 +size 215244 diff --git a/service/firmware-tools/winswup/files/winswup-0.97.7z b/service/firmware-tools/winswup/files/winswup-0.97.7z new file mode 100644 index 0000000..f4e0835 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.97.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cace85ee4ef5085b645855c502f74f18b11d8301c135c0f34442fc27c4b149c3 +size 622407 diff --git a/service/firmware-tools/winswup/files/winswup-0.98-pre.7z b/service/firmware-tools/winswup/files/winswup-0.98-pre.7z new file mode 100644 index 0000000..830af0b --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.98-pre.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd0e8b50fa2fdb33208eb0b73d69b04a94fbb8bc102fb99548fae0e98e83075f +size 196555 diff --git a/service/firmware-tools/winswup/files/winswup-0.98.7z b/service/firmware-tools/winswup/files/winswup-0.98.7z new file mode 100644 index 0000000..ade63af --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-0.98.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:754d3e84d6653c1ef69713e7de3163dc87cc9bef0a5427fe5c792d51a3a3e263 +size 205322 diff --git a/service/firmware-tools/winswup/files/winswup-1.04.7z b/service/firmware-tools/winswup/files/winswup-1.04.7z new file mode 100644 index 0000000..5d41559 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.04.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cea1c7c0b1db441a1d35e364716d71d64e30710b6165b980e7f883a2f7fb4343 +size 6176468 diff --git a/service/firmware-tools/winswup/files/winswup-1.23.7z b/service/firmware-tools/winswup/files/winswup-1.23.7z new file mode 100644 index 0000000..062c712 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.23.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2c65b13d9e88f0a7bcbfc44b25b9b1b2901c8c5186c617acbd849b6cab8f76c +size 168168 diff --git a/service/firmware-tools/winswup/files/winswup-1.27.7z b/service/firmware-tools/winswup/files/winswup-1.27.7z new file mode 100644 index 0000000..c1eb155 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.27.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:986eb13ce887f77ed5b15d29fd587edbdf4b6bc3f41a510ad540dc385ef9ee95 +size 470254 diff --git a/service/firmware-tools/winswup/files/winswup-1.28.7z b/service/firmware-tools/winswup/files/winswup-1.28.7z new file mode 100644 index 0000000..5b7dcdf --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.28.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:783d123f2ce62253dd3c697efc8a622d027dd34388db6165b6a682ecf44246d0 +size 468469 diff --git a/service/firmware-tools/winswup/files/winswup-1.30.7z b/service/firmware-tools/winswup/files/winswup-1.30.7z new file mode 100644 index 0000000..ee2a52b --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.30.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c12b5563409d9ff356299b5f7277ebeaaefe564b1cb71a7856636daf0156f690 +size 461270 diff --git a/service/firmware-tools/winswup/files/winswup-1.34.7z b/service/firmware-tools/winswup/files/winswup-1.34.7z new file mode 100644 index 0000000..4b8fc86 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.34.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15ee3c94cb31c01d877898456d8aceababd4e5f7cd1313b4adb9e1afed3d2af5 +size 220250 diff --git a/service/firmware-tools/winswup/files/winswup-1.35.7z b/service/firmware-tools/winswup/files/winswup-1.35.7z new file mode 100644 index 0000000..0324d37 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.35.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a947c38253e40502cee5019f62a5e9868a1f8e3661105a8a3a753187b5f92cc +size 228880 diff --git a/service/firmware-tools/winswup/files/winswup-1.40.7z b/service/firmware-tools/winswup/files/winswup-1.40.7z new file mode 100644 index 0000000..db84309 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.40.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19e6d4ff841c00445fc953268efbe98d69aba261f9204ee896917a4d28472a95 +size 949541 diff --git a/service/firmware-tools/winswup/files/winswup-1.44.7z b/service/firmware-tools/winswup/files/winswup-1.44.7z new file mode 100644 index 0000000..79b8be6 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-1.44.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:810f8f7b24ea27bd2c7e6746ea13ff8be4b7117fec46989a07c522d9eb60ef21 +size 730425 diff --git a/service/firmware-tools/winswup/files/winswup-3.002.7z b/service/firmware-tools/winswup/files/winswup-3.002.7z new file mode 100644 index 0000000..072bed7 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-3.002.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20dc66b4b95651633ed5a5ea9d55cda430bce7ed089ca4031626b60e86b88d41 +size 184530 diff --git a/service/firmware-tools/winswup/files/winswup-3.05.7z b/service/firmware-tools/winswup/files/winswup-3.05.7z new file mode 100644 index 0000000..813a89d --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-3.05.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:613b329574723539cc5ec38630977dc5ca0db14718330f4d1e09f73c8e8016e3 +size 2089945 diff --git a/service/firmware-tools/winswup/files/winswup-3.17.7z b/service/firmware-tools/winswup/files/winswup-3.17.7z new file mode 100644 index 0000000..47627c4 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-3.17.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a1e770a3f0f8c77108f6841b7d1fc605c41052f21cd734c3d5684bbdbdd1877 +size 3151337 diff --git a/service/firmware-tools/winswup/files/winswup-3.19.7z b/service/firmware-tools/winswup/files/winswup-3.19.7z new file mode 100644 index 0000000..8fb824d --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-3.19.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a797f2097ae96c678cc987b08fafd0b11b0c929e550751f8190b793f564dbc55 +size 3146606 diff --git a/service/firmware-tools/winswup/files/winswup-3.20.rar b/service/firmware-tools/winswup/files/winswup-3.20.rar new file mode 100644 index 0000000..e93bae1 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-3.20.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d497519b7f6c4bd95aacd93828f12d977110da86f612d7f55c3bcc2dc40e3677 +size 5612252 diff --git a/service/firmware-tools/winswup/files/winswup-4.07.7z b/service/firmware-tools/winswup/files/winswup-4.07.7z new file mode 100644 index 0000000..c26b1d6 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-4.07.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e27536eb975c6127ca7d61ac39d9edceb142fb3e4eaf91348992ea214f30d8f5 +size 1008836 diff --git a/service/firmware-tools/winswup/files/winswup-4.14p3.7z b/service/firmware-tools/winswup/files/winswup-4.14p3.7z new file mode 100644 index 0000000..8efdc10 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-4.14p3.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99a33142bb9b008a051bd6fe3212ffa3ccd9e38be3472059d5125dcd9783c21e +size 599244 diff --git a/service/firmware-tools/winswup/files/winswup-4.20.7z b/service/firmware-tools/winswup/files/winswup-4.20.7z new file mode 100644 index 0000000..e75a268 --- /dev/null +++ b/service/firmware-tools/winswup/files/winswup-4.20.7z @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d317695a4ab32856167370d3f7cd527bf09c9f34db13530e23de34700d6c3efe +size 1228159 diff --git a/service/firmware-tools/winswup/index.yaml b/service/firmware-tools/winswup/index.yaml new file mode 100644 index 0000000..41d3b51 --- /dev/null +++ b/service/firmware-tools/winswup/index.yaml @@ -0,0 +1,186 @@ +format: 1 +type: program +name: WinSwup +description: |- + Сервисная программа Siemens для обновления программного обеспечения + телефонов. В каталоге представлены исполняемые комплекты и developer-пакеты + с Update DLL, загрузчиками, библиотеками, заголовочными файлами, примерами и + документацией. +screenshots: [] +versions: + - version: "4.20-pre1" + status: current + released: "2006-05-08" + files: + - path: files/winswup-4.20.7z + description: Полный developer-пакет WinSwup 4.20 prerelease 1 с SDK, + документацией и утилитами + platform: win32 + sha256: d317695a4ab32856167370d3f7cd527bf09c9f34db13530e23de34700d6c3efe + - version: "4.14p3" + status: archived + files: + - path: files/winswup-4.14p3.7z + description: Developer-пакет WinSwup 4.14p3 для SL75 Escada + platform: win32 + sha256: 99a33142bb9b008a051bd6fe3212ffa3ccd9e38be3472059d5125dcd9783c21e + - version: "4.07" + status: archived + released: "2004-09-08" + files: + - path: files/winswup-4.07.7z + description: Полный developer-пакет WinSwup 4.07 с SDK и документацией + platform: win32 + sha256: e27536eb975c6127ca7d61ac39d9edceb142fb3e4eaf91348992ea214f30d8f5 + - version: "3.20" + status: current + files: + - path: files/winswup-3.20.rar + description: Прошивальщик для телефонов Siemens EGold и EGoldLite с + поддержкой XBI, XBZ и XFS + platform: win32 + sha256: d497519b7f6c4bd95aacd93828f12d977110da86f612d7f55c3bcc2dc40e3677 + - version: "3.19" + status: archived + files: + - path: files/winswup-3.19.7z + description: Полный developer-пакет WinSwup 3.19 для AL21 + platform: win32 + sha256: a797f2097ae96c678cc987b08fafd0b11b0c929e550751f8190b793f564dbc55 + - version: "3.17" + status: archived + files: + - path: files/winswup-3.17.7z + description: Полный developer-пакет WinSwup 3.17 с SDK и документацией + platform: win32 + sha256: 4a1e770a3f0f8c77108f6841b7d1fc605c41052f21cd734c3d5684bbdbdd1877 + - version: "3.05" + status: archived + files: + - path: files/winswup-3.05.7z + description: Полный предварительный пакет WinSwup 3.05 с SDK и документацией + platform: win32 + sha256: 613b329574723539cc5ec38630977dc5ca0db14718330f4d1e09f73c8e8016e3 + - version: "3.002" + status: archived + files: + - path: files/winswup-3.002.7z + description: Компактный исполняемый комплект WinSwup 3.002 + platform: win32 + sha256: 20dc66b4b95651633ed5a5ea9d55cda430bce7ed089ca4031626b60e86b88d41 + - version: "1.44" + status: archived + files: + - path: files/winswup-1.44.7z + description: Полный developer-пакет WinSwup 1.44 с SDK + platform: win32 + sha256: 810f8f7b24ea27bd2c7e6746ea13ff8be4b7117fec46989a07c522d9eb60ef21 + - version: "1.40" + status: archived + files: + - path: files/winswup-1.40.7z + description: Полный developer-пакет WinSwup 1.40 с SDK и документацией + platform: win32 + sha256: 19e6d4ff841c00445fc953268efbe98d69aba261f9204ee896917a4d28472a95 + - version: "1.35" + status: archived + files: + - path: files/winswup-1.35.7z + description: Исполняемый комплект WinSwup 1.35 с загрузчиком SGOLD + platform: win32 + sha256: 4a947c38253e40502cee5019f62a5e9868a1f8e3661105a8a3a753187b5f92cc + - version: "1.34" + status: archived + files: + - path: files/winswup-1.34.7z + description: Исполняемый комплект WinSwup 1.34 + platform: win32 + sha256: 15ee3c94cb31c01d877898456d8aceababd4e5f7cd1313b4adb9e1afed3d2af5 + - version: "1.30" + status: archived + files: + - path: files/winswup-1.30.7z + description: Полный developer-пакет WinSwup 1.30 с SDK + platform: win32 + sha256: c12b5563409d9ff356299b5f7277ebeaaefe564b1cb71a7856636daf0156f690 + - version: "1.28" + status: archived + files: + - path: files/winswup-1.28.7z + description: Полный developer-пакет WinSwup 1.28 с SDK + platform: win32 + sha256: 783d123f2ce62253dd3c697efc8a622d027dd34388db6165b6a682ecf44246d0 + - version: "1.27" + status: archived + files: + - path: files/winswup-1.27.7z + description: Полный developer-пакет WinSwup 1.27 с SDK + platform: win32 + sha256: 986eb13ce887f77ed5b15d29fd587edbdf4b6bc3f41a510ad540dc385ef9ee95 + - version: "1.23" + status: archived + files: + - path: files/winswup-1.23.7z + description: Исполняемый комплект WinSwup 1.23 + platform: win32 + sha256: d2c65b13d9e88f0a7bcbfc44b25b9b1b2901c8c5186c617acbd849b6cab8f76c + - version: "1.04" + status: archived + files: + - path: files/winswup-1.04.7z + description: Комплект WinSwup 1.04 с пакетами WC3I 2001 и 2008 + platform: win32 + sha256: cea1c7c0b1db441a1d35e364716d71d64e30710b6165b980e7f883a2f7fb4343 + - version: "0.98" + status: archived + files: + - path: files/winswup-0.98.7z + platform: win32 + sha256: 754d3e84d6653c1ef69713e7de3163dc87cc9bef0a5427fe5c792d51a3a3e263 + - version: "0.98-pre" + status: archived + files: + - path: files/winswup-0.98-pre.7z + platform: win32 + sha256: cd0e8b50fa2fdb33208eb0b73d69b04a94fbb8bc102fb99548fae0e98e83075f + - version: "0.97" + status: archived + files: + - path: files/winswup-0.97.7z + description: Комплект WinSwup 0.97 «Alle Produkte» с исходным ZIP-пакетом + platform: win32 + sha256: cace85ee4ef5085b645855c502f74f18b11d8301c135c0f34442fc27c4b149c3 + - version: "0.95" + status: archived + files: + - path: files/winswup-0.95.7z + description: Обычная сборка WinSwup 0.95 + platform: win32 + sha256: a1792894d1a1efa7e95de3f747a86c1e5eefc00c8914a7e78859dabeac57c2a3 + - path: files/winswup-0.95-amd32.7z + description: Сборка WinSwup 0.95 с комплектом DLL AMD32 + platform: win32 + sha256: 5df6de4c09f872f2175dd7fe26d456ce7cb1dba254bfe6e2b41bd47e6acc9482 + - version: "0.91" + status: archived + files: + - path: files/winswup-0.91.7z + platform: win32 + sha256: 7ae4a7be7abc7f17fc6f0dd55d601da56226571aa8634dae38ba16f5f65b47ad + - version: "0.91-pre2" + status: archived + files: + - path: files/winswup-0.91-pre2.7z + platform: win32 + sha256: c0c19ca1f49ab76f2c544adf0291d82172f1024c44606a1443bb365c588eced1 + - version: "0.91-pre1" + status: archived + files: + - path: files/winswup-0.91-pre1.7z + platform: win32 + sha256: 9254f44bc15d6e1027d96112860eb2b392d83de20b15a680037534704e460a9e +additional_files: + - path: files/WSMPlus2.rar + description: WinSwup Menu Plus 2 для включения дополнительных меню в сервисных SWUP + platform: win32 + sha256: b1eb247567a4b5b66b8f796e6e3012481d819c825f400693fb26eae8b79f785f diff --git a/service/firmware-tools/wsff/files/WSFF4.rar b/service/firmware-tools/wsff/files/WSFF4.rar new file mode 100644 index 0000000..61737eb --- /dev/null +++ b/service/firmware-tools/wsff/files/WSFF4.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e63fe5b665dad8322dbfab081b7c41bc0e40520d922d9a7d8166c5b53fe1b2c1 +size 162002 diff --git a/service/firmware-tools/wsff/index.yaml b/service/firmware-tools/wsff/index.yaml new file mode 100644 index 0000000..0ded6a3 --- /dev/null +++ b/service/firmware-tools/wsff/index.yaml @@ -0,0 +1,16 @@ +format: 1 +type: program +name: WSFF +description: |- + Утилита для анализа структуры и распаковки баз сервисных прошивок Siemens + WinSwup. +homepage: https://web.archive.org/web/20130825050857/http://papuas.allsiemens.com/ +screenshots: [] +versions: + - version: "4" + released: "2006-02-10" + files: + - path: files/WSFF4.rar + description: Программа WSFF4 + platform: win32 + sha256: e63fe5b665dad8322dbfab081b7c41bc0e40520d922d9a7d8166c5b53fe1b2c1 diff --git a/service/flashers/index.yaml b/service/flashers/index.yaml new file mode 100644 index 0000000..474c4be --- /dev/null +++ b/service/flashers/index.yaml @@ -0,0 +1,4 @@ +format: 1 +type: category +name: Флешеры +description: Программы для чтения, записи и восстановления флеш-памяти телефонов. diff --git a/service/flashers/v-klay/files/v_klay_setup.zip b/service/flashers/v-klay/files/v_klay_setup.zip new file mode 100644 index 0000000..aa37896 --- /dev/null +++ b/service/flashers/v-klay/files/v_klay_setup.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ef29148ea0a6f9c0ef2cb9a09da992bd1063920d891878709b066b22707b80f +size 1691594 diff --git a/service/flashers/v-klay/files/v_klay_setup_v2152.rar b/service/flashers/v-klay/files/v_klay_setup_v2152.rar new file mode 100644 index 0000000..ee434ad --- /dev/null +++ b/service/flashers/v-klay/files/v_klay_setup_v2152.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc7c32ed37b9e75aa5316cef46661eb78240dd2911b89ba26ab30d88fff6d9a9 +size 2329332 diff --git a/service/flashers/v-klay/files/v_klay_setup_v25.zip b/service/flashers/v-klay/files/v_klay_setup_v25.zip new file mode 100644 index 0000000..5dc3e62 --- /dev/null +++ b/service/flashers/v-klay/files/v_klay_setup_v25.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d78f69d0750a8e0d93349049d4dac3361202ad8fedb9f5479ca9f95505d250db +size 2362704 diff --git a/service/flashers/v-klay/files/v_klay_setup_v272.zip b/service/flashers/v-klay/files/v_klay_setup_v272.zip new file mode 100644 index 0000000..dcc2c5c --- /dev/null +++ b/service/flashers/v-klay/files/v_klay_setup_v272.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4e31a5fd9cdfb6b5f3b2612116ad0ca575d281dc5e4c0c4f85bba6226985cde +size 2622662 diff --git a/service/flashers/v-klay/files/v_klay_update_v2112.rar b/service/flashers/v-klay/files/v_klay_update_v2112.rar new file mode 100644 index 0000000..8c61679 --- /dev/null +++ b/service/flashers/v-klay/files/v_klay_update_v2112.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b6e4fe30ea81ef3a07892b297772aba811d04b15e2a93c482eb3da7d74e3b72 +size 840128 diff --git a/service/flashers/v-klay/index.yaml b/service/flashers/v-klay/index.yaml new file mode 100644 index 0000000..0ae9542 --- /dev/null +++ b/service/flashers/v-klay/index.yaml @@ -0,0 +1,54 @@ +format: 1 +type: program +name: V_KLay +description: |- + Патчер, флешер и редактор раскладки клавиатуры для мобильных телефонов + Siemens. + + Возможности: + - чтение и запись flash-памяти телефона; + - установка и отмена патчей в формате VKP; + - изменение раскладки клавиатуры; + - подключение через Password Boot, Chaos BootPatch, Bootcore bug, Patched + bootcore и Test point; + - работа с телефоном без выключения в режиме online, если модель и прошивка + поддерживают такой способ; + - многоязычный интерфейс, включая русский и украинский языки. + + Версия 3.3 поддерживает Siemens 1168, 2118, 2128, 3118, 3618, 6618, 6688, + A35, A36, A40, A50, A52, A55, A60, A65, C30, C35, C45, C55, C60, C65, + CF62, CX65, M35, M50, M55, M65, MC60, ME45, MT50, S35, S40, S45, S55, + S65, SL42, SL45, SL55, SL65 и SX1. +homepage: https://web.archive.org/web/20130813164842/http://vi-soft.com.ua/ +screenshots: [] +versions: + - version: "3.3" + files: + - path: files/v_klay_setup.zip + description: Установочный пакет V_KLay 3.3 + platform: win32 + sha256: 9ef29148ea0a6f9c0ef2cb9a09da992bd1063920d891878709b066b22707b80f + - version: "2.7.2" + files: + - path: files/v_klay_setup_v272.zip + description: Установочный пакет V_KLay 2.7.2 + platform: win32 + sha256: f4e31a5fd9cdfb6b5f3b2612116ad0ca575d281dc5e4c0c4f85bba6226985cde + - version: "2.5" + files: + - path: files/v_klay_setup_v25.zip + description: Установочный пакет V_KLay 2.5 + platform: win32 + sha256: d78f69d0750a8e0d93349049d4dac3361202ad8fedb9f5479ca9f95505d250db + - version: "2.1.12" + files: + - path: files/v_klay_update_v2112.rar + description: Обновление до V_KLay 2.1.12 + platform: win32 + sha256: 5b6e4fe30ea81ef3a07892b297772aba811d04b15e2a93c482eb3da7d74e3b72 + - version: "2.1.5.2" + files: + - path: files/v_klay_setup_v2152.rar + description: Англоязычный установочный пакет V_KLay 2.1.5.2 + platform: win32 + sha256: bc7c32ed37b9e75aa5316cef46661eb78240dd2911b89ba26ab30d88fff6d9a9 diff --git a/service/flashers/x65flasher/files/bsReader.zip b/service/flashers/x65flasher/files/bsReader.zip new file mode 100644 index 0000000..226e254 --- /dev/null +++ b/service/flashers/x65flasher/files/bsReader.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7c38947a9e042b0a9107760d79b3f5f6daa95a71b33c26d219453c80d943f55 +size 61749 diff --git a/service/flashers/x65flasher/files/px75v1.rar b/service/flashers/x65flasher/files/px75v1.rar new file mode 100644 index 0000000..0a1ad1d --- /dev/null +++ b/service/flashers/x65flasher/files/px75v1.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64fd3cca1fcb253a43f1c2101256a0050731598c6c35a0805d6a874c5893ce5c +size 39784 diff --git a/service/flashers/x65flasher/files/x65flasher-2103.rar b/service/flashers/x65flasher/files/x65flasher-2103.rar new file mode 100644 index 0000000..922bd1d --- /dev/null +++ b/service/flashers/x65flasher/files/x65flasher-2103.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad5ba3574b1f5a774948a8d62dc7fb51ef05b762d27e3000c0e5ba38360d4f41 +size 423000 diff --git a/service/flashers/x65flasher/index.yaml b/service/flashers/x65flasher/index.yaml new file mode 100644 index 0000000..ef0896e --- /dev/null +++ b/service/flashers/x65flasher/index.yaml @@ -0,0 +1,32 @@ +format: 1 +type: program +name: x65flasher +description: |- + Флешер для телефонов Siemens 65–75-й серии и мидлеты для поиска boot-ключей. + + Возможности: + - чтение и запись flash-памяти телефона; + - резервное копирование и восстановление как всего fullflash, так и отдельных + частей: файловой системы, прошивки и EEPROM; + - просмотр карты flash-памяти; + - работа на скорости от 57600 до 1600000 бит/с; + - генерация загрузчиков для V_Klay. +homepage: https://web.archive.org/web/20130813164842/http://chaos.allsiemens.com/software.html +screenshots: [] +versions: + - version: "2.103" + released: "2006-12-06" + files: + - path: files/x65flasher-2103.rar + description: Флешер, документация и вспомогательные мидлеты + platform: win32 + sha256: ad5ba3574b1f5a774948a8d62dc7fb51ef05b762d27e3000c0e5ba38360d4f41 +additional_files: + - path: files/px75v1.rar + description: Мидлет для получения HASH и ESN на младших моделях телефонов + platform: j2me + sha256: 64fd3cca1fcb253a43f1c2101256a0050731598c6c35a0805d6a874c5893ce5c + - path: files/bsReader.zip + description: Мидлет для получения HASH и ESN на S75, SL75 и BenQ-Siemens + platform: j2me + sha256: e7c38947a9e042b0a9107760d79b3f5f6daa95a71b33c26d219453c80d943f55 diff --git a/service/index.yaml b/service/index.yaml new file mode 100644 index 0000000..a8477e5 --- /dev/null +++ b/service/index.yaml @@ -0,0 +1,4 @@ +format: 1 +type: category +name: Сервисные программы +description: Программы для диагностики, обслуживания и восстановления телефонов. diff --git a/service/repair-tools/index.yaml b/service/repair-tools/index.yaml new file mode 100644 index 0000000..9fef34d --- /dev/null +++ b/service/repair-tools/index.yaml @@ -0,0 +1,6 @@ +format: 1 +type: category +name: Ремонт и восстановление +description: >- + Сервисные программы для диагностики, восстановления и ремонта программной + части телефонов. diff --git a/service/repair-tools/joker/files/JokerSorceV0341.rar b/service/repair-tools/joker/files/JokerSorceV0341.rar new file mode 100644 index 0000000..775d2be --- /dev/null +++ b/service/repair-tools/joker/files/JokerSorceV0341.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6e539597dbe6d8af1e6a813a305ea30322e561ec5a9786aadba520d9c1963c5 +size 129019 diff --git a/service/repair-tools/joker/files/JokerV0295.rar b/service/repair-tools/joker/files/JokerV0295.rar new file mode 100644 index 0000000..6ac3686 --- /dev/null +++ b/service/repair-tools/joker/files/JokerV0295.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37a8805c5731ce74aa99b11c5f90580bce39b96c95b36cbd8adb72008df25e30 +size 206353 diff --git a/service/repair-tools/joker/index.yaml b/service/repair-tools/joker/index.yaml new file mode 100644 index 0000000..c059fa8 --- /dev/null +++ b/service/repair-tools/joker/index.yaml @@ -0,0 +1,38 @@ +format: 1 +type: program +name: Joker +description: |- + Сервисная программа для восстановления программных неисправностей телефонов + Siemens на платформе EGOLD с помощью обычного кабеля с минимальными + доработками. Поддерживаются A50–A75, AX72/AX75, C55/C56/C60, CF62/CF110, + M55, MC60, S55/S56, SL55, SX1 и совместимые модели. + + Возможности: + - чтение информации о телефоне и работа в режимах BFB и Service mode; + - чтение и запись FullFlash и отдельных flash-сегментов; + - резервное копирование и восстановление EEPROM и секретных блоков; + - вычисление и сохранение SKEY, BKEY, ESN, HASH и мастер-кодов; + - пересчёт ключей после записи FullFlash от другого аппарата; + - подготовка BCORE, устранение Freeze и дефрагментация EEPROM; + - автоматическое определение flash-памяти и контроль CRC при операциях записи. + + Перед записью автор рекомендует обязательно сохранить ESN, HASH и полный + FullFlash рабочего телефона. Программа создавалась как экспериментальный + ремонтный инструмент; часть операций требует TestPoint. +homepage: https://web.archive.org/web/20130825050857/http://papuas.allsiemens.com/Joker.htm +screenshots: [] +versions: + - version: "0.3.4.1" + released: "2006-01-25" + files: + - path: files/JokerSorceV0341.rar + description: Исходный код Joker 0.3.4.1 для Borland Delphi + platform: win32 + sha256: b6e539597dbe6d8af1e6a813a305ea30322e561ec5a9786aadba520d9c1963c5 + - version: "0.2.9.5" + released: "2005-11-25" + files: + - path: files/JokerV0295.rar + description: Исполняемая программа Joker 0.2.9.5 + platform: win32 + sha256: 37a8805c5731ce74aa99b11c5f90580bce39b96c95b36cbd8adb72008df25e30 diff --git a/service/repair-tools/siemens-eeprom-tool/files/SiemensEEPROMtool315plus.rar b/service/repair-tools/siemens-eeprom-tool/files/SiemensEEPROMtool315plus.rar new file mode 100644 index 0000000..3c15be3 --- /dev/null +++ b/service/repair-tools/siemens-eeprom-tool/files/SiemensEEPROMtool315plus.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75249994aceab0836cfe26820f110dcaf61f411986b7d600d51ca57496d83e16 +size 76448 diff --git a/service/repair-tools/siemens-eeprom-tool/index.yaml b/service/repair-tools/siemens-eeprom-tool/index.yaml new file mode 100644 index 0000000..3df31f1 --- /dev/null +++ b/service/repair-tools/siemens-eeprom-tool/index.yaml @@ -0,0 +1,20 @@ +format: 1 +type: program +name: Siemens EEPROM Tool +description: |- + Редактор файлов EEPROM телефонов Siemens. Используется совместно с + x65PapuaUtils и Joker для восстановления программно неисправных аппаратов, + работы с резервными копиями блоков EEPROM и исправления их содержимого. + + Номер `3.01.0005` получен из ресурса версии исполняемого файла; имя исходного + архива — `SiemensEEPROMtool315plus.rar`. +homepage: https://web.archive.org/web/20130825050857/http://papuas.allsiemens.com/ +screenshots: [] +versions: + - version: "3.01.0005" + released: "2004-12-26" + files: + - path: files/SiemensEEPROMtool315plus.rar + description: Программа Siemens EEPROM Tool + platform: win32 + sha256: 75249994aceab0836cfe26820f110dcaf61f411986b7d600d51ca57496d83e16 diff --git a/service/repair-tools/x65-papua-utils/files/AllBugSGold.rar b/service/repair-tools/x65-papua-utils/files/AllBugSGold.rar new file mode 100644 index 0000000..d2677e5 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/AllBugSGold.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e743043a1a9c1ebc7e5cfe2fb92ba19f3cfd491e1cfcfc53667bd4b5cb8b1aae +size 449428 diff --git a/service/repair-tools/x65-papua-utils/files/SWP2.rar b/service/repair-tools/x65-papua-utils/files/SWP2.rar new file mode 100644 index 0000000..c076b7a --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/SWP2.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5bf27c1023637716bdbb1b47ff14da52dbe1145ec7b282d2cc949bb9a887e42 +size 256546 diff --git a/service/repair-tools/x65-papua-utils/files/SWP3.rar b/service/repair-tools/x65-papua-utils/files/SWP3.rar new file mode 100644 index 0000000..85845ab --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/SWP3.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8d28fcfb54ee5888e7b20dbcdcc06e43f8c8e5049a5a3dae829c1cc3d9b60de +size 278635 diff --git a/service/repair-tools/x65-papua-utils/files/SWPEXE.rar b/service/repair-tools/x65-papua-utils/files/SWPEXE.rar new file mode 100644 index 0000000..2870e21 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/SWPEXE.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4406effbdfc740ef0a9a0fc35bfa578eb31facd54af64856addc824552bf56fa +size 127296 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV036.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV036.rar new file mode 100644 index 0000000..0ff74d4 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV036.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0fc8dabb213982cd6efc7b082a4bd15e55703920f86b6b3f75cba35b4d846d18 +size 349275 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV038.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV038.rar new file mode 100644 index 0000000..93a1d7f --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV038.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:934e1dfc639b169739e91148e4c776bed45b55fecb8f0de5e1572161927d013e +size 350969 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV041.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV041.rar new file mode 100644 index 0000000..1519e97 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV041.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e75d16376506c1058cfbaf5c23bfe936a6e951b9f6e8aa673bc805e1f7bff874 +size 317749 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV043.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV043.rar new file mode 100644 index 0000000..6fdebce --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV043.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:122b60beb4754b10f07f66eb2de3c00ff2e1d0fc5755b8c977486943235062fc +size 321272 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV044.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV044.rar new file mode 100644 index 0000000..1e33c1b --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV044.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df538d7444014bb1d03b088911e0fbd67e90087f441e891b2c1c6890b184101f +size 320982 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV045.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV045.rar new file mode 100644 index 0000000..5940535 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV045.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:011df539dc179731d8e860752ce433266d4fb4e0616d50f5b406f58c24929f24 +size 328595 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV046.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV046.rar new file mode 100644 index 0000000..6083638 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV046.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac7fa346ec3bb951e8ded2412a9fb8079435af6baf5c1a6b69f90a07fa197e7f +size 329505 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV047.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV047.rar new file mode 100644 index 0000000..6fc890a --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV047.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0921d459063ede951daa1a813c4efcb01b8cbee86c778587077e619f9974ccb +size 331456 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV048.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV048.rar new file mode 100644 index 0000000..ae7fedb --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV048.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d443a7931d9256b26db52e9e0cfe60baaf95a1214219a492f58829a0846b8a3 +size 330453 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV050.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV050.rar new file mode 100644 index 0000000..7446bb9 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV050.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:874e8e209294bdc76394e20d05547cdf616c8752b72d8594e35fe650a5e48610 +size 330644 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV051.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV051.rar new file mode 100644 index 0000000..865f3d8 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV051.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f7bda62da5ac752239041d4842ae5ee260b462868a4d0907bbfd35b5e2b2dbc +size 331606 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV054.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV054.rar new file mode 100644 index 0000000..cefdf5d --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV054.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e86772910a36b21664e5c06843b0154b8a1ceb3cd905187906c8b211db42b370 +size 477217 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV055.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV055.rar new file mode 100644 index 0000000..a952a3b --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV055.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7d32065e5d13b376fca635919841c4ac48c1e878a2d33ac239bb100aa803a85 +size 477302 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV056.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV056.rar new file mode 100644 index 0000000..abab165 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV056.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fc712572c3d6e84b82765fc6a71e9837a2d2bddaf3d0846d105611902a66926 +size 481404 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV060.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV060.rar new file mode 100644 index 0000000..174186c --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV060.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38f15d7b1fe7b49712682e0aaed0b731e070fa8c95bf2b4990a442684fc4d05c +size 527737 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV062.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV062.rar new file mode 100644 index 0000000..b279b13 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV062.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c5eadfa0b4d67116e35d2fa5a0abaefc905060e06411b8abf0280ee37db5c07 +size 396015 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV064.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV064.rar new file mode 100644 index 0000000..111c686 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV064.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e175ef0711763b6905b9482eac94d197c3691a2c7d96109ad4be17ed8810c889 +size 397263 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV065.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV065.rar new file mode 100644 index 0000000..3638629 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV065.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32c859e29478758ad558d29ac9ec562f14467b89487048bd4ab9941b6be04975 +size 398848 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV066.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV066.rar new file mode 100644 index 0000000..ed01081 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV066.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4bd9c397caa1b95edd68ebf0afce45e3dde51220c2567a6217170fd48b54a5f +size 399470 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV067c.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV067c.rar new file mode 100644 index 0000000..3abb5e0 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV067c.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bed53e2f20e8e8612093457de6d1e3729fadf08f78d277ebdd7e311a40b24965 +size 399655 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV068.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV068.rar new file mode 100644 index 0000000..efd9bb3 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV068.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fff633734b473fad335b8cedf4958ff3128321324127739ab78357da275f35c +size 399815 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV069.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV069.rar new file mode 100644 index 0000000..cca3910 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV069.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ece0d737a855b69bdfd931c8e14af6a7d3895c4c2685e714380c50c96dc99db +size 399694 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV070.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV070.rar new file mode 100644 index 0000000..cd04102 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV070.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bc8574961048d3eb98b14c555fcb49836a1cdc90166f8a14c7ba9f3445645ca +size 397908 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV074.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV074.rar new file mode 100644 index 0000000..5ba74cb --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV074.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41f39790bc07e692e13dcd1eb744215f4091e5c7345815caa7be1df6c6e179ac +size 469388 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV075.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV075.rar new file mode 100644 index 0000000..23862ed --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV075.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2af3b05f56e147e957d5ad34fb895292a4bd62f7e6eccdd3d9dfdca9750cc430 +size 470383 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV076b.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV076b.rar new file mode 100644 index 0000000..ec16c77 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV076b.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f35a1e5b10dbc2309b25f1ff65ff05f12708c3148c9f3eb84c0cae9fff6e69fb +size 470068 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV077.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV077.rar new file mode 100644 index 0000000..4f20cbb --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV077.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d84b245b50465cb2274bbb53c88221be04e450ec1a1baf715e6c329eacf52d7 +size 473015 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV078.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV078.rar new file mode 100644 index 0000000..81fef9a --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV078.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67736ce7e6f0612c428a2b1afadea9cd0096d59e62eea777f9698713e2a5879b +size 446927 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV079d.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV079d.rar new file mode 100644 index 0000000..8968f01 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV079d.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19c66d8de5ffbada50d589150fb755d940bcca40e7d7cf87c54a1588bc697b81 +size 525033 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111b.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111b.rar new file mode 100644 index 0000000..6470a6e --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111b.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5bcbbe5b4e8cdf44319c0ce7aa8e943f6bf2a408239c0310b8c955a83f238d5 +size 625333 diff --git a/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111c_rus.rar b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111c_rus.rar new file mode 100644 index 0000000..34f0230 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/files/x65PapuaUtilsV111c_rus.rar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40422af6400b8b03fe86dd872bd09362975f667f6dbdd7de2475e4fbe3bb4c01 +size 632114 diff --git a/service/repair-tools/x65-papua-utils/index.yaml b/service/repair-tools/x65-papua-utils/index.yaml new file mode 100644 index 0000000..356a0e6 --- /dev/null +++ b/service/repair-tools/x65-papua-utils/index.yaml @@ -0,0 +1,259 @@ +format: 1 +type: program +name: x65PapuaUtils +description: |- + Комплексная сервисная программа для телефонов Siemens на платформе SGOLD: + моделей семейств R65, X65, X75 и X85, включая S65, S68, S75, SL65, SL75, + M65, M75, ME75, CX65, CX70, CX75, C65, C72, C75 и их варианты. + + Возможности: + - получение сведений о телефоне, ESN, HASH, SKEY и BootKey; + - перевод телефона в сервисный режим и работа через загрузчики; + - чтение и запись flash-памяти, создание полного бэкапа и восстановление BCORE; + - чтение, сохранение и восстановление EEPROM, генерация и пересчёт секретных + блоков и ключей; + - создание загрузчиков для V_KLay; + - преобразование FullFlash и отдельных сегментов в XBI и UserSwup, а также + извлечение XBZ/XBZI из сервисных WinSwup; + - тестирование RAM и шин ExtRAM/ROM, работа с камерой и проверка звука; + - восстановление программно неисправных аппаратов с помощью обычного кабеля; + для первой записи BCORE в полностью неработающий телефон требуется TestPoint. + + Автор предупреждает, что методы и поддержка отдельных моделей носили + экспериментальный характер. Перед операциями записи следует сохранить ESN, + HASH и полный FullFlash исправного телефона. +homepage: https://web.archive.org/web/20130825050857/http://papuas.allsiemens.com/PapuaUtils.htm +screenshots: [] +versions: + - version: "1.1.1c" + description: Отличается от версии 1.1.1b русским языком интерфейса. + files: + - path: files/x65PapuaUtilsV111c_rus.rar + platform: win32 + sha256: 40422af6400b8b03fe86dd872bd09362975f667f6dbdd7de2475e4fbe3bb4c01 + - version: "1.1.1b" + files: + - path: files/x65PapuaUtilsV111b.rar + description: Программа x65PapuaUtils 1.1.1b + platform: win32 + sha256: c5bcbbe5b4e8cdf44319c0ce7aa8e943f6bf2a408239c0310b8c955a83f238d5 + - version: "0.7.9d" + released: "2006-04-08" + files: + - path: files/x65PapuaUtilsV079d.rar + description: Программа x65PapuaUtils 0.7.9d + platform: win32 + sha256: 19c66d8de5ffbada50d589150fb755d940bcca40e7d7cf87c54a1588bc697b81 + - version: "0.7.8" + released: "2006-03-16" + files: + - path: files/x65PapuaUtilsV078.rar + description: Программа x65PapuaUtils 0.7.8 + platform: win32 + sha256: 67736ce7e6f0612c428a2b1afadea9cd0096d59e62eea777f9698713e2a5879b + - version: "0.7.7" + released: "2006-02-23" + files: + - path: files/x65PapuaUtilsV077.rar + description: Программа x65PapuaUtils 0.7.7 + platform: win32 + sha256: 4d84b245b50465cb2274bbb53c88221be04e450ec1a1baf715e6c329eacf52d7 + - version: "0.7.6b" + released: "2006-02-09" + files: + - path: files/x65PapuaUtilsV076b.rar + description: Программа x65PapuaUtils 0.7.6b + platform: win32 + sha256: f35a1e5b10dbc2309b25f1ff65ff05f12708c3148c9f3eb84c0cae9fff6e69fb + - version: "0.7.5c" + released: "2006-01-16" + files: + - path: files/x65PapuaUtilsV075.rar + description: Программа x65PapuaUtils 0.7.5c + platform: win32 + sha256: 2af3b05f56e147e957d5ad34fb895292a4bd62f7e6eccdd3d9dfdca9750cc430 + - version: "0.7.4" + released: "2005-12-31" + files: + - path: files/x65PapuaUtilsV074.rar + description: Программа x65PapuaUtils 0.7.4 + platform: win32 + sha256: 41f39790bc07e692e13dcd1eb744215f4091e5c7345815caa7be1df6c6e179ac + - version: "0.7.0" + released: "2005-12-17" + files: + - path: files/x65PapuaUtilsV070.rar + description: Программа x65PapuaUtils 0.7.0 + platform: win32 + sha256: 0bc8574961048d3eb98b14c555fcb49836a1cdc90166f8a14c7ba9f3445645ca + - version: "0.6.9" + released: "2005-11-26" + files: + - path: files/x65PapuaUtilsV069.rar + description: Программа x65PapuaUtils 0.6.9 + platform: win32 + sha256: 3ece0d737a855b69bdfd931c8e14af6a7d3895c4c2685e714380c50c96dc99db + - version: "0.6.8" + released: "2005-11-18" + files: + - path: files/x65PapuaUtilsV068.rar + description: Программа x65PapuaUtils 0.6.8 + platform: win32 + sha256: 9fff633734b473fad335b8cedf4958ff3128321324127739ab78357da275f35c + - version: "0.6.7c" + released: "2005-11-13" + files: + - path: files/x65PapuaUtilsV067c.rar + description: Программа x65PapuaUtils 0.6.7c + platform: win32 + sha256: bed53e2f20e8e8612093457de6d1e3729fadf08f78d277ebdd7e311a40b24965 + - version: "0.6.6b" + released: "2005-10-14" + files: + - path: files/x65PapuaUtilsV066.rar + description: Программа x65PapuaUtils 0.6.6b + platform: win32 + sha256: d4bd9c397caa1b95edd68ebf0afce45e3dde51220c2567a6217170fd48b54a5f + - version: "0.6.5" + released: "2005-10-11" + files: + - path: files/x65PapuaUtilsV065.rar + description: Программа x65PapuaUtils 0.6.5 + platform: win32 + sha256: 32c859e29478758ad558d29ac9ec562f14467b89487048bd4ab9941b6be04975 + - version: "0.6.4" + released: "2005-10-04" + files: + - path: files/x65PapuaUtilsV064.rar + description: Программа x65PapuaUtils 0.6.4 + platform: win32 + sha256: e175ef0711763b6905b9482eac94d197c3691a2c7d96109ad4be17ed8810c889 + - version: "0.6.2" + released: "2005-10-02" + files: + - path: files/x65PapuaUtilsV062.rar + description: Программа x65PapuaUtils 0.6.2 + platform: win32 + sha256: 2c5eadfa0b4d67116e35d2fa5a0abaefc905060e06411b8abf0280ee37db5c07 + - version: "0.6.0" + released: "2005-09-26" + files: + - path: files/x65PapuaUtilsV060.rar + description: Программа x65PapuaUtils 0.6.0 + platform: win32 + sha256: 38f15d7b1fe7b49712682e0aaed0b731e070fa8c95bf2b4990a442684fc4d05c + - version: "0.5.6" + released: "2005-09-22" + files: + - path: files/x65PapuaUtilsV056.rar + description: Программа x65PapuaUtils 0.5.6 + platform: win32 + sha256: 1fc712572c3d6e84b82765fc6a71e9837a2d2bddaf3d0846d105611902a66926 + - version: "0.5.5" + released: "2005-09-20" + files: + - path: files/x65PapuaUtilsV055.rar + description: Программа x65PapuaUtils 0.5.5 + platform: win32 + sha256: c7d32065e5d13b376fca635919841c4ac48c1e878a2d33ac239bb100aa803a85 + - version: "0.5.4" + released: "2005-09-19" + files: + - path: files/x65PapuaUtilsV054.rar + description: Программа x65PapuaUtils 0.5.4 + platform: win32 + sha256: e86772910a36b21664e5c06843b0154b8a1ceb3cd905187906c8b211db42b370 + - version: "0.5.1" + released: "2005-08-26" + files: + - path: files/x65PapuaUtilsV051.rar + description: Программа x65PapuaUtils 0.5.1 + platform: win32 + sha256: 2f7bda62da5ac752239041d4842ae5ee260b462868a4d0907bbfd35b5e2b2dbc + - version: "0.5.0" + released: "2005-08-16" + files: + - path: files/x65PapuaUtilsV050.rar + description: Программа x65PapuaUtils 0.5.0 + platform: win32 + sha256: 874e8e209294bdc76394e20d05547cdf616c8752b72d8594e35fe650a5e48610 + - version: "0.4.8a" + released: "2005-07-19" + files: + - path: files/x65PapuaUtilsV048.rar + description: Программа x65PapuaUtils 0.4.8a + platform: win32 + sha256: 8d443a7931d9256b26db52e9e0cfe60baaf95a1214219a492f58829a0846b8a3 + - version: "0.4.7r" + released: "2005-07-11" + files: + - path: files/x65PapuaUtilsV047.rar + description: Программа x65PapuaUtils 0.4.7r + platform: win32 + sha256: f0921d459063ede951daa1a813c4efcb01b8cbee86c778587077e619f9974ccb + - version: "0.4.6" + released: "2005-07-01" + files: + - path: files/x65PapuaUtilsV046.rar + description: Программа x65PapuaUtils 0.4.6 + platform: win32 + sha256: ac7fa346ec3bb951e8ded2412a9fb8079435af6baf5c1a6b69f90a07fa197e7f + - version: "0.4.5b" + released: "2005-06-30" + files: + - path: files/x65PapuaUtilsV045.rar + description: Программа x65PapuaUtils 0.4.5b + platform: win32 + sha256: 011df539dc179731d8e860752ce433266d4fb4e0616d50f5b406f58c24929f24 + - version: "0.4.4a" + released: "2005-06-24" + files: + - path: files/x65PapuaUtilsV044.rar + description: Программа x65PapuaUtils 0.4.4a + platform: win32 + sha256: df538d7444014bb1d03b088911e0fbd67e90087f441e891b2c1c6890b184101f + - version: "0.4.3" + released: "2005-06-19" + files: + - path: files/x65PapuaUtilsV043.rar + description: Программа x65PapuaUtils 0.4.3 + platform: win32 + sha256: 122b60beb4754b10f07f66eb2de3c00ff2e1d0fc5755b8c977486943235062fc + - version: "0.4.1g" + released: "2005-06-07" + files: + - path: files/x65PapuaUtilsV041.rar + description: Программа x65PapuaUtils 0.4.1g + platform: win32 + sha256: e75d16376506c1058cfbaf5c23bfe936a6e951b9f6e8aa673bc805e1f7bff874 + - version: "0.3.8d" + released: "2005-06-01" + files: + - path: files/x65PapuaUtilsV038.rar + description: Программа x65PapuaUtils 0.3.8d + platform: win32 + sha256: 934e1dfc639b169739e91148e4c776bed45b55fecb8f0de5e1572161927d013e + - version: "0.3.6" + released: "2005-05-28" + files: + - path: files/x65PapuaUtilsV036.rar + description: Программа x65PapuaUtils 0.3.6 и FAQ + platform: win32 + sha256: 0fc8dabb213982cd6efc7b082a4bd15e55703920f86b6b3f75cba35b4d846d18 +additional_files: + - path: files/SWP3.rar + description: Файлы SWP 4.15 и 4.14 для создания UserSwup в новых версиях программы + platform: win32 + sha256: f8d28fcfb54ee5888e7b20dbcdcc06e43f8c8e5049a5a3dae829c1cc3d9b60de + - path: files/SWP2.rar + description: Файлы SWP 4.14 и 4.12 для создания UserSwup + platform: win32 + sha256: d5bf27c1023637716bdbb1b47ff14da52dbe1145ec7b282d2cc949bb9a887e42 + - path: files/SWPEXE.rar + description: Файл SWPEXE 4.09 для создания UserSwup в версиях ниже 0.7.4 + platform: win32 + sha256: 4406effbdfc740ef0a9a0fc35bfa578eb31facd54af64856addc824552bf56fa + - path: files/AllBugSGold.rar + description: Интерактивная видеоинструкция по устранению программных неисправностей SGOLD + platform: win32 + sha256: e743043a1a9c1ebc7e5cfe2fb92ba19f3cfd491e1cfcfc53667bd4b5cb8b1aae diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3cb0ea5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "types": ["node"] + }, + "include": ["scripts/**/*.ts"] +}