Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73e642c1ec | ||
|
|
66f5749fc1 | ||
|
|
823d1eb841 | ||
|
|
860072e542 |
No files matched your search
@@ -143,6 +143,11 @@ jobs:
|
||||
fi
|
||||
./gradlew --stop
|
||||
|
||||
# Только arm64-v8a, все нужные .so на месте и выровнены по 16 КБ — иначе APK падает при запуске
|
||||
# на части устройств (Android 15+ с 16 КБ страницами, эмуляторы x86).
|
||||
- name: Проверка APK (ABI, 16 КБ страницы)
|
||||
run: node scripts/check-apk.mjs apps/mobile/android/app/build/outputs/apk/release/app-release.apk
|
||||
|
||||
- name: Диагностика сбоя (диск, память, OOM)
|
||||
if: failure()
|
||||
run: |
|
||||
|
||||
@@ -2014,6 +2014,10 @@ components:
|
||||
web_player:
|
||||
type: string
|
||||
enum: [bar, island]
|
||||
search_position:
|
||||
type: string
|
||||
enum: [center, left, right]
|
||||
description: Где в топбаре веба поиск (по умолчанию center)
|
||||
mobile_player:
|
||||
type: string
|
||||
enum: [cover, wave]
|
||||
|
||||
@@ -31,6 +31,8 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
|
||||
// Сервер часто живёт в домашней сети без TLS (http://192.168.1.10:8080), а release-сборка
|
||||
// Android по умолчанию запрещает незашифрованный HTTP.
|
||||
['expo-build-properties', { android: { usesCleartextTraffic: true } }],
|
||||
// APK только под arm64-v8a — та же ABI, под которую собираются нативные модули (plugins/withArm64Only.js).
|
||||
'./plugins/withArm64Only',
|
||||
],
|
||||
extra: { versionCode },
|
||||
experiments: { typedRoutes: false },
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Только arm64-v8a в APK. Наши нативные модули (Expo, Skia, Reanimated) собираются под одну ABI
|
||||
// (-PreactNativeArchitectures=arm64-v8a в release.yml), а готовые библиотеки React Native приносят
|
||||
// каталоги всех ABI. Без фильтра x86/x86_64-эмулятор и 32-битные устройства выбирают неполный каталог
|
||||
// и падают при старте: «couldn't find DSO to load: libexpo-modules-core.so».
|
||||
const { withAppBuildGradle } = require('expo/config-plugins');
|
||||
|
||||
const MARKER = '// pipu: arm64-v8a only';
|
||||
|
||||
module.exports = function withArm64Only(config) {
|
||||
return withAppBuildGradle(config, (cfg) => {
|
||||
if (cfg.modResults.contents.includes(MARKER)) return cfg;
|
||||
cfg.modResults.contents = cfg.modResults.contents.replace(
|
||||
/defaultConfig\s*\{/,
|
||||
(m) => `${m}\n ${MARKER}\n ndk { abiFilters "arm64-v8a" }`,
|
||||
);
|
||||
return cfg;
|
||||
});
|
||||
};
|
||||
@@ -8,6 +8,8 @@ WORKDIR /repo
|
||||
# Сначала только манифесты workspace: слой с установкой зависимостей пересобирается лишь при их изменении,
|
||||
# а не при любой правке кода. Новый пакет в apps/ или packages/ — добавить его package.json сюда.
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||
# pnpm-патчи зависимостей (lockfile ссылается на них, без них --frozen-lockfile падает)
|
||||
COPY patches/ patches/
|
||||
COPY apps/web/package.json apps/web/
|
||||
COPY apps/mobile/package.json apps/mobile/
|
||||
COPY packages/api-client/package.json packages/api-client/
|
||||
|
||||
@@ -126,6 +126,19 @@ function AppearanceSection() {
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div className={s.settingRow}>
|
||||
<span>{t('settings.search_position')}</span>
|
||||
<Segmented<'left' | 'center' | 'right'>
|
||||
label={t('settings.search_position')}
|
||||
value={user.ui_prefs.search_position ?? 'center'}
|
||||
onChange={(v) => void setPrefs({ search_position: v })}
|
||||
options={[
|
||||
{ value: 'left', label: t('settings.search_left') },
|
||||
{ value: 'center', label: t('settings.search_center') },
|
||||
{ value: 'right', label: t('settings.search_right') },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div className={s.settingRow}>
|
||||
<span>{t('settings.ambient')}</span>
|
||||
<Segmented<'on' | 'off'>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
gap: 28px;
|
||||
padding: 24px 0;
|
||||
text-align: center;
|
||||
user-select: none; /* главная — только элементы управления волной */
|
||||
}
|
||||
|
||||
.orbLabel {
|
||||
|
||||
@@ -41,6 +41,19 @@ button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Элементы управления не выделяются при кликах и двойных кликах — текст остаётся выделяемым на страницах. */
|
||||
button,
|
||||
[role='button'],
|
||||
[role='tab'],
|
||||
[role='option'],
|
||||
[role='menuitem'],
|
||||
[role='listitem'],
|
||||
nav a,
|
||||
label {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
|
||||
@@ -31,10 +31,11 @@
|
||||
.top {
|
||||
grid-area: top;
|
||||
z-index: 30;
|
||||
display: flex;
|
||||
/* Три зоны: логотип, середина, профиль; поиск — в одной из них (настройка «Расположение поиска»). */
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 0 20px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
background: var(--bar-a);
|
||||
@@ -53,9 +54,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
.topLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.topCenter {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.topRight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,8 @@ function Shell() {
|
||||
const name = user.display_name ?? user.username;
|
||||
const staff = user.role !== 'user';
|
||||
const island = user.ui_prefs.web_player === 'island';
|
||||
const searchAt = user.ui_prefs.search_position ?? 'center';
|
||||
const search = <SearchBox align={searchAt} />;
|
||||
const counts = useCollectionCounts();
|
||||
const pending = usePendingUploads(user.role === 'admin');
|
||||
|
||||
@@ -100,11 +102,15 @@ function Shell() {
|
||||
<div className={cx(s.shell, island && s.island)}>
|
||||
{user.ui_prefs.ambient !== false && <ShellAmbient />}
|
||||
<header className={s.top}>
|
||||
<div className={s.topLeft}>
|
||||
<Link to="/" className={s.logoLink}>
|
||||
<Logo />
|
||||
</Link>
|
||||
{searchAt === 'left' && search}
|
||||
</div>
|
||||
<div className={s.topCenter}>{searchAt === 'center' && search}</div>
|
||||
<div className={s.topRight}>
|
||||
<SearchBox />
|
||||
{searchAt === 'right' && search}
|
||||
<Menu
|
||||
label={t('profile.menu')}
|
||||
triggerClassName={s.profileButton}
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
|
||||
.popover {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: min(520px, calc(100vw - 32px));
|
||||
top: calc(100% + 8px);
|
||||
z-index: 45;
|
||||
@@ -98,6 +97,20 @@
|
||||
animation: pipuIn 0.15s ease-out;
|
||||
}
|
||||
|
||||
/* Подсказки раскрываются в сторону свободного места: слева — вправо, справа — влево, по центру — от середины. */
|
||||
.left .popover {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.right .popover {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.center .popover {
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.corrected {
|
||||
margin: 4px 10px 8px;
|
||||
font-size: 13px;
|
||||
|
||||
@@ -27,7 +27,7 @@ type Item = {
|
||||
* Поиск в топбаре: подсказки по мере ввода, Enter — страница поиска или выбранный элемент.
|
||||
* Без фокуса и текста свёрнут в кнопку с лупой; поле раскрывается влево с анимацией.
|
||||
*/
|
||||
export function SearchBox() {
|
||||
export function SearchBox({ align = 'center' }: { align?: 'left' | 'center' | 'right' }) {
|
||||
const { t } = useTranslation();
|
||||
const session = useSession();
|
||||
const navigate = useNavigate();
|
||||
@@ -38,6 +38,7 @@ export function SearchBox() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [active, setActive] = useState(-1);
|
||||
const [focused, setFocused] = useState(false);
|
||||
const blurTimer = useRef<ReturnType<typeof setTimeout>>(undefined);
|
||||
// Свёрнут в круглую кнопку, пока не нужен: раскрывается по клику, «/» или Ctrl+K.
|
||||
const expanded = focused || q !== '';
|
||||
|
||||
@@ -147,7 +148,7 @@ export function SearchBox() {
|
||||
const optionId = (i: number) => `${listId}-${i}`;
|
||||
|
||||
return (
|
||||
<div className={cx(s.box, expanded && s.expanded)}>
|
||||
<div className={cx(s.box, expanded && s.expanded, s[align])}>
|
||||
<Icon src={searchIcon} size={18} className={s.icon} />
|
||||
<input
|
||||
ref={inputRef}
|
||||
@@ -167,12 +168,14 @@ export function SearchBox() {
|
||||
setActive(-1);
|
||||
}}
|
||||
onFocus={() => {
|
||||
// Вернулись в поле раньше, чем сработало закрытие по blur, — подсказки не прячем.
|
||||
clearTimeout(blurTimer.current);
|
||||
setFocused(true);
|
||||
setOpen(true);
|
||||
}}
|
||||
onBlur={() => {
|
||||
setFocused(false);
|
||||
setTimeout(close, 120);
|
||||
blurTimer.current = setTimeout(close, 120);
|
||||
}}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
|
||||
+4
-2
@@ -45,6 +45,8 @@ SUPPORTED_LOCALES=ru,en
|
||||
MIN_ANDROID_VERSION_CODE=0
|
||||
|
||||
# --- Самообновление Android (M5) ---
|
||||
GITEA_URL=https://git.example.lan
|
||||
GITEA_REPO=owner/pipu-music
|
||||
# Пусто — install.sh и update.sh возьмут из origin клона (например, https://gitea.example.com и owner/pipu-music).
|
||||
# Если сервер не видит Gitea по внешнему адресу, укажите внутренний: GITEA_URL=http://10.0.0.5:3000
|
||||
GITEA_URL=
|
||||
GITEA_REPO=
|
||||
GITEA_TOKEN=
|
||||
@@ -76,6 +76,39 @@ for key in JWT_PRIVATE_KEY STREAM_SIGNING_KEY; do
|
||||
fi
|
||||
done
|
||||
|
||||
# Самообновление Android: адрес Gitea и репозиторий — из origin этого клона, если в .env пусто
|
||||
# или осталась заглушка из .env.example (https://host/owner/repo, git@host:owner/repo, ssh://git@host:port/owner/repo).
|
||||
fill_gitea() {
|
||||
local url repo origin host path
|
||||
url="$(sed -n 's/^GITEA_URL=//p' .env)"
|
||||
repo="$(sed -n 's/^GITEA_REPO=//p' .env)"
|
||||
case "$url" in "" | *example.*) url="" ;; esac
|
||||
case "$repo" in "" | owner/*) repo="" ;; esac
|
||||
[ -n "$url" ] && [ -n "$repo" ] && return 0
|
||||
origin="$(git -c safe.directory='*' remote get-url origin 2>/dev/null || true)"
|
||||
[ -n "$origin" ] || return 0
|
||||
case "$origin" in
|
||||
http://* | https://*)
|
||||
host="$(printf '%s' "$origin" | sed -E 's#^(https?://)([^@/]*@)?([^/]+)/.*#\1\3#')"
|
||||
path="$(printf '%s' "$origin" | sed -E 's#^https?://[^/]+/##')" ;;
|
||||
ssh://*)
|
||||
host="https://$(printf '%s' "$origin" | sed -E 's#^ssh://([^@/]*@)?([^:/]+).*#\2#')"
|
||||
path="$(printf '%s' "$origin" | sed -E 's#^ssh://[^/]+/##')" ;;
|
||||
*:*)
|
||||
host="https://$(printf '%s' "$origin" | sed -E 's#^([^@]*@)?([^:]+):.*#\2#')"
|
||||
path="${origin#*:}" ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
path="${path%.git}"
|
||||
[ -n "$url" ] || url="$host"
|
||||
[ -n "$repo" ] || repo="$path"
|
||||
for kv in "GITEA_URL=$url" "GITEA_REPO=$repo"; do
|
||||
if grep -q "^${kv%%=*}=" .env; then sed -i "s|^${kv%%=*}=.*|$kv|" .env; else echo "$kv" >> .env; fi
|
||||
done
|
||||
echo "→ самообновление Android: $url, $repo (из git remote; поменять — в .env)"
|
||||
}
|
||||
fill_gitea
|
||||
|
||||
# LIBRARY_HOST, переданный при повторном запуске, попадает и в уже существующий .env
|
||||
if [ -n "$LIBRARY_HOST" ]; then
|
||||
if grep -q '^LIBRARY_HOST=' .env; then
|
||||
|
||||
@@ -26,6 +26,39 @@ for key in JWT_PRIVATE_KEY STREAM_SIGNING_KEY; do
|
||||
fi
|
||||
done
|
||||
|
||||
# Самообновление Android: адрес Gitea и репозиторий — из origin этого клона, если в .env пусто
|
||||
# или осталась заглушка из .env.example (https://host/owner/repo, git@host:owner/repo, ssh://git@host:port/owner/repo).
|
||||
fill_gitea() {
|
||||
local url repo origin host path
|
||||
url="$(sed -n 's/^GITEA_URL=//p' .env)"
|
||||
repo="$(sed -n 's/^GITEA_REPO=//p' .env)"
|
||||
case "$url" in "" | *example.*) url="" ;; esac
|
||||
case "$repo" in "" | owner/*) repo="" ;; esac
|
||||
[ -n "$url" ] && [ -n "$repo" ] && return 0
|
||||
origin="$(git -c safe.directory='*' remote get-url origin 2>/dev/null || true)"
|
||||
[ -n "$origin" ] || return 0
|
||||
case "$origin" in
|
||||
http://* | https://*)
|
||||
host="$(printf '%s' "$origin" | sed -E 's#^(https?://)([^@/]*@)?([^/]+)/.*#\1\3#')"
|
||||
path="$(printf '%s' "$origin" | sed -E 's#^https?://[^/]+/##')" ;;
|
||||
ssh://*)
|
||||
host="https://$(printf '%s' "$origin" | sed -E 's#^ssh://([^@/]*@)?([^:/]+).*#\2#')"
|
||||
path="$(printf '%s' "$origin" | sed -E 's#^ssh://[^/]+/##')" ;;
|
||||
*:*)
|
||||
host="https://$(printf '%s' "$origin" | sed -E 's#^([^@]*@)?([^:]+):.*#\2#')"
|
||||
path="${origin#*:}" ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
path="${path%.git}"
|
||||
[ -n "$url" ] || url="$host"
|
||||
[ -n "$repo" ] || repo="$path"
|
||||
for kv in "GITEA_URL=$url" "GITEA_REPO=$repo"; do
|
||||
if grep -q "^${kv%%=*}=" .env; then sed -i "s|^${kv%%=*}=.*|$kv|" .env; else echo "$kv" >> .env; fi
|
||||
done
|
||||
echo "→ самообновление Android: $url, $repo (из git remote; поменять — в .env)"
|
||||
}
|
||||
fill_gitea
|
||||
|
||||
# Папка с музыкой пуста — почти всегда это несмонтированный диск: api отдавал бы ошибки воспроизведения.
|
||||
LIBRARY_HOST="$(sed -n 's/^LIBRARY_HOST=//p' .env)"
|
||||
if [ -n "$LIBRARY_HOST" ] && [ -z "$(ls -A "$LIBRARY_HOST" 2>/dev/null)" ] && [ "${PIPU_ALLOW_EMPTY_LIBRARY:-}" != 1 ]; then
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@
|
||||
| `BOOTSTRAP_ADMIN_PASSWORD` | пусто → сгенерировать и вывести в лог | |
|
||||
| `TRANSCODE_CACHE_LIMIT_GB` | `50` | |
|
||||
| `TRANSCODE_CONCURRENCY` | `2` | |
|
||||
| `GITEA_URL`, `GITEA_REPO`, `GITEA_TOKEN` | `https://git.home.lan`, `owner/pipu-music`, read-only токен | Для самообновления Android |
|
||||
| `GITEA_URL`, `GITEA_REPO`, `GITEA_TOKEN` | пусто — из `git remote` (`install.sh`, `update.sh`); токен — для закрытого репозитория | Самообновление Android и страница `/android` |
|
||||
| `PIPU_FILE_UID`, `PIPU_FILE_GID` | `1000` | Владелец файлов, которые агент записывает в принимающие хранилища |
|
||||
| `UPLOADS_DIR` | `/uploads` | Staging очереди на добавление (лимит очереди задаётся в админке) |
|
||||
| `LOG_LEVEL` | `info` | |
|
||||
|
||||
@@ -250,8 +250,10 @@ curl -s https://music.example.com/readyz
|
||||
приложение попросит обновиться.
|
||||
|
||||
Дальше приложение обновляется само: с версии M5 оно проверяет новые релизы через ваш сервер
|
||||
и предлагает обновиться ([mobile.md](mobile.md#самообновление)). Для этого в `.env` сервера нужно заполнить
|
||||
`GITEA_URL`, `GITEA_REPO` и `GITEA_TOKEN` (токен только на чтение).
|
||||
и предлагает обновиться ([mobile.md](mobile.md#самообновление)). Адрес Gitea и репозиторий (`GITEA_URL`, `GITEA_REPO`)
|
||||
`install.sh` и `update.sh` берут из `git remote` клона; `GITEA_TOKEN` (только на чтение) нужен, если репозиторий
|
||||
закрытый. Если сервер не видит Gitea по внешнему адресу — впишите внутренний в `GITEA_URL`. Раздать приложение —
|
||||
ссылка `https://<ваш-домен>/android`.
|
||||
|
||||
> Приложению нужен настоящий сертификат. С самоподписанным сертификатом и голым IP-адресом подключиться не получится.
|
||||
> Поэтому нужен домен с Let's Encrypt, как в этой инструкции.
|
||||
|
||||
@@ -16,6 +16,18 @@
|
||||
| i18n | i18next, словари из `packages/i18n` |
|
||||
| Минимальная версия | Android 8.0 (API 26), target — актуальный API |
|
||||
|
||||
## Сборка APK: ABI и 16 КБ страницы
|
||||
|
||||
- APK только под `arm64-v8a` (`plugins/withArm64Only.js`): нативные модули собираются под одну ABI, а без фильтра
|
||||
в APK попадали неполные каталоги `x86`, `x86_64`, `armeabi-v7a` из библиотек React Native — эмулятор x86 и
|
||||
32-битные устройства выбирали их и падали при старте (`couldn't find DSO to load: libexpo-modules-core.so`).
|
||||
Эмулятор для проверки — образ arm64 или настоящее устройство.
|
||||
- Все `.so` выровнены по 16 КБ: устройства с Android 15+ и 16 КБ страницами памяти не загружают библиотеки
|
||||
с выравниванием 4 КБ, приложение закрывается сразу после запуска. Skia 2.0.0-next.4 собиралась без
|
||||
`ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES` — флаг добавлен pnpm-патчем (`patches/`).
|
||||
- `scripts/check-apk.mjs` в релизе проверяет ABI, наличие ключевых библиотек и выравнивание; без этого релиз
|
||||
не публикуется.
|
||||
|
||||
## Экраны
|
||||
|
||||
Макет — `Pipu Android.dc.html`, сводка решений — [design.md](design.md#android).
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
"generate": "turbo run generate",
|
||||
"i18n:check": "pnpm --filter @pipu/i18n check",
|
||||
"version:info": "node scripts/version.mjs",
|
||||
"test:scripts": "node --test scripts/version.test.mjs scripts/release.test.mjs"
|
||||
"test:scripts": "node --test scripts/version.test.mjs scripts/release.test.mjs scripts/check-apk.test.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"turbo": "2.5.4",
|
||||
|
||||
@@ -1509,6 +1509,11 @@ export interface components {
|
||||
wave_variant?: "orb" | "liquid";
|
||||
/** @enum {string} */
|
||||
web_player?: "bar" | "island";
|
||||
/**
|
||||
* @description Где в топбаре веба поиск (по умолчанию center)
|
||||
* @enum {string}
|
||||
*/
|
||||
search_position?: "center" | "left" | "right";
|
||||
/** @enum {string} */
|
||||
mobile_player?: "cover" | "wave";
|
||||
ambient?: boolean;
|
||||
|
||||
@@ -115,7 +115,11 @@
|
||||
"player_island": "Island",
|
||||
"ambient": "Ambient background",
|
||||
"on": "On",
|
||||
"off": "Off"
|
||||
"off": "Off",
|
||||
"search_position": "Search position",
|
||||
"search_left": "Left",
|
||||
"search_center": "Center",
|
||||
"search_right": "Right"
|
||||
},
|
||||
"form": {
|
||||
"show_password": "Show password",
|
||||
|
||||
@@ -115,7 +115,11 @@
|
||||
"player_island": "Остров",
|
||||
"ambient": "Живой фон",
|
||||
"on": "Вкл.",
|
||||
"off": "Выкл."
|
||||
"off": "Выкл.",
|
||||
"search_position": "Расположение поиска",
|
||||
"search_left": "Слева",
|
||||
"search_center": "По центру",
|
||||
"search_right": "Справа"
|
||||
},
|
||||
"form": {
|
||||
"show_password": "Показать пароль",
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index c5431ee7db4fccb4a67fc790ef95db00b5b545dc..bc5feca88bf56c0bf5ac5c4b03f8ab57b693eef5 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -156,7 +156,9 @@ android {
|
||||
arguments '-DANDROID_STL=c++_shared',
|
||||
"-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
|
||||
"-DNODE_MODULES_DIR=${nodeModules}",
|
||||
- "-DPREBUILT_DIR=${prebuiltDir}"
|
||||
+ "-DPREBUILT_DIR=${prebuiltDir}",
|
||||
+ // 16 КБ страницы памяти (Android 15+): иначе librnskia.so не загружается на таких устройствах
|
||||
+ "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
||||
|
||||
}
|
||||
}
|
||||
Generated
+5
-2
@@ -4,6 +4,9 @@ settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
patchedDependencies:
|
||||
'@shopify/react-native-skia@2.0.0-next.4': ae341532dba11d4a93999214787e561932c027da2a86640d9f1bcad8ba5910b7
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
@@ -37,7 +40,7 @@ importers:
|
||||
version: 11.4.1(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))
|
||||
'@shopify/react-native-skia':
|
||||
specifier: 2.0.0-next.4
|
||||
version: 2.0.0-next.4(react-native-reanimated@3.17.5(@babel/core@7.29.7)(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0))(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0)
|
||||
version: 2.0.0-next.4(patch_hash=ae341532dba11d4a93999214787e561932c027da2a86640d9f1bcad8ba5910b7)(react-native-reanimated@3.17.5(@babel/core@7.29.7)(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0))(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.104.4
|
||||
version: 5.104.4(@types/react@19.0.14)(react@19.0.0)
|
||||
@@ -5396,7 +5399,7 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc@4.64.10':
|
||||
optional: true
|
||||
|
||||
'@shopify/react-native-skia@2.0.0-next.4(react-native-reanimated@3.17.5(@babel/core@7.29.7)(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0))(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0)':
|
||||
'@shopify/react-native-skia@2.0.0-next.4(patch_hash=ae341532dba11d4a93999214787e561932c027da2a86640d9f1bcad8ba5910b7)(react-native-reanimated@3.17.5(@babel/core@7.29.7)(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0))(react-native@0.79.6(@babel/core@7.29.7)(@types/react@19.0.14)(react@19.0.0)(supports-color@10.2.2))(react@19.0.0)':
|
||||
dependencies:
|
||||
canvaskit-wasm: 0.40.0
|
||||
react: 19.0.0
|
||||
|
||||
@@ -6,6 +6,9 @@ packages:
|
||||
allowBuilds:
|
||||
esbuild: true
|
||||
|
||||
patchedDependencies:
|
||||
'@shopify/react-native-skia@2.0.0-next.4': patches/@shopify__react-native-skia@2.0.0-next.4.patch
|
||||
|
||||
# Изолированная раскладка node_modules (pnpm 11). Expo вычисляет react-native.config.js пакета expo
|
||||
# по пути через симлинк apps/mobile/node_modules/expo, и оттуда require('expo-modules-autolinking')
|
||||
# находится только в корневом node_modules. Без этого autolinking молча генерирует неверный импорт
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env node
|
||||
// Проверка собранного APK перед публикацией (release.yml):
|
||||
// - нативные библиотеки только под arm64-v8a: неполный каталог другой ABI роняет приложение при старте
|
||||
// («couldn't find DSO to load: libexpo-modules-core.so» на x86-эмуляторе);
|
||||
// - есть библиотеки, без которых приложение не запустится;
|
||||
// - PT_LOAD-сегменты каждой .so выровнены по 16 КБ: иначе на устройствах с 16 КБ страницами памяти
|
||||
// (Android 15+) библиотека не загружается и приложение закрывается сразу после запуска.
|
||||
// Запуск: node scripts/check-apk.mjs app-release.apk
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { inflateRawSync } from 'node:zlib';
|
||||
|
||||
export const ABI = 'arm64-v8a';
|
||||
export const REQUIRED = ['libreactnative.so', 'libhermes.so', 'libexpo-modules-core.so', 'librnskia.so', 'libreanimated.so'];
|
||||
const PAGE = 16384;
|
||||
|
||||
/** Файлы ZIP по центральному каталогу: имя → содержимое. */
|
||||
export function zipEntries(buf) {
|
||||
let eocd = buf.length - 22;
|
||||
while (eocd >= 0 && buf.readUInt32LE(eocd) !== 0x06054b50) eocd--;
|
||||
if (eocd < 0) throw new Error('not a zip file');
|
||||
const count = buf.readUInt16LE(eocd + 10);
|
||||
let p = buf.readUInt32LE(eocd + 16);
|
||||
const out = new Map();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const method = buf.readUInt16LE(p + 10);
|
||||
const size = buf.readUInt32LE(p + 20);
|
||||
const nameLen = buf.readUInt16LE(p + 28);
|
||||
const extraLen = buf.readUInt16LE(p + 30);
|
||||
const commentLen = buf.readUInt16LE(p + 32);
|
||||
const local = buf.readUInt32LE(p + 42);
|
||||
const name = buf.toString('utf8', p + 46, p + 46 + nameLen);
|
||||
out.set(name, () => {
|
||||
const start = local + 30 + buf.readUInt16LE(local + 26) + buf.readUInt16LE(local + 28);
|
||||
const raw = buf.subarray(start, start + size);
|
||||
return method === 0 ? raw : inflateRawSync(raw);
|
||||
});
|
||||
p += 46 + nameLen + extraLen + commentLen;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Наименьшее выравнивание PT_LOAD-сегментов 64-битной ELF-библиотеки. */
|
||||
export function loadAlignment(elf) {
|
||||
if (elf.readUInt32BE(0) !== 0x7f454c46 || elf[4] !== 2) throw new Error('not a 64-bit ELF');
|
||||
const phoff = Number(elf.readBigUInt64LE(0x20));
|
||||
const phentsize = elf.readUInt16LE(0x36);
|
||||
const phnum = elf.readUInt16LE(0x38);
|
||||
let min = Infinity;
|
||||
for (let i = 0; i < phnum; i++) {
|
||||
const off = phoff + i * phentsize;
|
||||
if (elf.readUInt32LE(off) === 1) min = Math.min(min, Number(elf.readBigUInt64LE(off + 0x30)));
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
export function checkApk(buf) {
|
||||
const problems = [];
|
||||
const entries = zipEntries(buf);
|
||||
const libs = [...entries.keys()].filter((n) => n.startsWith('lib/') && n.endsWith('.so'));
|
||||
const abis = new Set(libs.map((n) => n.split('/')[1]));
|
||||
for (const abi of abis) if (abi !== ABI) problems.push(`лишняя ABI в APK: lib/${abi}/`);
|
||||
const mine = new Set(libs.filter((n) => n.startsWith(`lib/${ABI}/`)).map((n) => n.split('/')[2]));
|
||||
for (const lib of REQUIRED) if (!mine.has(lib)) problems.push(`нет lib/${ABI}/${lib}`);
|
||||
for (const name of libs.filter((n) => n.startsWith(`lib/${ABI}/`))) {
|
||||
const align = loadAlignment(entries.get(name)());
|
||||
if (align < PAGE) problems.push(`${name}: сегменты выровнены по ${align} байт, нужно ${PAGE} (16 КБ страницы)`);
|
||||
}
|
||||
return { libs: mine.size, problems };
|
||||
}
|
||||
|
||||
if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith('check-apk.mjs')) {
|
||||
const file = process.argv[2];
|
||||
if (!file) {
|
||||
console.error('usage: node scripts/check-apk.mjs <apk>');
|
||||
process.exit(2);
|
||||
}
|
||||
const { libs, problems } = checkApk(readFileSync(file));
|
||||
if (problems.length) {
|
||||
for (const p of problems) console.error(`✗ ${p}`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`APK: ${libs} библиотек ${ABI}, все выровнены по 16 КБ`);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { test } from 'node:test';
|
||||
|
||||
import { checkApk, loadAlignment, REQUIRED } from './check-apk.mjs';
|
||||
|
||||
/** ELF64 с одним PT_LOAD и заданным выравниванием. */
|
||||
function elf(align) {
|
||||
const b = Buffer.alloc(64 + 56);
|
||||
b.writeUInt32BE(0x7f454c46, 0);
|
||||
b[4] = 2;
|
||||
b.writeBigUInt64LE(64n, 0x20);
|
||||
b.writeUInt16LE(56, 0x36);
|
||||
b.writeUInt16LE(1, 0x38);
|
||||
b.writeUInt32LE(1, 64);
|
||||
b.writeBigUInt64LE(BigInt(align), 64 + 0x30);
|
||||
return b;
|
||||
}
|
||||
|
||||
/** ZIP без сжатия из пар [имя, содержимое]. */
|
||||
function zip(files) {
|
||||
const locals = [];
|
||||
const central = [];
|
||||
let offset = 0;
|
||||
for (const [name, data] of files) {
|
||||
const n = Buffer.from(name);
|
||||
const lh = Buffer.alloc(30);
|
||||
lh.writeUInt32LE(0x04034b50, 0);
|
||||
lh.writeUInt32LE(data.length, 18);
|
||||
lh.writeUInt32LE(data.length, 22);
|
||||
lh.writeUInt16LE(n.length, 26);
|
||||
locals.push(lh, n, data);
|
||||
const ch = Buffer.alloc(46);
|
||||
ch.writeUInt32LE(0x02014b50, 0);
|
||||
ch.writeUInt32LE(data.length, 20);
|
||||
ch.writeUInt32LE(data.length, 24);
|
||||
ch.writeUInt16LE(n.length, 28);
|
||||
ch.writeUInt32LE(offset, 42);
|
||||
central.push(ch, n);
|
||||
offset += 30 + n.length + data.length;
|
||||
}
|
||||
const cd = Buffer.concat(central);
|
||||
const end = Buffer.alloc(22);
|
||||
end.writeUInt32LE(0x06054b50, 0);
|
||||
end.writeUInt16LE(files.length, 8);
|
||||
end.writeUInt16LE(files.length, 10);
|
||||
end.writeUInt32LE(cd.length, 12);
|
||||
end.writeUInt32LE(offset, 16);
|
||||
return Buffer.concat([...locals, cd, end]);
|
||||
}
|
||||
|
||||
test('reads the smallest PT_LOAD alignment', () => {
|
||||
assert.equal(loadAlignment(elf(16384)), 16384);
|
||||
assert.equal(loadAlignment(elf(4096)), 4096);
|
||||
});
|
||||
|
||||
test('accepts an arm64-only APK aligned to 16 KB', () => {
|
||||
const apk = zip(REQUIRED.map((l) => [`lib/arm64-v8a/${l}`, elf(16384)]));
|
||||
assert.deepEqual(checkApk(apk).problems, []);
|
||||
});
|
||||
|
||||
test('rejects other ABIs, missing libraries and 4 KB alignment', () => {
|
||||
const libs = REQUIRED.filter((l) => l !== 'libexpo-modules-core.so').map((l) => [
|
||||
`lib/arm64-v8a/${l}`,
|
||||
elf(l === 'librnskia.so' ? 4096 : 16384),
|
||||
]);
|
||||
const { problems } = checkApk(zip([...libs, ['lib/x86_64/libjsi.so', elf(16384)]]));
|
||||
assert.equal(problems.length, 3);
|
||||
assert.match(problems.join('\n'), /lib\/x86_64/);
|
||||
assert.match(problems.join('\n'), /libexpo-modules-core\.so/);
|
||||
assert.match(problems.join('\n'), /librnskia\.so.*4096/);
|
||||
});
|
||||
@@ -137,6 +137,13 @@ const (
|
||||
UiPrefsMobilePlayerWave UiPrefsMobilePlayer = "wave"
|
||||
)
|
||||
|
||||
// Defines values for UiPrefsSearchPosition.
|
||||
const (
|
||||
Center UiPrefsSearchPosition = "center"
|
||||
Left UiPrefsSearchPosition = "left"
|
||||
Right UiPrefsSearchPosition = "right"
|
||||
)
|
||||
|
||||
// Defines values for UiPrefsTheme.
|
||||
const (
|
||||
Dark UiPrefsTheme = "dark"
|
||||
@@ -910,6 +917,9 @@ type UiPrefs struct {
|
||||
CrossfadeS *int `json:"crossfade_s,omitempty"`
|
||||
MobilePlayer *UiPrefsMobilePlayer `json:"mobile_player,omitempty"`
|
||||
Normalize *bool `json:"normalize,omitempty"`
|
||||
|
||||
// SearchPosition Где в топбаре веба поиск (по умолчанию center)
|
||||
SearchPosition *UiPrefsSearchPosition `json:"search_position,omitempty"`
|
||||
Theme *UiPrefsTheme `json:"theme,omitempty"`
|
||||
WaveVariant *UiPrefsWaveVariant `json:"wave_variant,omitempty"`
|
||||
WebPlayer *UiPrefsWebPlayer `json:"web_player,omitempty"`
|
||||
@@ -918,6 +928,9 @@ type UiPrefs struct {
|
||||
// UiPrefsMobilePlayer defines model for UiPrefs.MobilePlayer.
|
||||
type UiPrefsMobilePlayer string
|
||||
|
||||
// UiPrefsSearchPosition Где в топбаре веба поиск (по умолчанию center)
|
||||
type UiPrefsSearchPosition string
|
||||
|
||||
// UiPrefsTheme defines model for UiPrefs.Theme.
|
||||
type UiPrefsTheme string
|
||||
|
||||
@@ -9210,250 +9223,251 @@ func (sh *strictHandler) GetReadyz(w http.ResponseWriter, r *http.Request) {
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"H4sIAAAAAAAC/+x9/3PcxpXnv4Ka3asisyOSsi1nQ9XWlSzbsW+tmBGV811FuhlwpkliNQOMAQwlRqUq",
|
||||
"Uowt+6iIsS+7m9qN7XhzW3dV+WVEccQRv1b5L2j8C/lLrvq9bqAb6AYwJIayt+4XW8PBNLpfv379vn7e",
|
||||
"g1rL6/Y8l7hhUJt/UOvZvt0lIfHh0/W+H3g++1ebBC3f6YWO59bma/QrOqSn0QY9ofvRBh1Ej+lxtE1f",
|
||||
"WvQg2oo2ok16Em1YdET3raZL7oeNFgzUtOBHQ7oXbdO9aCv6nA7pSyvajB6xUegxHUWfRtu1es1hb/m4",
|
||||
"T/z1Wr3m2l1Sm6/hGLV6LWitkq7NZhWu99g3Qeg77krt4cN67R03dML199vsWxikZ4eryRhOu1av+eTj",
|
||||
"vuOTdm0+9PtEHm/Z87t2WJuv9fvwZHb8D5yuE8aDp2bYgS/lAdtk2e53wtr8lbl6rWvfd7r9bm3+tTn2",
|
||||
"yXHx0+X4PY4bkhXiw4sWvb7fIpNbyC96Hc9uL4Z22A/edToh0W3zt9EjOogeRVvRZrRtRY/pELZv36L7",
|
||||
"dEBPox347mmtXiP3ex2vTWrzy3YnIPoNDOBlCn2ckHSB0/7aJ8u1+dpfzSbsOIuPBbPyVGsP48XYvm+v",
|
||||
"s89BuN5hf2CLZp9/ERB/UoR7yH4c9Dw3IDDvBd9b6pAu+2fLc0PiAnPYvV7HadmMjLM9fOJv/iFgNH0g",
|
||||
"vStvzWJceGNqV76OPqMj+owe0IE1dfPd69ZP3rjy42nYVf5zNvq1dtdxGSngWPtej/ihg5Nu+cQOSbth",
|
||||
"h8qS23ZILoVOl2TXXa+1naDXsdcbSMYHNbff6dhLjO5IwswPnHYJetZrTtBY6nitu6QtHeglz+sQ22Xf",
|
||||
"d+wgbHS8FcfNm27hbDpey+4Qjcyo17r9IGy0Vm13hTRaPmkTN3TsTqCfjvxwzw6Ce55vmLjv4fvydvkm",
|
||||
"e+ZhvdYPiC8Imz2qCbf+Etk3fjy1Lfyl8WoV6hrmbl5/XeaT9EbciWnsLf0DaYVsFTHHLdgrJMt18Vkv",
|
||||
"degT9tWceOlOKcGLaRLC69VBtMvpLPW72WXYfugEYeH04ambZJmN1PLWiN9oeR3PVwmQ4cX0QvGXfb9T",
|
||||
"6si1+z7InIYyenyrlD6ToRMazkro26275TfxFntct651YuftnHwRZrgfZ8fHkEmUInRdbJVKmHgRxj1n",
|
||||
"u5aVmRe0h+feoosgrZF0i/1u1/bXf1CnpppD0Wh5fbz8s8fugrldnk/RTn3Ad+Vcolre+cx2aKWvdlqu",
|
||||
"3VkPnIArelkWYt//iviNNeKXE4eeS/Qbsmw7HUXhkL77uE/6pu/8vuuywbVfhl6vQXxfay99Swf0iA6i",
|
||||
"HaZED5jBAx/oiaTKRZtoG9GRRY/pMNqie3RAd9kT0SfRZrRj/WXjdxY9pSd0L9pkP6H77L91K3ocPaIn",
|
||||
"bOgR2FCPoifFOlFqX/iykzVy+sXEqqsbIK9Xv5tt33PaN0mH2IFGG2h791ym1otjmlXLHLcR9Hs9zw9x",
|
||||
"O1Ik/ZIZI9EmHSG9RvQFHVr0hD6LdsA6OY624SM9pid0F6nCqFira/bO9UISNLq69/wfoC0f5YQ+pyfW",
|
||||
"1A3bv8sWgCYubNsh+ycdTOtER7Bqv3blTe0qA+dXRBE/jhu++YZ2jmvEDxy0Ich9u9sDm2du5s2Zy7p3",
|
||||
"8qcbLbDKHhTJGjF46ocSZfhc49XU1S1Mb5iWJ+JLIHWymQDJE6AlRbRBhS6U0Dq5yxVqeWolJGt8f2VF",
|
||||
"6rmWYJyhdhb9thNea4Wef+ZpnNUgMU7nHTfUqgWtMMPSbLAZND10U7PFwuxO58Pl2vwvCy6nhBgP76RN",
|
||||
"aSYiQaoyOQJSecjENDvWh3RkcRF8GH1Bj4WDi4nfw+gJ3Qd5MICfHGrk7cP6mczskvvTs9fZyQMytNsO",
|
||||
"W47dWZBIiyLfcAUkexPa/goJG/q3Fl6w/Nf497HNMLhSYGPqgg/UIeXpJUtW6Grkt0pM0IRxX5kN2g9X",
|
||||
"b3l3iavTh1otEgSNkH2tlXrkfs/xSdBwXK1rb4Oe0AOLvoCL65iOLBzwErvv6AEd0mPQLTbpkB5EW/SY",
|
||||
"7oFrVqMVkWWfBKvJTFKv+jd+ZA7YPbpHD6Mdq9nqOMTFfZ63bNQVmlq1mw0asxhxmUn+y9pbxPaJTDJV",
|
||||
"dBXt7A2S2RGFmsprFULy8XV79ZbnhUHo273riRPlJvm4T3RXnkvu6fxH0kVA7jXKS2Hl6bo6um6u18Hd",
|
||||
"s8AfMc6y1fd9tk2FM815QDPT/KkBZ9xKbfg9sgQaKDCKdt+vg1T4RUB843LSPsyuff8D4q6Eq7X5N9/Q",
|
||||
"DDkZF560T/ACLRFQxOndtyHp9jzf9tcVsqcO3TdwiAd0P9pm9xQdRo/AhmDWAzMTLIi47NfOeIIk95xm",
|
||||
"eWzU7CR1C31njbjhW3bYWs2uk6yJqFQpcb3QsddhOLAe7Pvv44+uzM0VmKT8PfnTu0kCCOTopHAvNBmM",
|
||||
"7T4GAojBIecT9iatffMtU0Giz5jUpEcWNxk3om06tKZu9+fmXifW63NMnh7TIX05Hessm2A9glDfpUP4",
|
||||
"HVNdjiwIsg1xvFqh8yFel7IIacY6cr3rkE77HWEDpx1obb1yvsx+VHxs8LE6jqN7+XvE7oSrJu9BEP9d",
|
||||
"iBTvrkaOpF7Kf6V9nROEnr/OuOzMajaTRmMqiGCClPS76jSu5JVirJzFVaFFyXR6VWrUe14Qvu34emdX",
|
||||
"2xnXvwgRxUKG5XFHGF43qQ+cJSYfDccl9iRpzkuHNEoymE86DcNs67UAQszlhsocRpyDPIj0tnrN7BiS",
|
||||
"l10FfylkfFUMxidhdF12lvqmmIzN3Z6FN67qHn0oHL6GYWGHYBdyHjB81XWCwHFXGjmP4LaX3yVMZ8C5",
|
||||
"m0RBElzKvu+evVaoin1kr5EbJPSdVpC9zjit6mIv4tcJSqSXrZIwWbG0Y3xaWobwVhzXrFcn1k/RoiR1",
|
||||
"GDIB1pwWiRXYTFbOABJsRvSIDqMN67s/X1/1vS6xZq2PHLft3Qu+O6xb3/15wblPOtbffndYq8s68GVJ",
|
||||
"U5JdDTm6/5m0Xin2LBNCR8Yb5PudvfA9TytwGj2fLBcn2DgL8NgkMxHiuZwvD0HHJB+6S57tt3lgRhd3",
|
||||
"VOXURAK76Rwd+owe0hP6god2IP6D0QP6DP0h0WfiDwNwj7A/o/Mx2kQ3IwZzwMG4U8Yf9+rc5PIvx4wb",
|
||||
"p6m6Qlyf5G1YRdPXzLzM9JIhsqcz9Yb433Xp+uHLy+fj66ue0yImbm44bZU+hTsuW8OlKF54KyQjvl5k",
|
||||
"XkuTzl3+gh2uLthhSHxXoxMGDeIy5jeJRbJC7mdnPlek4OHv6vL4hrmxeekNiB5+OYanQlppwe5kbQp8",
|
||||
"Vc4kF3yy5pB759Wr+TAmZa3vdu2wtap3fBi06OQ3xdM36k6TpHa9FvAo1HlSd8tvWOyx0txKbshsDhTp",
|
||||
"hcdRPJ72k4N+ynVeOUUkILbfWgXx3OkQEXxZRVO9xpMgtG7WZd/rFuSXqVfhL37x/ttrP7boSfTIogcQ",
|
||||
"Jx/S4+gRHWA+wwE9jJ5Gjy06onsQfjtlj/JnjukJeLBGTB0vknJeC/zV42mG3vJyx1HyRCSpwp0lpuX2",
|
||||
"vMDJzbfDy6VsglFq70CbCkLbD7nbpkFcsLjvOj3YQnIXlOl+APoWCfqwwo5zF/Qtl/+j7QTxn8S/dRvL",
|
||||
"WKURkACC/2fxCSSPSAtXd8V0CJbs1t3ryMImX1pW9baXSCdHT3tQ0RKNE2bGLDGe3PIR6jQBHt7RxJK5",
|
||||
"4YeTLlQECxkTz/dYOkRaUsIQDcdt472r8233iB02utzvG7tdl5cZV7golzpaXgxW+8vLHcOhzDtUhZTp",
|
||||
"99pFxmPhGGtep6+ooG6/u6SR/dIhkDdEUF8lYSzDa8nyVRrGL5a5QVnRnSJufd/t9cNclh2LUVNsWexK",
|
||||
"UNkyvkbn6tWwaG7QJ8Ox+a//XnJvwnmxQnK5rltIFRyp5SZJKTS7rIvlkx2uNiCgE5hTWMwWeDIfrl4l",
|
||||
"m5rxiJ1wX1i0CQk7pzylcgiWd/QZHXBDHZId4nwgyIcQoVLzzij8kuNp9+PgYWHU5gYJbWCiu06vZ7J2",
|
||||
"QnvlXITLGEGx314laDINdc/4DOKF5fn7pQopfUAwtWV/oANIio0zrg7YPsipsiORReJc/lu3zvZKdXs2",
|
||||
"7X64OuO4a3bHacuuJG2CSZuEttPRR9CjnWgToqnHTGsVrwV+ec7YyZpi38Z/PxUxdzowJYo91SaIJn56",
|
||||
"Y6nXCDRoUJHZqMfRdvQJfwkUUfKKvA2mMNMBs2jL2EZSwFYb5/LtblCUZJbZ8STUqtGIuW4WW1c1e8nr",
|
||||
"h/NLHdu9WysZjs0JAt8kdisk7VsiSnp+1/E5Aq5K/ZQ52CrPuYqImEKDc0fE6rXQC+3OGGY+Pl8cNIN5",
|
||||
"ivRPfr+mjBbd9Sp+ZlBmfGnUQiqx57LSkH9hmHPbGOZrrRIewDIJZvV4N727TZG30Vy2nU7TmkJJxlP5",
|
||||
"0USGhLw4gW5XyJ8h5OZFG5DcvmlIPU/Jkz/SId2PtsD9DKW9Fi/j3oWRQMwwCfaC7tETIVVwfCZdE2M8",
|
||||
"59BL+RXs/Su+3Sbt0qkWdUFFPfUh09DoGxonE5EXKFy12NrpMyZLh7wAYxB9ET2ykjxIRvSW5911SDkL",
|
||||
"8SaP0QhK2O0upA4yZdK3MeM1lUaY7Nhiy3YXfG/FJ4Euktxum3KNyqtf+WFh1wlWz2khLXt91zDL5X6n",
|
||||
"Y4iBYfjVEJL21kzr7vleiwRB+Zod6Z3gXhn3QvAa/JX6F3KDrITATEptgCrKdNSdECRV3i4vvc45I3m9",
|
||||
"oFlC2Hjj89Q1xn7G8yU2L6MpwclhQosDBjyx6C6TTlb0azqgL+lhtF23mFbE1CVVnkFhDaS1MeEzovtM",
|
||||
"i6PHcc79MNkDOdCSnTi4NDFNLzcFo4Katro2rli6sjEbSPR9SKprIGJClsL/nCh3cAPsRRvRFuigLyGR",
|
||||
"E+rBDumA7jGJVbfoMNqEa4VpiBBRjD4Bc4ZR+yjaAgMneszNIFRij0HxPgQh/6TMKT+THqHXcj8FHfuA",
|
||||
"ccgJfQa4IM95RRssZCDbb3tcIX+JJ6Bsnk1etow59aR0Hok2eFhJufQYqSycxFmWKtbGFom/Rvz33WVP",
|
||||
"c3h6TkNbframrT1bEpnwDTlaqhUau2jj7SJ7WrC7R7yMkcPCMHHB/s+Y+vPoC86tqJgMo43oMyYq4liC",
|
||||
"CC9YEG9/QYeg4ySGGQqnVBFltKURMljRxlPOG+l6uozVCnOmRzyYj7Yr/9F1r02EvnGJm6qYHACMHO3U",
|
||||
"wcrlCz1hy4MJMk6PNqBCg6dwJyrfMNqAygS+E5fn5n7yE21lI4+WJ3vWc3r9S91+4LS0tYqigq+BqRuB",
|
||||
"8mN2Z7HXgnJcPlNC4h1TFWe0o6yNDqypRdL9r8SflpdZm5u5PDNXaCfy2H5S1CgzsG6NOXutZWf9AQrE",
|
||||
"IivK9lLN1TTlQFk9inbi0wNmfzkdhhd2aNPOh9Embkgdy1sV1nzJdgmcEHTAFGPJ66A9QqmEtcryruwg",
|
||||
"bPSDsTQ3XbhKnp6ajaZDPxEvTOiXwwdVVNYLljp7UT3mXZrKFoJGH7CVdJfyNyCmhEwDMTri0dkN/LBv",
|
||||
"0ZMYE4qXrQ8ssByfgXQ+jD1nUz97dxEl8jEzIEF7iStSBsyYhS9O6FEs5cVwwGFwGzyZ1rLYBMssYdeD",
|
||||
"ll0B9lDsHNbU6eyBWnPK9R8R9o5zv56wz9YH779189rN/95478PFW3Vmtm+BMX6CNx+WejwB653p4Ogj",
|
||||
"KKXFmdKp3OWgQe4zQVnq5LLHPVhWYBwuAB2j1HCM6uVjqIrRrA2gwi6ye9FfszuNruP2Q51Lhv6W7iIj",
|
||||
"Ah1BRwY9YYSijykMx1KgIOWbYYwNYHiIilYcNkjcJmWzp5NfNbokCLi/sESt7kqj5zue74TrhXqovbIg",
|
||||
"HpV8tsUzFBfXPd8JSSMk3V6Hx8hTVP6/SdwFWfkRnncwBaNPYrMRnextrxXMckk1023/1Y+n1VANVwf3",
|
||||
"2N6MDXyhpDGi5JdYVTkGKpMrBztFYBO/1TOCN0OsuoSTp25zSh6lbig4MOYrwOAt1dwDGgw2RYAZJUhh",
|
||||
"/FeVKOeUIFqJoT3hcXz0SpkT+YoPikTEK8XpizLfmve+ElUEFYnzaiIL+lLPYnXkW3QLYWQNVQ60kXj+",
|
||||
"GNdRfvbu4qXoE4EmCiWUnzP9w78Hde3RY7xkE5VjoFcqpGRTdSKAb4mCh93U4u0AL2Pp3hyXXY54EScX",
|
||||
"cztC/TkG7Qlc69EWPWWm43TdYuwpAf6kX7TJAWkG2tn/wA+sSvE5E7UhlF90V9cqPuOVXm1X03pctEWf",
|
||||
"oc8jejJjAcwumsPoT4AwDHAtPUDIEvhV843XXrMg2g0odzNidg0eA2/edqNNq4nh3Bmf2IHnNmcsUPGT",
|
||||
"0A/3vaHHRYr28Bs2RlaStNKBCH0D4q9gfu7UwG0bMl3+NFuMbjWBkpfEXGch7NOcue2qRUkGIWgQL4uZ",
|
||||
"KFSPuG10fne9vouOcfR+Q5QxnfItxWHSFWtnLfKtxogwqumVK8oXo5HmaGGl9Z8ClecWCUJj2X6/7XhJ",
|
||||
"gWPmsjmQ1foBAAGN6ImilkLeyUvujT7hkVv1OMUCH63hkYrEwM7P5bm5uWmtjJJImU1avqtX1FA4jWMW",
|
||||
"4C9wvBQR/oTgRxgPQP/7PgRHQfYm6EhcGjdnwLEoTnUQNtndl4V+SV31Vy2MdDPhDUr9tPk0mAptINKc",
|
||||
"cIm8tznckUq3dpdjlV4vD0Kf2N2f9+0OvzTi6G4/9Gr1muc7K44LiQ+rzsoqzKjtQNp9x7unHVK+WqQB",
|
||||
"Q3slaCw7PmTq87Qr9kE7hIDZWJCqBsvAheQfx5LoHYY0G1sg5xZG2HhArNJomr1mO5x7Mjz9j6BlPbHS",
|
||||
"Che7W/nZtqY0WlxKCYMTX09+glfhEYfbGOpVyrYTtBquVwYItASU7zKxw74v6F1G9MNmvSt+lgVDo78V",
|
||||
"Yo6HKPZBcDHFdQrcfpv0kJEC5ZnAO8RbnifADYS/MPoUcRl3sYwx2gZ/HlOANkAWHnNZiIoCfQ6S8wg8",
|
||||
"zSLDJHMxacrUCgMPpWESkpyhcsRMsof0dyiTFYbSUOHxg6QdegzCj2lQ0Wa0TQ/x5gB+iq8da+rya1b0",
|
||||
"ePqq7HdCqyJrPgzL+ECK4WzLMWoeYq0KupyKWialgMnBkF4tn2KFnNJeSWfAKJvelU6JKqOWet2cBYr8",
|
||||
"aWYIEn9lvdSjHa/fdkkQNDp9rLku+EWKeGxG8fvSoxlX+H470GmmQYWZ85lNzplOFa6GcmFws6chyaM2",
|
||||
"30xZWEkA+kxgqrMPmL9iDFxOrJ9FhhWc1HIvPiMEdVwwqJAnOcPirMdnmcNU48w4ZXR7JCAHsjvUXXKI",
|
||||
"UsCthHq8IFi226QRKEUQb9YLqjm63pLTIQ2o5/NlXQvK07NAHpLdxY5Oh6P0ajLxV0lXUSPbtn8XqvBW",
|
||||
"VsFEWQ+Y7WgsuFuzfcfG5cZ5k/4SDPBx34B0d48saVayBIR3go7tGrIts5sAqWI3SGnAvEyIcCuGsubZ",
|
||||
"GmDnC0jVZzwdnbtrRvQIcAyKYPdyQDXGRrQwL3sspMCLWXhRL5Ty2B/6ZTODC8DsOLyg5lZk35YtWI2t",
|
||||
"ZxOyBobTDfWbOdB3/yIqPh7F5RSMsCIChEVKy/1Opx7/rR8Qv/Fx3wvt1Beh5zU6tr9Ckj/FeHbSz90k",
|
||||
"J4Svu4wOdZ5arrAflG5RgNNs5CB/jedtSXYmM3YyMWmLpKUWY2Sk1RrBUoJh7uTzphk0yet2+c1QBPIw",
|
||||
"Jm8W+8GzDvPXrlwpwFvLJDlq4vocUzra4jmzcXADhMvnYGgeYya+SBEYZkCb5iYEOZ/DNMJTpyDC6zY2",
|
||||
"pVh2HZd/vFzANkW88q7T0aW19MNVrxC8FEU/OA+QOyXWKjyLY4nIJSdstEkPGaJYS1tyQp9HFYof5vsh",
|
||||
"s1zh5Ftem7TKPXkWlC0hWBsdsobF+UI7iZsGdElot+3QxgT3FeL3fMcNa3U2oTv1Mj2OxDu85ca5BHDK",
|
||||
"xVJMcPGG6tLYOBxKA7VrHXoGYLpxJzPIByW/hw7hYvzuz/QZ+AogSyudf3Vi0QOmpUC7RVBbdqOt6ClI",
|
||||
"F0gFl+Cnoi0AhRublvFCBNbPGVeSeNSSVYyEvzx/FTrUrKdnWovg0NLOIJRIWLmrcweJERuk7YQm5U74",
|
||||
"jxvGSE/PCwJnqUMa8RkwYSG1iLNG2o2ldR5QLdFdBAu7z1n3g+g5jfIyjF0gY02zXHQq3TGSB5Iw8lk2",
|
||||
"Xeqcpem8d0GORvBNcu0bXM6WGm22plJZT6fc78fMjxE9ZMekbqUqCOmupSx/eozODrkIseNouHkdAXgU",
|
||||
"P9qAUxwHiyVZsCvgr6ETKR1ytR3DulVAfpSITUpqrKoz1IXSIQUu1bOcvaoVxs8c2Fhmifs6UQzUIybr",
|
||||
"F5kmd1igL123aSmkk9qaK8l05Wave62E0vBS9mykT6gqjlKJbtJ+JjyWryhWUVUtqZ2vCmVYumfMns2C",
|
||||
"3Anuu0u8mcXPl390TEdoKdsrdn8Wvv2i3aH53tBxnKGwr4bUOFkdKauElBPgpTyEMDOfQHaOuS60wNrO",
|
||||
"8Z2PZ4gXhkWrabVmcrnnWMRjm8Lnsn6THdGnt5zPNadXNDM5MqIeE9pOKJkeR+jAwIxsrOJNqfccr4Vp",
|
||||
"QHWp6g966UHHw0faGHoCpBNnX2j6VEAhJHf7aT3ost2YXhYCIByw2SktM+QK1ENriu5FW/QZW7JAcABt",
|
||||
"7BMo6wOwGA0Rpse3R3JYLgbfUWGd0ls3tseuiPl+3vd0NxB0vx9Lme/a99HvOM6PesSHVkeNovcV3wJQ",
|
||||
"zzXOu+G9Y/4qRVx51soMDCvLvjRDN/NO3cyHUm2TlhOkAFjsXs/31kjs/dWDgKKz+HxB5hxfIET5A23B",
|
||||
"6DeqccOzggHAK5t3ugugoqPokWRllHCf6ptdQKqCoFgxzfWCOatzGjDUSmJHcnAtrduhpBNKn0yos4Eg",
|
||||
"z84MHXHGcD031kkYOu5KoONSgIo6pzH6qmUNBq3GlZG6Jr0p8WCQGqn11jVkLN6MWCVNHcJ/hSwvOFfH",
|
||||
"ZqyzHcgSNXg2oi0oBz2Eyg12bp+qCDxPhdcPcEToc/ZH2f+xG22nygFm06Vg9GR6JgMRoeUmQ1dQ+owO",
|
||||
"6X52CQPTEs7mOi1kzDy8aTOTmhaVpRwk85XYT3l5VXN+Xv5GGlNbz/FjMXimTkB2KXFYHf4BCwgaHFW9",
|
||||
"Lm5ItrlOt+f5IT6H/5b+3IgbZ8uKKS/JUKOr95xwte3b99y42aQ+80MErr4PbX0/stfIW6ZqrtBZ40nN",
|
||||
"xVhRdqezxA13DVrZASJ40mNMPcfAqTbrUVRLDXiRF+jrz/jRHbDTikAFnyO0EKTsH4I9ckBHdYudCPoM",
|
||||
"jBIEI8rGE+hIn9nb9bxyuMxjYU9PCD5GmkM92Sm+CLkrktgX0+YbAbvH2v6StHtomMS7hLSXtEnoXj9s",
|
||||
"eWpuFqNZh6AblYOo33V6DWL7nfUEOT0Pe3AMQHcz9K6YmYmwooeVDmVmCCbpCJH6pOzqfTqwfhx3g8zc",
|
||||
"ekvrgGSs98UPLeydf6SODshRu3KX/SPIXB7G1m6cnTO1dtmata59sGjNWvzAvaAjLIeJPmcDTvPUqDj/",
|
||||
"O8ZUZZo7HsPjsqilQCS2nLjbV9aAgE1twP4WhKOkBF7nbhK8yqg8KClE5Y91eW5O9g/smu9C+QVBSNxG",
|
||||
"uOp7/ZXV8hODIkoDvh0/z2XAq/gw+nlkSSYTRHpPPeEmIwfLm5O1cc67NROjM6yqYaxXNe5Cis7JMPXz",
|
||||
"0NxE3Z9ppe6yJAlLn6JYfBa3odFO5cNeqIU8clpa4/33iFc0ghNzDGLmhh0S37E71uJ6d8kD7LIM4e+S",
|
||||
"dRXCKgFOzBe67Id1nMyd3BUExlvMGaPJoUQRjURiN101Y2Va9cYzFW8xrXYR2olcyI0NHUraZ1ZV091Q",
|
||||
"RBAl1cqmEFaWQ3porQEtV/tOSG7xgPv1VaJTLbpOgGHSMbZTHvYG/7166i5rWhZoCzO/hBh4XFuOjbwT",
|
||||
"XZepA0kh9zF2nGN2bAKuKQAUmYH+l8//3frJ3H9S3NvYRxrutgTO7kgG/lWykvtuuxH6Ts9wQdldksYi",
|
||||
"kGMtJdGlwfkkoKWld8ovqMtbc6fU7hqdo2cH5Yh/WTiDmBHO0UshaaOgqTM7VLEFwbKBbX0e/QYgBE6j",
|
||||
"bZ1/g2OKnkLNLy/3i8FbB/TgqtXknQKaSTqKwkEnUg+FY8RGwuK/F0L1q42DIJiTRvNHhUuldNq4Wnug",
|
||||
"r/lz28QATSkSc05TPSKirQzwkCYFZ+ygjpQHEc8q3tg8j6vCTIv9lRUS6O9jmZnPzLwg0lt93wnXF5lY",
|
||||
"46YFsX3iX+vj3uCnd4V0/y8f3YI6fayS4d8mu7Eahr3aQzaww3FHszsBtB8BqBbb3ZvvLN6yri28by04",
|
||||
"vb51ox84rRmL/h4xNNhTTLtAxNtHAJaxLWFUKPCSnt1zLrW8Nlkh7vRtF6HPk/ZkgDzl9YjLHmPzxYlN",
|
||||
"z1gQ+nzO+AoaiSRBB8CpsnvOTLeNOBY8jlxL5sqmLiFTCkBLJurxVbX52uszczOv89JvIDEbc3bt8izg",
|
||||
"iM/a/bYD8mqFwP/YPkNQ/P12bb72gROE1+AJ3r+BhMQPjIGE5JHZD5yuw7iq8MHrmKHy8A6EIHueGyAn",
|
||||
"vDY3F3cTwmRqu4eOL8dzZ/+Bx3PwRiys8GZLgLQdYI90kBaRYYH0n9KBRV9EW9EGF1QDxJ3k/SX0r4nn",
|
||||
"nURQAPsU8Z7na/SfkgEtsHlfYs4p3JpTsBHTdRm8OtrktvInCCYL+YMC+v0OG13dxQ52DJ8VzaRnfRIi",
|
||||
"9HPPCzT7epN9fS3pPH0uyqdR88FFWwqxXDyqkQ6abVJhNLhjPnoswRdBJrCCIlnF7n3JMXOSsgrpFexm",
|
||||
"iDGZMrcj3mRbCvYFR/aQC9+5c4OjYXCGkPadb2/ezico/MaDLPe2D37YBzrT9r/UuRZNf07oQRV88b8l",
|
||||
"MPqy266g2p9po1e9ILzUdgr2+j0vCN92dNts0k5MSKGwNMb+O1mcUPyK3XBPIBhRm6/FAOEQGKiJhMx4",
|
||||
"V9P6wiS5hBMBqsh1DKKipVYiK1JDpusSBgrwahJBe8YIacm/Qy0DilcvaVTqM7FOku6u5ZufEiEiFkXq",
|
||||
"8aQPsEiq157ex9EX0SNIzgCKjGIUtmi7iq36lsODnEQ7wnv8DMTDIYAzPeIwe0jpuhW3WylJdGyKO+uT",
|
||||
"uJuc6SqGBxZFD90UyV8zd8iArBWmTTDTC0BSoh2Bob3Fy/0G1TA1VhFuJp4AAXs/gj1Jem4kM4q2NUzK",
|
||||
"OwVryYVJArMSaKOJS1M5HhNk09SbdHz6FbNtucn2sioxkhk0DY6dJa2g2x1sZKjNtPgT74byRJgabM/i",
|
||||
"cD1CxYwwfLMPB20HTBfe1SPV4kPcb9EOVIpxIzZmBTbAc4Dm3scFvKB7PEFT1GSk9Ci4fHahUusEE62Y",
|
||||
"/TtTq6c4gFfcZ5kAfC9vee31Ce0/JrA8VNVYnh71H44Ffx+793hax/F5eDJ73iGvIl+JWeTPTJC6EqSt",
|
||||
"3uZAZKUTepBxbFVB5H8f62Kvx1dIqvMbqAlNGeBVgoDXFEcqSojqybhqNd3lgI+Vgdi3gtDz7RVyyV4h",
|
||||
"bjhz282sYKigd6Js4JVke+ivU9sJpcFoYxTblP48r1RtcW3gJO7vg7IM9SnUZXchYXqIrhOVtxCwgmMQ",
|
||||
"T0ZwyDDZpQTG5YpfrWVn/WYhECOT3dVpwMVIxuMosFxYzD5w2g+R/SHxQpN+kFjiSa8wxTqLPrHoM4BG",
|
||||
"G2VaIUa/4V0jsvOtS9ddkk3IG5ooGn72vnobZiuxm7Lxb+SAZQ6r2pSvs3DHGcjNMTepblTPTCudeyUs",
|
||||
"PgkxXUSZ8TwrXFa0wWViUt1+n4q2AXTiHlfLBxZ0RIkrR2IrMg/cPLvfJlXrAiTlK1GtLpqN0ipVlWJx",
|
||||
"lkfQcg2nmNb45ARJy99hVKwkXHMmoCE7DJsB7TBGjbaqoHf6JRDiHiYu9wmc3n6Y23d7YPEU1FMI7+1w",
|
||||
"ZFMd7HrSOx1R1y0JdB08Bk0mw9Mw7JkTvNDX7Xr1xziz4Rd3jIt47VtJH437gKqR2EocSv9MB+rx/uws",
|
||||
"/FfulM/2eAb5/INz8avWJbWAY18k3/BXivyJV8NBfBJaJvojpMVwP23sssVGHBKOeyUaNLeoRf/9I6a9",
|
||||
"RhsiNeeZaGCZ8JMoLdH1TTg7r4leABXwlyaUBw3/RnQPumMz5fvXWHZ3VQTInqNyw7tS0F2r+dN3blla",
|
||||
"l3ZzxqJ/QttSjIgide4nFn9yBoD+eaqfRk4utmx3snqO1Ar5IefvrKe3slclbRkMoVSp4SJ3FlclA0WQ",
|
||||
"KG4ugy87OyOGIqWqakF3iwQXZq1I/SP08qWol35VokUMOZKa1ypY9KNz6aG6RiyTkSKp3jgAAQDu7Z2k",
|
||||
"K8aBdUVKrB/obPtBPZP9+Awi8lLZIHd7p7LOoh16hFlpUn5kVrRAZqCSXDUhEWPOR7zg+1ST9qrj+d9j",
|
||||
"dOGCOF1Wx3hloqZD0bhh+TzeDzCHbjLc/2U6A1LL2VIW5S4EfYbMjoDUE8yEOIRgEMBTiPbo0DdVUi4U",
|
||||
"bYcjgg3pLlDuc7kFza5C45nbLv0qmwcxxS756JHalFG4LjIHLM6LRD/GLnTa5s3OphO7SVzyca+qvhtD",
|
||||
"/jd1LmCe3pg9lRdxIqTcSm1aAtf/kqbevKeIRNzqPLVySFc9InG7MUhc1YMlvuSI1dEWPQDX/Ma4l0dR",
|
||||
"vJeZdb+I21uOd47k8tx3nU4IOeIPtIkqCexavJ+FJXn6kQDQrYqBtPhnmUwaCWPhh5XDlQJUK5nBVXFu",
|
||||
"39dqBNrccnqc2Cb/ahagb+KgxXis+44bOuF6gVO4EPOR521wr/+23DGM21nxMtEp8ghUnZHcKBt+JSEo",
|
||||
"pHGXlE7eZicybvdE4/SvMD6PSH4aFuZJglWpNALC9okeFksPkXFO5pWSic/BwuY8ZKTg+13eFfkV75SS",
|
||||
"TpxckMPq7lwOHST1c0j64CedsRTYh7NtoeQiNFCffZ9crpM7mTdfpXdPg6SUb41g1ivTQvcQxjoJJlcS",
|
||||
"l/g65qoYa0ZGnhop9UbaPLq8zQ+IkhuscYZvYEoHMPmBwJ/h8esRPY62Zqzmx00LpQfnSuV7S0j9IZZl",
|
||||
"cffjFqZsYsUX3CM8YUgTFAe1DqaaUep0utDHiuqT3/rEpE9Bw5N6SaYRnU9+YIUujAUYWcurVFp0HoB9",
|
||||
"qEjcZQcvSKoVVS5G0/cbOgDuBeyW5xgUh8MkspTklCZLYFvsqyar9aMfYZoh4kQO6P6PfnQ1VmlO+QBg",
|
||||
"C+8CEOMepC7x/Mdoi76A9Hjwz8cxH2bz/gGf5Y6Fk2hD7nb6BZudnHbSZOe1qaBWgrsb8GNEheUJI5o5",
|
||||
"k4lt+ITEd/KCsYT35Yon0IYlmnL4s+BST5TEpoqyxeWGtWZMq8JaLRDQmlQmXdJQvLNlU4aiL6pZ7p+U",
|
||||
"1CAjJFv2ZpIO73imekD8Amvnj+LIS17eVA5XfIigrlL0+BcnyMK76hDSj5UL8Ig+50of75GDN/J+Yvzg",
|
||||
"iw7QUjIShJ3/b4QKx/FznuPEDsDLuAuvea7MFfOuseJmn5lYp6gGQGHYIwkSdj/2zhykSsbiaBcw1wx0",
|
||||
"toad0Dq/kpZlE1P62meRGhO4B7Uy42v6jO/2YZwQ8NK0p08mkkwNTdzqlrjG6hq+LFf5mUgTNgsSXpLb",
|
||||
"Mp/9COov3q94ej84hZmKdyS5JwEsLb6WNTcu+g/UO/cqh2TEK3tTYEMZISD3wQIeRhvRZ4lTIqtd3mSk",
|
||||
"QD2IU2OCzJbtmq1jui9zCVbNFZXqFCiPn89KnaV+N7mTTOlj1zhayuSOLbxAR73fJl2FAExEiuhV4wjM",
|
||||
"f0FCvZYd2h1v5Qw3nOQOkUnf683abtv3nPZs27vnMrtu9gGv6Dfvxtv80Wv402u9uwY7ihdgchNIIAWk",
|
||||
"ZbFsFfEUo9p87X/cvt3+m9u3Z6T/TV3yW/yf0//5rzW+7PGsmzW3PcNXP9OzW3ehtMBvrTprROWa2IW+",
|
||||
"5Lg2GHXpF2d45trC35+dMTgyRW3+l3dkNrm28Pcqit0UPYh+AxDz3PYQ9QsDta5iWBeRdjQNXvCW5UyF",
|
||||
"uWm7KyTuer6HxVEAOzlSNKteL3VqJdbp2CJJwmT2JwYRdAo/snhn9gGE/8RcfuqExLZ4HRaC1gu1B22h",
|
||||
"kZVesVRuIbDsLFRsknIvkVkfbYlIfRLcGkVPb7sY5kOzClp6SXCcFj3Aec1Y9Kv4NXEt0lB8LfQkOLm8",
|
||||
"ozw7y2zTuIL0hmX3ejPY86UwRsgkHpL3A6TuJCUfvugm6RA7ICZLR9IrR/SltNDKGV19W7QDnn/B99GO",
|
||||
"xed7SbObO9YUFEZI23BCdwVniXDLvnI+8vkcm70XX0+ig8rkdgnfoPceZhvGVaM6agee4IUkUZsrBvnw",
|
||||
"MPD8NXxw0rrBItLFmOor3eLMStN18duxpoR441VkmNtwzOvMo03h5VF1gOmKtYzq53dBPBF6vUsJlnAB",
|
||||
"X9zyercEBnAJNy9gcCs+2pjil+fqSYv2K3P5OOYTdbLCgowsKJegwUUrAH0Ooy3IrxgKTGjuY+RgeBV5",
|
||||
"W08hh3AHEDswoivmY2Q3Xn3BbQecJmoEPMeN22jRJzne4omyXz9cne14K44rx7LS9hUd0mfWVJP3tGEc",
|
||||
"MW/dI0vNaTHrrbj0ySfLPglWLyXKjUV3rZbn3XWI1ew5vX7DD5u33anme2HY+9DtrF+1FtlNSa5ai3aX",
|
||||
"LDoh+bvF0Hda4VVrwQ5X/06eanO6Lu7HuCIVyT60mvzVjdC7S8A7w1QariRyszAOtMgVXZKnYMBh8zDh",
|
||||
"WTHEBTBSxkskG514AaNUkf3bAo4k7pBw222+MXfZYmua4WUojZZP2sQNHbsDWdff8FywbUQUUMD/T4Ed",
|
||||
"t5HIILfkijWeu/UTHD70vEbXdtcbzPjo9sJAq5F9ADwwGZ8VjP2q3FX9cPUWYwh9uvaf4NwOo8/EHvIN",
|
||||
"q17r+5Jzgj7il7DhU1lf64dpRA9+Xj2shtIHnz/A70s5t78VvqG0Cwj8u/XMybU40FKFGChfRtvyKYm9",
|
||||
"w5gyc8Bz6F8qfqyyRLpkdzpFhLrW6ZSj1ZdndacNq6qDSkjFW8byywPLAhA/guPfDaJPionERaZZ9t/U",
|
||||
"iPNnsKov5ErtDJdMgb//2XQsZ8FswSttYE1xGQ4YjZCTv4FpmPFbbruIScCdyXFr6fieTUjO5e/R1TiE",
|
||||
"eCplgrDfD0Vi7V70P6MdJflMjkWg/bsbbUZPYZPpUfSE/VM203d1spMTiYsZvTaGFJIyEJFSxQBe1Ytj",
|
||||
"Pt3cipkLE8Bf8XOzI2TgIEXw6iXxH2HTBapTVmFBGFrjwWl5a3KU0eAUguy+Qya9rOhTbq1je8I4WN2E",
|
||||
"kRp9v9NUeruzAxJjjYxA0wVRHJeiwTk/oIN5SLPnHgLspGJJOWtHVnOtifGvBFD6mA6mr952ZQRVJS2T",
|
||||
"x/6agfMrwrQQkboFNBMzd1cc977scPhvl661WqRz6SZpOz5phQafz3UPsfbPqrkask/Wcp2uJVNYAmel",
|
||||
"mmF+RfRW1utzc3WBkv7mG3X28fJrc3N3zmRiOV17hczeI0u9cztz6b+A/AUQXsZF1R+4rxUmTbP6R2Rp",
|
||||
"QW/iSIeOrLEX59go36gyXzRX34SWJXFhMsKsbUOS1o41Bc8/wq4qTntagOPIOb1Jdu4e3BEv6F60rakF",
|
||||
"94LwHZzjZIQ2DP7Wq8jCTd6ck+EH3R4Fqlk1BneqPRRsGqKGG6xpa4oJMuvK3JzMTr2OvY7tkWR+wn5D",
|
||||
"JnfnjYkWrNwgRhKeRL8G9IJK3Jv/FmvPo7wYfEKqLsmFuOM49Vaz7zR6PlkOmhaiTSnnJNpUYapEFsAR",
|
||||
"HV1NlRwp6dWnfHR8hOehmMPQmAdxg0w0zeIGeUVWq4FFTNkVVXOOMadiB3Tlg7oWsm4EgGbMNvg14nAr",
|
||||
"ihQwl3ICZ5c8LwxC3+5dklwfOTL+3+R8JMwmbHb7QdhordruCsk4UOSkiT3wEvEIGNNlEKt+kACjnWAm",
|
||||
"UmJxPqcnM7fdpIsHxxjOmICpdCYOybYbbQt9SQQuCzRdbTEdCd8SVLouEWkyXK971ffVb4P50Fx4KJJk",
|
||||
"PwYLAbu7XoL01UG58hweUf2/SQ8y8J2yEzKV2pMkrsX53VynKThKvBdeLkTR2+KZHzQ++U1it0LShkhB",
|
||||
"2VTsKrb3d2BEyX0oC3sKtLxOh7RgTun9WnWC0MPKH1Oa6vUOsf33+HOl/FNfS565k6pK+EYS4AT/gBU2",
|
||||
"TyGaJuvTHPVZ0ZmxoQfiLsTNPlLpFwqdzOB3CS1+wOzLF1G+iEAieUXos9Ie7hjVafrynBxeKI4++P+y",
|
||||
"6Kxb+K8VSSHPXfJsH5opM62rr9moRXuNfJg8Nhm9I3nB9VXPEbiBRcrGG4YaLBmm6aQqOPu49JNXBSed",
|
||||
"BU7oMY/4QfYttCKYisOLcLcrmgDH8BFbdsqB3hWJeM9ey97xSvqxHq241fd94oYN8WgTgTh2mD4SB5SP",
|
||||
"6xY9wABlEj5/DOqRok4ng0zFcUzebFYNjPLksySENZ3ozYWq8lVV6YaSwEw0g41fjUJ9Hdam5C5PoLRH",
|
||||
"ecn3U4NWrKPYP8zMyotSmL9VbUx9SrVG1xUenUtByDulma6YBf7kYjhhDBL1RSakRKUlxtVMy5dTOJ1Q",
|
||||
"VzeMPo++4K4QyZQA1+lmtFNRRotSS8PRxVNtO+I5MaEmEl54wu0+XGgjsHaVdgMG91tdf8Ms9DX7NAE0",
|
||||
"RPkdY6CHXzSTKH4zCF5m92Uyl1rh/nfsILyEQEz3HDco42Wd9ZmK5HhuMIuJbYXVeWD2gEZ1k/+0bCJD",
|
||||
"hd5nPhgjCvZWPQBOf2o2Ws6D36DVu0iYJcIkYsE4/BgH4sLULq7lxikEe7IFLqVoltN15fbrxszKG+uL",
|
||||
"Sff0yaEW4jvKtcZI9Kcci6yS/Nm4jFKMnyhuU7oEk+n8a1oQvPDE3yRr3l0Sk75UtY3Tzg3WFsFC3akg",
|
||||
"N6oqTE8xaCyExUuf8mKXLOmHOZRXbTptdkJTEE7qa3IA6Iy8BDtj0swbw0eW3LeIOxM+4ZWIh5ZoRqza",
|
||||
"QUyNwWRLzMYGKDzFz4GVLY8RIw1A7QwZBSnTdEIHVnqLtv4QNNcRXNuPIPl8Qnf21+l9sbCaNc761OUh",
|
||||
"8+LsFzC9DTY9XS82USOVIBIOcu1R3m7MyGLsxP2d3ZFa5+BGbiqtRjF9RMZmRczCBCIGwUHpiJl+cX/0",
|
||||
"UzpADzpm8dARZrQwtj2ALNhHAtePSbRTmILwp6MfJtoG0HeX3A8bLfAU6bEMReu4kjgqZokk4aq8pu1M",
|
||||
"rh+Ud8XXpJPUbEhbFG338ROvJhDt99k/eD3BHe0rf0jONtwLzEEIygH9VtTNUIfrgk6bQUEDPt6pUEIr",
|
||||
"1aeL/aPUtklYfOCWjbY07eEAY/QldAM8pif1FCaLlP3Ik7lijF2L7kFp4XN2l4je8QegUu0x297iH9h5",
|
||||
"w3ZQG9H2bXfquz+vrC61Q/e7Q+svn35pffdnXpsGlYnfHU4bgWBQHslYeCJmLa0RAMhbnu+TVkjaDTgB",
|
||||
"OaeRQ3xexKF8tewMIKL8vtyvCrz3y2gbxOceeOAwNST2QjKFU+ZulN179MR6XX+1DJlS+rqa0nVCd+vW",
|
||||
"lUQ/P6G7hafEXyP+JdFaXn9E2MT3VZzF+D4YcERdbKj2a4gw8Zth3sJMZMaionJEBkXGHBO5AvNpqm1b",
|
||||
"/bbLoX6POEarjGistKIfWEnrtVQxsihW4hkUoFP/Bm4rQIvXQIVHO9MGpWcR6PU+I9dEGTR+i95I2QXf",
|
||||
"UYwmfJIqy64+j7DwlbEWI29Kiv/Wg5B0U/wX+sTuVpHRiyNhSm9ioKrpvHmgP6A5Ynqvdfk1K3o8fdVS",
|
||||
"U3WPsBxYzdpF06H5MRQ9nS1jd97iujfXq0B5p/sa5Ou4Fpzfilyl22Ni/MNePxC926CUfaCV40AlcG9U",
|
||||
"nwzcP5dhaBiU3O+VG9ZxwzffqGlSeiebdfxxafA9pP3P+3aHnbBSV1y/7XizPzp/nvFvAa58dB7nkEky",
|
||||
"xEPrTp0BFqLYfck9lksiH1JfRPRT7qkL3uLo1JPw08Eb3m8HF+2zLlmQKwoxRZOxJG6ByQWDq0mTxy+k",
|
||||
"nM/YK/B5dTVS0qQQXV2EWKMty2lDZRK7vOXyIqUeSILBLkxLT/m0TXEoIeomu015W1QhYSdYjSwB1htS",
|
||||
"QH+H1+Rpkm4OfUeVjgdQ/hr2A7yGp8J+YF2emZuZq6uIdu+9c+1ta9ZauHbr+nsQEUff1AgV3jffsOgf",
|
||||
"6BfTCIyCN3ai/+1CqswQlNC/bPzuttvkU5/5uE/6pLHc73Sa1qwV/7kfEL/xcd8LbfyuzkyxLfTC4ITF",
|
||||
"kzEifTOu+IlfLFoO76LjJge2EgabpECS3vCK4CulGXAkS2OcWyokEA15BxNBroRX8ZLeffAKDuk+11BV",
|
||||
"WMF4T0+sqRiqtW6VgyPWo+CbWvfKjM5looQZ9ELpdxptiSSVDTqKvqBHydHiYMbsOE0B2OIQOy4ec0Xw",
|
||||
"ABj0wx5xry28P53N2P/ICVfbvn1PQqsvkdH4CL0KKKrrMtmUnvYvhDekqpa+/K3CJ89O3BdxGakMyoNW",
|
||||
"B7oyRe9/Ba002cFKheRs13FJQTCr4uYe/9FbYOh2txKs5j8g5Ixm/GjnHMe/55OkB5gJVjLlO0yLJAQa",
|
||||
"m7EW37t26bUrb1rYu5t3qpAtT9HqQrQ4RqSzqbbXCsSEZrrtv3pDc/IX+DwvAg5fvOuVAuInk/geQOIr",
|
||||
"PS/jTmCDRAGB8NuecDw/B57YRxfVmVkTVJ08lRgJ9XN4bOL7ga/RbcO/CkwVDNsBBXgeCS9Dw9umio34",
|
||||
"F663pZvt5PXGGXsD7tlrZNaD9eVmX39kr5EP+WOTbM4lvaZE6LSqmDpu4Qg9ailIQ1ErGjftF15D5/Lf",
|
||||
"urz9Ao8lFiXlArHlxBK9h2AxtH0g+KSaE9prBN6hx3K4XOmLpBrkvHQJCeg/TiN9fL7y8mSLv4LBUDn7",
|
||||
"7s/seo2eYgDqkB5HW98dlt+1wuyUd9x2vHWF+uo/v4okEbHu7eyq65W0xtJV3k6Yna+zge5ffHfNXAZP",
|
||||
"YZVUxs6pROjkDmJXwKxGfvEYsMVuiuhRbLPFlm7SngzuFOi4KoJmYx6NWZdtwyQaVP2M3J+0UPwZZ6FX",
|
||||
"xzLfVMsnkK7NO0SqfAh196JLECBtS4mrTMHjeFHbSq1sAmGoZ4tVYnfC1V/lKRLv8UcmWTMHr0BzNAc6",
|
||||
"4VPe0xxd/fkBg3+CaEAcxD2VB1CzOuR4oU/s9nouNW7iE5OtOWuv59CCl6vv88DgZhKt5q5Ngf0s/O1X",
|
||||
"5l6/sMl9DcUGcQhRkxGmnfgQGXiYnX7eHv8v0LZPsDGI2OkT+gwrnkRAKJG5IuVm25oqSb5pLaOoc3pQ",
|
||||
"WyK2T/xr/XCVTZEJREx4QEHa9zu1+dosCEo+1oM4OohjPqw/kHupyp+7RPkW+g9IfxDNYaU/CZ+99Cee",
|
||||
"kyH9JY6HyT9Mcqulv4KwkKfQ69Ue3nn4/wIAAP//8doNsq86AQA=",
|
||||
"H4sIAAAAAAAC/+y9f3Pcxpkn/lZQs/utIrMjkrItZ0PV1rdk2Y59a8WMqJzvKtLNgDNNEqsZYAxgKDEq",
|
||||
"VZFibNlHRYy92d3UbmzHm9u6q8o/I4ojjvizyq+g8RbySq76ebqBbqAbwJAYyt66f2xxBtPofvrpp5+f",
|
||||
"n+dBreV1e55L3DCozT+o9Wzf7pKQ+PDX9b4feD77V5sELd/phY7n1uZr9Cs6pKfRBj2h+9EGHUSP6XG0",
|
||||
"TV9a9CDaijaiTXoSbVh0RPetpkvuh40WDNS04EdDuhdt071oK/qcDulLK9qMHrFR6DEdRZ9G27V6zWFv",
|
||||
"+bhP/PVavebaXVKbr+EYtXotaK2Srs1mFa732DdB6DvuSu3hw3rtHTd0wvX32+xbGKRnh6vJGE67Vq/5",
|
||||
"5OO+45N2bT70+0Qeb9nzu3ZYm6/1+/BkdvwPnK4TxoOnZtiBL+UB22TZ7nfC2vyVuXqta993uv1ubf61",
|
||||
"OfaX4+Jfl+P3OG5IVogPL1r0+n6LTG4hv+h1PLu9GNphP3jX6YREt83fRo/oIHoUbUWb0bYVPaZD2L59",
|
||||
"i+7TAT2NduC7p7V6jdzvdbw2qc0v252A6DcwgJcp9HFC0gVO+2ufLNfma381m7DjLD4WzMpTrT2MF2P7",
|
||||
"vr3O/g7C9Q77gC2a/f2LgPiTItxD9uOg57kBgXkv+N5Sh3TZP1ueGxIXmMPu9TpOy2ZknO3hE3/zDwGj",
|
||||
"6QPpXXlrFuPCG1O78nX0GR3RZ/SADqypm+9et37yxpUfT8Ou8p+z0a+1u47LSAHH2vd6xA8dnHTLJ3ZI",
|
||||
"2g07VJbctkNyKXS6JLvueq3tBL2Ovd5AMj6ouf1Ox15idEcSZn7gtEvQs15zgsZSx2vdJW3pQC95XofY",
|
||||
"Lvu+Ywdho+OtOG7edAtn0/FadodoZEa91u0HYaO1arsrpNHySZu4oWN3Av105Id7dhDc83zDxH0P35e3",
|
||||
"yzfZMw/rtX5AfEHY7FFNuPWXyL7x46lt4S+NV6tQ1zB38/rrMp+kN+JOTGNv6R9IK2SriDluwV4hWa6L",
|
||||
"z3qpQ5+wr+bES3dKCV5MkxBerw6iXU5nqd/NLsP2QycIC6cPT90ky2yklrdG/EbL63i+SoAML6YXir/s",
|
||||
"+51SR67d90HmNJTR41ul9JkMndBwVkLfbt0tv4m32OO6da0TO2/n5Isww/04Oz6GTKIUoetiq1TCxIsw",
|
||||
"7jnbtazMvKA9PPcWXQRpjaRb7He7tr/+gzo11RyKRsvr4+WfPXYXzO3yfIp26gO+K+cS1fLOZ7ZDK321",
|
||||
"03LtznrgBFzRy7IQ+/5XxG+sEb+cOPRcot+QZdvpKAqH9N3HfdI3fef3XZcNrv0y9HoN4vtae+lbOqBH",
|
||||
"dBDtMCV6wAwe+IOeSKpctIm2ER1Z9JgOoy26Rwd0lz0RfRJtRjvWXzZ+Z9FTekL3ok32E7rP/lu3osfR",
|
||||
"I3rChh6BDfUoelKsE6X2hS87WSOnX0ysuroB8nr1u9n2Pad9k3SIHWi0gbZ3z2VqvTimWbXMcRtBv9fz",
|
||||
"/BC3I0XSL5kxEm3SEdJrRF/QoUVP6LNoB6yT42gb/qTH9ITuIlUYFWt1zd65XkiCRlf3nv8NtOWjnNDn",
|
||||
"9MSaumH7d9kC0MSFbTtk/6SDaZ3oCFbt1668qV1l4PyKKOLHccM339DOcY34gYM2BLlvd3tg88zNvDlz",
|
||||
"WfdO/nSjBVbZgyJZIwZP/VCiDJ9rvJq6uoXpDdPyRHwJpE42EyB5ArSkiDao0IUSWid3uUItT62EZI3v",
|
||||
"r6xIPdcSjDPUzqLfdsJrrdDzzzyNsxokxum844ZataAVZliaDTaDpoduarZYmN3pfLhcm/9lweWUEOPh",
|
||||
"nbQpzUQkSFUmR0AqD5mYZsf6kI4sLoIPoy/osXBwMfF7GD2h+yAPBvCTQ428fVg/k5ldcn969jo7eUCG",
|
||||
"dtthy7E7CxJpUeQbroBkb0LbXyFhQ//WwguW/xo/H9sMgysFNqYu+EAdUp5esmSFrkZ+q8QETRj3ldmg",
|
||||
"/XD1lneXuDp9qNUiQdAI2ddaqUfu9xyfBA3H1br2NugJPbDoC7i4junIwgEvsfuOHtAhPQbdYpMO6UG0",
|
||||
"RY/pHrhmNVoRWfZJsJrMJPWqf+dH5oDdo3v0MNqxmq2OQ1zc53nLRl2hqVW72aAxixGXmeS/rL1FbJ/I",
|
||||
"JFNFV9HO3iCZHVGoqbxWISQfX7dXb3leGIS+3bueOFFuko/7RHflueSezn8kXQTkXqO8FFaerquj6+Z6",
|
||||
"Hdw9C/wR4yxbfd9n21Q405wHNDPNnxpwxq3Uht8jS6CBAqNo9/06SIVfBMQ3Liftw+za9z8g7kq4Wpt/",
|
||||
"8w3NkJNx4Un7BC/QEgFFnN59G5Juz/Ntf10he+rQfQOHeED3o212T9Fh9AhsCGY9MDPBgojLfu2MJ0hy",
|
||||
"z2mWx0bNTlK30HfWiBu+ZYet1ew6yZqISpUS1wsdex2GA+vBvv8+/ujK3FyBScrfkz+9mySAQI5OCvdC",
|
||||
"k8HY7mMggBgccj5hb9LaN98yFST6jElNemRxk3Ej2qZDa+p2f27udWK9Psfk6TEd0pfTsc6yCdYjCPVd",
|
||||
"OoTfMdXlyIIg2xDHqxU6H+J1KYuQZqwj17sO6bTfETZw2oHW1ivny+xHxccGH6vjOLqXv0fsTrhq8h4E",
|
||||
"8edCpHh3NXIk9VL+K+3rnCD0/HXGZWdWs5k0GlNBBBOkpN9Vp3ElrxRj5SyuCi1KptOrUqPe84LwbcfX",
|
||||
"O7vazrj+RYgoFjIsjzvC8LpJfeAsMfloOC6xJ0lzXjqkUZLBfNJpGGZbrwUQYi43VOYw4hzkQaS31Wtm",
|
||||
"x5C87Cr4SyHjq2IwPgmj67Kz1DfFZGzu9iy8cVX36EPh8DUMCzsEu5DzgOGrrhMEjrvSyHkEt738LmE6",
|
||||
"A87dJAqS4FL2fffstUJV7CN7jdwgoe+0gux1xmlVF3sRv05QIr1slYTJiqUd49PSMoS34rhmvTqxfooW",
|
||||
"JanDkAmw5rRIrMBmsnIGkGAzokd0GG1Y3/35+qrvdYk1a33kuG3vXvDdYd367s8Lzn3Ssf72u8NaXdaB",
|
||||
"L0uakuxqyNH9z6T1SrFnmRA6Mt4g3+/she95WoHT6PlkuTjBxlmAxyaZiRDP5Xx5CDom+dBd8my/zQMz",
|
||||
"urijKqcmEthN5+jQZ/SQntAXPLQD8R+MHtBn6A+JPhMfDMA9wj5G52O0iW5GDOaAg3GnjD/u1bnJ5V+O",
|
||||
"GTdOU3WFuD7J27CKpq+ZeZnpJUNkT2fqDfG/69L1w5eXz8fXVz2nRUzc3HDaKn0Kd1y2hktRvPBWSEZ8",
|
||||
"vci8liadu/wFO1xdsMOQ+K5GJwwaxGXMbxKLZIXcz858rkjBw9/V5fENc2Pz0hsQPfxyDE+FtNKC3cna",
|
||||
"FPiqnEku+GTNIffOq1fzYUzKWt/t2mFrVe/4MGjRyW+Kp2/UnSZJ7Xot4FGo86Tult+w2GOluZXckNkc",
|
||||
"KNILj6N4PO0nB/2U67xyikhAbL+1CuK50yEi+LKKpnqNJ0Fo3azLvtctyC9Tr8Jf/OL9t9d+bNGT6JFF",
|
||||
"DyBOPqTH0SM6wHyGA3oYPY0eW3RE9yD8dsoe5c8c0xPwYI2YOl4k5bwW+KvH0wy95eWOo+SJSFKFO0tM",
|
||||
"y+15gZObb4eXS9kEo9TegTYVhLYfcrdNg7hgcd91erCF5C4o0/0A9C0S9GGFHecu6Fsu/0fbCeKPxL91",
|
||||
"G8tYpRGQAIL/Z/EJJI9IC1d3xXQIluzW3evIwiZfWlb1tpdIJ0dPe1DREo0TZsYsMZ7c8hHqNAEe3tHE",
|
||||
"krnhh5MuVAQLGRPP91g6RFpSwhANx23jvavzbfeIHTa63O8bu12XlxlXuCiXOlpeDFb7y8sdw6HMO1SF",
|
||||
"lOn32kXGY+EYa16nr6igbr+7pJH90iGQN0RQXyVhLMNryfJVGsYvlrlBWdGdIm593+31w1yWHYtRU2xZ",
|
||||
"7EpQ2TK+Rufq1bBobtAnw7H5r/9ecm/CebFCcrmuW0gVHKnlJkkpNLusi+WTHa42IKATmFNYzBZ4Mh+u",
|
||||
"XiWbmvGInXBfWLQJCTunPKVyCJZ39BkdcEMdkh3ifCDIhxChUvPOKPyS42n34+BhYdTmBgltYKK7Tq9n",
|
||||
"snZCe+VchMsYQbHfXiVoMg11z/gM4oXl+fulCil9QDC1ZX+gA0iKjTOuDtg+yKmyI5FF4lz+W7fO9kp1",
|
||||
"ezbtfrg647hrdsdpy64kbYJJm4S209FH0KOdaBOiqcdMaxWvBX55ztjJmmLfxp+fipg7HZgSxZ5qE0QT",
|
||||
"P72x1GsEGjSoyGzU42g7+oS/BIooeUXeBlOY6YBZtGVsIylgq41z+XY3KEoyy+x4EmrVaMRcN4utq5q9",
|
||||
"5PXD+aWO7d6tlQzH5gSBbxK7FZL2LRElPb/r+BwBV6V+yhxsledcRURMocG5I2L1WuiFdmcMMx+fLw6a",
|
||||
"wTxF+ie/X1NGi+56FT8zKDO+NGohldhzWWnIvzDMuW0M87VWCQ9gmQSzeryb3t2myNtoLttOp2lNoSTj",
|
||||
"qfxoIkNCXpxAtyvkzxBy86INSG7fNKSep+TJH+mQ7kdb4H6G0l6Ll3HvwkggZpgEe0H36ImQKjg+k66J",
|
||||
"MZ5z6KX8Cvb+Fd9uk3bpVIu6oKKe+pBpaPQNjZOJyAsUrlps7fQZk6VDXoAxiL6IHllJHiQjesvz7jqk",
|
||||
"nIV4k8doBCXsdhdSB5ky6duY8ZpKI0x2bLFluwu+t+KTQBdJbrdNuUbl1a/8sLDrBKvntJCWvb5rmOVy",
|
||||
"v9MxxMAw/GoISXtrpnX3fK9FgqB8zY70TnCvjHsheA3+Sv0LuUFWQmAmpTZAFWU66k4Ikipvl5de55yR",
|
||||
"vF7QLCFsvPF56hpjP+P5EpuX0ZTg5DChxQEDnlh0l0knK/o1HdCX9DDarltMK2LqkirPoLAG0tqY8BnR",
|
||||
"fabF0eM4536Y7IEcaMlOHFyamKaXm4JRQU1bXRtXLF3ZmA0k+j4k1TUQMSFL4X9JlDu4AfaijWgLdNCX",
|
||||
"kMgJ9WCHdED3mMSqW3QYbcK1wjREiChGn4A5w6h9FG2BgRM95mYQKrHHoHgfgpB/UuaUn0mP0Gu5n4KO",
|
||||
"fcA45IQ+A1yQ57yiDRYykO23Pa6Qv8QTUDbPJi9bxpx6UjqPRBs8rKRceoxUFk7iLEsVa2OLxF8j/vvu",
|
||||
"sqc5PD2noS0/W9PWni2JTPiGHC3VCo1dtPF2kT0t2N0jXsbIYWGYuGD/Z0z9efQF51ZUTIbRRvQZExVx",
|
||||
"LEGEFyyIt7+gQ9BxEsMMhVOqiDLa0ggZrGjjKeeNdD1dxmqFOdMjHsxH25X/6LrXJkLfuMRNVUwOAEaO",
|
||||
"dupg5fKFnrDlwQQZp0cbUKHBU7gTlW8YbUBlAt+Jy3NzP/mJtrKRR8uTPes5vf6lbj9wWtpaRVHB18DU",
|
||||
"jUD5Mbuz2GtBOS6fKSHxjqmKM9pR1kYH1tQi6f5X4k/Ly6zNzVyemSu0E3lsPylqlBlYt8acvdays/4A",
|
||||
"BWKRFWV7qeZqmnKgrB5FO/HpAbO/nA7DCzu0aefDaBM3pI7lrQprvmS7BE4IOmCKseR10B6hVMJaZXlX",
|
||||
"dhA2+sFYmpsuXCVPT81G06GfiBcm9Mvhgyoq6wVLnb2oHvMuTWULQaMP2Eq6S/kbEFNCpoEYHfHo7Ab+",
|
||||
"sW/RkxgTipetDyywHJ+BdD6MPWdTP3t3ESXyMTMgQXuJK1IGzJiFL07oUSzlxXDAYXAbPJnWstgEyyxh",
|
||||
"14OWXQH2UOwc1tTp7IFac8r1HxH2jnO/nrC/rQ/ef+vmtZv/vfHeh4u36sxs3wJj/ARvPiz1eALWO9PB",
|
||||
"0UdQSoszpVO5y0GD3GeCstTJZY97sKzAOFwAOkap4RjVy8dQFaNZG0CFXWT3or9mdxpdx+2HOpcM/S3d",
|
||||
"RUYEOoKODHrCCEUfUxiOpUBByjfDGBvA8BAVrThskLhNymZPJ79qdEkQcH9hiVrdlUbPdzzfCdcL9VB7",
|
||||
"ZUE8Kvlsi2coLq57vhOSRki6vQ6Pkaeo/H+SuAuy8iM872AKRp/EZiM62dteK5jlkmqm2/6rH0+roRqu",
|
||||
"Du6xvRkb+EJJY0TJL7GqcgxUJlcOdorAJn6rZwRvhlh1CSdP3eaUPErdUHBgzFeAwVuquQc0GGyKADNK",
|
||||
"kML4rypRzilBtBJDe8Lj+OiVMifyFR8UiYhXitMXZb41730lqggqEufVRBb0pZ7F6si36BbCyBqqHGgj",
|
||||
"8fwxrqP87N3FS9EnAk0USig/Z/qHfw/q2qPHeMkmKsdAr1RIyabqRADfEgUPu6nF2wFextK9OS67HPEi",
|
||||
"Ti7mdoT6cwzaE7jWoy16ykzH6brF2FMC/Em/aJMD0gy0s/+BH1iV4nMmakMov+iurlV8xiu92q6m9bho",
|
||||
"iz5Dn0f0ZMYCmF00h9GfAGEY4Fp6gJAl8KvmG6+9ZkG0G1DuZsTsGjwG3rztRptWE8O5Mz6xA89tzlig",
|
||||
"4iehH+57Q4+LFO3hN2yMrCRppQMR+gbEX8H83KmB2zZkuvxpthjdagIlL4m5zkLYpzlz21WLkgxC0CBe",
|
||||
"FjNRqB5x2+j87np9Fx3j6P2GKGM65VuKw6Qr1s5a5FuNEWFU0ytXlC9GI83RwkrrPwUqzy0ShMay/X7b",
|
||||
"8ZICx8xlcyCr9QMAAhrRE0UthbyTl9wbfcIjt+pxigU+WsMjFYmBnZ/Lc3Nz01oZJZEym7R8V6+ooXAa",
|
||||
"xyzAX+B4KSL8CcGPMB6A/vd9CI6C7E3Qkbg0bs6AY1Gc6iBssrsvC/2SuuqvWhjpZsIblPpp82kwFdpA",
|
||||
"pDnhEnlvc7gjlW7tLscqvV4ehD6xuz/v2x1+acTR3X7o1eo1z3dWHBcSH1adlVWYUduBtPuOd087pHy1",
|
||||
"SAOG9krQWHZ8yNTnaVfsD+0QAmZjQaoaLAMXkn8cS6J3GNJsbIGcWxhh4wGxSqNp9prtcO7J8PQ/gZb1",
|
||||
"xEorXOxu5WfbmtJocSklDE58PfkJXoVHHG5jqFcp207QarheGSDQElC+y8QO+76gdxnRD5v1rvhZFgyN",
|
||||
"/laIOR6i2AfBxRTXKXD7bdJDRgqUZwLvEG95ngA3EP7C6FPEZdzFMsZoG/x5TAHaAFl4zGUhKgr0OUjO",
|
||||
"I/A0iwyTzMWkKVMrDDyUhklIcobKETPJHtLfoUxWGEpDhccPknboMQg/pkFFm9E2PcSbA/gpvnasqcuv",
|
||||
"WdHj6auy3wmtiqz5MCzjAymGsy3HqHmItSrocipqmZQCJgdDerV8ihVySnslnQGjbHpXOiWqjFrqdXMW",
|
||||
"KPKnmSFI/JX1Uo92vH7bJUHQ6PSx5rrgFynisRnF70uPZlzh++1Ap5kGFWbOZzY5ZzpVuBrKhcHNnoYk",
|
||||
"j9p8M2VhJQHoM4Gpzj5g/ooxcDmxfhYZVnBSy734jBDUccGgQp7kDIuzHp9lDlONM+OU0e2RgBzI7lB3",
|
||||
"ySFKAbcS6vGCYNluk0agFEG8WS+o5uh6S06HNKCez5d1LShPzwJ5SHYXOzodjtKrSSCDrKOGqKbQiPt/",
|
||||
"ZBaCRXcxVHBKn9EBE9087VBkirPL4ADvWaZYH4He/JjfkE+tFnFDHgoXE4dPmJwgy2xHfGdlVa8ihquk",
|
||||
"q2i6bdu/C4WC7Bf1WrAeMPPWWBO4ZvuOjTsSp3b6SzDAx30DGN89sqQh9hLwhhN0bNeQEJrlE8hmu0FK",
|
||||
"Y/plophbMdo2TygBV4RAfX3GM+a5R2lEjwBqoQgZMAf3Y2zQDfOyxwIzvJiFF7VrKQ9Pol82swkBb48j",
|
||||
"IGoubvZt2Zra2MA3gX9gxN9QYpqDzvevoijlUVzxwQgrglRYR7Xc73Tq8Wf9gPiNj/teaKe+CD2v0bH9",
|
||||
"FZJ8FEPuST93k7QVvu4yat55ys3CflC6iwJOs5EDTjaeQyjZmczYycSkLZKWWgzjkda8BEsJhrmTz5tm",
|
||||
"XCev2+WXVxEOxZi8Weyqz/r0X7typQASLpOHqUk94LDX0RZP643jLyBcPgdb+BiLBUQWwzCDKzU3IVT8",
|
||||
"HKYRzkQFtF63sSndt+u4/M/LBWxTxCvvOh1d5k0/XPUK8VVR9IN/A7lTYq3CsziWiFxywkab9JAhihXJ",
|
||||
"JSf0eeCj+GG+HzLLFU6+5bVJq9yTZwECE4K10SFriB8gtJO4r0GXhHbbDm3MwV8hfs933LBWZxO6Uy/T",
|
||||
"hkm8w1tunEsAp7xAxQQXb6gu044jtjTQANABfADsHPeDg3xQUpDoEC7G7/5Mn4E7AxLJ0iliJxY9YFoK",
|
||||
"dIQEtWU32oqegnSBbHUJISvaAty6sWkZL0TAEZ1xJYnTL1nFSLj081ehA/Z6eqa1CA4t7a9CiYTFxTqP",
|
||||
"lRixQdpOaFLuhIu7YQxG9bwgcJY6pBGfARNcU4s4a6TdWFrnMd8SDVCw9vycpUkI8NMoL8PYBTLWNMsF",
|
||||
"0NJNLXmsC4OzZTO6zlk9z9sr5GgE3yTXvsErbqkBcWsqlZh1yl2TzPwY0UN2TOpWqsiR7lrK8qfHaD6R",
|
||||
"C2I7joab17SAJxpEG3CK43i2JAt2BUI3NEulQ662Y+S5ClSSEuFTSY1VdYa6UDqk2Kp6lrNXtcL4mQMb",
|
||||
"yyxxXyeKgXrEZP0i04cPMQSk6zYthXRSW3Mlma7c7HWvlVAaXsqejfQJVcVRKhdP2s+Ex/IVxSoKvyW1",
|
||||
"81UBIUv3jNn5WpDewd2LicO1+Pnyj47pqy1le8Ue2sK3X7THNt9hO46/FvbVkL0nqyNllZByAryUhxBm",
|
||||
"5hNIIDKXrhZY2znu/fEM8cLIbTXd4ExRgRyLeGxT+FzWb7Ij+gyc87nm9IpmJo1HlIxCZwwlGeUIHRiY",
|
||||
"NI6Fxin1nkPKMA2oLhUmQrs/aMr4SBvmT7B+4gQRTSsNqNXkbj+9116yG9PLQoyGAzY7pauHXCR7aE3R",
|
||||
"vWiLPmNLFiAToI19ApWHgGejIcL0+PZIDsvF+EAq8lR668b22BUx38/7nu4Gggb9YynzXfs++h3H+VGP",
|
||||
"+NCNqVH0vuJbAErOxnk3vHfMX6WIK89amYFhZdmXZuhm3qmb+WivbdJyghRGjN3r+d4aib2/epxSdBaf",
|
||||
"Lw6e4wuERIRAG/H7RjVueOIyYIxlU2N3Afd0FD2SrIwS7lN9Pw7IphAUK6a5XjBndU4DzFtJeEuO/6V1",
|
||||
"O5R0QunzHXU2EKQCmtEtzphRwI11EoaOuxLouBTQrM5pjL5qWYNBq3FlpK6PcEo8GKRGar11DRmLNyNW",
|
||||
"SVOH8N8gEQ3O1bEZjm0HElkNng1NHF4BCXoqvH4AdUKfsw9l/8dutJ2qWJhNV6vRk+mZDIqFlpsMjUvp",
|
||||
"Mzqk+9klDExLOJvrtJAx8yCxzUxqWlSWcpBvWGI/5eVVzfl5KSZp2G89x4/F4JlSBtmlxJF/+B9Y49Dg",
|
||||
"wO91cUOyzXW6Pc8P8Tn8t/RxI+7tLSumvGpEja7ec8LVtm/fc+N+mPrMDxG4+j50Hv7IXiNvmQrOQmeN",
|
||||
"510Xw1nZnc4SN9w1gGoHCDJKjzE7HgOn2sRMUdA14HVooK8/40d3wE4rYil8juhHUFVwCPbIAR3VLXYi",
|
||||
"6DMwShAvKRtPoCN98nHX88pBR48Fjz0hhBtpDvVkp/gi5MZNYl9Mm2/EFB9r+0vS7qFhEu8S0l7S5sl7",
|
||||
"/bDlqblZjGYdgm5UjvN+1+k1iO131hNw9zx4xDEw583owGJmJsKKNls6IJwhmKQjBBOUEsD36cD6cdyw",
|
||||
"MnPrLa0D2LLeFz+0sL3/kTo6gFvtCggZ9skRJFcPY2s3zs6ZWrtszVrXPli0Zi1+4F7QEVbsRJ+zAad5",
|
||||
"alScoh7DvjLNHY/hcVlgVSASW07ckCxrQMCmNmB/C8JRUo6xczcJXmVUHpQUojjJujw3J/sHds13ofyC",
|
||||
"ICRuI1z1vf7KavmJQZ2nAYKPn+cy+Fp8GP08siSTCSK9p55wk5GD5c3J2jjn3ZqJ0RlW1TCW1Bp3IUXn",
|
||||
"ZJj6eWhuou7PtFJ3WZKEpU9RLD6LO+Vop/JhL9SiMjktrfH+e4RUGsGJOQYxc8MOie/YHWtxvbvkAbxa",
|
||||
"hvB3ybqKspVgO+YLXfbDOk7mTu4KAuMt5ozRh1GiiEYisZuumrEy3YTjmYq3mFa7CB1PLuTGhiYq7TOr",
|
||||
"qumGLSKIkuq2U4h8y1FHtNaAlqt9JyS3eMD9+irRqRZdJ8Aw6RjbKQ97g/9ePXWXNV0VtLWjX0IMPC5/",
|
||||
"x17jia7L1IGk1vwYm+IxOzbB/xQYj8xA/8vn/2H9ZO7/U9zb2Ooa7rYEce9IxiZWspL7brsR+k7PcEHZ",
|
||||
"XZKGS5BjLSUBsMH5JNCvpXfKL6jLW3On1O4anaNnxw2Jf1k4g5gRztHuIen0oCmFO1ThD8GygW19Hv0G",
|
||||
"UA5Oo22df4PDnp5CWTKvSIzxZQf04KrV5M0Mmkk6isJBJ1Kbh2OEb8L6xBdC9auNA3KYk0bzR4VLpXTa",
|
||||
"uKB8oC9LdNvEgJ4pEnNOU20soq0MNpImBWfsoI6UBxHPKt7YPI+rwkyL/ZUVEujvY5mZz8y8INJbfd8J",
|
||||
"1xeZWOOmBbF94l/r497gX+8K6f5fProFUAJYJcO/TXZjNQx7tYdsYIdDo2Z3Amg/Atwvtrs331m8ZV1b",
|
||||
"eN9acHp960Y/cFozFv09wnywp5h2gaC8jwDPY1uC0VAQMD2751xqeW2yQtzp2y6isycd1AAcy+sRlz3G",
|
||||
"5osTm56xIPT5nPEV9DpJgg4ApWX3nJluG6E2eBy5lsyVTV0CzxSYm0zU46tq87XXZ+ZmXufV6UBiNubs",
|
||||
"2uVZgDqftfttB+TVCoH/sX2GoPj77dp87QMnCK/BE7zFBAmJHxgDCckjsx84XYdxVeGD1zFD5eEdCEH2",
|
||||
"PDdATnhtbi5ueITJ1HYPHV+O587+A4/n4I1YWITOlgBpO8Ae6SAtgtcC6T+lA4u+iLaiDS6oBgiNyVtg",
|
||||
"6F8TzzuJoAA8K0JSz9foPycDWmDzvsScU7g1p2Ajpusyvna0yW3lTxDvFvIHBTr9HTa6uosdbGo+K/pd",
|
||||
"z/okRHTqnhdo9vUm+/pa0hz7XJRPA/uDi7YUqLp4VCMdNNukIn1wx3z0WEJYgkxgBeiyit37ksP6JGUV",
|
||||
"0ivYzRDDRmVuR7zJthR4Dg4+Itfmc+cGB+zgDCHtO9/evJ1PGgUYD7Lcfj/4YR9oeSnlz7XoS3RCD6rg",
|
||||
"i/8l4eWX3XYFeP9MG73qBeGltlOw1+95Qfi2o9tmk3ZiAjOFpTH238lCmeJX7IZ7AsGI2nwtxjCHwEBN",
|
||||
"JGTGu5rWFybJJZwIUOiuYxAV0LUSWZEaMl2XMFCwYZMI2jNGSEv+HWoZULx6SaNSn4l1knR3Ld/8lAgR",
|
||||
"sShSjyd9gEVSvfb0Po6+iB5BcgZQZBQDxUXbVWzVtxzB5CTaEd7jZyAeDgE/6hFHAkRK1624I0xJomO5",
|
||||
"+axP4oZ3pqsYHlgUbX5TJH/N3MQDslaYNsFML8BxiXYEzPcWL/cbVMPUWEW4mXgCBDI/FMNLbUGSGUXb",
|
||||
"GiblzYy15MIkgVkJV9LEpakcjwmyaepNOj79itm23GR7WZUYyQyaxu/OklbQ7Q72WtRmWvyJN2x5IkwN",
|
||||
"tmdxuB7RbEYYvtmHg7YDpgtvPJLqQiLut2gHKsW4ERuzAhvgOaCH7+MCXtA9nqApajJSehRcPrtQqXWC",
|
||||
"iVbM/p2p1VMcwCvus0wAvpe3vPb6hPYfE1geqmosT4/6T8eCv4/dezyt4/g8PJk975BXka/ELPJnJkhd",
|
||||
"CXVXb3Mg+NMJPcg4tqog8n+MdbHX4ysk1ZwO1ISmjEErodRriiMVJUT1ZFy1mu5ywMfKdAGwgtDz7RVy",
|
||||
"yV4hbjhz282sYKgAjKJs4JVke+ivUzsepfFyY6DdlP48r1RtcW3gJG5BhLIM9SnUZXchYXqIrhOVtxCw",
|
||||
"gsMkT0ZwyEjepQTG5YpfrWVn/WYhViST3dVpwMVgy+MosFxYzD5w2g+R/SHxQpN+kFjiSTszxTqLPrHo",
|
||||
"M0BvG2W6NUa/4Y0tsvOtS9ddkk3Ie64oGn72vnobZiuxm7Lxb+TgeQ6r2pSvs4jMGVTQMTepblTPTCud",
|
||||
"eyUsPgkxXUSZ8TwrXFa0wWViUt1+n4q2AbrjHlfLBxY0bYkrR2IrMg9/PbvfJlXrAiTlK1GtLpqN0ipV",
|
||||
"lWJxlkfQcg2nmNb45ARJy99hVKwk6HUmoCE7DPsV7TBGjbaqoHf6JRDiHiYu9wmc3n6Y2xp8YPEU1FMI",
|
||||
"7+1w8FUdMnzS3h2B4S0JFx48Bk0mw9NI8ZkTvNDX7Xr1xziz4Rd3jIt47VtJH41blaqR2EocSv9CB+rx",
|
||||
"/uws/FfulM/2eAb5/INz8avWJbWAY18k3/BXivyJV8NBfBJaJvojpMVwP23sssVeIRLUfCUaNLeoebM+",
|
||||
"aO/wKNoQqTnPRI/NhJ9EaYmutcPZeU20K6iAvzShPOhJOKJ70MCbKd+/xrK7qyJA9hyVG944g+5azZ++",
|
||||
"c8vSurSbMxb9E9qWYkQUqXM/sfiTM9CLgKf6aeTkYst2J6vnSN2aH3L+znp6K3tV0jnCEEqVekJyZ3FV",
|
||||
"MlAEieL+N/iyszNiKFKqqhZ0t0hwYdaK1OJCL1+K2v1XJVrEkCOpv64Clz86lx6q6xUzGSmSat8DEADg",
|
||||
"3t5JGnccWFekxPqBzrYf1DPZj88gIi+VDXK3dyrrLNqhR5iVJuVHZkULZAYqyVUTEjHmfMQLvk81aa86",
|
||||
"nv89RhcuiNNldYxXJmqaKI0bls/j/QBz6CbD/V+mMyC1nC1lUe5C0GfI7AhIPcFMiEMIBgE8hejgDq1d",
|
||||
"JeVC0XY4ItiQ7gLlPpe75OwqNJ657dKvsnkQU+ySjx6pfSOF6yJzwOK8SPRj7EIzcN6PbTqxm8QlH7fT",
|
||||
"6rtxV4KmzgXM0xuzp/IiToSUW6lNS+D6X9J3nLc9kYhbnadWDumqRyTuiAaJq3qwxJccsTraogfgmt8Y",
|
||||
"9/Ioivcys+4XcQfO8c6RXJ77rtMJIUf8gTZRJYFdi/ezsCRPPxIAulUxkBb/LJNJI2Es/LByuFKAaiUz",
|
||||
"uCrO7ftajUCbu2KPE9vkX80C9E0ctBiPdd9xQydcL3AKF2I+8rwN7vXflpuacTsrXiY6RR6BqjOSe3nD",
|
||||
"ryQEhTTuktJs3OxExu2eaJz+FcbnEclPw8I8SbAqlUZA2D7Rw2LpITLOybxSMvE5WNich4wUfL/LGze/",
|
||||
"4p1S0omTC3JY3Z3LoYOkfg5Jq/6keZcC+3C2LZRchAbqs++Ty3VyJ/Pmq/TuaZCU8q0RzHplWugewlgn",
|
||||
"weRK4hJfx1wVY83IyFMjpd5Im0eXt/kBUXKDNc7wDUzpACY/EPgzPH49osfR1ozV/LhpofTgXKl8bwmp",
|
||||
"P8SyLO5+3MKUTaz4gnuEJwxpguKg1sFUM0qdThf6WFF98lufmPQpaHhSL8k0ovPJD6zQhbEAI2t5lUqL",
|
||||
"zgOwDxWJu+zgBUm1osrFaPp+A32ZThC75TkGxeEwiSwlOaXJEtgW+6rJav3oR5hmiDiRA7r/ox9djVWa",
|
||||
"Uz4A2MK7AMQIvaFE/mO0RV9Aejz45+OYD7N5/4DPcsfCSbQhN2T9gs1OTjtpsvPaVFArwd0N+DGiwvKE",
|
||||
"Ec2cycQ2fELiO3nBWML7csUTaMMSTTn8WXCpJ0piU0XZ4nJPXTOmVWGtFghoTSqTLmko3tmyKUPRF9Us",
|
||||
"909KapARki17M0mHdzxTPSB+gbXzR3HkJS9vKocrPkRQV4kHcxCfIAvvqkNIP1YuwCP6nCt9vEcO3sj7",
|
||||
"ifGDLzpAS8lIEHb+vxEqHMfPeY4TOwAv4y685rkyV8y7xoqbfWZinaIaAIVhjyRI2P3YO3OQKhmLo13A",
|
||||
"XDPQfBt2Quv8SlqWTUzpa59FakzgHtTKjK/pM77bh3FCwEvTnj6ZSDI1NHGrW+Iaq2v4slzlZyJN2CxI",
|
||||
"eEnuHH32I6i/eL/i6f3gFGYq3pHkngSwtPha1ty46D9Q79yrHJIRr+xNgQ1lhIDcBwt4GG1EnyVOiax2",
|
||||
"eZORAvUgTo0JMlu2sbeO6b7MJVg1V1SqU6A8fj4rdZb63eROMqWPXeNoKZM7tvACHfV+m3QVAjARKaJX",
|
||||
"jSMw/wUJ9Vp2aHe8lTPccJI7RCZ9rzdru23fc9qzbe+ey+y62Qe8ot+8G2/zR6/hT6/17hrsKF6AyU0g",
|
||||
"gRSQlsWyVcRTjGrztf9x+3b7b27fnpH+N3XJb/F/Tv//f63xZY9n3ay57Rm++pme3boLpQV+a9VZIyrX",
|
||||
"xC70Jce1wahLvzjDM9cW/v7sjMGRKWrzv7wjs8m1hb9XUeym6EH0G4CY57aHqF8YqHUVw7qItKNp8IJ3",
|
||||
"VWcqzE3bXSFxY/Y9LI4C2MmRoln1eqlTK7FOxxZJEiazPzGIoJn5kcWbxw8g/Cfm8lMnJLbF67AQtF6o",
|
||||
"PWgLjaz0iqVyC4FlZ6Fik5R7icz6aEtE6pPg1ih6etvFMB+aVdDSS4LjtOgBzmvGol/Fr4lrkYbia6En",
|
||||
"wcnlTe/ZWWabxhWkNyy715vBni+FMUIm8ZC8HyB1Jyn58EU3SYfYATFZOpJeOaIvpYVWzujq26Id8PwL",
|
||||
"vo92LD7fS5rd3LGmoDBC2oYTuis4S4Rb9pXzkc/n2I+++HoSHVQmt0v4Br33MNswrhrVUTvwBC8kidpc",
|
||||
"MciHh4Hnr+GDk9YNFpEuxlRf6RZnVpqui9+ONSXEG68iw9yGY15nHm0KL4+qA0xXrGVUP78L4onQ611K",
|
||||
"sIQL+OKW17slMIBLuHkBg1vx0cYUvzxXT7rIX5nLxzGfqJMVFmRkQbkEDS5aAehzGG1BfsVQYEJzHyMH",
|
||||
"w6vI23oKOYQ7gNiBEV0xHyO78eoLbjvgNFEj4Dlu3EaLPsnxFk+U/frh6mzHW3FcOZaVtq/okD6zppq8",
|
||||
"pw3jiHnrHllqTotZb8WlTz5Z9kmweilRbiy6a7U8765DrGbP6fUbfti87U413wvD3oduZ/2qtchuSnLV",
|
||||
"WrS7ZNEJyd8thr7TCq9aC3a4+nfyVJvTdXE/xhWpSPah1eSvboTeXQLeGabScCWRm4VxoEWu6JI8BQMO",
|
||||
"m4cJz4ohLoCRMl4i2ejECxiliuzfFnAkcYeE227zjbnLFlvTDC9DabR80iZu6NgdyLr+hueCbSOigAL+",
|
||||
"fwrsuI1EBrklV6zx3K2f4PCh5zW6trveYMZHtxcGWo3sA+CByfisYOxX5a7qh6u3GEPo07X/BOd2GH0m",
|
||||
"9pBvWPVa35ecE/QRv4QNn8r6Wj9MI3rw8+phNZQ++PwBfl/Kuf2t8A2lXUDg361nTq7FgZYqxED5MtqW",
|
||||
"T0nsHcaUmQOeQ/9S8WOVJdIlu9MpItS1Tqccrb48qzttWFUdVEIq3jKWXx5YFoD4ERz/bhB9UkwkLjLN",
|
||||
"sv+mRpw/g1V9IVdqZ7hkCvz9z6ZjOQtmC15pA2uKy3DAaISc/A1Mw4zfcttFTALuTI5bS8f3bEJyLn+P",
|
||||
"rsYhxFMpE4T9figSa/ei/xntKMlnciwC7d/daDN6CptMj6In7J+ymb6rk52cSFzM6LUxpJCUgYiUKgbw",
|
||||
"ql4c8+nmVsxcmAD+ip+bHSEDBymCVy+J/wibLlCdsgoLwtAaD07LW5OjjAanEGT3HTLpZUWfcmsd2xPG",
|
||||
"weomjNTo+52m0tudHZAYa2QEmi6I4rgUDc75AR3MQ5o99xBgJxVLylk7spprTYx/JYDSx3QwffW2KyOo",
|
||||
"KmmZPPbXDJxfEaaFiNQtoJmYubviuPdlh8N/u3St1SKdSzdJ2/FJKzT4fK57iLV/Vs3VkH2ylut0LZnC",
|
||||
"Ejgr1QzzK6K3sl6fm6sLlPQ336izPy+/Njd350wmltO1V8jsPbLUO7czl/4ryF8A4WVcVP2B+1ph0jSr",
|
||||
"f0SWFvQmjnToyBp7cY6N8o0q80Vz9U1oWRIXJiPM2jYkae1YU/D8I+yq4rSnBTiOnNObZOfuwR3xgu5F",
|
||||
"25pacC8I38E5TkZow+BvvYos3OTNORl+0O1RoJpVY3Cn2kPBpiFquMGatqaYILOuzM3J7NTr2OvYHknm",
|
||||
"J+w3ZHJ33phowcoNYiThSfRrQC+oxL3577H2PMqLwSek6pJciDuOU281+06j55PloGkh2pRyTqJNFaZK",
|
||||
"ZAEc0dHVVMmRkl59ykfHR3geijkMjXkQN8hE0yxukFdktRpYxJRdUTXnGHMqdkBXPqhrIetGAGjGbINf",
|
||||
"Iw63okgBcykncHbJ88Ig9O3eJcn1kSPj/13OR8Jswma3H4SN1qrtrpCMA0VOmtgDLxGPgDFdBrHqBwkw",
|
||||
"2glmIiUW53N6MnPbTbp4cIzhjAmYSmfikGy70bbQl0TgskDT1RbTkfAtQaXrEpEmw/W6V31f/TaYD82F",
|
||||
"hyJJ9mOwELC76yVIXx2UK8/hEdX/m/QgA98pOyFTqT1J4lqc3811moKjxHvh5UIUvS2e+UHjk98kdisk",
|
||||
"bYgUlE3FrmJ7fwdGlNyHsrCnQMvrdEgL5pTer1UnCD2s/DGlqV7vENt/jz9Xyj/1teSZO6mqhG8kAU7w",
|
||||
"P7DC5ilE02R9mqM+KzozNvRA3IW42Ucq/UKhkxn8LqHFD5h9+SLKFxFIJK8IfVbawx2jOk1fnpPDC8XR",
|
||||
"B/9PFp11C/+tIinkuUue7UMzZaZ19TUbtWivkQ+TxyajdyQvuL7qOQI3sEjZeMNQgyXDNJ1UBWcfl37y",
|
||||
"quCks8AJPeYRP8i+hVYEU3F4Ee52RRPgGD5iy0450LsiEe/Za9k7Xkk/1qMVt/q+T9ywIR5tIhDHDtNH",
|
||||
"4oDycd2iBxigTMLnj0E9UtTpZJCpOI7Jm82qgVGefJaEsKYTvblQVb6qKt1QEpiJZrDxq1Gor8PalNzl",
|
||||
"CZT2KC/5fmrQinUU+4eZWXlRCvO3qo2pT6nW6LrCo3MpCHmnNNMVs8CfXAwnjEGivsiElKi0xLiaafly",
|
||||
"CqcT6uqG0efRF9wVIpkS4DrdjHYqymhRamk4uniqbUc8JybURMILT7jdhwttBNau0m7A4H6r62+Yhb5m",
|
||||
"nyaAhii/Ywz08ItmEsVvBsHL7L5M5lIr3P+OHYSXEIjpnuMGZbyssz5TkRzPDWYxsa2wOg/MHtCobvKf",
|
||||
"lk1kqND7zAdjRMHeqgfA6U/NRst58Bu0ehcJs0SYRCwYhx/jQFyY2sW13DiFYE+2wKUUzXK6rtx+3ZhZ",
|
||||
"eWN9MemePjnUQnxHudYYif6UY5FVkj8bl1GK8RPFbUqXYDKdf00Lghee+JtkzbtLYtKXqrZx2rnB2iJY",
|
||||
"qDsV5EZVhekpBo2FsHjpU17skiX9MIfyqk2nzU5oCsJJfU0OAJ2Rl2BnTJp5Y/jIkvsWcWfCJ7wS8dAS",
|
||||
"zYhVO4ipMZhsidnYAIWn+DmwsuUxYqQBqJ0hoyBlmk7owEpv0dYfguY6gmv7ESSfT+jO/jq9LxZWs8ZZ",
|
||||
"n7o8ZF6c/QKmt8Gmp+vFJmqkEkTCQa49ytuNGVmMnbi/sztS6xzcyE2l1Simj8jYrIhZmEDEIDgoHTHT",
|
||||
"L+6PfkoH6EHHLB46wowWxrYHkAX7SOD6MYl2ClMQ/nT0w0TbAPrukvthowWeIj2WoWgdVxJHxSyRJFyV",
|
||||
"17SdyfWD8q74mnSSmg1pi6LtPv7FqwlE+332D15PcEf7yh+Ssw33AnMQgnJAvxV1M9ThuqDTZlDQgI93",
|
||||
"KpTQSvXpYv8ktW0SFh+4ZaMtTXs4wBh9Cd0Aj+lJPYXJImU/8mSuGGPXontQWvic3SWid/wBqFR7zLa3",
|
||||
"+B/svGE7qI1o+7Y79d2fV1aX2qH73aH1l0+/tL77M69Ng8rE7w6njUAwKI9kLDwRs5bWCADkLc/3SSsk",
|
||||
"7QacgJzTyCE+L+JQvlp2BhBRfl/uVwXe+2W0DeJzDzxwmBoSeyGZwilzN8ruPXpiva6/WoZMKX1dTek6",
|
||||
"obt160qin5/Q3cJT4q8R/5JoLa8/Imzi+yrOYnwfDDiiLjZU+zVEmPjNMG9hJjJjUVE5IoMiY46JXIH5",
|
||||
"NNW2rX7b5VC/RxyjVUY0VlrRD6yk9VqqGFkUK/EMCtCpfwO3FaDFa6DCo51pg9KzCPR6n5Frogwav0Vv",
|
||||
"pOyC7yhGEz5JlWVXn0dY+MpYi5E3JcV/60FIuin+C31id6vI6MWRMKU3MVDVdN480B/QHDG917r8mhU9",
|
||||
"nr5qqam6R1gOrGbtounQ/BiKns6WsTtvcd2b61WgvNN9DfJ1XAvOb0Wu0u0xMf5hrx+I3m1Qyj7QynGg",
|
||||
"Erg3qk8G7p/LMDQMSu73yg3ruOGbb9Q0Kb2TzTr+uDT4HtL+5327w05YqSuu33a82R+dP8/4twBXPjqP",
|
||||
"c8gkGeKhdafOAAtR7L7kHsslkQ+pLyL6KffUBW9xdOpJ+OngDe+3g4v2WZcsyBWFmKLJWBK3wOSCwdWk",
|
||||
"yeMXUs5n7BX4vLoaKWlSiK4uQqzRluW0oTKJXd5yeZFSDyTBYBempad82qY4lBB1k92mvC2qkLATrEaW",
|
||||
"AOsNKaC/w2vyNEk3h76jSscDKH8N+wFew1NhP7Auz8zNzNVVRLv33rn2tjVrLVy7df09iIijb2qECu+b",
|
||||
"b1j0D/SLaQRGwRs70f92IVVmCEroXzZ+d9tt8qnPfNwnfdJY7nc6TWvWij/uB8RvfNz3Qhu/qzNTbAu9",
|
||||
"MDhh8WSMSN+MK37iF4uWw7vouMmBrYTBJimQpDe8IvhKaQYcydIY55YKCURD3sFEkCvhVbykdx+8gkO6",
|
||||
"zzVUFVYw3tMTayqGaq1b5eCI9Sj4pta9MqNzmShhBr1Q+p1GWyJJZYOOoi/oUXK0OJgxO05TALY4xI6L",
|
||||
"x1wRPAAG/bBH3GsL709nM/Y/csLVtm/fk9DqS2Q0PkKvAorqukw2paf9C+ENqaqlL3+r8MmzE/dFXEYq",
|
||||
"g/Kg1YGuTNH7X0ErTXawUiE523VcUhDMqri5x3/2Fhi63a0Eq/kPCDmjGT/aOcfx7/kk6QFmgpVM+Q7T",
|
||||
"IgmBxmasxfeuXXrtypsW9u7mnSpky1O0uhAtjhHpbKrttQIxoZlu+6/e0Jz8BT7Pi4DDF+96pYD4ySS+",
|
||||
"B5D4Ss/LuBPYIFFAIPy2JxzPz4En9tFFdWbWBFUnTyVGQv0cHpv4fuBrdNvwbwJTBcN2QAGeR8LL0PC2",
|
||||
"qWIj/pXrbelmO3m9ccbegHv2Gpn1YH252dcf2WvkQ/7YJJtzSa8pETqtKqaOWzhCj1oK0lDUisZN+4XX",
|
||||
"0Ln8ty5vv8BjiUVJuUBsObFE7yFYDG0fCD6p5oT2GoF36LEcLlf6IqkGOS9dQgL6j9NIH5+vvDzZ4q9g",
|
||||
"MFTOvvszu16jpxiAOqTH0dZ3h+V3rTA75R23HW9dob76L68iSUSsezu76nolrbF0lbcTZufrbKD7F99d",
|
||||
"M5fBU1gllbFzKhE6uYPYFTCrkV88BmyxmyJ6FNtssaWbtCeDOwU6roqg2ZhHY9Zl2zCJBlU/I/cnLRR/",
|
||||
"xlno1bHMN9XyCaRr8w6RKh9C3b3oEgRI21LiKlPwOF7UtlIrm0AY6tlildidcPVXeYrEe/yRSdbMwSvQ",
|
||||
"HM2BTviU9zRHV39+wOCfIRoQB3FP5QHUrA45XugTu72eS42b+MRka87a6zm04OXq+zwwuJlEq7lrU2A/",
|
||||
"C3/7lbnXL2xyX0OxQRxC1GSEaSc+RAYeZqeft8f/CNr2CTYGETt9Qp9hxZMICCUyV6TcbFtTJck3rWUU",
|
||||
"dU4PakvE9ol/rR+usikygYgJDyhI+36nNl+bBUHJx3oQRwdxzIf1B3IvVfnvLlG+hf4D0geiOaz0kfDZ",
|
||||
"Sx/xnAzpkzgeJv8wya2WPgVhIU+h16s9vPPw/wYAAP//DtshAlI7AQA=",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
||||
@@ -100,8 +100,10 @@ func NewHandler(cfg Config, log *slog.Logger) *Handler {
|
||||
return &Handler{cfg: cfg, client: &http.Client{Timeout: 10 * time.Minute}, log: log}
|
||||
}
|
||||
|
||||
// configured — адрес и репозиторий заданы, и это не заглушка из .env.example.
|
||||
func (h *Handler) configured() bool {
|
||||
return h.cfg.GiteaURL != "" && h.cfg.Repo != ""
|
||||
return h.cfg.GiteaURL != "" && h.cfg.Repo != "" &&
|
||||
!strings.Contains(h.cfg.GiteaURL, "example.") && !strings.HasPrefix(h.cfg.Repo, "owner/")
|
||||
}
|
||||
|
||||
func (h *Handler) get(ctx context.Context, url string) (*http.Response, error) {
|
||||
|
||||
@@ -244,6 +244,7 @@ func uiPrefsDTO(p UIPrefs) gen.UiPrefs {
|
||||
Theme: (*gen.UiPrefsTheme)(p.Theme),
|
||||
WaveVariant: (*gen.UiPrefsWaveVariant)(p.WaveVariant),
|
||||
WebPlayer: (*gen.UiPrefsWebPlayer)(p.WebPlayer),
|
||||
SearchPosition: (*gen.UiPrefsSearchPosition)(p.SearchPos),
|
||||
MobilePlayer: (*gen.UiPrefsMobilePlayer)(p.MobilePlayer),
|
||||
Ambient: p.Ambient,
|
||||
CrossfadeS: p.CrossfadeS,
|
||||
@@ -256,6 +257,7 @@ func uiPrefsFromDTO(p gen.UiPrefs) UIPrefs {
|
||||
Theme: (*string)(p.Theme),
|
||||
WaveVariant: (*string)(p.WaveVariant),
|
||||
WebPlayer: (*string)(p.WebPlayer),
|
||||
SearchPos: (*string)(p.SearchPosition),
|
||||
MobilePlayer: (*string)(p.MobilePlayer),
|
||||
Ambient: p.Ambient,
|
||||
CrossfadeS: p.CrossfadeS,
|
||||
|
||||
@@ -37,6 +37,7 @@ type UIPrefs struct {
|
||||
Theme *string `json:"theme,omitempty"`
|
||||
WaveVariant *string `json:"wave_variant,omitempty"`
|
||||
WebPlayer *string `json:"web_player,omitempty"`
|
||||
SearchPos *string `json:"search_position,omitempty"`
|
||||
MobilePlayer *string `json:"mobile_player,omitempty"`
|
||||
Ambient *bool `json:"ambient,omitempty"`
|
||||
CrossfadeS *int `json:"crossfade_s,omitempty"`
|
||||
|
||||
@@ -89,6 +89,7 @@ var uiPrefEnums = map[string][]string{
|
||||
"theme": {"dark", "light", "system"},
|
||||
"wave_variant": {"orb", "liquid"},
|
||||
"web_player": {"bar", "island"},
|
||||
"search_position": {"center", "left", "right"},
|
||||
"mobile_player": {"cover", "wave"},
|
||||
}
|
||||
|
||||
@@ -107,6 +108,7 @@ func ValidateUIPrefs(p UIPrefs) error {
|
||||
}
|
||||
for name, v := range map[string]*string{
|
||||
"theme": p.Theme, "wave_variant": p.WaveVariant, "web_player": p.WebPlayer, "mobile_player": p.MobilePlayer,
|
||||
"search_position": p.SearchPos,
|
||||
} {
|
||||
if err := check(name, v); err != nil {
|
||||
return err
|
||||
@@ -130,6 +132,9 @@ func MergeUIPrefs(base, patch UIPrefs) UIPrefs {
|
||||
if patch.WebPlayer != nil {
|
||||
base.WebPlayer = patch.WebPlayer
|
||||
}
|
||||
if patch.SearchPos != nil {
|
||||
base.SearchPos = patch.SearchPos
|
||||
}
|
||||
if patch.MobilePlayer != nil {
|
||||
base.MobilePlayer = patch.MobilePlayer
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user