From dfb2c91b8d78c25161b703e911fbce22ace575be Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 12 Oct 2026 13:57:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=94=AF=E4=BB=98=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 28 +- README.md | 4 +- README.zh-CN.md | 6 +- backend/README.md | 14 + backend/cmd/zhinian-api/main.go | 18 +- backend/cmd/zhinian-api/main_test.go | 23 + backend/go.mod | 3 +- backend/go.sum | 8 + backend/internal/application/application.go | 44 +- backend/internal/application/payments.go | 130 +++++ backend/internal/application/payments_test.go | 48 ++ .../internal/httpapi/method_compat_test.go | 4 +- backend/internal/httpapi/payment_refunds.go | 172 ++++++ .../internal/httpapi/payment_refunds_test.go | 157 ++++++ backend/internal/httpapi/payments.go | 199 +++++++ backend/internal/httpapi/payments_test.go | 129 +++++ backend/internal/httpapi/route_surface.go | 2 + backend/internal/migrations/migrations.go | 272 +++++++++ .../migrations/migrations_integration_test.go | 162 ++++++ .../internal/migrations/migrations_test.go | 97 ++++ backend/internal/migrations/role.go | 90 +++ .../migrations/sql/0001_initial_schema.sql | 467 +++++++++++++++ .../sql/0002_generation_lifecycle_fencing.sql | 69 +++ .../sql/0003_platform_runtime_settings.sql | 12 + .../sql/0004_seedream_billing_provider.sql | 14 + .../sql/0005_seedream_layer_compositions.sql | 14 + .../sql/0006_minimax_h3_billing_provider.sql | 13 + .../sql/0007_wechat_native_payments.sql | 32 ++ .../migrations/sql/0008_wechat_refunds.sql | 34 ++ backend/internal/payments/model.go | 84 +++ backend/internal/payments/refund_model.go | 78 +++ backend/internal/payments/refunds.go | 215 +++++++ backend/internal/payments/refunds_test.go | 193 +++++++ backend/internal/payments/service.go | 236 ++++++++ backend/internal/payments/service_test.go | 298 ++++++++++ backend/internal/payments/wechat.go | 136 +++++ backend/internal/payments/wechat_refunds.go | 185 ++++++ .../internal/payments/wechat_refunds_test.go | 138 +++++ backend/internal/payments/wechat_test.go | 83 +++ backend/internal/postgres/database.go | 4 +- backend/internal/postgres/payments.go | 331 +++++++++++ .../postgres/payments_integration_test.go | 116 ++++ backend/internal/postgres/payments_test.go | 177 ++++++ backend/internal/postgres/refunds.go | 533 ++++++++++++++++++ .../postgres/refunds_integration_test.go | 285 ++++++++++ components/admin-wechat-payments.module.css | 40 ++ components/admin-wechat-payments.tsx | 193 +++++++ components/billing-manager.tsx | 9 +- components/wechat-recharge.module.css | 37 ++ components/wechat-recharge.tsx | 241 ++++++++ contracts/http/route-surface.v1.json | 12 +- .../0007_wechat_native_payments.sql | 32 ++ database/migrations/0008_wechat_refunds.sql | 34 ++ deploy/ack/configmap.yaml | 10 + deploy/ack/go-api.yaml | 13 +- deploy/ack/secrets.example.yaml | 26 +- docs/API.md | 13 +- docs/DEPLOYMENT.md | 50 +- docs/PAYMENTS.md | 79 +++ docs/manual-images/billing-overview.jpg | Bin 0 -> 56591 bytes docs/manual-images/image-create.jpg | Bin 0 -> 73283 bytes docs/manual-images/organization-members.jpg | Bin 0 -> 70883 bytes docs/manual-images/task-failure.jpg | Bin 0 -> 48412 bytes docs/manual-images/task-result.jpg | Bin 0 -> 35680 bytes docs/manual-images/video-reference-guide.jpg | Bin 0 -> 27808 bytes docs/manual-images/video-settings.jpg | Bin 0 -> 79062 bytes docs/智念AIGC平台操作手册.docx | Bin 0 -> 340385 bytes lib/billing.ts | 7 +- lib/client/payment-api.ts | 124 ++++ package-lock.json | 10 + package.json | 3 + scripts/check-ack-manifests.mjs | 18 + scripts/migrate-postgres.mjs | 4 +- scripts/run-go-command.mjs | 6 +- scripts/sync-go-migrations.mjs | 32 ++ tests/billing.test.ts | 8 +- tests/payment-api.test.ts | 57 ++ 77 files changed, 6370 insertions(+), 45 deletions(-) create mode 100644 backend/internal/application/payments.go create mode 100644 backend/internal/application/payments_test.go create mode 100644 backend/internal/httpapi/payment_refunds.go create mode 100644 backend/internal/httpapi/payment_refunds_test.go create mode 100644 backend/internal/httpapi/payments.go create mode 100644 backend/internal/httpapi/payments_test.go create mode 100644 backend/internal/migrations/migrations.go create mode 100644 backend/internal/migrations/migrations_integration_test.go create mode 100644 backend/internal/migrations/migrations_test.go create mode 100644 backend/internal/migrations/role.go create mode 100644 backend/internal/migrations/sql/0001_initial_schema.sql create mode 100644 backend/internal/migrations/sql/0002_generation_lifecycle_fencing.sql create mode 100644 backend/internal/migrations/sql/0003_platform_runtime_settings.sql create mode 100644 backend/internal/migrations/sql/0004_seedream_billing_provider.sql create mode 100644 backend/internal/migrations/sql/0005_seedream_layer_compositions.sql create mode 100644 backend/internal/migrations/sql/0006_minimax_h3_billing_provider.sql create mode 100644 backend/internal/migrations/sql/0007_wechat_native_payments.sql create mode 100644 backend/internal/migrations/sql/0008_wechat_refunds.sql create mode 100644 backend/internal/payments/model.go create mode 100644 backend/internal/payments/refund_model.go create mode 100644 backend/internal/payments/refunds.go create mode 100644 backend/internal/payments/refunds_test.go create mode 100644 backend/internal/payments/service.go create mode 100644 backend/internal/payments/service_test.go create mode 100644 backend/internal/payments/wechat.go create mode 100644 backend/internal/payments/wechat_refunds.go create mode 100644 backend/internal/payments/wechat_refunds_test.go create mode 100644 backend/internal/payments/wechat_test.go create mode 100644 backend/internal/postgres/payments.go create mode 100644 backend/internal/postgres/payments_integration_test.go create mode 100644 backend/internal/postgres/payments_test.go create mode 100644 backend/internal/postgres/refunds.go create mode 100644 backend/internal/postgres/refunds_integration_test.go create mode 100644 components/admin-wechat-payments.module.css create mode 100644 components/admin-wechat-payments.tsx create mode 100644 components/wechat-recharge.module.css create mode 100644 components/wechat-recharge.tsx create mode 100644 database/migrations/0007_wechat_native_payments.sql create mode 100644 database/migrations/0008_wechat_refunds.sql create mode 100644 docs/PAYMENTS.md create mode 100644 docs/manual-images/billing-overview.jpg create mode 100644 docs/manual-images/image-create.jpg create mode 100644 docs/manual-images/organization-members.jpg create mode 100644 docs/manual-images/task-failure.jpg create mode 100644 docs/manual-images/task-result.jpg create mode 100644 docs/manual-images/video-reference-guide.jpg create mode 100644 docs/manual-images/video-settings.jpg create mode 100644 docs/智念AIGC平台操作手册.docx create mode 100644 lib/client/payment-api.ts create mode 100644 scripts/sync-go-migrations.mjs create mode 100644 tests/payment-api.test.ts diff --git a/.env.example b/.env.example index 785ce24..eca7ad2 100644 --- a/.env.example +++ b/.env.example @@ -20,6 +20,24 @@ ZHINIAN_BILLING_ACCOUNT_NAME= ZHINIAN_BILLING_ACCOUNT_BANK= ZHINIAN_BILLING_ACCOUNT_NUMBER= ZHINIAN_BILLING_CONTACT= + +# Optional WeChat Native recharge. Keep false until 0007 migration, credentials, +# Native permission and the authenticated mini-program/service-account AppID binding are ready. +# Server only; never use NEXT_PUBLIC_ names for payment credentials. +WECHAT_PAY_ENABLED=false +WECHAT_PAY_MCH_ID= +WECHAT_PAY_APP_ID= +WECHAT_PAY_NOTIFY_URL=https://YOUR_DOMAIN/api/payments/wechat/notify +WECHAT_PAY_MERCHANT_SERIAL= +WECHAT_PAY_API_V3_KEY= +WECHAT_PAY_PUBLIC_KEY_ID= +# PKCS#8 merchant private key and WeChat payment public key (PEM files). +# File paths are relative to the Go process/container. *_PEM inline values are also supported. +WECHAT_PAY_PRIVATE_KEY_FILE= +WECHAT_PAY_PUBLIC_KEY_FILE= +WECHAT_PAY_MIN_AMOUNT_FEN=100 +WECHAT_PAY_MAX_AMOUNT_FEN=1000000 +WECHAT_PAY_PRESET_AMOUNTS_FEN=10000,50000,100000 # Run `npm run bootstrap:admin -- --phone 13800138000 --password 'change-me-now'` once to create the first super admin. # Public API v1 and worker task management. @@ -45,7 +63,15 @@ ZHINIAN_GO_EMBEDDED_WORKER=true # an explicitly non-production single-process development run. ZHINIAN_DATA_BACKEND=postgres DATABASE_URL= -# Migration runner only: PostgreSQL role used by the Go API DATABASE_URL. +# Optional Go startup migration. ACK enables this with a separate Secret; +# default false for local/Compose. Keep the migration role's URL server-side. +# ACK/Compose inject environment variables; direct `go run` needs explicit +# exported variables and does not load these database startup flags from here. +DATABASE_AUTO_MIGRATE=false +DATABASE_MIGRATION_URL= +DATABASE_MIGRATION_TIMEOUT_SECONDS=180 +# PostgreSQL role used by the Go API DATABASE_URL; startup and manual migration +# grant new tables/functions to this role. DATABASE_APP_ROLE= # PostgreSQL transport is intentionally plaintext; clients force sslmode=disable. # Example: postgresql://user:password@rds-host:5432/app?sslmode=disable diff --git a/README.md b/README.md index c8de0cf..bae8cf6 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ https://你的域名/api/auth/callback 计费目录由平台维护各接口的标准成本与参数档案,超级管理员只调整上浮倍率。真实生成任务提交时按“基础标准成本 × 参数档位系数 × 任务数量 × 组合倍率”报价并从组织余额冻结,单价、参数、倍率、数量和最终金额会快照到任务;每个任务在创作结果和历史任务中显示扣费状态。普通用户余额不足时会被拒绝提交并提示“余额不足,请先充值”,不会提交服务商;超级管理员仍计算并记录生成费用,但不检查或扣减组织额度,也不产生钱包扣费、退款流水。Seedance 成功后按上游 `usage.completion_tokens` 重新结算,MiniMax H3 成功后按上游实际输出秒数和输入图数量重新结算,Wan 3.0 按实际输出时长重新结算,多退少补;没有返回用量时保留冻结金额并标记为估算。组织成员通过 `/billing` 查看组织余额、自己的消耗和账务流水,余额属于组织而不是个人;充值和人工余额调整也只记入组织账本,不设置个人上账归属。 -当前组织余额由超级管理员直接上账,充值和人工余额调整不选择个人归属;未来接入用户自主支付时,支付成功回调自动入账,不设置人工审核队列。余额不足或未配置对应计费规则时,真实生成任务不会提交给服务商。未绑定组织的开放 API 任务暂保持兼容,不纳入组织余额扣费。 +组织余额支持超级管理员人工上账,以及配置启用后的组织管理员微信 Native 扫码充值(固定档位和自定义金额)。充值只归组织,支付成功后自动幂等入账,无人工审核队列;接入配置见 [微信支付部署说明](docs/PAYMENTS.md)。余额不足或未配置对应计费规则时,真实生成任务不会提交给服务商。未绑定组织的开放 API 任务暂保持兼容,不纳入组织余额扣费。 系统首次打开超管计费中心或提交真实任务时会自动补齐平台标准价格目录,不覆盖已有目录。当前默认目录为:百炼 `wan2.7-image-pro` ¥0.50/张,百炼 `wan2.7-i2v-2026-04-25` 720P ¥0.60/秒、1080P ¥1.00/秒;百炼 `wan3.0-video` 480P/720P/1080P 标准价分别为 ¥0.30/¥0.60/¥1.20 每秒(独立规则,按官网原价维护,不计限时折扣);MiniMax H3 的 768P/2K 分别为 ¥0.50/秒、¥0.80/秒,前 5 张参考图免费、第 6 张起每张标准成本 ¥0.20,并计入预估与预扣;火山方舟 `doubao-seedance-2-0-260128` 480P/720P/1080P/4K 分别为 ¥0.46/秒、¥0.99/秒、¥2.48/秒、¥5.05/秒,`doubao-seedance-2-5-260628` 480P/720P/1080P 分别为 ¥0.67/秒、¥1.51/秒、¥3.74/秒;EvoLink `gpt-image-2` medium/1K/1:1/无参考图基础估算 ¥0.34/张(固定汇率 1 USD = 7.20 CNY),并列出质量、分辨率、画面比例和参考图数量档位;即梦 `jimeng_seedream46_cvtob` 暂按公开资源包折算参考 ¥0.20/张,官方实时计费以控制台为准;Seedream 5.0 Pro 的 1K/1.5K 基础生图为 ¥0.30/张、2K 为 ¥0.60/张,首张输入图免费,从第 2 张起 ¥0.02/张。各标准成本均按平台 `1.2×` 上浮并向上取整到分。参数化报价按基础成本乘以所选参数档位系数,组合倍率取所选档位中的最高倍率;超管只在 `/billing` 调整倍率,标准成本和参数档案由平台维护。 @@ -266,7 +266,7 @@ cp .env.example .env.local database/migrations/ ``` -首次部署和每次 schema 变更均按 `database/migrations/*.sql` 中的版本化 SQL 文件手工执行(当前依次执行 0001 至 0006,再加角色授权语句),不部署迁移 Job Pod;执行完成后再滚动工作负载。 +ACK 模板启用 Go 服务启动前自动迁移:使用独立的 `DATABASE_MIGRATION_URL` 执行镜像内已同步的版本化 SQL,并通过 `DATABASE_APP_ROLE` 给应用数据库账号授权;成功后服务才开始监听。新增 SQL 后先运行 `npm run db:bundle`,提交生成的 Go 迁移包,再构建镜像。默认代码不自动迁移,其他部署可按需启用或手工执行 `npm run db:migrate`;生产不部署迁移 Job Pod。配置及失败处理见 [`docs/DEPLOYMENT.md`](./docs/DEPLOYMENT.md)。 当前仍保留必要数据表,供上传、生成任务和用量记录使用: diff --git a/README.zh-CN.md b/README.zh-CN.md index 5bae882..eeab1e0 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -141,7 +141,7 @@ npm run bootstrap:admin -- --phone 13800138000 --password '请替换为强密码 ## 组织账号管理 -组织、账号、角色、停用、密码重置和归档均由平台本地接口处理,不再调用外部组织服务。生产部署前由部署负责人手工执行 [`database/migrations`](./database/migrations) 中的版本化 SQL 文件(依次执行 0001、0002、0003、0004)及角色授权语句完成建库建表,不部署迁移 Job Pod;超级管理员由 Go 后端首次启动时通过 `ZHINIAN_BOOTSTRAP_ADMIN_*` 环境变量自动创建一次。 +组织、账号、角色、停用、密码重置和归档均由平台本地接口处理,不再调用外部组织服务。ACK 模板启用 Go 服务启动前自动迁移,通过独立迁移账号执行镜像内尚未应用的版本化 SQL,再向应用账号授权;全部成功后才开始提供服务。新增 SQL 后先运行 `npm run db:bundle` 同步 Go 迁移包并提交,再构建镜像。生产不部署迁移 Job Pod;超级管理员由 Go 后端首次启动时通过 `ZHINIAN_BOOTSTRAP_ADMIN_*` 环境变量自动创建一次。详见 [`docs/DEPLOYMENT.md`](./docs/DEPLOYMENT.md)。 ## 账号、组织用量与计费 @@ -154,7 +154,7 @@ npm run bootstrap:admin -- --phone 13800138000 --password '请替换为强密码 普通用户点击页头账号 ID,可切换今天、近 7 天、近 30 天和本月,并查看最近 5 条记录。管理员通过 `/usage` 按日期、组织、账号、功能类型和服务商查看汇总、趋势及明细;所有组织成员可在 `/billing` 查看组织余额和自己的净消耗。 -超级管理员在 `/billing` 配置各接口来源的标准单价与上浮倍率。真实生成任务按“标准计费单位 × 数量 × 上浮倍率”在提交时从组织余额冻结,并在任务中保存计费快照;失败、取消、过期任务会在最终终态退款。普通用户余额不足时会被拒绝提交并提示“余额不足,请先充值”,不会提交服务商;超级管理员仍计算并记录生成费用,但不检查或扣减组织额度,也不产生钱包扣费、退款流水。Seedance 成功后按上游返回的 `usage.completion_tokens` 重新结算,多退少补;上游没有返回用量时保留冻结金额。当前充值和人工余额调整由超级管理员在“余额与上账”中直接记入组织额度,不设置个人上账归属;未来接入用户自主支付时,支付成功回调将自动入账,不进入人工审核队列。未绑定组织的开放 API 任务暂保持兼容,不纳入组织余额扣费。 +超级管理员在 `/billing` 配置各接口来源的标准单价与上浮倍率。真实生成任务按“标准计费单位 × 数量 × 上浮倍率”在提交时从组织余额冻结,并在任务中保存计费快照;失败、取消、过期任务会在最终终态退款。普通用户余额不足时会被拒绝提交并提示“余额不足,请先充值”,不会提交服务商;超级管理员仍计算并记录生成费用,但不检查或扣减组织额度,也不产生钱包扣费、退款流水。Seedance 成功后按上游返回的 `usage.completion_tokens` 重新结算,多退少补;上游没有返回用量时保留冻结金额。超级管理员可以在“余额与上账”中手工调整组织额度;配置启用后,组织管理员也可以通过微信 Native 扫码充值,支持固定档位和自定义金额。支付成功后自动幂等计入组织额度,不进入人工审核队列。配置见 [微信支付部署说明](docs/PAYMENTS.md)。未绑定组织的开放 API 任务暂保持兼容,不纳入组织余额扣费。 首次打开超管计费中心或提交真实任务时,系统会自动补齐以下平台标准成本目录(不会覆盖已有目录)。默认上浮倍率为 `1.2×`,最终用户价按整数分计算并向上取整: @@ -178,7 +178,7 @@ npm run bootstrap:admin -- --phone 13800138000 --password '请替换为强密码 其中 Seedream 5.0 Pro 首张输入图免费,从第 2 张起按 ¥0.02/张计入基础成本;平台统一在基础成本合计后乘以 1.2 并向上取整到分。EvoLink 按固定 `1 USD = 7.20 CNY` 换算,并在价格目录中列出质量、分辨率、画面比例和参考图数量档位;参数化报价按基础成本乘以所选档位系数,组合倍率取所选档位中的最高倍率。即梦 4.6 官方计费说明要求以控制台实时价格为准,因此该条目是平台维护的参考基准。超管只在价格目录中调整上浮倍率,标准成本、参数档案和规则状态由平台维护;来源链接和定价口径会随规则保留。 -使用 PostgreSQL 时,首次部署和每次 schema 变更均按 `database/migrations/*.sql` 中的版本化 SQL 文件手工执行(拒绝已应用脚本被静默改写),执行完成后再滚动工作负载。`local` 模式下,本地 JSON 数据会在读取时按相同口径兼容旧记录。 +使用 PostgreSQL 时,ACK 模板中的 Go 服务在启动前自动执行镜像内尚未应用的迁移,并拒绝已应用脚本被静默改写;迁移失败时服务不会开始监听。其他部署可手工运行 `npm run db:migrate`。`local` 模式下,本地 JSON 数据会在读取时按相同口径兼容旧记录。 ## 引擎说明 diff --git a/backend/README.md b/backend/README.md index f22e217..5d41d0a 100644 --- a/backend/README.md +++ b/backend/README.md @@ -77,6 +77,20 @@ docker build -f backend/Dockerfile.runtime \ ``` The runner defaults to `CGO_ENABLED=0` for reproducible cross-platform builds. +When adding a SQL migration, run `npm run db:bundle` at the repository root and +commit the resulting Go migration bundle before building any backend image. +The image uses the existing `backend/` build context and needs no Node/npm at +runtime. In the ACK template, `DATABASE_AUTO_MIGRATE=true` runs unapplied +bundled migrations with `DATABASE_MIGRATION_URL` before the HTTP server +listens. `DATABASE_APP_ROLE` names the application database user to grant; +`DATABASE_MIGRATION_TIMEOUT_SECONDS` defaults to 180. Other deployments leave +automatic migration disabled unless explicitly configured. See +[`../docs/DEPLOYMENT.md`](../docs/DEPLOYMENT.md) for Secret and rollout details. +The migration and application URLs must target the same database host, port, +and database name; their usernames may differ. ACK/Compose inject environment +variables into Go. When starting `go run` or the binary directly, explicitly +export the database startup variables; `.env.local` alone does not supply them. + To exercise the backend locally, listen on port 8080 and route browser API requests there with a same-origin development proxy: diff --git a/backend/cmd/zhinian-api/main.go b/backend/cmd/zhinian-api/main.go index 0d2b8e8..4e882bf 100644 --- a/backend/cmd/zhinian-api/main.go +++ b/backend/cmd/zhinian-api/main.go @@ -14,6 +14,7 @@ import ( "time" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/application" + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/migrations" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/settings" ) @@ -33,9 +34,9 @@ func run() error { if err != nil { return fmt.Errorf("load Go backend runtime settings: %w", err) } - app, err := application.New(application.Options{Context: ctx, Getenv: getenv}) + app, err := initializeApplication(ctx, getenv) if err != nil { - return fmt.Errorf("initialize Go backend: %w", err) + return err } defer app.Close() @@ -71,6 +72,19 @@ func run() error { return nil } +// Complete schema updates before constructing services, bootstrapping accounts, +// starting background workers, or opening the HTTP listener. +func initializeApplication(ctx context.Context, getenv func(string) string) (*application.App, error) { + if err := migrations.Run(ctx, getenv); err != nil { + return nil, fmt.Errorf("migrate database before startup: %w", err) + } + app, err := application.New(application.Options{Context: ctx, Getenv: getenv}) + if err != nil { + return nil, fmt.Errorf("initialize Go backend: %w", err) + } + return app, nil +} + func runtimeGetenv(process func(string) string) (func(string) string, error) { path := strings.TrimSpace(process("ZHINIAN_SETTINGS_FILE")) if path == "" { diff --git a/backend/cmd/zhinian-api/main_test.go b/backend/cmd/zhinian-api/main_test.go index 9207bed..6c6a33d 100644 --- a/backend/cmd/zhinian-api/main_test.go +++ b/backend/cmd/zhinian-api/main_test.go @@ -1,11 +1,34 @@ package main import ( + "context" "os" "path/filepath" + "strings" "testing" ) +func TestInitializeApplicationFailsBeforeCreatingServicesWhenMigrationIsInvalid(t *testing.T) { + runtimeDir := filepath.Join(t.TempDir(), "not-created") + values := map[string]string{ + "DATABASE_AUTO_MIGRATE": "true", + "ZHINIAN_DATA_BACKEND": "local", + "ZHINIAN_RUNTIME_DIR": runtimeDir, + "ZHINIAN_AUTH_REQUIRED": "false", + } + app, err := initializeApplication(context.Background(), func(name string) string { return values[name] }) + if app != nil { + app.Close() + t.Fatal("application was created despite invalid migration configuration") + } + if err == nil || !strings.Contains(err.Error(), "migrate database before startup:") { + t.Fatalf("expected migration failure before application initialization, got %v", err) + } + if _, err := os.Stat(runtimeDir); !os.IsNotExist(err) { + t.Fatalf("application startup touched runtime storage before migration succeeded: %v", err) + } +} + func TestListenAddressDefaultsToLoopbackAndSupportsExplicitBinding(t *testing.T) { if got := listenAddress(func(string) string { return "" }); got != "127.0.0.1:8080" { t.Fatalf("listenAddress(defaults) = %q", got) diff --git a/backend/go.mod b/backend/go.mod index 684693a..112f632 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -4,7 +4,9 @@ go 1.21 require ( github.com/jackc/pgx/v5 v5.5.5 + github.com/wechatpay-apiv3/wechatpay-go v0.2.21 golang.org/x/crypto v0.17.0 + golang.org/x/text v0.14.0 ) require ( @@ -12,5 +14,4 @@ require ( github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/text v0.14.0 // indirect ) diff --git a/backend/go.sum b/backend/go.sum index 59b2f34..d0738f3 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -1,3 +1,5 @@ +github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= +github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -12,10 +14,16 @@ github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFr github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/wechatpay-apiv3/wechatpay-go v0.2.21 h1:uIyMpzvcaHA33W/QPtHstccw+X52HO1gFdvVL9O6Lfs= +github.com/wechatpay-apiv3/wechatpay-go v0.2.21/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= diff --git a/backend/internal/application/application.go b/backend/internal/application/application.go index a4b5691..50fc12e 100644 --- a/backend/internal/application/application.go +++ b/backend/internal/application/application.go @@ -20,6 +20,7 @@ import ( "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/layercompositions" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/localstore" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/orchestration" + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/postgres" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/prompt" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/publicapi" @@ -56,9 +57,11 @@ type Options struct { } type App struct { - handler http.Handler - db *postgres.Module - worker *jobs.WorkerLoop + handler http.Handler + db *postgres.Module + worker *jobs.WorkerLoop + paymentCancel context.CancelFunc + paymentDone <-chan struct{} } func New(options Options) (*App, error) { @@ -79,6 +82,13 @@ func New(options Options) (*App, error) { if err != nil { return nil, err } + payConfig, err := paymentConfig(getenv, readFile) + if err != nil { + return nil, err + } + if payConfig.Enabled && config.Backend != postgres.BackendPostgres { + return nil, fmt.Errorf("WeChat payments require persistent PostgreSQL storage") + } database, err := postgres.Open(ctx, config) if err != nil { return nil, err @@ -174,6 +184,23 @@ func New(options Options) (*App, error) { } cookieSecure := startupGetenv("ZHINIAN_AUTH_COOKIE_SECURE") publicBaseURL := firstAuthEnv(startupGetenv, "NEXT_PUBLIC_APP_URL", "ZHINIAN_PUBLIC_BASE_URL") + var paymentService *payments.Service + var paymentHTTPService httpapi.PaymentService + if payConfig.Enabled { + if !authConfig.Configured || !authConfig.Required { + return nil, fmt.Errorf("WeChat payments require configured, mandatory authentication") + } + provider, err := payments.NewWeChatProvider(payConfig) + if err != nil { + return nil, fmt.Errorf("initialize WeChat payments: %w", err) + } + paymentService = payments.NewService(database.Store, provider, payConfig) + paymentHTTPService = paymentService + } else if config.Backend == postgres.BackendPostgres { + // Historical payment and refund records remain available when collection is disabled. + paymentHTTPService = payments.NewService(database.Store, nil, payConfig) + } + paymentHandler := httpapi.NewPaymentHandler(platformAuthorizer, paymentHTTPService, publicBaseURL) authPassword, err := httpapi.NewAuthPasswordHandler(httpapi.PasswordAuthConfig{ Configured: authConfig.Configured, SessionSecret: authConfig.SessionSecret, @@ -362,6 +389,7 @@ func New(options Options) (*App, error) { mux.Handle("/api/billing/", billingHandler) mux.Handle("/api/admin/billing", billingHandler) mux.Handle("/api/admin/billing/", billingHandler) + mux.Handle("/api/payments/", paymentHandler) mux.Handle("/api/usage", usageHandler) mux.Handle("/api/admin/usage", usageHandler) mux.Handle("/api/generations/", jobsHandler) @@ -378,8 +406,14 @@ func New(options Options) (*App, error) { mux.Handle("/api/v1/openapi.json", miscHandler) mux.Handle("/", foundation) closeOnError = false + var paymentCancel context.CancelFunc + var paymentDone <-chan struct{} + if paymentService != nil { + paymentCancel, paymentDone = startPaymentReconciliation(ctx, paymentService) + } return &App{ db: database, handler: WithHTTPEventLogging(httpapi.WithRouteMethodCompatibility(mux), eventLogger), worker: workerLoop, + paymentCancel: paymentCancel, paymentDone: paymentDone, }, nil } @@ -388,6 +422,10 @@ func (app *App) Handler() http.Handler { } func (app *App) Close() { + if app.paymentCancel != nil { + app.paymentCancel() + <-app.paymentDone + } if app.worker != nil { app.worker.Stop() } diff --git a/backend/internal/application/payments.go b/backend/internal/application/payments.go new file mode 100644 index 0000000..25cc476 --- /dev/null +++ b/backend/internal/application/payments.go @@ -0,0 +1,130 @@ +package application + +import ( + "context" + "fmt" + "log" + "net/url" + "strconv" + "strings" + "time" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/postgres" +) + +func paymentConfig(getenv postgres.Getenv, readFile postgres.ReadFile) (payments.Config, error) { + config := payments.Config{Enabled: parseBool(getenv("WECHAT_PAY_ENABLED")), MinAmountFen: 100, MaxAmountFen: 1000000, PresetAmountsFen: []int64{10000, 50000, 100000}, OrderTTL: 15 * time.Minute} + if !config.Enabled { + return config, nil + } + config.MchID = strings.TrimSpace(getenv("WECHAT_PAY_MCH_ID")) + config.AppID = strings.TrimSpace(getenv("WECHAT_PAY_APP_ID")) + config.NotifyURL = strings.TrimSpace(getenv("WECHAT_PAY_NOTIFY_URL")) + config.MerchantSerial = strings.TrimSpace(getenv("WECHAT_PAY_MERCHANT_SERIAL")) + config.APIv3Key = strings.TrimSpace(getenv("WECHAT_PAY_API_V3_KEY")) + config.WechatPublicKeyID = strings.TrimSpace(getenv("WECHAT_PAY_PUBLIC_KEY_ID")) + for _, value := range []struct{ name, value string }{ + {"WECHAT_PAY_MCH_ID", config.MchID}, {"WECHAT_PAY_APP_ID", config.AppID}, + {"WECHAT_PAY_MERCHANT_SERIAL", config.MerchantSerial}, {"WECHAT_PAY_PUBLIC_KEY_ID", config.WechatPublicKeyID}, + } { + if value.value == "" { + return config, fmt.Errorf("%s is required when WECHAT_PAY_ENABLED=true", value.name) + } + } + if len(config.APIv3Key) != 32 { + return config, fmt.Errorf("WECHAT_PAY_API_V3_KEY must contain 32 bytes") + } + notify, err := url.Parse(config.NotifyURL) + if err != nil || notify.Scheme != "https" || notify.Host == "" || notify.User != nil || notify.RawQuery != "" || notify.Fragment != "" || notify.Path != "/api/payments/wechat/notify" { + return config, fmt.Errorf("WECHAT_PAY_NOTIFY_URL must be an HTTPS URL ending in /api/payments/wechat/notify without query or credentials") + } + config.PrivateKeyPEM, err = paymentPEM(getenv, readFile, "WECHAT_PAY_PRIVATE_KEY") + if err != nil { + return config, err + } + config.WechatPublicKeyPEM, err = paymentPEM(getenv, readFile, "WECHAT_PAY_PUBLIC_KEY") + if err != nil { + return config, err + } + for _, bound := range []struct { + name string + dest *int64 + }{ + {"WECHAT_PAY_MIN_AMOUNT_FEN", &config.MinAmountFen}, {"WECHAT_PAY_MAX_AMOUNT_FEN", &config.MaxAmountFen}, + } { + if raw := strings.TrimSpace(getenv(bound.name)); raw != "" { + value, err := strconv.ParseInt(raw, 10, 64) + if err != nil || value < 1 || value > 1000000 { + return config, fmt.Errorf("%s must be an integer between 1 and 1000000", bound.name) + } + *bound.dest = value + } + } + if config.MinAmountFen > config.MaxAmountFen { + return config, fmt.Errorf("payment minimum exceeds maximum") + } + if raw := strings.TrimSpace(getenv("WECHAT_PAY_PRESET_AMOUNTS_FEN")); raw != "" { + config.PresetAmountsFen = nil + parts := strings.Split(raw, ",") + if len(parts) > 8 { + return config, fmt.Errorf("WECHAT_PAY_PRESET_AMOUNTS_FEN allows at most 8 amounts") + } + seen := map[int64]bool{} + for _, part := range parts { + value, err := strconv.ParseInt(strings.TrimSpace(part), 10, 64) + if err != nil || value < config.MinAmountFen || value > config.MaxAmountFen || seen[value] { + return config, fmt.Errorf("WECHAT_PAY_PRESET_AMOUNTS_FEN must contain unique integer amounts within the configured bounds") + } + seen[value] = true + config.PresetAmountsFen = append(config.PresetAmountsFen, value) + } + } else { + valid := make([]int64, 0, len(config.PresetAmountsFen)) + for _, value := range config.PresetAmountsFen { + if value >= config.MinAmountFen && value <= config.MaxAmountFen { + valid = append(valid, value) + } + } + config.PresetAmountsFen = valid + } + return config, nil +} + +func paymentPEM(getenv postgres.Getenv, readFile postgres.ReadFile, name string) (string, error) { + if path := strings.TrimSpace(getenv(name + "_FILE")); path != "" { + data, err := readFile(path) + if err != nil { + return "", fmt.Errorf("unable to read %s_FILE", name) + } + return string(data), nil + } + if value := strings.TrimSpace(getenv(name + "_PEM")); value != "" { + return strings.ReplaceAll(value, `\n`, "\n"), nil + } + return "", fmt.Errorf("%s_FILE or %s_PEM is required", name, name) +} + +func startPaymentReconciliation(parent context.Context, service *payments.Service) (context.CancelFunc, <-chan struct{}) { + ctx, cancel := context.WithCancel(parent) + done := make(chan struct{}) + go func() { + defer close(done) + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() + for { + run, stop := context.WithTimeout(ctx, 25*time.Second) + err := service.Reconcile(run) + stop() + if err != nil && ctx.Err() == nil { + log.Print("wechat payment reconciliation encountered an error; pending orders will be retried") + } + select { + case <-ctx.Done(): + return + case <-ticker.C: + } + } + }() + return cancel, done +} diff --git a/backend/internal/application/payments_test.go b/backend/internal/application/payments_test.go new file mode 100644 index 0000000..47f28da --- /dev/null +++ b/backend/internal/application/payments_test.go @@ -0,0 +1,48 @@ +package application + +import ( + "fmt" + "strings" + "testing" +) + +func TestPaymentConfigDisabledDoesNotRequireCredentials(t *testing.T) { + c, err := paymentConfig(func(string) string { return "" }, nil) + if err != nil || c.Enabled { + t.Fatalf("config=%+v err=%v", c, err) + } +} +func TestPaymentConfigLoadsOnlyServerCredentialsAndValidatesLimits(t *testing.T) { + values := map[string]string{ + "WECHAT_PAY_ENABLED": "true", "WECHAT_PAY_MCH_ID": "merchant", "WECHAT_PAY_APP_ID": "wxapp", + "WECHAT_PAY_NOTIFY_URL": "https://pay.example.test/api/payments/wechat/notify", + "WECHAT_PAY_MERCHANT_SERIAL": "serial", "WECHAT_PAY_API_V3_KEY": strings.Repeat("a", 32), + "WECHAT_PAY_PUBLIC_KEY_ID": "PUB_KEY_ID_test", "WECHAT_PAY_PRIVATE_KEY_FILE": "/private/key.pem", + "WECHAT_PAY_PUBLIC_KEY_PEM": "PUBLIC\\nKEY", "WECHAT_PAY_MIN_AMOUNT_FEN": "1", + "WECHAT_PAY_PRESET_AMOUNTS_FEN": "1,10000,50000", + } + read := func(path string) ([]byte, error) { + if path != "/private/key.pem" { + return nil, fmt.Errorf("unexpected file") + } + return []byte("PRIVATE"), nil + } + c, err := paymentConfig(func(key string) string { return values[key] }, read) + if err != nil || c.MinAmountFen != 1 || c.PrivateKeyPEM != "PRIVATE" || c.WechatPublicKeyPEM != "PUBLIC\nKEY" || len(c.PresetAmountsFen) != 3 { + t.Fatalf("config load err=%v", err) + } + for _, test := range []struct{ key, value string }{ + {"WECHAT_PAY_NOTIFY_URL", "http://pay.example.test/api/payments/wechat/notify"}, + {"WECHAT_PAY_NOTIFY_URL", "https://user:secret@pay.example.test/api/payments/wechat/notify"}, + {"WECHAT_PAY_API_V3_KEY", "secret"}, {"WECHAT_PAY_MAX_AMOUNT_FEN", "1000001"}, + {"WECHAT_PAY_PRESET_AMOUNTS_FEN", "100,100"}, {"WECHAT_PAY_PRESET_AMOUNTS_FEN", "1.50"}, + } { + old := values[test.key] + values[test.key] = test.value + _, err := paymentConfig(func(key string) string { return values[key] }, read) + values[test.key] = old + if err == nil || strings.Contains(err.Error(), "user:secret") { + t.Fatalf("key=%s err=%v", test.key, err) + } + } +} diff --git a/backend/internal/httpapi/method_compat_test.go b/backend/internal/httpapi/method_compat_test.go index 875fd99..2b9793a 100644 --- a/backend/internal/httpapi/method_compat_test.go +++ b/backend/internal/httpapi/method_compat_test.go @@ -12,8 +12,8 @@ import ( func TestRouteMethodCompatibilityDerivesEverySurfacePath(t *testing.T) { patterns := routeMethodPatterns(GoRouteSurface()) - if len(patterns) != 50 { - t.Fatalf("route patterns=%d want 50", len(patterns)) + if len(patterns) != 58 { + t.Fatalf("route patterns=%d want 58", len(patterns)) } for _, pattern := range patterns { if _, ok := pattern.methods[http.MethodOptions]; !ok { diff --git a/backend/internal/httpapi/payment_refunds.go b/backend/internal/httpapi/payment_refunds.go new file mode 100644 index 0000000..d37d7d3 --- /dev/null +++ b/backend/internal/httpapi/payment_refunds.go @@ -0,0 +1,172 @@ +package httpapi + +import ( + "context" + "encoding/json" + "errors" + "io" + "mime" + "net/http" + "strconv" + "strings" + "unicode/utf8" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" +) + +type PaymentRefundService interface { + AdminList(context.Context, string, int, int) (payments.AdminOrdersPage, error) + CreateRefund(context.Context, string, string, string, string, int64) (payments.Refund, error) + GetRefund(context.Context, string) (payments.Refund, error) + ListRefunds(context.Context, string) ([]payments.Refund, error) + RefundNotify(context.Context, *http.Request) error +} + +func (h *paymentHandler) adminPayments(w http.ResponseWriter, r *http.Request) { + parts := strings.Split(strings.TrimPrefix(r.URL.Path, "/api/payments/admin/"), "/") + list := len(parts) == 1 && parts[0] == "orders" + order := len(parts) == 3 && parts[0] == "orders" && parts[2] == "refunds" && len(parts[1]) <= 32 && paymentIdentifier.MatchString(parts[1]) + refund := len(parts) == 2 && parts[0] == "refunds" && len(parts[1]) <= 64 && paymentIdentifier.MatchString(parts[1]) + if !list && !order && !refund { + http.NotFound(w, r) + return + } + if r.Method != http.MethodGet && !(order && r.Method == http.MethodPost) { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + session, err := h.authorizer.Authorize(r, PlatformSuperAdmin) + if err != nil { + writePaymentError(w, err) + return + } + service, ok := h.service.(PaymentRefundService) + if !ok { + writeRefundError(w, payments.ErrUnavailable) + return + } + if list { + limit, offset := 50, 0 + if raw := r.URL.Query().Get("limit"); raw != "" { + limit, err = strconv.Atoi(raw) + if err != nil || limit < 1 || limit > 100 { + writeAPIError(w, 400, "分页参数无效。") + return + } + } + if raw := r.URL.Query().Get("offset"); raw != "" { + offset, err = strconv.Atoi(raw) + if err != nil || offset < 0 || offset > 10000000 { + writeAPIError(w, 400, "分页参数无效。") + return + } + } + org := r.URL.Query().Get("organizationId") + if len(org) > 128 { + writeAPIError(w, 400, "组织参数无效。") + return + } + page, err := service.AdminList(r.Context(), org, limit, offset) + if err != nil { + writeRefundError(w, err) + return + } + if page.Orders == nil { + page.Orders = []payments.AdminOrder{} + } + for i := range page.Orders { + page.Orders[i].CodeURL = "" + } + writeJSON(w, 200, page) + return + } + if refund { + value, err := service.GetRefund(r.Context(), parts[1]) + if err != nil { + writeRefundError(w, err) + return + } + writeJSON(w, 200, map[string]any{"refund": value}) + return + } + if r.Method == http.MethodGet { + values, err := service.ListRefunds(r.Context(), parts[1]) + if err != nil { + writeRefundError(w, err) + return + } + if values == nil { + values = []payments.Refund{} + } + writeJSON(w, 200, map[string]any{"refunds": values}) + return + } + if !h.sameOrigin(r) { + writeAPIError(w, 403, "请从本站发起退款。") + return + } + mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil || mediaType != "application/json" { + writeAPIError(w, 415, "请使用 JSON 请求。") + return + } + var body struct { + AmountFen int64 `json:"amountFen"` + Reason string `json:"reason"` + RequestKey string `json:"requestKey"` + } + r.Body = http.MaxBytesReader(w, r.Body, 4096) + decoder := json.NewDecoder(r.Body) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&body); err != nil { + writeAPIError(w, 400, "退款参数无效,金额必须是整数分。") + return + } + body.Reason = strings.TrimSpace(body.Reason) + if err := decoder.Decode(&struct{}{}); err != io.EOF || body.AmountFen <= 0 || !paymentIdentifier.MatchString(body.RequestKey) || body.Reason == "" || len(body.Reason) > 80 || !utf8.ValidString(body.Reason) { + writeAPIError(w, 400, "退款金额、请求标识或原因无效(原因最多 80 字节)。") + return + } + value, err := service.CreateRefund(r.Context(), parts[1], session.User.ID, body.RequestKey, body.Reason, body.AmountFen) + if err != nil { + writeRefundError(w, err) + return + } + writeJSON(w, 200, map[string]any{"refund": value}) +} + +func (h *paymentHandler) refundNotify(w http.ResponseWriter, r *http.Request) { + if !allow(w, r, http.MethodPost) { + return + } + service, ok := h.service.(PaymentRefundService) + if !ok { + writeJSON(w, 503, map[string]string{"code": "FAIL", "message": "退款服务未启用"}) + return + } + r.Body = http.MaxBytesReader(w, r.Body, 64<<10) + if err := service.RefundNotify(r.Context(), r); err != nil { + status := http.StatusInternalServerError + if errors.Is(err, payments.ErrVerification) { + status = http.StatusBadRequest + } + writeJSON(w, status, map[string]string{"code": "FAIL", "message": "退款通知处理失败"}) + return + } + w.WriteHeader(http.StatusNoContent) +} + +func writeRefundError(w http.ResponseWriter, err error) { + status, message := 500, "退款服务暂时不可用,请稍后刷新记录。" + switch { + case errors.Is(err, payments.ErrNotFound): + status, message = 404, "充值或退款记录不存在。" + case errors.Is(err, payments.ErrConflict): + status, message = 409, "订单状态、可退金额或退款请求已变化,请刷新记录后重试。" + case errors.Is(err, payments.ErrInvalidAmount): + status, message = 400, "退款金额超过可退金额或参数无效。" + case errors.Is(err, payments.ErrUnavailable): + status, message = 503, "微信退款尚未启用。" + } + writeAPIError(w, status, message) +} diff --git a/backend/internal/httpapi/payment_refunds_test.go b/backend/internal/httpapi/payment_refunds_test.go new file mode 100644 index 0000000..f83a6de --- /dev/null +++ b/backend/internal/httpapi/payment_refunds_test.go @@ -0,0 +1,157 @@ +package httpapi + +import ( + "context" + "errors" + "net/http" + "strings" + "testing" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/identity" + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" +) + +type refundHTTPStub struct { + paymentStub + refundCalls, notifyCalls, readCalls int + order, operator, key, reason, filter string + refundAmount int64 + limit, offset int + refundErr error +} + +func (s *refundHTTPStub) AdminList(_ context.Context, org string, limit, offset int) (payments.AdminOrdersPage, error) { + s.readCalls++ + s.filter, s.limit, s.offset = org, limit, offset + return payments.AdminOrdersPage{Orders: []payments.AdminOrder{{Order: payments.Order{ID: "cross-org", OrganizationID: "org2", Status: payments.StatusPending, CodeURL: "weixin://private"}}}}, s.refundErr +} +func (s *refundHTTPStub) CreateRefund(_ context.Context, order, operator, key, reason string, amount int64) (payments.Refund, error) { + s.refundCalls++ + s.order, s.operator, s.key, s.reason, s.refundAmount = order, operator, key, reason, amount + return payments.Refund{ID: "refund1", Status: payments.RefundPending, AmountFen: amount}, s.refundErr +} +func (s *refundHTTPStub) GetRefund(_ context.Context, id string) (payments.Refund, error) { + s.readCalls++ + return payments.Refund{ID: id, Status: payments.RefundSuccess}, s.refundErr +} +func (s *refundHTTPStub) ListRefunds(_ context.Context, id string) ([]payments.Refund, error) { + s.readCalls++ + s.order = id + return nil, s.refundErr +} +func (s *refundHTTPStub) RefundNotify(_ context.Context, _ *http.Request) error { + s.notifyCalls++ + return s.refundErr +} + +func TestAdminRefundRoutesRequireSuperAdmin(t *testing.T) { + for _, role := range []string{"user", "organization_admin", "super_admin"} { + for _, authenticated := range []bool{false, true} { + for _, route := range []struct{ method, path string }{ + {"GET", "/api/payments/admin/orders"}, + {"GET", "/api/payments/admin/orders/order1/refunds"}, + {"POST", "/api/payments/admin/orders/order1/refunds"}, + {"GET", "/api/payments/admin/refunds/refund1"}, + } { + s := &refundHTTPStub{} + got := paymentRequest(paymentTestHandler(t, role, s), route.method, route.path, `{"amountFen":100,"requestKey":"retry-1","reason":"用户申请"}`, "https://pay.example.test", authenticated) + want := 200 + if !authenticated { + want = 401 + } else if role != "super_admin" { + want = 403 + } + if got.Code != want { + t.Fatalf("%s %s role=%s auth=%t got=%d body=%s", route.method, route.path, role, authenticated, got.Code, got.Body.String()) + } + if want != 200 && s.refundCalls+s.readCalls != 0 { + t.Fatal("unauthorized service call") + } + } + } + } +} + +func TestAdminWithoutOrganizationCanViewAllOrdersAndRefund(t *testing.T) { + s := &refundHTTPStub{} + auth, err := NewPlatformAuthorizer(AuthState{Required: true, Configured: true}, &fixedSessionResolver{session: identity.Session{AuthMode: identity.AuthModeAdmin, User: identity.User{ID: "global-admin", Role: "super_admin"}}}) + if err != nil { + t.Fatal(err) + } + h := NewPaymentHandler(auth, s, "https://pay.example.test") + got := paymentRequest(h, "GET", "/api/payments/admin/orders?organizationId=org2&limit=10&offset=20", "", "", true) + if got.Code != 200 || s.filter != "org2" || s.limit != 10 || s.offset != 20 || strings.Contains(got.Body.String(), "weixin:") { + t.Fatalf("status=%d body=%s", got.Code, got.Body.String()) + } + got = paymentRequest(h, "POST", "/api/payments/admin/orders/order2/refunds", `{"amountFen":123,"requestKey":"retry-1","reason":" 用户申请 "}`, "", true) + if got.Code != 200 || s.operator != "global-admin" || s.order != "order2" || s.refundAmount != 123 || s.reason != "用户申请" || s.key != "retry-1" { + t.Fatalf("status=%d stub=%+v", got.Code, s) + } +} + +func TestAdminRefundRejectsTamperedBodyAndCrossOrigin(t *testing.T) { + s := &refundHTTPStub{} + h := paymentTestHandler(t, "super_admin", s) + for _, body := range []string{ + `{"amountFen":1.1,"requestKey":"x","reason":"ok"}`, + `{"amountFen":0,"requestKey":"x","reason":"ok"}`, + `{"amountFen":-1,"requestKey":"x","reason":"ok"}`, + `{"amountFen":100,"requestKey":"x","reason":"ok","operatorId":"victim"}`, + `{"amountFen":100,"requestKey":"x","reason":"ok","organizationId":"victim"}`, + `{"amountFen":100,"requestKey":"a/b","reason":"ok"}`, + `{"amountFen":100,"requestKey":"x","reason":" "}`, + `{"amountFen":100,"requestKey":"x","reason":"` + strings.Repeat("退", 27) + `"}`, + `{"amountFen":100,"requestKey":"x","reason":"ok"} {}`, + } { + got := paymentRequest(h, "POST", "/api/payments/admin/orders/order1/refunds", body, "", true) + if got.Code != 400 { + t.Fatalf("body=%s status=%d", body, got.Code) + } + } + got := paymentRequest(h, "POST", "/api/payments/admin/orders/order1/refunds", `{"amountFen":100,"requestKey":"x","reason":"ok"}`, "https://evil.test", true) + if got.Code != 403 || s.refundCalls != 0 { + t.Fatalf("status=%d calls=%d", got.Code, s.refundCalls) + } + for _, query := range []string{"limit=0", "limit=101", "limit=abc", "offset=-1", "offset=10000001"} { + if got := paymentRequest(h, "GET", "/api/payments/admin/orders?"+query, "", "", true); got.Code != 400 { + t.Fatalf("query=%s status=%d", query, got.Code) + } + } +} + +func TestRefundCallbackHasNoSessionAndOnlyAcknowledgesDurableSuccess(t *testing.T) { + for _, test := range []struct { + err error + want int + }{{nil, 204}, {payments.ErrVerification, 400}, {errors.New("secret database details"), 500}} { + s := &refundHTTPStub{refundErr: test.err} + h := paymentTestHandler(t, "user", s) + got := paymentRequest(h, "POST", "/api/payments/wechat/refund-notify", `{}`, "", false) + if got.Code != test.want || s.notifyCalls != 1 || strings.Contains(got.Body.String(), "secret") { + t.Fatalf("status=%d body=%s", got.Code, got.Body.String()) + } + got = paymentRequest(h, "GET", "/api/payments/wechat/refund-notify", "", "", false) + if got.Code != 405 || s.notifyCalls != 1 { + t.Fatal("GET invoked refund callback") + } + } +} + +func TestRefundErrorMappingAndStrictRoutes(t *testing.T) { + for _, test := range []struct { + err error + want int + }{{payments.ErrNotFound, 404}, {payments.ErrConflict, 409}, {payments.ErrInvalidAmount, 400}, {payments.ErrUnavailable, 503}, {errors.New("secret"), 500}} { + s := &refundHTTPStub{refundErr: test.err} + got := paymentRequest(paymentTestHandler(t, "super_admin", s), "GET", "/api/payments/admin/refunds/refund1", "", "", true) + if got.Code != test.want || strings.Contains(got.Body.String(), "secret") { + t.Fatalf("status=%d body=%s", got.Code, got.Body.String()) + } + } + h := paymentTestHandler(t, "super_admin", &refundHTTPStub{}) + for _, path := range []string{"/api/payments/admin/", "/api/payments/admin/orders/a/b/refunds", "/api/payments/admin/orders/order1/refunds/"} { + if got := paymentRequest(h, "GET", path, "", "", true); got.Code != 404 { + t.Fatalf("%s status=%d", path, got.Code) + } + } +} diff --git a/backend/internal/httpapi/payments.go b/backend/internal/httpapi/payments.go new file mode 100644 index 0000000..95f04b1 --- /dev/null +++ b/backend/internal/httpapi/payments.go @@ -0,0 +1,199 @@ +package httpapi + +import ( + "context" + "encoding/json" + "errors" + "io" + "mime" + "net/http" + "net/url" + "regexp" + "strings" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" +) + +type PaymentService interface { + Options() payments.Options + Create(context.Context, string, string, string, int64) (payments.Order, error) + Get(context.Context, string, string) (payments.Order, error) + List(context.Context, string) ([]payments.Order, error) + Notify(context.Context, *http.Request) error +} + +type paymentHandler struct { + authorizer *PlatformAuthorizer + service PaymentService + publicOrigin string +} + +func NewPaymentHandler(authorizer *PlatformAuthorizer, service PaymentService, publicOrigin string) http.Handler { + return &paymentHandler{authorizer: authorizer, service: service, publicOrigin: publicOrigin} +} + +var paymentIdentifier = regexp.MustCompile(`^[a-zA-Z0-9_-]{1,64}$`) + +func (h *paymentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Cache-Control", "no-store") + if r.URL.Path == "/api/payments/wechat/refund-notify" { + h.refundNotify(w, r) + return + } + if strings.HasPrefix(r.URL.Path, "/api/payments/admin/") { + h.adminPayments(w, r) + return + } + if r.URL.Path == "/api/payments/wechat/notify" { + if !allow(w, r, http.MethodPost) { + return + } + if h.service == nil { + writeJSON(w, 503, map[string]string{"code": "FAIL", "message": "支付服务未启用"}) + return + } + r.Body = http.MaxBytesReader(w, r.Body, 64<<10) + if err := h.service.Notify(r.Context(), r); err != nil { + status := http.StatusInternalServerError + if errors.Is(err, payments.ErrVerification) { + status = http.StatusBadRequest + } + // Acknowledge only after durable settlement; never leak decrypted data. + writeJSON(w, status, map[string]string{"code": "FAIL", "message": "支付通知处理失败"}) + return + } + w.WriteHeader(http.StatusNoContent) + return + } + optionsPath := r.URL.Path == "/api/payments/options" + ordersPath := r.URL.Path == "/api/payments/orders" + orderID := strings.TrimPrefix(r.URL.Path, "/api/payments/orders/") + itemPath := strings.HasPrefix(r.URL.Path, "/api/payments/orders/") && len(orderID) <= 32 && paymentIdentifier.MatchString(orderID) + if !optionsPath && !ordersPath && !itemPath { + http.NotFound(w, r) + return + } + if r.Method != http.MethodGet && !(ordersPath && r.Method == http.MethodPost) { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + session, err := h.authorizer.Authorize(r, PlatformApp) + if err != nil { + writePaymentError(w, err) + return + } + canRecharge := session.User.OrganizationID != "" && (session.User.Role == "organization_admin" || session.User.Role == "super_admin") + if optionsPath { + options := payments.Options{PresetAmountsFen: []int64{}} + if h.service != nil { + options = h.service.Options() + } + options.CanRecharge = options.Enabled && canRecharge + writeJSON(w, http.StatusOK, options) + return + } + if !canRecharge { + writeAPIError(w, http.StatusForbidden, "需要所属组织的管理员权限。") + return + } + if h.service == nil { + writePaymentError(w, payments.ErrUnavailable) + return + } + org := session.User.OrganizationID + if itemPath { + order, err := h.service.Get(r.Context(), org, orderID) + if err != nil { + writePaymentError(w, err) + return + } + writeJSON(w, http.StatusOK, map[string]any{"order": publicPaymentOrder(order)}) + return + } + if r.Method == http.MethodGet { + orders, err := h.service.List(r.Context(), org) + if err != nil { + writePaymentError(w, err) + return + } + if orders == nil { + orders = []payments.Order{} + } + for i := range orders { + orders[i] = publicPaymentOrder(orders[i]) + } + writeJSON(w, http.StatusOK, map[string]any{"orders": orders}) + return + } + if !h.sameOrigin(r) { + writeAPIError(w, http.StatusForbidden, "请从本站发起充值。") + return + } + mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil || mediaType != "application/json" { + writeAPIError(w, http.StatusUnsupportedMediaType, "请使用 JSON 请求。") + return + } + var body struct { + AmountFen int64 `json:"amountFen"` + RequestKey string `json:"requestKey"` + } + r.Body = http.MaxBytesReader(w, r.Body, 4096) + decoder := json.NewDecoder(r.Body) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&body); err != nil { + writeAPIError(w, 400, "充值参数无效,金额必须是整数分。") + return + } + if err := decoder.Decode(&struct{}{}); err != io.EOF || !paymentIdentifier.MatchString(body.RequestKey) { + writeAPIError(w, 400, "充值请求标识无效。") + return + } + order, err := h.service.Create(r.Context(), org, session.User.ID, body.RequestKey, body.AmountFen) + if err != nil { + writePaymentError(w, err) + return + } + writeJSON(w, http.StatusOK, map[string]any{"order": publicPaymentOrder(order)}) +} + +func publicPaymentOrder(order payments.Order) payments.Order { + if order.Status != payments.StatusPending { + order.CodeURL = "" + } + return order +} + +func (h *paymentHandler) sameOrigin(r *http.Request) bool { + if site := r.Header.Get("Sec-Fetch-Site"); site != "" && site != "same-origin" && site != "none" { + return false + } + origin := r.Header.Get("Origin") + if origin == "" { + return true + } + actual, err := url.Parse(origin) + if err != nil || actual.User != nil || actual.RawQuery != "" || actual.Fragment != "" || actual.Path != "" { + return false + } + expected, err := url.Parse(h.publicOrigin) + return err == nil && expected.Host != "" && actual.Scheme == expected.Scheme && strings.EqualFold(actual.Host, expected.Host) +} + +func writePaymentError(w http.ResponseWriter, err error) { + status, message := http.StatusInternalServerError, "支付服务暂时不可用,请稍后重试。" + var authErr *PlatformAuthError + switch { + case errors.As(err, &authErr): + status, message = authErr.Status, authErr.Message + case errors.Is(err, payments.ErrNotFound): + status, message = 404, "充值订单不存在。" + case errors.Is(err, payments.ErrConflict): + status, message = 409, "充值请求与已有订单不一致,请刷新后重试。" + case errors.Is(err, payments.ErrInvalidAmount): + status, message = 400, "充值金额不在允许范围内。" + case errors.Is(err, payments.ErrUnavailable): + status, message = 503, "微信支付尚未启用。" + } + writeAPIError(w, status, message) +} diff --git a/backend/internal/httpapi/payments_test.go b/backend/internal/httpapi/payments_test.go new file mode 100644 index 0000000..cab989a --- /dev/null +++ b/backend/internal/httpapi/payments_test.go @@ -0,0 +1,129 @@ +package httpapi + +import ( + "context" + "errors" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/identity" + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" +) + +type paymentStub struct { + org, account, requestKey string + amount int64 + notifications int + err error +} + +func (s *paymentStub) Options() payments.Options { + return payments.Options{Enabled: true, PresetAmountsFen: []int64{10000}, MinAmountFen: 100, MaxAmountFen: 1000000} +} +func (s *paymentStub) Create(_ context.Context, org, account, key string, amount int64) (payments.Order, error) { + s.org, s.account, s.requestKey, s.amount = org, account, key, amount + return payments.Order{ID: "order1", OrganizationID: org, AmountFen: amount, Status: payments.StatusPending}, s.err +} +func (s *paymentStub) Get(_ context.Context, org, id string) (payments.Order, error) { + s.org = org + return payments.Order{ID: id, Status: payments.StatusPaid, CodeURL: "weixin://stale"}, s.err +} +func (s *paymentStub) List(_ context.Context, org string) ([]payments.Order, error) { + s.org = org + return nil, s.err +} +func (s *paymentStub) Notify(_ context.Context, _ *http.Request) error { + s.notifications++ + return s.err +} + +func paymentTestHandler(t *testing.T, role string, service PaymentService) http.Handler { + t.Helper() + auth, err := NewPlatformAuthorizer(AuthState{Required: true, Configured: true}, &fixedSessionResolver{session: identity.Session{AuthMode: identity.AuthModeAdmin, User: identity.User{ID: "account1", OrganizationID: "org1", Role: role}}}) + if err != nil { + t.Fatal(err) + } + return NewPaymentHandler(auth, service, "https://pay.example.test") +} +func paymentRequest(h http.Handler, method, path, body, origin string, authenticated bool) *httptest.ResponseRecorder { + r := httptest.NewRequest(method, path, strings.NewReader(body)) + r.Header.Set("Content-Type", "application/json") + if origin != "" { + r.Header.Set("Origin", origin) + } + if authenticated { + r.AddCookie(&http.Cookie{Name: identity.SessionCookieName, Value: "valid"}) + } + w := httptest.NewRecorder() + h.ServeHTTP(w, r) + return w +} +func TestPaymentCreateUsesSessionAndRejectsMoneyTampering(t *testing.T) { + s := &paymentStub{} + h := paymentTestHandler(t, "organization_admin", s) + got := paymentRequest(h, "POST", "/api/payments/orders", `{"amountFen":12345,"requestKey":"retry-1"}`, "https://pay.example.test", true) + if got.Code != 200 || s.org != "org1" || s.account != "account1" || s.amount != 12345 { + t.Fatalf("status=%d scope=%s/%s amount=%d", got.Code, s.org, s.account, s.amount) + } + for _, body := range []string{ + `{"amountFen":1.01,"requestKey":"x"}`, `{"amountFen":1e4,"requestKey":"x"}`, + `{"amountFen":100,"requestKey":"x","organizationId":"victim"}`, + `{"amountFen":100,"requestKey":"x"} {}`, `{"amountFen":100,"requestKey":"a/b"}`, + } { + if got := paymentRequest(h, "POST", "/api/payments/orders", body, "", true); got.Code != 400 { + t.Fatalf("body=%s status=%d", body, got.Code) + } + } +} +func TestPaymentAuthorizationAndOrigin(t *testing.T) { + for _, test := range []struct { + role, origin string + authenticated bool + want int + }{ + {"user", "", true, 403}, {"organization_admin", "https://evil.example", true, 403}, + {"organization_admin", "null", true, 403}, {"organization_admin", "", false, 401}, + } { + s := &paymentStub{} + h := paymentTestHandler(t, test.role, s) + got := paymentRequest(h, "POST", "/api/payments/orders", `{"amountFen":100,"requestKey":"x"}`, test.origin, test.authenticated) + if got.Code != test.want || s.account != "" { + t.Fatalf("test=%+v status=%d", test, got.Code) + } + } +} +func TestPaymentCallbackUsesVerifierWithoutBrowserSessionAndRetriesFailures(t *testing.T) { + for _, test := range []struct { + err error + want int + }{ + {nil, 204}, {payments.ErrVerification, 400}, {errors.New("secret error detail"), 500}, + } { + s := &paymentStub{err: test.err} + h := paymentTestHandler(t, "user", s) + got := paymentRequest(h, "POST", "/api/payments/wechat/notify", `{}`, "", false) + if got.Code != test.want || s.notifications != 1 || strings.Contains(got.Body.String(), "secret") { + t.Fatalf("status=%d body=%s", got.Code, got.Body.String()) + } + } +} +func TestPaymentDisabledOptionsAndScopedReads(t *testing.T) { + h := paymentTestHandler(t, "organization_admin", nil) + got := paymentRequest(h, "GET", "/api/payments/options", "", "", true) + if got.Code != 200 || !strings.Contains(got.Body.String(), `"enabled":false`) || got.Header().Get("Cache-Control") != "no-store" { + t.Fatal(got.Body.String()) + } + s := &paymentStub{} + h = paymentTestHandler(t, "organization_admin", s) + got = paymentRequest(h, "GET", "/api/payments/orders/order1?organizationId=victim", "", "", true) + if got.Code != 200 || s.org != "org1" || strings.Contains(got.Body.String(), "weixin") { + t.Fatalf("status=%d body=%s", got.Code, got.Body.String()) + } + h = paymentTestHandler(t, "user", s) + got = paymentRequest(h, "GET", "/api/payments/options", "", "", true) + if !strings.Contains(got.Body.String(), `"canRecharge":false`) { + t.Fatal(got.Body.String()) + } +} diff --git a/backend/internal/httpapi/route_surface.go b/backend/internal/httpapi/route_surface.go index 7ebf8e8..753b57e 100644 --- a/backend/internal/httpapi/route_surface.go +++ b/backend/internal/httpapi/route_surface.go @@ -13,6 +13,8 @@ type RouteSurface struct { } var goRouteSurface = []RouteSurface{ + {"GET", "/api/payments/options"}, {"GET", "/api/payments/orders"}, {"POST", "/api/payments/orders"}, {"GET", "/api/payments/orders/{id}"}, {"POST", "/api/payments/wechat/notify"}, + {"GET", "/api/payments/admin/orders"}, {"GET", "/api/payments/admin/orders/{id}/refunds"}, {"POST", "/api/payments/admin/orders/{id}/refunds"}, {"GET", "/api/payments/admin/refunds/{id}"}, {"POST", "/api/payments/wechat/refund-notify"}, {"DELETE", "/api/admin/accounts"}, {"GET", "/api/admin/accounts"}, {"PATCH", "/api/admin/accounts"}, {"POST", "/api/admin/accounts"}, {"PUT", "/api/admin/accounts"}, {"POST", "/api/admin/accounts/groups"}, {"POST", "/api/admin/accounts/password"}, {"GET", "/api/admin/billing"}, {"PATCH", "/api/admin/billing/account"}, {"POST", "/api/admin/billing/adjustments"}, {"GET", "/api/admin/billing/prices"}, {"PATCH", "/api/admin/billing/prices"}, {"PATCH", "/api/admin/billing/prices/{id}"}, {"DELETE", "/api/admin/organizations"}, {"GET", "/api/admin/organizations"}, {"PATCH", "/api/admin/organizations"}, {"POST", "/api/admin/organizations"}, {"GET", "/api/admin/usage"}, {"GET", "/api/assets"}, {"POST", "/api/assets"}, {"POST", "/api/assets/upload"}, {"POST", "/api/assets/import-image"}, {"DELETE", "/api/assets/{id}"}, {"GET", "/api/assets/{id}/download"}, {"GET", "/api/auth/callback"}, {"GET", "/api/auth/captcha"}, {"GET", "/api/auth/login"}, {"GET", "/api/auth/logout"}, {"POST", "/api/auth/logout"}, {"GET", "/api/auth/me"}, {"POST", "/api/auth/password"}, {"POST", "/api/auth/password/change"}, diff --git a/backend/internal/migrations/migrations.go b/backend/internal/migrations/migrations.go new file mode 100644 index 0000000..411885b --- /dev/null +++ b/backend/internal/migrations/migrations.go @@ -0,0 +1,272 @@ +// Package migrations applies the canonical SQL migrations before the API starts. +// SQL in sql/ is generated from database/migrations by scripts/sync-go-migrations.mjs. +package migrations + +import ( + "context" + "crypto/sha256" + "embed" + "encoding/hex" + "errors" + "fmt" + "io/fs" + "log" + "sort" + "strconv" + "strings" + "time" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/postgres" + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +//go:embed sql/*.sql +var sqlFiles embed.FS + +const migrationLockID int64 = 7308731946202608 + +type migration struct { + version string + checksum string + sql string +} + +// Run is a no-op unless DATABASE_AUTO_MIGRATE=true. Its context covers +// connection, advisory-lock waiting, every migration, and role provisioning. +func Run(ctx context.Context, getenv func(string) string) error { + if getenv == nil { + return errors.New("environment getter is required") + } + switch strings.ToLower(strings.TrimSpace(getenv("DATABASE_AUTO_MIGRATE"))) { + case "", "false": + return nil + case "true": + default: + return errors.New("DATABASE_AUTO_MIGRATE must be true or false") + } + if strings.ToLower(strings.TrimSpace(getenv("ZHINIAN_DATA_BACKEND"))) != "postgres" { + return errors.New("DATABASE_AUTO_MIGRATE requires ZHINIAN_DATA_BACKEND=postgres") + } + timeout := 180 * time.Second + if raw := strings.TrimSpace(getenv("DATABASE_MIGRATION_TIMEOUT_SECONDS")); raw != "" { + seconds, err := strconv.ParseInt(raw, 10, 64) + if err != nil || seconds < 1 || seconds > 86400 { + return errors.New("DATABASE_MIGRATION_TIMEOUT_SECONDS must be an integer from 1 to 86400") + } + timeout = time.Duration(seconds) * time.Second + } + role := strings.TrimSpace(getenv("DATABASE_APP_ROLE")) + if role == "" && strings.EqualFold(strings.TrimSpace(getenv("NODE_ENV")), "production") { + return errors.New("DATABASE_APP_ROLE is required in production") + } + if role != "" && !rolePattern.MatchString(role) { + return errors.New("DATABASE_APP_ROLE must match [a-z_][a-z0-9_]{0,62}") + } + all, err := discover(sqlFiles) + if err != nil { + return err + } + migrationURL := strings.TrimSpace(getenv("DATABASE_MIGRATION_URL")) + appURL := strings.TrimSpace(getenv("DATABASE_URL")) + if migrationURL == "" { + migrationURL = appURL + } + if migrationURL == "" { + return errors.New("DATABASE_MIGRATION_URL or DATABASE_URL is required") + } + // Reuse the application's URI validation and forced transport policy. + config, err := postgres.ParseConfig(func(key string) string { + if key == "DATABASE_URL" { + return migrationURL + } + return getenv(key) + }, nil) + if err != nil { + return fmt.Errorf("migration database configuration: %w", err) + } + pgconfig, err := pgx.ParseConfig(config.DatabaseURL) + if err != nil { + return errors.New("invalid migration database connection configuration") + } + if appURL != "" && strings.TrimSpace(getenv("DATABASE_MIGRATION_URL")) != "" { + appConfig, err := postgres.ParseConfig(func(key string) string { + if key == "DATABASE_URL" { + return appURL + } + return getenv(key) + }, nil) + if err != nil { + return fmt.Errorf("application database configuration: %w", err) + } + appPGConfig, err := pgx.ParseConfig(appConfig.DatabaseURL) + if err != nil { + return errors.New("invalid application database connection configuration") + } + if !strings.EqualFold(pgconfig.Host, appPGConfig.Host) || pgconfig.Port != appPGConfig.Port || pgconfig.Database != appPGConfig.Database { + return errors.New("DATABASE_MIGRATION_URL must target the same host, port, and database as DATABASE_URL") + } + } + pgconfig.RuntimeParams["application_name"] = "zhinian-migrate" + pgconfig.ConnectTimeout = config.ConnectionTimeout + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + log.Printf("zhinian-api checking database migrations (%d bundled versions)", len(all)) + conn, err := pgx.ConnectConfig(ctx, pgconfig) + if err != nil { + return safeDBError("connect", "", err) + } + defer conn.Close(context.Background()) + log.Print("zhinian-api waiting for database migration lock") + if _, err := conn.Exec(ctx, "SELECT pg_advisory_lock($1)", migrationLockID); err != nil { + return safeDBError("acquire migration lock", "", err) + } + // Session-level lock is released when conn closes, including on timeout. + if err := apply(ctx, conn, all, role); err != nil { + return err + } + log.Printf("zhinian-api database migrations ready (%d versions)", len(all)) + return nil +} + +func apply(ctx context.Context, conn *pgx.Conn, all []migration, role string) error { + if _, err := conn.Exec(ctx, `CREATE TABLE IF NOT EXISTS schema_migrations ( + version text PRIMARY KEY, + checksum text NOT NULL, + applied_at timestamptz NOT NULL DEFAULT now() + )`); err != nil { + return safeDBError("create migration tracking table", "", err) + } + rows, err := conn.Query(ctx, "SELECT version, checksum FROM schema_migrations") + if err != nil { + return safeDBError("read migration history", "", err) + } + applied := make(map[string]string) + for rows.Next() { + var version, checksum string + if err := rows.Scan(&version, &checksum); err != nil { + rows.Close() + return safeDBError("read migration history", "", err) + } + applied[version] = checksum + } + err = rows.Err() + rows.Close() + if err != nil { + return safeDBError("read migration history", "", err) + } + known := make(map[string]string, len(all)) + for _, item := range all { + known[item.version] = item.checksum + } + for version, checksum := range applied { + expected, exists := known[version] + if !exists { + return fmt.Errorf("applied migration %q is absent from bundle", version) + } + if checksum != expected { + return fmt.Errorf("applied migration %q checksum differs from bundle", version) + } + } + for _, item := range all { + if _, exists := applied[item.version]; exists { + continue + } + body, err := withoutOuterTransaction(item.sql) + if err != nil { + return fmt.Errorf("migration %s: %w", item.version, err) + } + tx, err := conn.Begin(ctx) + if err != nil { + return safeDBError("begin migration", item.version, err) + } + // PostgreSQL's simple protocol permits multi-statement migration files. + _, err = tx.Exec(ctx, body, pgx.QueryExecModeSimpleProtocol) + if err == nil { + _, err = tx.Exec(ctx, "INSERT INTO schema_migrations(version, checksum) VALUES ($1, $2)", item.version, item.checksum) + } + if err == nil { + err = tx.Commit(ctx) + } + if err != nil { + _ = tx.Rollback(context.Background()) + return safeDBError("apply migration", item.version, err) + } + log.Printf("zhinian-api applied database migration %s", item.version) + } + if role != "" { + if err := provisionRole(ctx, conn, role); err != nil { + return err + } + } + return nil +} + +func discover(fsys fs.FS) ([]migration, error) { + entries, err := fs.ReadDir(fsys, "sql") + if err != nil { + return nil, errors.New("read embedded migration bundle") + } + var all []migration + for _, entry := range entries { + name := entry.Name() + if entry.IsDir() || !strings.HasSuffix(name, ".sql") { + continue + } + data, err := fs.ReadFile(fsys, "sql/"+name) + if err != nil { + return nil, fmt.Errorf("read embedded migration %s", name) + } + checksum := sha256.Sum256(data) + all = append(all, migration{strings.TrimSuffix(name, ".sql"), hex.EncodeToString(checksum[:]), string(data)}) + } + sort.Slice(all, func(i, j int) bool { return all[i].version < all[j].version }) + if len(all) == 0 { + return nil, errors.New("embedded migration bundle is empty") + } + return all, nil +} + +// The canonical SQL may contain an explicit outer BEGIN/COMMIT. Strip only +// when both commands are the first and last non-comment statements; otherwise +// our transaction would commit before recording the checksum. +func withoutOuterTransaction(sql string) (string, error) { + first, last := -1, -1 + lines := strings.SplitAfter(sql, "\n") + for i, line := range lines { + trimmed := strings.TrimSpace(line) + if trimmed != "" && !strings.HasPrefix(trimmed, "--") { + if first < 0 { + first = i + } + last = i + } + } + if first < 0 { + return "", errors.New("empty migration SQL") + } + begin := strings.EqualFold(strings.TrimSpace(lines[first]), "begin;") + commit := strings.EqualFold(strings.TrimSpace(lines[last]), "commit;") + if begin != commit { + return "", errors.New("outer transaction must contain both BEGIN and COMMIT") + } + if !begin { + return sql, nil + } + lines[first], lines[last] = "", "" + return strings.Join(lines, ""), nil +} + +func safeDBError(operation, version string, err error) error { + if version != "" { + operation += " " + version + } + var pgErr *pgconn.PgError + if errors.As(err, &pgErr) { + return fmt.Errorf("%s failed (SQLSTATE %s)", operation, pgErr.Code) + } + if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) { + return fmt.Errorf("%s timed out or was canceled", operation) + } + return fmt.Errorf("%s failed (%T)", operation, err) +} diff --git a/backend/internal/migrations/migrations_integration_test.go b/backend/internal/migrations/migrations_integration_test.go new file mode 100644 index 0000000..fbe8632 --- /dev/null +++ b/backend/internal/migrations/migrations_integration_test.go @@ -0,0 +1,162 @@ +package migrations + +import ( + "context" + "os" + "strings" + "sync" + "testing" + "time" + + "github.com/jackc/pgx/v5" +) + +// Requires an independently disposable database with no valuable contents. +// It never consults the application's DATABASE_URL or .env files. +func TestIntegrationRunOnDisposableDatabase(t *testing.T) { + dsn := os.Getenv("NIAN_TEST_MIGRATION_DATABASE_URL") + if dsn == "" { + t.Skip("set NIAN_TEST_MIGRATION_DATABASE_URL for disposable PostgreSQL integration test") + } + ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second) + defer cancel() + conn, err := pgx.Connect(ctx, dsn) + if err != nil { + t.Fatal("connect disposable database:", err) + } + defer conn.Close(context.Background()) + if _, err := conn.Exec(ctx, `DO $$ BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'nian_migration_test') THEN + CREATE ROLE nian_migration_test NOLOGIN; + END IF; + END $$`); err != nil { + t.Fatal("create disposable test role:", err) + } + all, err := discover(sqlFiles) + if err != nil { + t.Fatal(err) + } + // Repair only markers this test might have left if an earlier assertion + // stopped execution before normal cleanup. + var trackingTable *string + if err := conn.QueryRow(ctx, "SELECT to_regclass('public.schema_migrations')::text").Scan(&trackingTable); err != nil { + t.Fatal(err) + } + if trackingTable != nil { + if _, err := conn.Exec(ctx, "UPDATE schema_migrations SET checksum=$1 WHERE version=$2 AND checksum='test-mismatch'", all[0].checksum, all[0].version); err != nil { + t.Fatal(err) + } + if _, err := conn.Exec(ctx, "DELETE FROM schema_migrations WHERE version='test_unknown'"); err != nil { + t.Fatal(err) + } + } + env := func(key string) string { + switch key { + case "DATABASE_AUTO_MIGRATE": + return "true" + case "ZHINIAN_DATA_BACKEND": + return "postgres" + case "DATABASE_MIGRATION_URL", "DATABASE_URL": + return dsn + case "DATABASE_APP_ROLE": + return "nian_migration_test" + case "NODE_ENV": + return "production" + default: + return "" + } + } + var wg sync.WaitGroup + results := make(chan error, 2) + for i := 0; i < 2; i++ { + wg.Add(1) + go func() { + defer wg.Done() + results <- Run(ctx, env) + }() + } + wg.Wait() + close(results) + for err := range results { + if err != nil { + t.Fatal("concurrent migration:", err) + } + } + if err := Run(ctx, env); err != nil { + t.Fatal("repeat migration:", err) + } + var count int + if err := conn.QueryRow(ctx, "SELECT count(*) FROM schema_migrations").Scan(&count); err != nil || count != len(all) { + t.Fatalf("recorded migrations: count=%d, err=%v", count, err) + } + var privilege bool + if err := conn.QueryRow(ctx, "SELECT has_table_privilege('nian_migration_test', 'public.payment_orders', 'SELECT,INSERT,UPDATE')").Scan(&privilege); err != nil || !privilege { + t.Fatalf("payment order privileges: granted=%v, err=%v", privilege, err) + } + // A mismatch must prevent any later migration or startup. + first := all[0] + if _, err := conn.Exec(ctx, "UPDATE schema_migrations SET checksum='test-mismatch' WHERE version=$1", first.version); err != nil { + t.Fatal(err) + } + defer func() { + cleanupCtx, cleanupCancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cleanupCancel() + _, _ = conn.Exec(cleanupCtx, "UPDATE schema_migrations SET checksum=$1 WHERE version=$2", first.checksum, first.version) + _, _ = conn.Exec(cleanupCtx, "DELETE FROM schema_migrations WHERE version='test_unknown'") + }() + if err := Run(ctx, env); err == nil || !strings.Contains(err.Error(), "checksum differs") { + t.Fatalf("expected checksum rejection, got %v", err) + } + if _, err := conn.Exec(ctx, "UPDATE schema_migrations SET checksum=$1 WHERE version=$2", first.checksum, first.version); err != nil { + t.Fatal(err) + } + if _, err := conn.Exec(ctx, "INSERT INTO schema_migrations(version, checksum) VALUES ('test_unknown', 'test')"); err != nil { + t.Fatal(err) + } + if err := Run(ctx, env); err == nil || !strings.Contains(err.Error(), "absent from bundle") { + t.Fatalf("expected unknown-version rejection, got %v", err) + } + if _, err := conn.Exec(ctx, "DELETE FROM schema_migrations WHERE version='test_unknown'"); err != nil { + t.Fatal(err) + } + if _, err := conn.Exec(ctx, "SELECT pg_advisory_lock($1)", migrationLockID); err != nil { + t.Fatal(err) + } + defer conn.Exec(context.Background(), "SELECT pg_advisory_unlock($1)", migrationLockID) + shortCtx, shortCancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer shortCancel() + if err := Run(shortCtx, env); err == nil || !strings.Contains(err.Error(), "timed out") { + t.Fatalf("expected advisory-lock timeout, got %v", err) + } + if _, err := conn.Exec(ctx, "SELECT pg_advisory_unlock($1)", migrationLockID); err != nil { + t.Fatal(err) + } + // The outer BEGIN/COMMIT in a legacy migration must not commit its DDL + // before the version/checksum row is inserted by apply. + const syntheticVersion = "9999_atomicity_test" + const syntheticTable = "public.nian_migration_atomicity_test" + if _, err := conn.Exec(ctx, "DROP TABLE IF EXISTS "+syntheticTable); err != nil { + t.Fatal(err) + } + if _, err := conn.Exec(ctx, "DELETE FROM schema_migrations WHERE version=$1", syntheticVersion); err != nil { + t.Fatal(err) + } + synthetic := migration{ + version: syntheticVersion, + sql: "-- synthetic migration\nBEGIN;\nCREATE TABLE " + syntheticTable + " (id integer PRIMARY KEY);\nSELECT 1 / 0;\nCOMMIT;\n", + } + if err := apply(ctx, conn, append(all, synthetic), ""); err == nil || !strings.Contains(err.Error(), syntheticVersion) { + t.Fatalf("expected synthetic migration failure with version, got %v", err) + } + var objectName *string + if err := conn.QueryRow(ctx, "SELECT to_regclass($1)::text", syntheticTable).Scan(&objectName); err != nil { + t.Fatal(err) + } + if objectName != nil { + t.Fatalf("failed migration left DDL object %s", *objectName) + } + var recorded int + if err := conn.QueryRow(ctx, "SELECT count(*) FROM schema_migrations WHERE version=$1", syntheticVersion).Scan(&recorded); err != nil || recorded != 0 { + t.Fatalf("failed migration recorded version: count=%d, err=%v", recorded, err) + } +} diff --git a/backend/internal/migrations/migrations_test.go b/backend/internal/migrations/migrations_test.go new file mode 100644 index 0000000..2944dbe --- /dev/null +++ b/backend/internal/migrations/migrations_test.go @@ -0,0 +1,97 @@ +package migrations + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/hex" + "os" + "path/filepath" + "strings" + "testing" + "testing/fstest" +) + +func TestEmbeddedBundleMatchesCanonicalSQL(t *testing.T) { + all, err := discover(sqlFiles) + if err != nil { + t.Fatal(err) + } + canonical, err := filepath.Glob("../../../database/migrations/*.sql") + if err != nil { + t.Fatal(err) + } + if len(canonical) != len(all) { + t.Fatalf("canonical count %d differs from embedded count %d", len(canonical), len(all)) + } + for i, path := range canonical { + data, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + version := strings.TrimSuffix(filepath.Base(path), ".sql") + if all[i].version != version || !bytes.Equal(data, []byte(all[i].sql)) { + t.Fatalf("embedded migration %s differs from canonical SQL", version) + } + checksum := sha256.Sum256(data) + if all[i].checksum != hex.EncodeToString(checksum[:]) { + t.Fatalf("checksum differs for %s", version) + } + } +} + +func TestDiscoverMigrations(t *testing.T) { + fsys := fstest.MapFS{ + "sql/0002.sql": {Data: []byte("select 2;\n")}, + "sql/0001.sql": {Data: []byte("select 1;\n")}, + } + all, err := discover(fsys) + if err != nil || len(all) != 2 || all[0].version != "0001" || all[1].version != "0002" { + t.Fatalf("discover: %+v, %v", all, err) + } +} + +func TestOuterTransactionRemoval(t *testing.T) { + for _, tc := range []struct { + in, want string + }{ + {"-- title\n\nBEGIN;\nselect 1;\nCOMMIT;\n", "-- title\n\nselect 1;\n"}, + {"do $$ begin raise notice 'x'; end $$;", "do $$ begin raise notice 'x'; end $$;"}, + } { + got, err := withoutOuterTransaction(tc.in) + if err != nil || got != tc.want { + t.Fatalf("got %q, %v; want %q", got, err, tc.want) + } + } + for _, sql := range []string{"begin;\nselect 1;", "select 1;\ncommit;"} { + if _, err := withoutOuterTransaction(sql); err == nil { + t.Fatalf("accepted unmatched transaction: %q", sql) + } + } +} + +func TestRunDisabledAndConfiguration(t *testing.T) { + getter := func(mapper map[string]string) func(string) string { + return func(key string) string { return mapper[key] } + } + if err := Run(context.Background(), getter(nil)); err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + env map[string]string + want string + }{ + {map[string]string{"DATABASE_AUTO_MIGRATE": "yes"}, "must be true or false"}, + {map[string]string{"DATABASE_AUTO_MIGRATE": "true", "ZHINIAN_DATA_BACKEND": "local"}, "requires ZHINIAN_DATA_BACKEND=postgres"}, + {map[string]string{"DATABASE_AUTO_MIGRATE": "true", "ZHINIAN_DATA_BACKEND": "postgres", "DATABASE_MIGRATION_TIMEOUT_SECONDS": "0"}, "must be an integer"}, + {map[string]string{"DATABASE_AUTO_MIGRATE": "true", "ZHINIAN_DATA_BACKEND": "postgres", "NODE_ENV": "production"}, "DATABASE_APP_ROLE is required"}, + {map[string]string{"DATABASE_AUTO_MIGRATE": "true", "ZHINIAN_DATA_BACKEND": "postgres"}, "DATABASE_MIGRATION_URL or DATABASE_URL is required"}, + {map[string]string{"DATABASE_AUTO_MIGRATE": "true", "ZHINIAN_DATA_BACKEND": "postgres", "DATABASE_APP_ROLE": "bad;role"}, "DATABASE_APP_ROLE must match"}, + {map[string]string{"DATABASE_AUTO_MIGRATE": "true", "ZHINIAN_DATA_BACKEND": "postgres", "DATABASE_MIGRATION_URL": "postgres://admin:secret@localhost/db1", "DATABASE_URL": "postgres://app:secret@localhost/db2"}, "must target the same"}, + } { + err := Run(context.Background(), getter(tc.env)) + if err == nil || !strings.Contains(err.Error(), tc.want) { + t.Fatalf("env %+v: got %v, want %q", tc.env, err, tc.want) + } + } +} diff --git a/backend/internal/migrations/role.go b/backend/internal/migrations/role.go new file mode 100644 index 0000000..f8b4090 --- /dev/null +++ b/backend/internal/migrations/role.go @@ -0,0 +1,90 @@ +package migrations + +import ( + "context" + "fmt" + "regexp" + "strings" + + "github.com/jackc/pgx/v5" +) + +var rolePattern = regexp.MustCompile(`^[a-z_][a-z0-9_]{0,62}$`) + +var appTables = []struct { + name string + privileges string +}{ + {"assets", "SELECT, INSERT, DELETE"}, + {"generation_jobs", "SELECT, INSERT, UPDATE, DELETE"}, + {"seedream_layer_compositions", "SELECT, INSERT, UPDATE, DELETE"}, + {"usage_events", "SELECT, INSERT, UPDATE"}, + {"projects", "SELECT, UPDATE"}, + {"image_templates", "SELECT, INSERT, UPDATE, DELETE"}, + {"platform_organizations", "SELECT, INSERT, UPDATE, DELETE"}, + {"platform_users", "SELECT, INSERT, UPDATE, DELETE"}, + {"platform_account_migrations", "SELECT, INSERT, UPDATE"}, + {"platform_runtime_settings", "SELECT, INSERT, UPDATE"}, + {"billing_price_rules", "SELECT, INSERT, UPDATE"}, + {"billing_wallets", "SELECT, INSERT, UPDATE"}, + {"billing_ledger", "SELECT, INSERT"}, + {"payment_orders", "SELECT, INSERT, UPDATE"}, + {"payment_refunds", "SELECT, INSERT, UPDATE"}, +} + +func provisionRole(ctx context.Context, conn *pgx.Conn, role string) error { + // rolePattern has already validated the identifier. Quote it consistently. + quotedRole := `"` + role + `"` + managed := make([]string, len(appTables)) + for i, table := range appTables { + managed[i] = `public."` + table.name + `"` + } + tx, err := conn.Begin(ctx) + if err != nil { + return safeDBError("begin application role provisioning", "", err) + } + commands := []string{ + "REVOKE CREATE ON SCHEMA public FROM PUBLIC", + "GRANT USAGE ON SCHEMA public TO " + quotedRole, + "REVOKE ALL ON TABLE " + strings.Join(managed, ", ") + " FROM " + quotedRole, + } + for _, table := range appTables { + commands = append(commands, fmt.Sprintf("GRANT %s ON TABLE public.\"%s\" TO %s", table.privileges, table.name, quotedRole)) + } + commands = append(commands, + "REVOKE ALL ON FUNCTION public.claim_generation_jobs(text, integer, integer) FROM PUBLIC", + "REVOKE ALL ON FUNCTION public.billing_post_wallet_entry(text, text, text, text, text, bigint, text, text, text, jsonb) FROM PUBLIC", + "GRANT EXECUTE ON FUNCTION public.claim_generation_jobs(text, integer, integer) TO "+quotedRole, + "GRANT EXECUTE ON FUNCTION public.billing_post_wallet_entry(text, text, text, text, text, bigint, text, text, text, jsonb) TO "+quotedRole, + ) + for _, command := range commands { + if _, err := tx.Exec(ctx, command); err != nil { + _ = tx.Rollback(context.Background()) + return safeDBError("provision application role", "", err) + } + } + if err := tx.Commit(ctx); err != nil { + return safeDBError("commit application role privileges", "", err) + } + tableNames := make([]string, len(appTables)) + privileges := make([]string, len(appTables)) + for i, table := range appTables { + tableNames[i] = "public." + table.name + privileges[i] = strings.ReplaceAll(table.privileges, " ", "") + } + var tablesReady, claimReady, billingReady bool + err = conn.QueryRow(ctx, `SELECT + bool_and(has_table_privilege($1, table_name, privileges)) AS tables_ready, + has_function_privilege($1, 'public.claim_generation_jobs(text,integer,integer)', 'EXECUTE') AS claim_ready, + has_function_privilege($1, + 'public.billing_post_wallet_entry(text,text,text,text,text,bigint,text,text,text,jsonb)', + 'EXECUTE') AS billing_ready + FROM unnest($2::text[], $3::text[]) AS required(table_name, privileges)`, role, tableNames, privileges).Scan(&tablesReady, &claimReady, &billingReady) + if err != nil { + return safeDBError("verify application role privileges", "", err) + } + if !tablesReady || !claimReady || !billingReady { + return fmt.Errorf("application role privilege verification failed") + } + return nil +} diff --git a/backend/internal/migrations/sql/0001_initial_schema.sql b/backend/internal/migrations/sql/0001_initial_schema.sql new file mode 100644 index 0000000..4b007d8 --- /dev/null +++ b/backend/internal/migrations/sql/0001_initial_schema.sql @@ -0,0 +1,467 @@ +create table if not exists assets ( + id text primary key, + owner_id text not null, + kind text not null, + name text not null, + url text not null, + storage_path text, + source text not null, + tags text[] not null default '{}', + metadata jsonb not null default '{}'::jsonb, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +create table if not exists generation_jobs ( + id text primary key, + owner_id text not null, + external_client_id text, + capability text not null, + provider text not null, + req_key text not null, + status text not null, + prompt text, + input_asset_ids text[] not null default '{}', + input_urls text[] not null default '{}', + output_asset_ids text[] not null default '{}', + provider_task_id text, + request_payload jsonb not null default '{}'::jsonb, + response_payload jsonb, + error jsonb, + retry_of text, + idempotency_key text, + idempotency_fingerprint text, + priority integer not null default 0, + attempts integer not null default 0, + max_attempts integer not null default 3, + scheduled_at timestamptz not null default now(), + locked_at timestamptz, + locked_by text, + started_at timestamptz, + completed_at timestamptz, + webhook_url text, + webhook_attempts integer not null default 0, + webhook_last_status jsonb, + usage_context jsonb, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +alter table generation_jobs add column if not exists external_client_id text; +alter table generation_jobs add column if not exists idempotency_key text; +alter table generation_jobs add column if not exists idempotency_fingerprint text; +alter table generation_jobs add column if not exists priority integer not null default 0; +alter table generation_jobs add column if not exists attempts integer not null default 0; +alter table generation_jobs add column if not exists max_attempts integer not null default 3; +alter table generation_jobs add column if not exists scheduled_at timestamptz not null default now(); +alter table generation_jobs add column if not exists locked_at timestamptz; +alter table generation_jobs add column if not exists locked_by text; +alter table generation_jobs add column if not exists started_at timestamptz; +alter table generation_jobs add column if not exists completed_at timestamptz; +alter table generation_jobs add column if not exists webhook_url text; +alter table generation_jobs add column if not exists webhook_attempts integer not null default 0; +alter table generation_jobs add column if not exists webhook_last_status jsonb; +alter table generation_jobs add column if not exists usage_context jsonb; + +create table if not exists usage_events ( + id text primary key, + owner_id text not null, + job_id text not null, + source text not null default 'platform', + capability text not null, + provider text, + req_key text, + account_username text, + account_display_name text, + tenant_id text, + organization_id text, + organization_name text, + quantity integer not null default 1, + estimated_unit text not null default 'job', + created_at timestamptz not null default now() +); + +alter table usage_events add column if not exists source text; +alter table usage_events add column if not exists provider text; +alter table usage_events add column if not exists req_key text; +alter table usage_events add column if not exists account_username text; +alter table usage_events add column if not exists account_display_name text; +alter table usage_events add column if not exists tenant_id text; +alter table usage_events add column if not exists organization_id text; +alter table usage_events add column if not exists organization_name text; +alter table usage_events add column if not exists quantity integer not null default 1; +alter table usage_events add column if not exists estimated_unit text not null default 'job'; + +update usage_events as usage +set source = case + when jobs.external_client_id is not null or usage.owner_id like 'api:%' then 'api' + else 'platform' + end, + provider = coalesce(usage.provider, jobs.provider), + req_key = coalesce(usage.req_key, jobs.req_key), + quantity = 1, + estimated_unit = 'job' +from generation_jobs as jobs +where jobs.id = usage.job_id; + +update usage_events +set source = case when owner_id like 'api:%' then 'api' else 'platform' end, + quantity = 1, + estimated_unit = 'job' +where source is null; + +alter table usage_events alter column source set default 'platform'; +alter table usage_events alter column source set not null; +alter table usage_events alter column estimated_unit set default 'job'; +alter table usage_events drop constraint if exists usage_events_job_id_fkey; + +create table if not exists projects ( + id text primary key, + owner_id text not null, + name text not null, + brief text not null default '', + type text not null default 'custom', + asset_ids text[] not null default '{}', + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +create table if not exists image_templates ( + id text primary key, + owner_id text not null, + name text not null, + description text, + prompt text not null, + preview_image_url text, + settings jsonb not null default '{}'::jsonb, + sort_order integer not null default 0, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +create index if not exists assets_owner_created_idx on assets(owner_id, created_at desc); +create index if not exists generation_jobs_owner_created_idx on generation_jobs(owner_id, created_at desc); +create index if not exists generation_jobs_status_idx on generation_jobs(status); +create index if not exists generation_jobs_claim_idx on generation_jobs(status, scheduled_at, locked_at, priority desc); +create index if not exists generation_jobs_external_client_idx on generation_jobs(owner_id, external_client_id, created_at desc); +create unique index if not exists generation_jobs_idempotency_idx + on generation_jobs(owner_id, external_client_id, idempotency_key) + where external_client_id is not null and idempotency_key is not null; +create index if not exists usage_events_owner_created_idx on usage_events(owner_id, created_at desc); +do $$ +begin + if exists ( + select 1 + from usage_events + group by job_id + having count(*) > 1 + ) then + raise exception using + errcode = '23505', + message = 'USAGE_EVENTS_DUPLICATE_JOB_ID: back up and clean duplicate usage_events.job_id rows before retrying this migration'; + end if; +end; +$$; +create unique index if not exists usage_events_job_id_idx on usage_events(job_id); +create index if not exists usage_events_source_created_idx on usage_events(source, created_at desc); +create index if not exists usage_events_organization_created_idx on usage_events(organization_id, created_at desc); +create index if not exists image_templates_owner_sort_idx on image_templates(owner_id, sort_order asc, updated_at desc); + +create or replace function claim_generation_jobs( + p_worker_id text, + p_limit integer default 1, + p_lock_timeout_seconds integer default 300 +) +returns setof generation_jobs +language plpgsql +set search_path = public, pg_temp +as $$ +declare + v_now timestamptz := now(); +begin + return query + with candidates as ( + select id + from generation_jobs + where status in ('queued', 'running') + and coalesce(scheduled_at, created_at) <= v_now + and ( + locked_at is null + or locked_at < v_now - make_interval(secs => p_lock_timeout_seconds) + ) + order by coalesce(priority, 0) desc, coalesce(scheduled_at, created_at) asc, created_at asc + limit greatest(1, least(coalesce(p_limit, 1), 20)) + for update skip locked + ), + updated as ( + update generation_jobs + set locked_at = v_now, + locked_by = p_worker_id, + started_at = coalesce(generation_jobs.started_at, v_now), + updated_at = v_now + where id in (select id from candidates) + returning generation_jobs.* + ) + select * from updated; +end; +$$; + +revoke all on function claim_generation_jobs(text, integer, integer) from public; + +create table if not exists platform_organizations ( + id text primary key, + name text not null unique, + status text not null default 'active' check (status in ('active', 'disabled')), + archive_owner_id text not null unique, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +create table if not exists platform_users ( + id text primary key, + phone text not null unique, + display_name text not null, + role text not null default 'user' check (role in ('super_admin', 'organization_admin', 'user')), + organization_id text references platform_organizations(id) on delete set null, + status text not null default 'active' check (status in ('active', 'disabled')), + password_hash text not null, + password_salt text not null, + failed_login_count integer not null default 0, + locked_until timestamptz, + session_version integer not null default 1, + last_login_at timestamptz, + legacy_subject text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +create table if not exists platform_account_migrations ( + id text primary key, + legacy_owner_id text not null unique, + legacy_phone text, + platform_user_id text not null, + created_at timestamptz not null default now() +); + +create index if not exists platform_users_organization_idx on platform_users(organization_id, created_at desc); +create index if not exists platform_users_status_idx on platform_users(status, role); +create index if not exists platform_account_migrations_user_idx on platform_account_migrations(platform_user_id); + +alter table generation_jobs add column if not exists billing jsonb; +alter table usage_events add column if not exists charged_amount_fen bigint; +alter table usage_events add column if not exists currency text; + +create table if not exists billing_price_rules ( + id text primary key, + provider text not null check (provider in ('volcengine-visual', 'evolink', 'seedance', 'bailian', 'mock')), + capability text not null check (capability in ('image.generate', 'video.generate')), + req_key text, + variant_key text, + unit text not null check (unit in ('request', 'image', 'video_second')), + standard_unit_price_fen bigint not null check (standard_unit_price_fen >= 0), + markup_multiplier numeric(12, 4) not null default 1.0000 check (markup_multiplier >= 1), + enabled boolean not null default true, + conditions jsonb not null default '{}'::jsonb, + quantity_source text check (quantity_source in ('request', 'image_count', 'duration')), + priority integer not null default 0, + note text, + source jsonb, + parameter_dimensions jsonb not null default '[]'::jsonb, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +alter table billing_price_rules add column if not exists variant_key text; +alter table billing_price_rules add column if not exists source jsonb; +alter table billing_price_rules add column if not exists conditions jsonb not null default '{}'::jsonb; +alter table billing_price_rules add column if not exists quantity_source text; +alter table billing_price_rules add column if not exists priority integer not null default 0; +alter table billing_price_rules add column if not exists parameter_dimensions jsonb not null default '[]'::jsonb; +alter table billing_price_rules drop constraint if exists billing_price_rules_quantity_source_check; +alter table billing_price_rules add constraint billing_price_rules_quantity_source_check check (quantity_source is null or quantity_source in ('request', 'image_count', 'duration')); + +drop index if exists billing_price_rules_match_idx; +create unique index if not exists billing_price_rules_match_idx + on billing_price_rules(provider, capability, coalesce(req_key, ''), coalesce(variant_key, ''), coalesce(conditions, '{}'::jsonb)); + +create table if not exists billing_wallets ( + organization_id text primary key references platform_organizations(id) on delete restrict, + balance_fen bigint not null default 0 check (balance_fen >= 0), + total_recharged_fen bigint not null default 0 check (total_recharged_fen >= 0), + total_charged_fen bigint not null default 0 check (total_charged_fen >= 0), + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); + +create table if not exists billing_ledger ( + id text primary key, + organization_id text not null references platform_organizations(id) on delete restrict, + account_id text, + job_id text, + kind text not null check (kind in ('recharge', 'charge', 'refund', 'adjustment')), + delta_fen bigint not null check (delta_fen <> 0), + balance_after_fen bigint not null check (balance_after_fen >= 0), + currency text not null default 'CNY' check (currency = 'CNY'), + idempotency_key text not null, + description text not null, + metadata jsonb not null default '{}'::jsonb, + created_at timestamptz not null default now() +); + +do $$ +declare + v_constraint record; + v_index record; +begin + for v_constraint in + select constraint_schema, constraint_name + from information_schema.table_constraints + where table_schema = current_schema() + and table_name = 'billing_ledger' + and constraint_type = 'UNIQUE' + and array( + select key_column_usage.column_name::text + from information_schema.key_column_usage + where key_column_usage.constraint_schema = table_constraints.constraint_schema + and key_column_usage.constraint_name = table_constraints.constraint_name + and key_column_usage.table_name = table_constraints.table_name + order by key_column_usage.ordinal_position + ) = array['idempotency_key']::text[] + loop + execute format('alter table %I.%I drop constraint %I', current_schema(), 'billing_ledger', v_constraint.constraint_name); + end loop; + + for v_index in + select indexes.schemaname, indexes.indexname + from pg_indexes as indexes + join pg_class as index_class on index_class.relname = indexes.indexname + join pg_namespace as index_namespace + on index_namespace.oid = index_class.relnamespace + and index_namespace.nspname = indexes.schemaname + join pg_index as index_metadata on index_metadata.indexrelid = index_class.oid + join pg_attribute as indexed_column + on indexed_column.attrelid = index_metadata.indrelid + and indexed_column.attnum = index_metadata.indkey[0] + left join pg_constraint as backing_constraint on backing_constraint.conindid = index_class.oid + where indexes.schemaname = current_schema() + and indexes.tablename = 'billing_ledger' + and index_metadata.indisunique + and index_metadata.indnkeyatts = 1 + and indexed_column.attname = 'idempotency_key' + and backing_constraint.oid is null + loop + execute format('drop index %I.%I', v_index.schemaname, v_index.indexname); + end loop; +end; +$$; + +create unique index if not exists billing_ledger_organization_idempotency_idx + on billing_ledger(organization_id, idempotency_key); +create index if not exists billing_ledger_organization_created_idx on billing_ledger(organization_id, created_at desc); +create index if not exists billing_ledger_account_created_idx on billing_ledger(account_id, created_at desc); +create index if not exists billing_ledger_job_idx on billing_ledger(job_id); + +create or replace function billing_post_wallet_entry( + p_ledger_id text, + p_organization_id text, + p_account_id text, + p_job_id text, + p_kind text, + p_delta_fen bigint, + p_currency text, + p_idempotency_key text, + p_description text, + p_metadata jsonb +) +returns table ( + ledger_id text, + balance_after_fen bigint, + balance_fen bigint, + total_recharged_fen bigint, + total_charged_fen bigint, + created_at timestamptz, + updated_at timestamptz, + delta_fen bigint +) +language plpgsql +set search_path = public, pg_temp +as $$ +declare + v_existing billing_ledger%rowtype; + v_wallet billing_wallets%rowtype; + v_entry billing_ledger%rowtype; + v_account_id text; +begin + if p_currency <> 'CNY' then + raise exception 'BILLING_UNSUPPORTED_CURRENCY'; + end if; + if p_delta_fen = 0 then + raise exception 'BILLING_ZERO_DELTA'; + end if; + + v_account_id := case when p_kind in ('recharge', 'adjustment') then null else p_account_id end; + + perform pg_advisory_xact_lock( + hashtextextended(jsonb_build_array(p_organization_id, p_idempotency_key)::text, 0) + ); + + select * into v_existing + from billing_ledger + where organization_id = p_organization_id + and idempotency_key = p_idempotency_key; + if found then + if v_existing.account_id is distinct from v_account_id + or v_existing.job_id is distinct from p_job_id + or v_existing.kind is distinct from p_kind + or v_existing.delta_fen is distinct from p_delta_fen + or v_existing.currency is distinct from p_currency + then + raise exception using + errcode = 'P0001', + message = 'BILLING_IDEMPOTENCY_PAYLOAD_MISMATCH'; + end if; + + select * into v_wallet from billing_wallets where organization_id = p_organization_id; + return query select v_existing.id, v_existing.balance_after_fen, v_wallet.balance_fen, + v_wallet.total_recharged_fen, v_wallet.total_charged_fen, v_existing.created_at, + v_wallet.updated_at, v_existing.delta_fen; + return; + end if; + + insert into billing_wallets(organization_id) + values (p_organization_id) + on conflict (organization_id) do nothing; + + select * into v_wallet from billing_wallets + where organization_id = p_organization_id + for update; + + if p_delta_fen < 0 and v_wallet.balance_fen < abs(p_delta_fen) then + raise exception 'BILLING_INSUFFICIENT_BALANCE'; + end if; + + update billing_wallets + set balance_fen = v_wallet.balance_fen + p_delta_fen, + total_recharged_fen = v_wallet.total_recharged_fen + case when p_kind = 'recharge' and p_delta_fen > 0 then p_delta_fen else 0 end, + total_charged_fen = v_wallet.total_charged_fen + case when p_kind = 'charge' and p_delta_fen < 0 then abs(p_delta_fen) else 0 end, + updated_at = now() + where organization_id = p_organization_id + returning * into v_wallet; + + insert into billing_ledger( + id, organization_id, account_id, job_id, kind, delta_fen, + balance_after_fen, currency, idempotency_key, description, metadata + ) values ( + p_ledger_id, p_organization_id, + v_account_id, + p_job_id, p_kind, p_delta_fen, + v_wallet.balance_fen, p_currency, p_idempotency_key, p_description, coalesce(p_metadata, '{}'::jsonb) + ) returning * into v_entry; + + return query select v_entry.id, v_entry.balance_after_fen, v_wallet.balance_fen, + v_wallet.total_recharged_fen, v_wallet.total_charged_fen, v_entry.created_at, + v_wallet.updated_at, v_entry.delta_fen; +end; +$$; + +revoke all on function billing_post_wallet_entry(text, text, text, text, text, bigint, text, text, text, jsonb) from public; diff --git a/backend/internal/migrations/sql/0002_generation_lifecycle_fencing.sql b/backend/internal/migrations/sql/0002_generation_lifecycle_fencing.sql new file mode 100644 index 0000000..22481b7 --- /dev/null +++ b/backend/internal/migrations/sql/0002_generation_lifecycle_fencing.sql @@ -0,0 +1,69 @@ +-- Recoverable generation finalization and charge-before-dispatch fencing. +-- Additive so the previous release remains rollback-compatible. + +alter table public.generation_jobs + add column if not exists dispatch_ready_at timestamptz; + +alter table public.generation_jobs + add column if not exists finalized_at timestamptz; + +alter table public.generation_jobs + add column if not exists provider_dispatch_started_at timestamptz; + +-- Existing rows were created before dispatch fencing and are therefore ready. +update public.generation_jobs +set dispatch_ready_at = coalesce(dispatch_ready_at, created_at, now()) +where dispatch_ready_at is null; + +-- Rows already terminal before this migration have completed their legacy +-- finalization path and must not be replayed into billing/webhook side effects. +update public.generation_jobs +set finalized_at = coalesce(finalized_at, completed_at, updated_at, now()) +where finalized_at is null + and status in ('succeeded', 'failed', 'expired', 'cancelled'); + +create index if not exists generation_jobs_finalize_claim_idx + on public.generation_jobs(finalized_at, scheduled_at, locked_at, priority desc); + +create or replace function public.claim_generation_jobs( + p_worker_id text, + p_limit integer default 1, + p_lock_timeout_seconds integer default 300 +) +returns setof public.generation_jobs +language plpgsql +set search_path = public, pg_temp +as $$ +declare + v_now timestamptz := now(); +begin + return query + with candidates as ( + select id + from public.generation_jobs + where dispatch_ready_at is not null + and finalized_at is null + and status in ('queued', 'running', 'succeeded', 'failed', 'expired', 'cancelled') + and coalesce(scheduled_at, created_at) <= v_now + and ( + locked_at is null + or locked_at < v_now - make_interval(secs => p_lock_timeout_seconds) + ) + order by coalesce(priority, 0) desc, coalesce(scheduled_at, created_at) asc, created_at asc + limit greatest(1, least(coalesce(p_limit, 1), 20)) + for update skip locked + ), + updated as ( + update public.generation_jobs + set locked_at = v_now, + locked_by = p_worker_id, + started_at = coalesce(public.generation_jobs.started_at, v_now), + updated_at = v_now + where id in (select id from candidates) + returning public.generation_jobs.* + ) + select * from updated; +end; +$$; + +revoke all on function public.claim_generation_jobs(text, integer, integer) from public; diff --git a/backend/internal/migrations/sql/0003_platform_runtime_settings.sql b/backend/internal/migrations/sql/0003_platform_runtime_settings.sql new file mode 100644 index 0000000..e03d480 --- /dev/null +++ b/backend/internal/migrations/sql/0003_platform_runtime_settings.sql @@ -0,0 +1,12 @@ +-- Mutable provider configuration is relational runtime state. Values are +-- intentionally plaintext in this first functional migration; at-rest +-- encryption and key rotation are separate hardening work. +create table if not exists platform_runtime_settings ( + setting_key text primary key, + setting_value text not null, + revision bigint not null default 1 check (revision > 0), + updated_at timestamptz not null default now() +); + +create index if not exists platform_runtime_settings_updated_at_idx + on platform_runtime_settings(updated_at desc); diff --git a/backend/internal/migrations/sql/0004_seedream_billing_provider.sql b/backend/internal/migrations/sql/0004_seedream_billing_provider.sql new file mode 100644 index 0000000..2c2f210 --- /dev/null +++ b/backend/internal/migrations/sql/0004_seedream_billing_provider.sql @@ -0,0 +1,14 @@ +-- Allow the independently routed Ark Seedream image provider in the durable +-- billing catalog. Keep the historical migration immutable and widen only the +-- existing provider constraint. + +begin; + +alter table public.billing_price_rules + drop constraint if exists billing_price_rules_provider_check; + +alter table public.billing_price_rules + add constraint billing_price_rules_provider_check + check (provider in ('volcengine-visual', 'evolink', 'seedance', 'seedream', 'bailian', 'mock')); + +commit; diff --git a/backend/internal/migrations/sql/0005_seedream_layer_compositions.sql b/backend/internal/migrations/sql/0005_seedream_layer_compositions.sql new file mode 100644 index 0000000..771cb6e --- /dev/null +++ b/backend/internal/migrations/sql/0005_seedream_layer_compositions.sql @@ -0,0 +1,14 @@ +create table if not exists public.seedream_layer_compositions ( + job_id text primary key references public.generation_jobs(id) on delete cascade, + owner_id text not null, + base_asset_id text not null, + base_visible boolean not null default true, + layers jsonb not null default '[]'::jsonb, + version bigint not null default 1 check (version > 0), + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + constraint seedream_layer_compositions_layers_array_check check (jsonb_typeof(layers) = 'array') +); + +create index if not exists seedream_layer_compositions_owner_updated_idx + on public.seedream_layer_compositions(owner_id, updated_at desc); diff --git a/backend/internal/migrations/sql/0006_minimax_h3_billing_provider.sql b/backend/internal/migrations/sql/0006_minimax_h3_billing_provider.sql new file mode 100644 index 0000000..e3d28b3 --- /dev/null +++ b/backend/internal/migrations/sql/0006_minimax_h3_billing_provider.sql @@ -0,0 +1,13 @@ +-- Allow MiniMax H3 rules in the durable billing catalog. Runtime provider +-- credentials already use the generic platform_runtime_settings table. + +begin; + +alter table public.billing_price_rules + drop constraint if exists billing_price_rules_provider_check; + +alter table public.billing_price_rules + add constraint billing_price_rules_provider_check + check (provider in ('volcengine-visual', 'evolink', 'seedance', 'seedream', 'bailian', 'minimax', 'mock')); + +commit; diff --git a/backend/internal/migrations/sql/0007_wechat_native_payments.sql b/backend/internal/migrations/sql/0007_wechat_native_payments.sql new file mode 100644 index 0000000..21d0f74 --- /dev/null +++ b/backend/internal/migrations/sql/0007_wechat_native_payments.sql @@ -0,0 +1,32 @@ +-- Orders are written before calling WeChat. Keep them when a user or +-- organization is deleted so paid money cannot lose its audit trail. +create table if not exists public.payment_orders ( + id text primary key check (length(id) between 1 and 32 and id ~ '^[A-Za-z0-9_-]+$'), + organization_id text not null references public.platform_organizations(id) on delete restrict, + account_id text not null references public.platform_users(id) on delete restrict, + request_key text not null check (length(request_key) between 1 and 64 and request_key ~ '^[A-Za-z0-9_-]+$'), + mch_id text not null check (length(mch_id) between 1 and 64), + app_id text not null check (length(app_id) between 1 and 64), + amount_fen bigint not null check (amount_fen between 1 and 1000000), + currency text not null check (currency = 'CNY'), + status text not null default 'pending' check (status in ('pending', 'paid', 'closed')), + code_url text, + transaction_id text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + expires_at timestamptz not null, + paid_at timestamptz, + constraint payment_orders_paid_fields_check check ( + (status = 'paid' and transaction_id is not null and length(transaction_id) > 0 and paid_at is not null) + or (status <> 'paid' and transaction_id is null and paid_at is null) + ), + constraint payment_orders_expiry_check check (expires_at > created_at), + constraint payment_orders_org_request_unique unique (organization_id, request_key) +); + +create unique index if not exists payment_orders_provider_transaction_unique + on public.payment_orders(mch_id, transaction_id) where transaction_id is not null; +create index if not exists payment_orders_org_created_idx + on public.payment_orders(organization_id, created_at desc); +create index if not exists payment_orders_pending_check_idx + on public.payment_orders(updated_at, created_at) where status = 'pending'; diff --git a/backend/internal/migrations/sql/0008_wechat_refunds.sql b/backend/internal/migrations/sql/0008_wechat_refunds.sql new file mode 100644 index 0000000..4a573fb --- /dev/null +++ b/backend/internal/migrations/sql/0008_wechat_refunds.sql @@ -0,0 +1,34 @@ +-- Reserve each requested refund against its original, successful payment. +-- A successful external refund can exceed the current wallet balance. +alter table public.billing_wallets drop constraint if exists billing_wallets_balance_fen_check; +alter table public.billing_ledger drop constraint if exists billing_ledger_balance_after_fen_check; +alter table public.billing_ledger drop constraint if exists billing_ledger_kind_check; +alter table public.billing_ledger add constraint billing_ledger_kind_check + check (kind in ('recharge', 'charge', 'refund', 'adjustment', 'recharge_refund')); + +create table public.payment_refunds ( + id text primary key check (length(id) between 1 and 32 and id ~ '^[A-Za-z0-9_-]+$'), + order_id text not null references public.payment_orders(id) on delete restrict, + organization_id text not null references public.platform_organizations(id) on delete restrict, + operator_id text not null references public.platform_users(id) on delete restrict, + request_key text not null check (length(request_key) between 1 and 64 and request_key ~ '^[A-Za-z0-9_-]+$'), + mch_id text not null check (length(mch_id) between 1 and 64), + transaction_id text not null check (length(transaction_id) > 0), + provider_id text, + amount_fen bigint not null check (amount_fen > 0), + total_fen bigint not null check (total_fen > 0 and total_fen >= amount_fen), + currency text not null check (currency = 'CNY'), + reason text not null, + status text not null default 'pending' check (status in ('pending', 'processing', 'success', 'closed', 'abnormal', 'rejected')), + failure_reason text not null default '', + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + succeeded_at timestamptz, + constraint payment_refunds_request_unique unique (order_id, request_key), + constraint payment_refunds_success_check check ((status = 'success') = (succeeded_at is not null)) +); +create unique index payment_refunds_provider_unique on public.payment_refunds(mch_id, provider_id) + where provider_id is not null; +create index payment_refunds_order_idx on public.payment_refunds(order_id, created_at desc, id desc); +create index payment_refunds_pending_idx on public.payment_refunds(updated_at, created_at, id) + where status in ('pending', 'processing', 'abnormal'); diff --git a/backend/internal/payments/model.go b/backend/internal/payments/model.go new file mode 100644 index 0000000..a8ba5b0 --- /dev/null +++ b/backend/internal/payments/model.go @@ -0,0 +1,84 @@ +// Package payments manages WeChat Native recharge orders for organization wallets. +package payments + +import ( + "context" + "errors" + "net/http" + "time" +) + +var ( + ErrNotFound = errors.New("payment order not found") + ErrConflict = errors.New("payment order conflicts with existing data") + ErrInvalidAmount = errors.New("invalid payment amount") + ErrUnavailable = errors.New("payment unavailable") + ErrVerification = errors.New("payment verification failed") + ErrRemoteNotFound = errors.New("remote payment order not found") +) + +const ( + StatusPending = "pending" + StatusPaid = "paid" + StatusClosed = "closed" +) + +type Order struct { + ID string `json:"id"` + OrganizationID string `json:"organizationId"` + AccountID string `json:"accountId"` + RequestKey string `json:"-"` + MchID string `json:"-"` + AppID string `json:"-"` + AmountFen int64 `json:"amountFen"` + Currency string `json:"currency"` + Status string `json:"status"` + CodeURL string `json:"codeUrl,omitempty"` + TransactionID string `json:"transactionId,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + ExpiresAt time.Time `json:"expiresAt"` + PaidAt *time.Time `json:"paidAt,omitempty"` +} + +type Transaction struct { + OrderID, MchID, AppID, TransactionID, TradeState, Currency string + AmountFen int64 + SuccessTime time.Time +} + +// Repository settlement must validate the stored order identity and amount, +// atomically post the wallet ledger and mark paid, and reject reused transaction IDs. +type Repository interface { + CreatePaymentOrder(context.Context, Order) (Order, error) + GetPaymentOrder(context.Context, string) (Order, error) + ListPaymentOrders(context.Context, string, int) ([]Order, error) + PendingPaymentOrders(context.Context, int) ([]Order, error) + UpdatePaymentOrder(context.Context, string, string, string) (Order, error) + SettlePaymentOrder(context.Context, Transaction) (Order, error) +} + +type Provider interface { + Create(context.Context, Order) (string, error) + Query(context.Context, string) (Transaction, error) + Close(context.Context, string) error + ParseNotification(context.Context, *http.Request) (Transaction, error) +} + +type Config struct { + Enabled bool + MchID, AppID, NotifyURL string + MerchantSerial, PrivateKeyPEM, APIv3Key string + WechatPublicKeyID, WechatPublicKeyPEM string + PresetAmountsFen []int64 + MinAmountFen, MaxAmountFen int64 + OrderTTL time.Duration +} + +type Options struct { + Enabled bool `json:"enabled"` + CanRecharge bool `json:"canRecharge"` + PresetAmountsFen []int64 `json:"presetAmountsFen"` + MinAmountFen int64 `json:"minAmountFen"` + MaxAmountFen int64 `json:"maxAmountFen"` +} diff --git a/backend/internal/payments/refund_model.go b/backend/internal/payments/refund_model.go new file mode 100644 index 0000000..e8736bf --- /dev/null +++ b/backend/internal/payments/refund_model.go @@ -0,0 +1,78 @@ +package payments + +import ( + "context" + "net/http" + "time" +) + +const ( + RefundPending = "pending" + RefundProcessing = "processing" + RefundSuccess = "success" + RefundClosed = "closed" + RefundAbnormal = "abnormal" + RefundRejected = "rejected" +) + +type Refund struct { + ID string `json:"id"` + OrderID string `json:"orderId"` + OrganizationID string `json:"organizationId"` + OperatorID string `json:"operatorId"` + OperatorName string `json:"operatorName,omitempty"` + RequestKey string `json:"-"` + MchID string `json:"-"` + TransactionID string `json:"transactionId"` + ProviderID string `json:"providerId,omitempty"` + AmountFen int64 `json:"amountFen"` + TotalFen int64 `json:"totalFen"` + Currency string `json:"currency"` + Reason string `json:"reason"` + Status string `json:"status"` + FailureReason string `json:"failureReason,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + SucceededAt *time.Time `json:"succeededAt,omitempty"` +} + +type RefundTransaction struct { + ID, OrderID, MchID, TransactionID, ProviderID, Status, Currency string + AmountFen, TotalFen int64 + SuccessTime time.Time +} + +type AdminOrder struct { + Order + OrganizationName string `json:"organizationName"` + AccountName string `json:"accountName"` + RefundedFen int64 `json:"refundedFen"` + RefundingFen int64 `json:"refundingFen"` + RefundableFen int64 `json:"refundableFen"` +} + +type AdminOrdersPage struct { + Orders []AdminOrder `json:"orders"` + HasMore bool `json:"hasMore"` + Enabled bool `json:"enabled"` +} + +// Creating a refund reserves the remaining refundable amount under the payment +// order lock. Successful settlement atomically debits the wallet once, allowing +// that specific debit to make the wallet balance negative. +type RefundRepository interface { + RejectPaymentRefund(context.Context, string, string) (Refund, error) + ListAdminPaymentOrders(context.Context, string, int, int) ([]AdminOrder, error) + CreatePaymentRefund(context.Context, Refund) (Refund, error) + GetPaymentRefund(context.Context, string) (Refund, error) + ListPaymentRefunds(context.Context, string) ([]Refund, error) + PendingPaymentRefunds(context.Context, int) ([]Refund, error) + TouchPaymentRefund(context.Context, string) (Refund, error) + RecordPaymentRefund(context.Context, RefundTransaction) (Refund, error) +} + +type RefundProvider interface { + CreateRefund(context.Context, Refund) (RefundTransaction, error) + QueryRefund(context.Context, string) (RefundTransaction, error) + ParseRefundNotification(context.Context, *http.Request) (RefundTransaction, error) +} diff --git a/backend/internal/payments/refunds.go b/backend/internal/payments/refunds.go new file mode 100644 index 0000000..98161e9 --- /dev/null +++ b/backend/internal/payments/refunds.go @@ -0,0 +1,215 @@ +package payments + +import ( + "context" + "errors" + "fmt" + "net/http" + "strings" + "time" +) + +func (s *Service) refundDependencies() (RefundRepository, RefundProvider, error) { + repo, repoOK := s.repo.(RefundRepository) + provider, providerOK := s.provider.(RefundProvider) + if !s.Options().CanRecharge || !repoOK || !providerOK { + return nil, nil, ErrUnavailable + } + return repo, provider, nil +} + +func (s *Service) AdminList(ctx context.Context, organizationID string, limit, offset int) (AdminOrdersPage, error) { + repo, ok := s.repo.(RefundRepository) + if !ok { + return AdminOrdersPage{}, ErrUnavailable + } + if limit < 1 || limit > 100 || offset < 0 { + return AdminOrdersPage{}, ErrInvalidAmount + } + orders, err := repo.ListAdminPaymentOrders(ctx, organizationID, limit+1, offset) + if err != nil { + return AdminOrdersPage{}, err + } + page := AdminOrdersPage{Orders: orders, Enabled: s.Options().CanRecharge} + if len(orders) > limit { + page.Orders = orders[:limit] + page.HasMore = true + } + return page, nil +} + +func (s *Service) CreateRefund(ctx context.Context, orderID, operatorID, requestKey, reason string, amountFen int64) (Refund, error) { + repo, provider, err := s.refundDependencies() + if err != nil { + return Refund{}, err + } + reason = strings.TrimSpace(reason) + if orderID == "" || operatorID == "" || !requestKeyPattern.MatchString(requestKey) || reason == "" || len([]byte(reason)) > 80 || amountFen <= 0 { + return Refund{}, ErrInvalidAmount + } + order, err := s.repo.GetPaymentOrder(ctx, orderID) + if err != nil { + return Refund{}, err + } + if order.Status != StatusPaid || order.TransactionID == "" || order.MchID != s.config.MchID || order.AppID != s.config.AppID || order.Currency != "CNY" || amountFen > order.AmountFen { + return Refund{}, ErrConflict + } + id, err := newOrderID() + if err != nil { + return Refund{}, err + } + now := s.now().UTC() + wanted := Refund{ID: id, OrderID: orderID, OrganizationID: order.OrganizationID, OperatorID: operatorID, + RequestKey: requestKey, MchID: order.MchID, TransactionID: order.TransactionID, + AmountFen: amountFen, TotalFen: order.AmountFen, Currency: order.Currency, Reason: reason, + Status: RefundPending, CreatedAt: now, UpdatedAt: now} + refund, err := repo.CreatePaymentRefund(ctx, wanted) + if err != nil { + return Refund{}, err + } + if refund.OrderID != wanted.OrderID || refund.OrganizationID != wanted.OrganizationID || refund.OperatorID != wanted.OperatorID || refund.RequestKey != wanted.RequestKey || refund.MchID != wanted.MchID || refund.TransactionID != wanted.TransactionID || refund.AmountFen != wanted.AmountFen || refund.TotalFen != wanted.TotalFen || refund.Currency != wanted.Currency || refund.Reason != wanted.Reason { + return Refund{}, ErrConflict + } + if refund.Status != RefundPending { + return refund, nil + } + if refund.ID != wanted.ID { + return refund, nil // A repeated request waits for reconciliation of the same remote ID. + } + // The durable refund ID is the WeChat out_refund_no. Retrying it never creates a second refund. + txn, err := provider.CreateRefund(ctx, refund) + if err != nil { + var rejected *RefundRejectionError + if errors.As(err, &rejected) { + return rejectRefund(ctx, repo, refund.ID, rejected.Reason) + } + return refund, nil + } // Remote acceptance can be ambiguous; reconciliation queries this exact ID. + return s.recordRefund(ctx, repo, refund, txn) +} + +func (s *Service) GetRefund(ctx context.Context, id string) (Refund, error) { + repo, ok := s.repo.(RefundRepository) + if !ok { + return Refund{}, ErrUnavailable + } + return repo.GetPaymentRefund(ctx, id) +} + +func (s *Service) ListRefunds(ctx context.Context, orderID string) ([]Refund, error) { + repo, ok := s.repo.(RefundRepository) + if !ok { + return nil, ErrUnavailable + } + return repo.ListPaymentRefunds(ctx, orderID) +} + +func (s *Service) RefundNotify(ctx context.Context, request *http.Request) error { + repo, provider, err := s.refundDependencies() + if err != nil { + return err + } + txn, err := provider.ParseRefundNotification(ctx, request) + if err != nil { + return err + } + refund, err := repo.GetPaymentRefund(ctx, txn.ID) + if err != nil { + return err + } + _, err = s.recordRefund(ctx, repo, refund, txn) + return err +} + +func (s *Service) recordRefund(ctx context.Context, repo RefundRepository, refund Refund, txn RefundTransaction) (Refund, error) { + if txn.ID != refund.ID || txn.OrderID != refund.OrderID || txn.MchID != refund.MchID || txn.MchID != s.config.MchID || + txn.TransactionID != refund.TransactionID || txn.ProviderID == "" || txn.AmountFen != refund.AmountFen || + txn.TotalFen != refund.TotalFen || txn.Currency != refund.Currency || + (txn.Status != RefundProcessing && txn.Status != RefundSuccess && txn.Status != RefundClosed && txn.Status != RefundAbnormal) || + (txn.Status == RefundSuccess && txn.SuccessTime.IsZero()) { + return Refund{}, ErrVerification + } + order, err := s.repo.GetPaymentOrder(ctx, txn.OrderID) + if err != nil { + return Refund{}, err + } + if order.Status != StatusPaid || order.ID != refund.OrderID || order.MchID != refund.MchID || order.TransactionID != refund.TransactionID || order.AmountFen != refund.TotalFen || order.Currency != refund.Currency || order.OrganizationID != refund.OrganizationID { + return Refund{}, ErrVerification + } + return repo.RecordPaymentRefund(ctx, txn) +} + +func (s *Service) reconcileRefunds(ctx context.Context) error { + repo, provider, err := s.refundDependencies() + if err != nil { + return nil + } // Existing payment-only providers have no refund queue. + refunds, err := repo.PendingPaymentRefunds(ctx, 100) + if err != nil { + return err + } + var failures []error + for _, refund := range refunds { + if ctx.Err() != nil { + return ctx.Err() + } + if s.now().Sub(refund.UpdatedAt) < refundQueryInterval(s.now().Sub(refund.CreatedAt)) { + continue + } + current, err := repo.TouchPaymentRefund(ctx, refund.ID) + if err != nil { + failures = append(failures, fmt.Errorf("refund %s: %w", refund.ID, err)) + continue + } + if current.Status == RefundClosed || current.Status == RefundSuccess || current.Status == RefundRejected { + continue + } + txn, err := provider.QueryRefund(ctx, current.ID) + if errors.Is(err, ErrRemoteNotFound) { + // An earlier create could have timed out before receipt; the same out_refund_no is safe to retry. + order, orderErr := s.repo.GetPaymentOrder(ctx, current.OrderID) + if orderErr != nil || order.AppID != s.config.AppID || order.MchID != s.config.MchID { + failures = append(failures, fmt.Errorf("refund %s: %w", current.ID, ErrVerification)) + continue + } + txn, err = provider.CreateRefund(ctx, current) + var rejected *RefundRejectionError + if errors.As(err, &rejected) { + if _, rejectErr := rejectRefund(ctx, repo, current.ID, rejected.Reason); rejectErr != nil { + failures = append(failures, fmt.Errorf("refund %s rejection: %w", current.ID, rejectErr)) + } + continue + } + } + if err != nil { + failures = append(failures, fmt.Errorf("refund %s: %w", current.ID, err)) + continue + } + if _, err = s.recordRefund(ctx, repo, current, txn); err != nil { + failures = append(failures, fmt.Errorf("refund %s: %w", current.ID, err)) + } + } + return errors.Join(failures...) +} + +func rejectRefund(ctx context.Context, repo RefundRepository, id, reason string) (Refund, error) { + refund, err := repo.RejectPaymentRefund(ctx, id, reason) + if errors.Is(err, ErrConflict) { + // A signed provider callback can win this race. Return its recorded state. + latest, getErr := repo.GetPaymentRefund(ctx, id) + if getErr == nil && latest.Status != RefundPending { + return latest, nil + } + } + return refund, err +} + +func refundQueryInterval(age time.Duration) time.Duration { + if age < 5*time.Minute { + return time.Minute + } + if age < time.Hour { + return 2 * time.Minute + } + return 5 * time.Minute +} diff --git a/backend/internal/payments/refunds_test.go b/backend/internal/payments/refunds_test.go new file mode 100644 index 0000000..f84c1ec --- /dev/null +++ b/backend/internal/payments/refunds_test.go @@ -0,0 +1,193 @@ +package payments + +import ( + "context" + "errors" + "net/http" + "testing" + "time" +) + +type refundTestRepo struct { + *testRepo + refunds map[string]Refund + byRefundKey map[string]string + records int +} + +func (r *refundTestRepo) ListAdminPaymentOrders(_ context.Context, _ string, _, _ int) ([]AdminOrder, error) { + return nil, nil +} +func (r *refundTestRepo) CreatePaymentRefund(_ context.Context, refund Refund) (Refund, error) { + if id := r.byRefundKey[refund.RequestKey]; id != "" { + return r.refunds[id], nil + } + r.refunds[refund.ID] = refund + r.byRefundKey[refund.RequestKey] = refund.ID + return refund, nil +} +func (r *refundTestRepo) GetPaymentRefund(_ context.Context, id string) (Refund, error) { + refund, ok := r.refunds[id] + if !ok { + return Refund{}, ErrNotFound + } + return refund, nil +} +func (r *refundTestRepo) ListPaymentRefunds(_ context.Context, orderID string) ([]Refund, error) { + var out []Refund + for _, refund := range r.refunds { + if refund.OrderID == orderID { + out = append(out, refund) + } + } + return out, nil +} +func (r *refundTestRepo) PendingPaymentRefunds(_ context.Context, _ int) ([]Refund, error) { + var out []Refund + for _, refund := range r.refunds { + if refund.Status != RefundSuccess && refund.Status != RefundClosed && refund.Status != RefundRejected { + out = append(out, refund) + } + } + return out, nil +} +func (r *refundTestRepo) TouchPaymentRefund(_ context.Context, id string) (Refund, error) { + refund := r.refunds[id] + refund.UpdatedAt = time.Now().UTC() + r.refunds[id] = refund + return refund, nil +} +func (r *refundTestRepo) RejectPaymentRefund(_ context.Context, id, reason string) (Refund, error) { + refund := r.refunds[id] + refund.Status, refund.FailureReason = RefundRejected, reason + r.refunds[id] = refund + return refund, nil +} +func (r *refundTestRepo) RecordPaymentRefund(_ context.Context, txn RefundTransaction) (Refund, error) { + refund := r.refunds[txn.ID] + if txn.Status == RefundSuccess && refund.Status != RefundSuccess { + r.records++ + } + refund.Status = txn.Status + refund.ProviderID = txn.ProviderID + r.refunds[txn.ID] = refund + return refund, nil +} + +type refundTestProvider struct { + *testProvider + txn RefundTransaction + createErr, queryErr error + createIDs []string + queries int +} + +func (p *refundTestProvider) CreateRefund(_ context.Context, refund Refund) (RefundTransaction, error) { + p.createIDs = append(p.createIDs, refund.ID) + if p.createErr != nil { + return RefundTransaction{}, p.createErr + } + txn := p.txn + txn.ID, txn.OrderID, txn.MchID, txn.TransactionID = refund.ID, refund.OrderID, refund.MchID, refund.TransactionID + txn.AmountFen, txn.TotalFen, txn.Currency = refund.AmountFen, refund.TotalFen, refund.Currency + return txn, nil +} +func (p *refundTestProvider) QueryRefund(_ context.Context, _ string) (RefundTransaction, error) { + p.queries++ + return p.txn, p.queryErr +} +func (p *refundTestProvider) ParseRefundNotification(_ context.Context, _ *http.Request) (RefundTransaction, error) { + return p.txn, nil +} + +func newRefundService() (*Service, *refundTestRepo, *refundTestProvider, Order) { + r := &refundTestRepo{testRepo: &testRepo{orders: map[string]Order{}, byKey: map[string]string{}}, refunds: map[string]Refund{}, byRefundKey: map[string]string{}} + p := &refundTestProvider{testProvider: &testProvider{}, txn: RefundTransaction{ProviderID: "wx-refund", Status: RefundProcessing}} + s := NewService(r, p, Config{Enabled: true, MchID: "mch", AppID: "app"}) + order := Order{ID: "order1", OrganizationID: "org1", MchID: "mch", AppID: "app", TransactionID: "wx-pay", AmountFen: 10000, Currency: "CNY", Status: StatusPaid} + r.orders[order.ID] = order + return s, r, p, order +} + +func TestRefundAcceptanceDoesNotDebitUntilVerifiedSuccess(t *testing.T) { + s, repo, provider, order := newRefundService() + refund, err := s.CreateRefund(context.Background(), order.ID, "admin", "key1", "客户申请", 5000) + if err != nil || refund.Status != RefundProcessing || repo.records != 0 { + t.Fatalf("acceptance incorrectly debited: %+v %v %d", refund, err, repo.records) + } + provider.txn = RefundTransaction{ID: refund.ID, OrderID: order.ID, MchID: "mch", TransactionID: order.TransactionID, ProviderID: "wx-refund", Status: RefundSuccess, AmountFen: 4999, TotalFen: order.AmountFen, Currency: "CNY", SuccessTime: time.Now()} + if err := s.RefundNotify(context.Background(), &http.Request{}); !errors.Is(err, ErrVerification) || repo.records != 0 { + t.Fatalf("mismatched callback: %v %d", err, repo.records) + } + provider.txn.AmountFen = 5000 + for i := 0; i < 2; i++ { + if err := s.RefundNotify(context.Background(), &http.Request{}); err != nil { + t.Fatal(err) + } + } + if repo.records != 1 { + t.Fatalf("duplicate debit: %d", repo.records) + } +} + +func TestRefundTimeoutReusesSameRemoteID(t *testing.T) { + s, repo, provider, order := newRefundService() + provider.createErr = errors.New("gateway timeout") + refund, err := s.CreateRefund(context.Background(), order.ID, "admin", "key1", "客户申请", 5000) + if err != nil || refund.Status != RefundPending || repo.records != 0 { + t.Fatalf("timeout not pending: %+v %v", refund, err) + } + again, err := s.CreateRefund(context.Background(), order.ID, "admin", "key1", "客户申请", 5000) + if err != nil || again.ID != refund.ID { + t.Fatalf("retry id changed: %+v %v", again, err) + } + provider.createErr = nil + provider.queryErr = ErrRemoteNotFound + current := repo.refunds[refund.ID] + current.UpdatedAt = time.Now().Add(-time.Minute) + repo.refunds[refund.ID] = current + if err := s.Reconcile(context.Background()); err != nil { + t.Fatal(err) + } + for _, id := range provider.createIDs { + if id != refund.ID { + t.Fatalf("new remote refund ID: %q", id) + } + } + if repo.refunds[refund.ID].Status != RefundProcessing || repo.records != 0 { + t.Fatalf("unexpected reconciled state: %+v", repo.refunds[refund.ID]) + } +} + +func TestRefundValidationAndMerchantRotation(t *testing.T) { + s, repo, provider, order := newRefundService() + for _, amount := range []int64{0, -1, 10001} { + if _, err := s.CreateRefund(context.Background(), order.ID, "admin", "key", "原因", amount); err == nil { + t.Fatalf("accepted amount %d", amount) + } + } + if _, err := s.CreateRefund(context.Background(), order.ID, "admin", "key", " ", 100); !errors.Is(err, ErrInvalidAmount) { + t.Fatal(err) + } + if len(provider.createIDs) != 0 { + t.Fatal("provider called before validation") + } + order.MchID = "old-merchant" + repo.orders[order.ID] = order + if _, err := s.CreateRefund(context.Background(), order.ID, "admin", "key", "原因", 100); !errors.Is(err, ErrConflict) { + t.Fatal(err) + } +} + +func TestDefinitiveRefundRejectionReleasesPendingAndDoesNotRetry(t *testing.T) { + s, repo, provider, order := newRefundService() + provider.createErr = &RefundRejectionError{Reason: "商户退款资金不足"} + refund, err := s.CreateRefund(context.Background(), order.ID, "admin", "key1", "客户申请", 5000) + if err != nil || refund.Status != RefundRejected || refund.FailureReason != "商户退款资金不足" || repo.records != 0 { + t.Fatalf("definitive rejection: %+v %v", refund, err) + } + again, err := s.CreateRefund(context.Background(), order.ID, "admin", "key1", "客户申请", 5000) + if err != nil || again.ID != refund.ID || len(provider.createIDs) != 1 { + t.Fatalf("rejected request retried remotely: %+v %v %v", again, err, provider.createIDs) + } +} diff --git a/backend/internal/payments/service.go b/backend/internal/payments/service.go new file mode 100644 index 0000000..90f9bf9 --- /dev/null +++ b/backend/internal/payments/service.go @@ -0,0 +1,236 @@ +package payments + +import ( + "context" + "crypto/rand" + "encoding/hex" + "errors" + "fmt" + "net/http" + "regexp" + "strings" + "time" +) + +const queryInterval = 5 * time.Second + +var requestKeyPattern = regexp.MustCompile(`^[A-Za-z0-9_-]{1,64}$`) + +type Service struct { + repo Repository + provider Provider + config Config + now func() time.Time +} + +func NewService(repo Repository, provider Provider, config Config) *Service { + if config.MinAmountFen == 0 { + config.MinAmountFen = 100 + } + if config.MaxAmountFen == 0 { + config.MaxAmountFen = 1000000 + } + if config.OrderTTL == 0 { + config.OrderTTL = 15 * time.Minute + } + if config.PresetAmountsFen == nil { + config.PresetAmountsFen = []int64{10000, 50000, 100000} + } + return &Service{repo: repo, provider: provider, config: config, now: time.Now} +} + +func (s *Service) Options() Options { + presets := make([]int64, len(s.config.PresetAmountsFen)) + copy(presets, s.config.PresetAmountsFen) + return Options{Enabled: s.config.Enabled, CanRecharge: s.config.Enabled && s.repo != nil && s.provider != nil, + PresetAmountsFen: presets, MinAmountFen: s.config.MinAmountFen, MaxAmountFen: s.config.MaxAmountFen} +} + +func (s *Service) Create(ctx context.Context, organizationID, accountID, requestKey string, amountFen int64) (Order, error) { + if !s.Options().CanRecharge { + return Order{}, ErrUnavailable + } + if organizationID == "" || accountID == "" || !requestKeyPattern.MatchString(requestKey) || amountFen < s.config.MinAmountFen || amountFen > s.config.MaxAmountFen { + return Order{}, ErrInvalidAmount + } + id, err := newOrderID() + if err != nil { + return Order{}, err + } + now := s.now().UTC() + wanted := Order{ID: id, OrganizationID: organizationID, AccountID: accountID, RequestKey: requestKey, + MchID: s.config.MchID, AppID: s.config.AppID, AmountFen: amountFen, Currency: "CNY", Status: StatusPending, + CreatedAt: now, UpdatedAt: now, ExpiresAt: now.Add(s.config.OrderTTL)} + order, err := s.repo.CreatePaymentOrder(ctx, wanted) + if err != nil { + return Order{}, err + } + if order.OrganizationID != organizationID || order.AccountID != accountID || order.RequestKey != requestKey || order.AmountFen != amountFen || order.MchID != s.config.MchID || order.AppID != s.config.AppID || order.Currency != "CNY" { + return Order{}, ErrConflict + } + if order.Status != StatusPending || order.CodeURL != "" { + return order, nil + } + if !s.now().Before(order.ExpiresAt) { + return s.refresh(ctx, order, true) + } + codeURL, err := s.provider.Create(ctx, order) + if err != nil { + return order, err + } + if !validCodeURL(codeURL) { + return order, ErrVerification + } + return s.repo.UpdatePaymentOrder(ctx, order.ID, StatusPending, codeURL) +} + +func (s *Service) Get(ctx context.Context, organizationID, id string) (Order, error) { + if s.repo == nil { + return Order{}, ErrUnavailable + } + order, err := s.repo.GetPaymentOrder(ctx, id) + if err != nil { + return Order{}, err + } + if order.OrganizationID != organizationID { + return Order{}, ErrNotFound + } + if order.Status != StatusPending || s.provider == nil || s.now().Sub(order.UpdatedAt) < queryInterval { + return order, nil + } + refreshed, err := s.refresh(ctx, order, true) + if err != nil { + return order, nil + } // Polling remains available during a provider outage. + return refreshed, nil +} + +func (s *Service) List(ctx context.Context, organizationID string) ([]Order, error) { + if s.repo == nil { + return nil, ErrUnavailable + } + return s.repo.ListPaymentOrders(ctx, organizationID, 100) +} + +func (s *Service) Notify(ctx context.Context, request *http.Request) error { + if s.repo == nil || s.provider == nil { + return ErrUnavailable + } + txn, err := s.provider.ParseNotification(ctx, request) + if err != nil { + return err + } + _, err = s.settle(ctx, txn) + return err +} + +func (s *Service) Reconcile(ctx context.Context) error { + if s.repo == nil || s.provider == nil { + return ErrUnavailable + } + // Payment and refund queues must each get a chance within the application's + // bounded reconciliation context, even when the other provider API is slow. + errorsCh := make(chan error, 1) + go func() { errorsCh <- s.reconcileRefunds(ctx) }() + paymentErr := s.reconcilePayments(ctx) + refundErr := <-errorsCh + return errors.Join(paymentErr, refundErr) +} + +func (s *Service) reconcilePayments(ctx context.Context) error { + orders, err := s.repo.PendingPaymentOrders(ctx, 100) + if err != nil { + return err + } + var failures []error + for _, order := range orders { + if ctx.Err() != nil { + return ctx.Err() + } + if s.now().Sub(order.UpdatedAt) < queryInterval { + continue + } + if _, err := s.refresh(ctx, order, true); err != nil { + failures = append(failures, fmt.Errorf("order %s: %w", order.ID, err)) + } + } + return errors.Join(failures...) +} + +func (s *Service) refresh(ctx context.Context, order Order, expire bool) (Order, error) { + // Advance the oldest-pending cursor before any remote call. Failed queries, + // prepay retries and close attempts must not starve newer paid orders. + current, err := s.repo.UpdatePaymentOrder(ctx, order.ID, StatusPending, "") + if err != nil { + return order, err + } + if current.Status != StatusPending { + return current, nil + } + order = current + txn, err := s.provider.Query(ctx, order.ID) + if err != nil && !errors.Is(err, ErrRemoteNotFound) { + return order, err + } + if err == nil { + if txn.OrderID != order.ID || txn.MchID != order.MchID || txn.AppID != order.AppID || + (txn.AmountFen != 0 && txn.AmountFen != order.AmountFen) || + (txn.Currency != "" && txn.Currency != order.Currency) { + return order, ErrVerification + } + if txn.TradeState == "SUCCESS" { + return s.settle(ctx, txn) + } + if txn.TradeState == "CLOSED" || txn.TradeState == "REVOKED" || txn.TradeState == "PAYERROR" { + return s.repo.UpdatePaymentOrder(ctx, order.ID, StatusClosed, "") + } + if txn.TradeState != "NOTPAY" && txn.TradeState != "USERPAYING" { + return order, ErrVerification + } + } + if expire && !s.now().Before(order.ExpiresAt) { + if err == nil { + if err = s.provider.Close(ctx, order.ID); err != nil { + return order, err + } + } + return s.repo.UpdatePaymentOrder(ctx, order.ID, StatusClosed, "") + } + if order.CodeURL == "" && (errors.Is(err, ErrRemoteNotFound) || (err == nil && txn.TradeState == "NOTPAY")) { + codeURL, createErr := s.provider.Create(ctx, order) + if createErr != nil { + return order, createErr + } + if !validCodeURL(codeURL) { + return order, ErrVerification + } + return s.repo.UpdatePaymentOrder(ctx, order.ID, StatusPending, codeURL) + } + return order, nil +} + +func (s *Service) settle(ctx context.Context, txn Transaction) (Order, error) { + if txn.OrderID == "" || txn.TransactionID == "" || txn.TradeState != "SUCCESS" || txn.MchID != s.config.MchID || txn.AppID != s.config.AppID || txn.Currency != "CNY" || txn.AmountFen <= 0 { + return Order{}, ErrVerification + } + order, err := s.repo.GetPaymentOrder(ctx, txn.OrderID) + if err != nil { + return Order{}, err + } + if txn.AmountFen != order.AmountFen || txn.MchID != order.MchID || txn.AppID != order.AppID || txn.Currency != order.Currency { + return Order{}, ErrVerification + } + return s.repo.SettlePaymentOrder(ctx, txn) +} + +func newOrderID() (string, error) { + var b [16]byte + if _, err := rand.Read(b[:]); err != nil { + return "", err + } + return hex.EncodeToString(b[:]), nil +} + +func validCodeURL(url string) bool { + return strings.HasPrefix(url, "weixin://wxpay/bizpayurl?") && len(url) <= 2048 && !strings.ContainsAny(url, "\r\n") +} diff --git a/backend/internal/payments/service_test.go b/backend/internal/payments/service_test.go new file mode 100644 index 0000000..852be84 --- /dev/null +++ b/backend/internal/payments/service_test.go @@ -0,0 +1,298 @@ +package payments + +import ( + "context" + "encoding/json" + "errors" + "net/http" + "testing" + "time" +) + +func TestOptionsExplicitEmptyPresetsMarshalAsArray(t *testing.T) { + s := NewService(nil, nil, Config{PresetAmountsFen: []int64{}, MinAmountFen: 500, MaxAmountFen: 900}) + options := s.Options() + if options.PresetAmountsFen == nil || options.MinAmountFen != 500 || options.MaxAmountFen != 900 { + t.Fatalf("unexpected options: %+v", options) + } + body, err := json.Marshal(options) + if err != nil { + t.Fatal(err) + } + var decoded map[string]any + if err := json.Unmarshal(body, &decoded); err != nil { + t.Fatal(err) + } + if presets, ok := decoded["presetAmountsFen"].([]any); !ok || len(presets) != 0 { + t.Fatalf("expected JSON empty array: %s", body) + } +} + +type testRepo struct { + orders map[string]Order + byKey map[string]string + settles int +} + +func (r *testRepo) CreatePaymentOrder(_ context.Context, o Order) (Order, error) { + if id := r.byKey[o.RequestKey]; id != "" { + return r.orders[id], nil + } + r.orders[o.ID] = o + r.byKey[o.RequestKey] = o.ID + return o, nil +} +func (r *testRepo) GetPaymentOrder(_ context.Context, id string) (Order, error) { + o, ok := r.orders[id] + if !ok { + return Order{}, ErrNotFound + } + return o, nil +} +func (r *testRepo) ListPaymentOrders(_ context.Context, org string, _ int) ([]Order, error) { + var out []Order + for _, o := range r.orders { + if o.OrganizationID == org { + out = append(out, o) + } + } + return out, nil +} +func (r *testRepo) PendingPaymentOrders(_ context.Context, _ int) ([]Order, error) { + var out []Order + for _, o := range r.orders { + if o.Status == StatusPending { + out = append(out, o) + } + } + return out, nil +} +func (r *testRepo) UpdatePaymentOrder(_ context.Context, id, status, url string) (Order, error) { + o := r.orders[id] + if o.Status == StatusPaid { + return o, nil + } + o.Status = status + if url != "" { + o.CodeURL = url + } + o.UpdatedAt = time.Now().UTC() + r.orders[id] = o + return o, nil +} +func (r *testRepo) SettlePaymentOrder(_ context.Context, txn Transaction) (Order, error) { + o := r.orders[txn.OrderID] + if o.AmountFen != txn.AmountFen { + return Order{}, ErrVerification + } + if o.Status != StatusPaid { + r.settles++ + } + o.Status = StatusPaid + o.TransactionID = txn.TransactionID + r.orders[o.ID] = o + return o, nil +} + +type testProvider struct { + txn Transaction + queryErr error + closeErr error + lastCreateID string + creates, queries, closes int +} + +func (p *testProvider) Create(_ context.Context, o Order) (string, error) { + p.creates++ + p.lastCreateID = o.ID + return "weixin://wxpay/bizpayurl?pr=abc", nil +} +func (p *testProvider) Query(_ context.Context, _ string) (Transaction, error) { + p.queries++ + return p.txn, p.queryErr +} +func (p *testProvider) Close(_ context.Context, _ string) error { p.closes++; return p.closeErr } +func (p *testProvider) ParseNotification(_ context.Context, _ *http.Request) (Transaction, error) { + return p.txn, nil +} + +func newTestService() (*Service, *testRepo, *testProvider) { + r := &testRepo{orders: map[string]Order{}, byKey: map[string]string{}} + p := &testProvider{} + s := NewService(r, p, Config{Enabled: true, MchID: "mch", AppID: "app"}) + return s, r, p +} + +func TestCreateRetryAndConflict(t *testing.T) { + s, _, p := newTestService() + ctx := context.Background() + a, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + b, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + if a.ID != b.ID || p.creates != 1 { + t.Fatalf("idempotency failed: %q %q creates=%d", a.ID, b.ID, p.creates) + } + if _, err := s.Create(ctx, "org", "account", "request", 20000); !errors.Is(err, ErrConflict) { + t.Fatalf("want conflict: %v", err) + } +} + +func TestNotifyRejectsMismatchedAmountAndSettlesOnce(t *testing.T) { + s, r, p := newTestService() + ctx := context.Background() + o, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + p.txn = Transaction{OrderID: o.ID, MchID: "mch", AppID: "app", TransactionID: "wx1", TradeState: "SUCCESS", Currency: "CNY", AmountFen: 9999} + if err := s.Notify(ctx, &http.Request{}); !errors.Is(err, ErrVerification) || r.settles != 0 { + t.Fatalf("mismatch settled: %v, %d", err, r.settles) + } + p.txn.AmountFen = 10000 + if err := s.Notify(ctx, &http.Request{}); err != nil { + t.Fatal(err) + } + if err := s.Notify(ctx, &http.Request{}); err != nil { + t.Fatal(err) + } + if r.settles != 1 { + t.Fatalf("duplicate credit: %d", r.settles) + } +} + +func TestReconcileQueriesBeforeClose(t *testing.T) { + s, r, p := newTestService() + ctx := context.Background() + o, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + o.ExpiresAt = time.Now().Add(-time.Minute) + o.UpdatedAt = time.Now().Add(-time.Minute) + r.orders[o.ID] = o + p.txn = Transaction{OrderID: o.ID, MchID: "mch", AppID: "app", TransactionID: "wx1", TradeState: "SUCCESS", Currency: "CNY", AmountFen: 10000} + if err := s.Reconcile(ctx); err != nil { + t.Fatal(err) + } + if r.settles != 1 || p.closes != 0 { + t.Fatalf("paid order closed: settles=%d closes=%d", r.settles, p.closes) + } +} + +func TestReconcileClosesOnlyAfterConfirmedUnpaid(t *testing.T) { + s, r, p := newTestService() + ctx := context.Background() + o, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + o.ExpiresAt = time.Now().Add(-time.Minute) + o.UpdatedAt = time.Now().Add(-time.Minute) + r.orders[o.ID] = o + p.queryErr = errors.New("gateway unavailable") + if err := s.Reconcile(ctx); err == nil { + t.Fatal("expected query error") + } + if r.orders[o.ID].Status != StatusPending || p.closes != 0 || r.settles != 0 { + t.Fatal("query outage changed payment state") + } + o = r.orders[o.ID] + o.UpdatedAt = time.Now().Add(-time.Minute) + r.orders[o.ID] = o + p.queryErr = nil + p.txn = Transaction{OrderID: o.ID, MchID: "mch", AppID: "app", TradeState: "NOTPAY", Currency: "CNY", AmountFen: 10000} + if err := s.Reconcile(ctx); err != nil { + t.Fatal(err) + } + if r.orders[o.ID].Status != StatusClosed || p.closes != 1 || r.settles != 0 { + t.Fatal("unpaid order was not safely closed") + } +} + +func TestRecoverMissingCodeURLFromRemoteUnpaid(t *testing.T) { + s, r, p := newTestService() + ctx := context.Background() + o, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + o.CodeURL = "" // Prepay succeeded, but local URL persistence was lost. + o.UpdatedAt = time.Now().Add(-time.Minute) + r.orders[o.ID] = o + p.txn = Transaction{OrderID: o.ID, MchID: "mch", AppID: "app", TradeState: "NOTPAY", Currency: "CNY", AmountFen: 10000} + got, err := s.Get(ctx, "org", o.ID) + if err != nil { + t.Fatal(err) + } + if got.ID != o.ID || got.CodeURL == "" || p.lastCreateID != o.ID || p.creates != 2 { + t.Fatalf("same-order prepay recovery failed: %+v lastCreateID=%s creates=%d", got, p.lastCreateID, p.creates) + } +} + +func TestFailedCloseAdvancesReconcileCursor(t *testing.T) { + s, r, p := newTestService() + ctx := context.Background() + o, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + o.ExpiresAt = time.Now().Add(-time.Minute) + o.UpdatedAt = time.Now().Add(-time.Minute) + r.orders[o.ID] = o + p.txn = Transaction{OrderID: o.ID, MchID: "mch", AppID: "app", TradeState: "NOTPAY", Currency: "CNY", AmountFen: 10000} + p.closeErr = errors.New("close unavailable") + before := o.UpdatedAt + if err := s.Reconcile(ctx); err == nil { + t.Fatal("expected close failure") + } + got := r.orders[o.ID] + if got.Status != StatusPending || !got.UpdatedAt.After(before) || p.closes != 1 { + t.Fatalf("failed close did not advance cursor: %+v closes=%d", got, p.closes) + } + if err := s.Reconcile(ctx); err != nil { + t.Fatal(err) + } + if p.closes != 1 { + t.Fatal("retry ignored query throttle") + } +} + +func TestGetScopesBeforeQuery(t *testing.T) { + s, r, p := newTestService() + ctx := context.Background() + o, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + o.UpdatedAt = time.Now().Add(-time.Minute) + r.orders[o.ID] = o + if _, err := s.Get(ctx, "other", o.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("scope: %v", err) + } + if p.queries != 0 { + t.Fatal("queried before authorization") + } +} + +func TestQueryCannotSettleDifferentOrder(t *testing.T) { + s, r, p := newTestService() + ctx := context.Background() + o, err := s.Create(ctx, "org", "account", "request", 10000) + if err != nil { + t.Fatal(err) + } + o.UpdatedAt = time.Now().Add(-time.Minute) + r.orders[o.ID] = o + p.txn = Transaction{OrderID: "other-order", MchID: "mch", AppID: "app", TransactionID: "wx1", TradeState: "SUCCESS", Currency: "CNY", AmountFen: 10000} + if _, err := s.Get(ctx, "org", o.ID); err != nil { + t.Fatal(err) + } + if r.settles != 0 || r.orders[o.ID].Status != StatusPending { + t.Fatal("mismatched query settled payment") + } +} diff --git a/backend/internal/payments/wechat.go b/backend/internal/payments/wechat.go new file mode 100644 index 0000000..e1fe66f --- /dev/null +++ b/backend/internal/payments/wechat.go @@ -0,0 +1,136 @@ +package payments + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "github.com/wechatpay-apiv3/wechatpay-go/core" + "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers" + "github.com/wechatpay-apiv3/wechatpay-go/core/notify" + "github.com/wechatpay-apiv3/wechatpay-go/core/option" + wechatpayments "github.com/wechatpay-apiv3/wechatpay-go/services/payments" + "github.com/wechatpay-apiv3/wechatpay-go/services/payments/native" + "github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic" + "github.com/wechatpay-apiv3/wechatpay-go/utils" +) + +type wechatProvider struct { + service native.NativeApiService + refunds refunddomestic.RefundsApiService + notifier *notify.Handler + config Config +} + +func NewWeChatProvider(config Config) (Provider, error) { + if config.MchID == "" || config.AppID == "" || config.NotifyURL == "" || config.MerchantSerial == "" || config.APIv3Key == "" || config.WechatPublicKeyID == "" || config.PrivateKeyPEM == "" || config.WechatPublicKeyPEM == "" { + return nil, fmt.Errorf("wechat payment configuration incomplete") + } + if len(config.APIv3Key) != 32 { + return nil, fmt.Errorf("APIv3 key must be 32 bytes") + } + privateKey, err := utils.LoadPrivateKey(config.PrivateKeyPEM) + if err != nil { + return nil, fmt.Errorf("merchant private key: %w", err) + } + publicKey, err := utils.LoadPublicKey(config.WechatPublicKeyPEM) + if err != nil { + return nil, fmt.Errorf("wechat public key: %w", err) + } + client, err := core.NewClient(context.Background(), + option.WithWechatPayPublicKeyAuthCipher(config.MchID, config.MerchantSerial, privateKey, config.WechatPublicKeyID, publicKey), + option.WithHTTPClient(&http.Client{Timeout: 10 * time.Second})) + if err != nil { + return nil, fmt.Errorf("wechat client: %w", err) + } + return &wechatProvider{service: native.NativeApiService{Client: client}, refunds: refunddomestic.RefundsApiService{Client: client}, + notifier: notify.NewNotifyHandler(config.APIv3Key, verifiers.NewSHA256WithRSAPubkeyVerifier(config.WechatPublicKeyID, *publicKey)), + config: config}, nil +} + +func (p *wechatProvider) Create(ctx context.Context, order Order) (string, error) { + ctx, cancel := context.WithTimeout(ctx, 12*time.Second) + defer cancel() + resp, _, err := p.service.Prepay(ctx, native.PrepayRequest{ + Appid: &p.config.AppID, Mchid: &p.config.MchID, Description: ptr("智念AIGC平台使用额度"), OutTradeNo: &order.ID, + TimeExpire: &order.ExpiresAt, NotifyUrl: &p.config.NotifyURL, + Amount: &native.Amount{Total: &order.AmountFen, Currency: ptr("CNY")}, + }) + if err != nil { + return "", err + } + if resp == nil || resp.CodeUrl == nil || !validCodeURL(*resp.CodeUrl) { + return "", ErrVerification + } + return *resp.CodeUrl, nil +} + +func (p *wechatProvider) Query(ctx context.Context, id string) (Transaction, error) { + ctx, cancel := context.WithTimeout(ctx, 12*time.Second) + defer cancel() + resp, _, err := p.service.QueryOrderByOutTradeNo(ctx, native.QueryOrderByOutTradeNoRequest{OutTradeNo: &id, Mchid: &p.config.MchID}) + if err != nil { + var apiErr *core.APIError + if errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusNotFound { + return Transaction{}, ErrRemoteNotFound + } + return Transaction{}, err + } + return transactionFromSDK(resp) +} + +func (p *wechatProvider) Close(ctx context.Context, id string) error { + ctx, cancel := context.WithTimeout(ctx, 12*time.Second) + defer cancel() + _, err := p.service.CloseOrder(ctx, native.CloseOrderRequest{OutTradeNo: &id, Mchid: &p.config.MchID}) + return err +} + +func (p *wechatProvider) ParseNotification(ctx context.Context, request *http.Request) (Transaction, error) { + if request == nil || request.Body == nil { + return Transaction{}, ErrVerification + } + request.Body = http.MaxBytesReader(nil, request.Body, 128*1024) + var sdkTxn wechatpayments.Transaction + n, err := p.notifier.ParseNotifyRequest(ctx, request, &sdkTxn) + if err != nil { + return Transaction{}, fmt.Errorf("%w: %v", ErrVerification, err) + } + if n.EventType != "TRANSACTION.SUCCESS" || n.ResourceType != "encrypt-resource" { + return Transaction{}, ErrVerification + } + return transactionFromSDK(&sdkTxn) +} + +func transactionFromSDK(t *wechatpayments.Transaction) (Transaction, error) { + if t == nil || t.OutTradeNo == nil || t.TradeState == nil || t.Mchid == nil || t.Appid == nil { + return Transaction{}, ErrVerification + } + txn := Transaction{OrderID: *t.OutTradeNo, MchID: *t.Mchid, AppID: *t.Appid, TradeState: *t.TradeState} + if t.TransactionId != nil { + txn.TransactionID = *t.TransactionId + } + if t.Amount != nil { + if t.Amount.Total != nil { + txn.AmountFen = *t.Amount.Total + } + if t.Amount.Currency != nil { + txn.Currency = *t.Amount.Currency + } + } + if txn.TradeState == "SUCCESS" { + if txn.TransactionID == "" || txn.AmountFen <= 0 || txn.Currency != "CNY" || t.SuccessTime == nil { + return Transaction{}, ErrVerification + } + parsed, err := time.Parse(time.RFC3339, *t.SuccessTime) + if err != nil { + return Transaction{}, ErrVerification + } + txn.SuccessTime = parsed + } + return txn, nil +} + +func ptr(s string) *string { return &s } diff --git a/backend/internal/payments/wechat_refunds.go b/backend/internal/payments/wechat_refunds.go new file mode 100644 index 0000000..60913a0 --- /dev/null +++ b/backend/internal/payments/wechat_refunds.go @@ -0,0 +1,185 @@ +package payments + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/wechatpay-apiv3/wechatpay-go/core" + "github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic" +) + +func (p *wechatProvider) CreateRefund(ctx context.Context, refund Refund) (RefundTransaction, error) { + if refund.MchID != p.config.MchID || refund.TransactionID == "" || refund.ID == "" || refund.AmountFen <= 0 || refund.TotalFen < refund.AmountFen || refund.Currency != "CNY" { + return RefundTransaction{}, ErrVerification + } + ctx, cancel := context.WithTimeout(ctx, 12*time.Second) + defer cancel() + notifyURL, err := refundNotifyURL(p.config.NotifyURL) + if err != nil { + return RefundTransaction{}, err + } + response, _, err := p.refunds.Create(ctx, refunddomestic.CreateRequest{ + TransactionId: &refund.TransactionID, + OutRefundNo: &refund.ID, + Reason: &refund.Reason, + NotifyUrl: ¬ifyURL, + Amount: &refunddomestic.AmountReq{Refund: &refund.AmountFen, Total: &refund.TotalFen, Currency: &refund.Currency}, + }) + if err != nil { + if rejection := classifyRefundRejection(err); rejection != nil { + return RefundTransaction{}, rejection + } + return RefundTransaction{}, err + } + return refundFromSDK(response, p.config.MchID) +} + +// Only the documented request-level failures can be treated as a definitive +// rejection. Rate limits, provider 5xx, transport and verification errors may +// hide an accepted refund and must keep the same out_refund_no reserved. +type RefundRejectionError struct{ Reason string } + +func (e *RefundRejectionError) Error() string { return e.Reason } + +func classifyRefundRejection(err error) *RefundRejectionError { + var apiErr *core.APIError + if !errors.As(err, &apiErr) { + return nil + } + var reason string + switch { + case apiErr.StatusCode == 400 && (apiErr.Code == "PARAM_ERROR" || apiErr.Code == "INVALID_REQUEST"): + reason = "微信支付拒绝退款参数或业务规则" + case apiErr.StatusCode == 401 && apiErr.Code == "SIGN_ERROR": + reason = "微信支付签名验证失败" + case apiErr.StatusCode == 403 && apiErr.Code == "NOT_ENOUGH": + reason = "商户退款资金不足" + case apiErr.StatusCode == 403 && apiErr.Code == "USER_ACCOUNT_ABNORMAL": + reason = "微信支付账户异常,退款申请被拒绝" + case apiErr.StatusCode == 404 && apiErr.Code == "MCH_NOT_EXISTS": + reason = "微信支付商户号不存在" + case apiErr.StatusCode == 404 && apiErr.Code == "RESOURCE_NOT_EXISTS": + reason = "微信支付原订单不存在" + default: + return nil + } + return &RefundRejectionError{Reason: reason} +} + +func (p *wechatProvider) QueryRefund(ctx context.Context, id string) (RefundTransaction, error) { + ctx, cancel := context.WithTimeout(ctx, 12*time.Second) + defer cancel() + response, _, err := p.refunds.QueryByOutRefundNo(ctx, refunddomestic.QueryByOutRefundNoRequest{OutRefundNo: &id}) + if err != nil { + var apiErr *core.APIError + if errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusNotFound { + return RefundTransaction{}, ErrRemoteNotFound + } + return RefundTransaction{}, err + } + return refundFromSDK(response, p.config.MchID) +} + +func (p *wechatProvider) ParseRefundNotification(ctx context.Context, request *http.Request) (RefundTransaction, error) { + if request == nil || request.Body == nil { + return RefundTransaction{}, ErrVerification + } + request.Body = http.MaxBytesReader(nil, request.Body, 128*1024) + var payload struct { + MchID string `json:"mchid"` + RefundID string `json:"refund_id"` + OutRefundNo string `json:"out_refund_no"` + TransactionID string `json:"transaction_id"` + OutTradeNo string `json:"out_trade_no"` + RefundStatus string `json:"refund_status"` + SuccessTime string `json:"success_time"` + Amount struct { + Total int64 `json:"total"` + Refund int64 `json:"refund"` + Currency string `json:"currency"` + } `json:"amount"` + } + notification, err := p.notifier.ParseNotifyRequest(ctx, request, &payload) + if err != nil { + return RefundTransaction{}, fmt.Errorf("%w: %v", ErrVerification, err) + } + if notification == nil || notification.ResourceType != "encrypt-resource" { + return RefundTransaction{}, ErrVerification + } + var status string + switch notification.EventType { + case "REFUND.SUCCESS": + status = RefundSuccess + case "REFUND.CLOSED": + status = RefundClosed + case "REFUND.ABNORMAL": + status = RefundAbnormal + default: + return RefundTransaction{}, ErrVerification + } + // The refund notification schema omits currency; this ordinary-merchant flow is CNY only. + if payload.RefundStatus != notification.EventType[len("REFUND."):] || payload.MchID == "" || payload.RefundID == "" || payload.OutRefundNo == "" || payload.OutTradeNo == "" || payload.TransactionID == "" || payload.Amount.Total <= 0 || payload.Amount.Refund <= 0 || (payload.Amount.Currency != "" && payload.Amount.Currency != "CNY") { + return RefundTransaction{}, ErrVerification + } + txn := RefundTransaction{ID: payload.OutRefundNo, OrderID: payload.OutTradeNo, MchID: payload.MchID, + TransactionID: payload.TransactionID, ProviderID: payload.RefundID, Status: status, + AmountFen: payload.Amount.Refund, TotalFen: payload.Amount.Total, Currency: "CNY"} + if status == RefundSuccess { + if payload.SuccessTime == "" { + return RefundTransaction{}, ErrVerification + } + txn.SuccessTime, err = time.Parse(time.RFC3339, payload.SuccessTime) + if err != nil { + return RefundTransaction{}, ErrVerification + } + } + return txn, nil +} + +func refundFromSDK(r *refunddomestic.Refund, mchID string) (RefundTransaction, error) { + if r == nil || r.RefundId == nil || r.OutRefundNo == nil || r.TransactionId == nil || r.OutTradeNo == nil || r.Status == nil || r.Amount == nil || r.Amount.Refund == nil || r.Amount.Total == nil || r.Amount.Currency == nil { + return RefundTransaction{}, ErrVerification + } + var status string + switch string(*r.Status) { + case "PROCESSING": + status = RefundProcessing + case "SUCCESS": + status = RefundSuccess + case "CLOSED": + status = RefundClosed + case "ABNORMAL": + status = RefundAbnormal + default: + return RefundTransaction{}, ErrVerification + } + txn := RefundTransaction{ID: *r.OutRefundNo, OrderID: *r.OutTradeNo, MchID: mchID, + TransactionID: *r.TransactionId, ProviderID: *r.RefundId, Status: status, + AmountFen: *r.Amount.Refund, TotalFen: *r.Amount.Total, Currency: *r.Amount.Currency} + if txn.ID == "" || txn.OrderID == "" || txn.TransactionID == "" || txn.ProviderID == "" || txn.TotalFen <= 0 || txn.AmountFen <= 0 || txn.Currency != "CNY" { + return RefundTransaction{}, ErrVerification + } + if status == RefundSuccess { + if r.SuccessTime == nil || r.SuccessTime.IsZero() { + return RefundTransaction{}, ErrVerification + } + txn.SuccessTime = *r.SuccessTime + } + return txn, nil +} + +func refundNotifyURL(paymentNotifyURL string) (string, error) { + u, err := url.Parse(paymentNotifyURL) + if err != nil || u.Scheme != "https" || u.Host == "" || u.User != nil { + return "", ErrVerification + } + u.Path = "/api/payments/wechat/refund-notify" + u.RawPath = "" + u.RawQuery = "" + u.Fragment = "" + return u.String(), nil +} diff --git a/backend/internal/payments/wechat_refunds_test.go b/backend/internal/payments/wechat_refunds_test.go new file mode 100644 index 0000000..770d23a --- /dev/null +++ b/backend/internal/payments/wechat_refunds_test.go @@ -0,0 +1,138 @@ +package payments + +import ( + "bytes" + "context" + "crypto" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/http/httptest" + "strconv" + "testing" + "time" + + "github.com/wechatpay-apiv3/wechatpay-go/core" + "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers" + "github.com/wechatpay-apiv3/wechatpay-go/core/notify" + "github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic" +) + +func TestRefundFromSDKRequiresVerifiedFieldsAndSuccessTime(t *testing.T) { + status := refunddomestic.Status("SUCCESS") + refundID, outRefundNo, transactionID, outTradeNo := "wx-refund", "local-refund", "wx-payment", "local-payment" + amount, total, currency := int64(500), int64(1000), "CNY" + response := &refunddomestic.Refund{RefundId: &refundID, OutRefundNo: &outRefundNo, + TransactionId: &transactionID, OutTradeNo: &outTradeNo, Status: &status, + Amount: &refunddomestic.Amount{Refund: &amount, Total: &total, Currency: ¤cy}} + if _, err := refundFromSDK(response, "mch"); !errors.Is(err, ErrVerification) { + t.Fatal("accepted SUCCESS without success_time", err) + } + now := time.Now() + response.SuccessTime = &now + txn, err := refundFromSDK(response, "mch") + if err != nil || txn.Status != RefundSuccess || txn.MchID != "mch" || txn.AmountFen != 500 { + t.Fatalf("mapping failed: %+v %v", txn, err) + } + currency = "USD" + if _, err := refundFromSDK(response, "mch"); !errors.Is(err, ErrVerification) { + t.Fatal("accepted non-CNY refund", err) + } +} + +func TestRefundNotifyURLUsesDedicatedPath(t *testing.T) { + got, err := refundNotifyURL("https://nianxxaigc.nianxx.cn/api/payments/wechat/notify") + if err != nil || got != "https://nianxxaigc.nianxx.cn/api/payments/wechat/refund-notify" { + t.Fatalf("unexpected URL: %q %v", got, err) + } + if _, err := refundNotifyURL("http://example.com/notify"); !errors.Is(err, ErrVerification) { + t.Fatal("accepted HTTP notify", err) + } +} + +func TestOnlyDocumentedDefinitiveRefundErrorsAreRejected(t *testing.T) { + cases := []struct { + status int + code string + rejected bool + }{ + {400, "PARAM_ERROR", true}, {400, "INVALID_REQUEST", true}, + {401, "SIGN_ERROR", true}, {403, "NOT_ENOUGH", true}, + {403, "USER_ACCOUNT_ABNORMAL", true}, {404, "MCH_NOT_EXISTS", true}, + {404, "RESOURCE_NOT_EXISTS", true}, {429, "FREQUENCY_LIMITED", false}, + {500, "SYSTEM_ERROR", false}, {403, "UNKNOWN", false}, + } + for _, tc := range cases { + got := classifyRefundRejection(&core.APIError{StatusCode: tc.status, Code: tc.code, Message: "sensitive raw message"}) + if (got != nil) != tc.rejected { + t.Fatalf("%d %s rejected=%v", tc.status, tc.code, got != nil) + } + if got != nil && got.Reason == "sensitive raw message" { + t.Fatal("raw provider message exposed") + } + } + if got := classifyRefundRejection(errors.New("network timeout")); got != nil { + t.Fatal("network error rejected") + } +} + +func TestRefundNotificationVerifiesSignatureAndDecrypts(t *testing.T) { + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatal(err) + } + const apiKey = "12345678901234567890123456789012" + const keyID = "PUB_KEY_ID_test" + provider := &wechatProvider{notifier: notify.NewNotifyHandler(apiKey, + verifiers.NewSHA256WithRSAPubkeyVerifier(keyID, privateKey.PublicKey))} + block, err := aes.NewCipher([]byte(apiKey)) + if err != nil { + t.Fatal(err) + } + aead, err := cipher.NewGCM(block) + if err != nil { + t.Fatal(err) + } + nonce := []byte("123456789012") + plaintext := []byte(`{"mchid":"mch","out_trade_no":"order","transaction_id":"wx-pay","out_refund_no":"refund","refund_id":"wx-refund","refund_status":"SUCCESS","success_time":"2026-10-12T10:00:00+08:00","amount":{"total":1000,"refund":500}}`) + resource := map[string]any{"algorithm": "AEAD_AES_256_GCM", "original_type": "refund", "ciphertext": base64.StdEncoding.EncodeToString(aead.Seal(nil, nonce, plaintext, nil)), "associated_data": "", "nonce": string(nonce)} + makeRequest := func(event string) *http.Request { + body, err := json.Marshal(map[string]any{"id": "notice", "event_type": event, "resource_type": "encrypt-resource", "resource": resource}) + if err != nil { + t.Fatal(err) + } + req := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(body)) + timestamp := strconv.FormatInt(time.Now().Unix(), 10) + const signNonce = "nonce123" + message := fmt.Sprintf("%s\n%s\n%s\n", timestamp, signNonce, body) + digest := sha256.Sum256([]byte(message)) + signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, digest[:]) + if err != nil { + t.Fatal(err) + } + req.Header.Set("Wechatpay-Serial", keyID) + req.Header.Set("Wechatpay-Timestamp", timestamp) + req.Header.Set("Wechatpay-Nonce", signNonce) + req.Header.Set("Wechatpay-Signature", base64.StdEncoding.EncodeToString(signature)) + return req + } + txn, err := provider.ParseRefundNotification(context.Background(), makeRequest("REFUND.SUCCESS")) + if err != nil || txn.Status != RefundSuccess || txn.Currency != "CNY" || txn.AmountFen != 500 || txn.MchID != "mch" { + t.Fatalf("signed refund notification rejected: %+v %v", txn, err) + } + badSignature := makeRequest("REFUND.SUCCESS") + badSignature.Header.Set("Wechatpay-Signature", "invalid") + if _, err := provider.ParseRefundNotification(context.Background(), badSignature); !errors.Is(err, ErrVerification) { + t.Fatal("accepted unsigned notification", err) + } + if _, err := provider.ParseRefundNotification(context.Background(), makeRequest("REFUND.CLOSED")); !errors.Is(err, ErrVerification) { + t.Fatal("accepted mismatched event and refund_status", err) + } +} diff --git a/backend/internal/payments/wechat_test.go b/backend/internal/payments/wechat_test.go new file mode 100644 index 0000000..d1163ab --- /dev/null +++ b/backend/internal/payments/wechat_test.go @@ -0,0 +1,83 @@ +package payments + +import ( + "bytes" + "context" + "crypto" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "fmt" + "net/http" + "strconv" + "testing" + "time" +) + +func TestVerifiedNotificationRejectsReplayAndTampering(t *testing.T) { + key, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatal(err) + } + pubDER, err := x509.MarshalPKIXPublicKey(&key.PublicKey) + if err != nil { + t.Fatal(err) + } + privDER, err := x509.MarshalPKCS8PrivateKey(key) + if err != nil { + t.Fatal(err) + } + config := Config{MchID: "mch", AppID: "app", NotifyURL: "https://example.com/notify", MerchantSerial: "serial", + PrivateKeyPEM: string(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privDER})), + WechatPublicKeyID: "PUB_KEY_ID_123", WechatPublicKeyPEM: string(pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubDER})), + APIv3Key: "12345678901234567890123456789012"} + provider, err := NewWeChatProvider(config) + if err != nil { + t.Fatal(err) + } + wp := provider.(*wechatProvider) + txn := map[string]any{"out_trade_no": "order1", "mchid": "mch", "appid": "app", "transaction_id": "wx1", + "trade_state": "SUCCESS", "amount": map[string]any{"total": 10000, "currency": "CNY"}, "success_time": time.Now().UTC().Format(time.RFC3339)} + plain, _ := json.Marshal(txn) + block, _ := aes.NewCipher([]byte(config.APIv3Key)) + aead, _ := cipher.NewGCM(block) + nonce := "123456789012" + ciphertext := aead.Seal(nil, []byte(nonce), plain, []byte("associated")) + body, _ := json.Marshal(map[string]any{"id": "event1", "event_type": "TRANSACTION.SUCCESS", "resource_type": "encrypt-resource", + "resource": map[string]any{"algorithm": "AEAD_AES_256_GCM", "ciphertext": base64.StdEncoding.EncodeToString(ciphertext), "associated_data": "associated", "nonce": nonce}}) + makeRequest := func(timestamp int64, tamper bool) *http.Request { + ts := strconv.FormatInt(timestamp, 10) + signed := fmt.Sprintf("%s\n%s\n%s\n", ts, "nonce1", body) + hash := sha256.Sum256([]byte(signed)) + signature, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, hash[:]) + if err != nil { + t.Fatal(err) + } + actualBody := body + if tamper { + actualBody = append(bytes.Clone(body), ' ') + } + req, _ := http.NewRequest(http.MethodPost, "https://example.com/notify", bytes.NewReader(actualBody)) + req.Header.Set("Wechatpay-Serial", config.WechatPublicKeyID) + req.Header.Set("Wechatpay-Timestamp", ts) + req.Header.Set("Wechatpay-Nonce", "nonce1") + req.Header.Set("Wechatpay-Signature", base64.StdEncoding.EncodeToString(signature)) + return req + } + valid, err := wp.ParseNotification(context.Background(), makeRequest(time.Now().Unix(), false)) + if err != nil || valid.AmountFen != 10000 || valid.OrderID != "order1" { + t.Fatalf("valid notification: %v %+v", err, valid) + } + if _, err := wp.ParseNotification(context.Background(), makeRequest(time.Now().Add(-10*time.Minute).Unix(), false)); err == nil { + t.Fatal("accepted stale timestamp") + } + if _, err := wp.ParseNotification(context.Background(), makeRequest(time.Now().Unix(), true)); err == nil { + t.Fatal("accepted tampered body") + } +} diff --git a/backend/internal/postgres/database.go b/backend/internal/postgres/database.go index 0cb213c..121a229 100644 --- a/backend/internal/postgres/database.go +++ b/backend/internal/postgres/database.go @@ -22,7 +22,9 @@ WITH required_table_privileges(table_name, privilege_name) AS ( ('platform_runtime_settings', 'SELECT'), ('platform_runtime_settings', 'INSERT'), ('platform_runtime_settings', 'UPDATE'), ('billing_price_rules', 'SELECT'), ('billing_price_rules', 'INSERT'), ('billing_price_rules', 'UPDATE'), ('billing_wallets', 'SELECT'), ('billing_wallets', 'INSERT'), ('billing_wallets', 'UPDATE'), - ('billing_ledger', 'SELECT'), ('billing_ledger', 'INSERT') + ('billing_ledger', 'SELECT'), ('billing_ledger', 'INSERT'), + ('payment_orders', 'SELECT'), ('payment_orders', 'INSERT'), ('payment_orders', 'UPDATE'), + ('payment_refunds', 'SELECT'), ('payment_refunds', 'INSERT'), ('payment_refunds', 'UPDATE') ), required_generation_job_columns(column_name) AS ( VALUES diff --git a/backend/internal/postgres/payments.go b/backend/internal/postgres/payments.go new file mode 100644 index 0000000..eecf7e7 --- /dev/null +++ b/backend/internal/postgres/payments.go @@ -0,0 +1,331 @@ +package postgres + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + "fmt" + "regexp" + "time" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" + "github.com/jackc/pgx/v5/pgconn" +) + +const paymentOrderColumns = `id, organization_id, account_id, request_key, mch_id, app_id, + amount_fen, currency, status, COALESCE(code_url, ''), COALESCE(transaction_id, ''), + created_at, updated_at, expires_at, paid_at` + +const createPaymentOrderSQL = `INSERT INTO public.payment_orders + (id, organization_id, account_id, request_key, mch_id, app_id, amount_fen, currency, expires_at) +SELECT $1::text, organization.id, account.id, $4::text, $5::text, $6::text, + $7::bigint, $8::text, $9::timestamptz +FROM public.platform_organizations AS organization +JOIN public.platform_users AS account ON account.id = $3::text +WHERE organization.id = $2::text AND organization.status = 'active' + AND account.status = 'active' AND account.organization_id = organization.id + AND account.role IN ('organization_admin', 'super_admin') +ON CONFLICT DO NOTHING +RETURNING ` + paymentOrderColumns + +const getPaymentOrderSQL = `SELECT ` + paymentOrderColumns + ` FROM public.payment_orders WHERE id = $1::text` +const getPaymentOrderByRequestSQL = `SELECT ` + paymentOrderColumns + ` FROM public.payment_orders WHERE organization_id = $1::text AND request_key = $2::text` +const listPaymentOrdersSQL = `SELECT ` + paymentOrderColumns + ` FROM public.payment_orders WHERE organization_id = $1::text ORDER BY created_at DESC, id DESC LIMIT $2::integer` +const pendingPaymentOrdersSQL = `SELECT ` + paymentOrderColumns + ` FROM public.payment_orders WHERE status = 'pending' ORDER BY updated_at ASC, created_at ASC, id ASC LIMIT $1::integer` +const updatePendingPaymentOrderSQL = `UPDATE public.payment_orders SET + code_url = CASE WHEN $2::text = '' THEN code_url ELSE $2::text END, + updated_at = now() +WHERE id = $1::text AND status = 'pending' +RETURNING ` + paymentOrderColumns +const closePaymentOrderSQL = `UPDATE public.payment_orders SET + status = 'closed', code_url = NULL, updated_at = now() +WHERE id = $1::text AND status = 'pending' +RETURNING ` + paymentOrderColumns +const lockPaymentOrderSQL = `SELECT ` + paymentOrderColumns + ` FROM public.payment_orders WHERE id = $1::text FOR UPDATE` +const paidPaymentOrderSQL = `UPDATE public.payment_orders SET + status = 'paid', transaction_id = $2::text, code_url = NULL, + paid_at = $3::timestamptz, updated_at = now() +WHERE id = $1::text AND status IN ('pending', 'closed') +RETURNING ` + paymentOrderColumns + +var paymentKeyPattern = regexp.MustCompile(`^[A-Za-z0-9_-]+$`) + +func (db *Database) paymentQuerier() (Querier, error) { + if db == nil || db.config.Backend != BackendPostgres || db.querier == nil { + return nil, payments.ErrUnavailable + } + return db.querier, nil +} + +func validPaymentKey(s string, maxLength int) bool { + return len(s) > 0 && len(s) <= maxLength && paymentKeyPattern.MatchString(s) +} + +func (db *Database) CreatePaymentOrder(ctx context.Context, input payments.Order) (payments.Order, error) { + q, err := db.paymentQuerier() + if err != nil { + return payments.Order{}, err + } + if !validPaymentKey(input.ID, 32) || !validPaymentKey(input.RequestKey, 64) || + input.OrganizationID == "" || input.AccountID == "" || input.MchID == "" || input.AppID == "" || + len(input.MchID) > 64 || len(input.AppID) > 64 || input.Currency != "CNY" || + input.ExpiresAt.IsZero() || !input.ExpiresAt.After(time.Now()) { + return payments.Order{}, payments.ErrConflict + } + if input.AmountFen < 1 || input.AmountFen > 1_000_000 { + return payments.Order{}, payments.ErrInvalidAmount + } + created, found, err := queryPaymentOrder(ctx, q, createPaymentOrderSQL, + input.ID, input.OrganizationID, input.AccountID, input.RequestKey, + input.MchID, input.AppID, input.AmountFen, input.Currency, input.ExpiresAt) + if err != nil { + return payments.Order{}, paymentSQLError("create payment order", err) + } + if found { + return created, nil + } + previous, found, err := queryPaymentOrder(ctx, q, getPaymentOrderByRequestSQL, input.OrganizationID, input.RequestKey) + if err != nil { + return payments.Order{}, paymentSQLError("read payment request", err) + } + if !found || previous.AccountID != input.AccountID || previous.AmountFen != input.AmountFen || + previous.Currency != input.Currency || previous.AppID != input.AppID || previous.MchID != input.MchID { + return payments.Order{}, payments.ErrConflict + } + return previous, nil +} + +func (db *Database) GetPaymentOrder(ctx context.Context, id string) (payments.Order, error) { + q, err := db.paymentQuerier() + if err != nil { + return payments.Order{}, err + } + order, found, err := queryPaymentOrder(ctx, q, getPaymentOrderSQL, id) + if err != nil { + return payments.Order{}, paymentSQLError("get payment order", err) + } + if !found { + return payments.Order{}, payments.ErrNotFound + } + return order, nil +} + +func (db *Database) ListPaymentOrders(ctx context.Context, organizationID string, limit int) ([]payments.Order, error) { + q, err := db.paymentQuerier() + if err != nil { + return nil, err + } + if organizationID == "" { + return nil, payments.ErrConflict + } + return queryPaymentOrders(ctx, q, listPaymentOrdersSQL, organizationID, boundedPaymentLimit(limit)) +} + +func (db *Database) PendingPaymentOrders(ctx context.Context, limit int) ([]payments.Order, error) { + q, err := db.paymentQuerier() + if err != nil { + return nil, err + } + return queryPaymentOrders(ctx, q, pendingPaymentOrdersSQL, boundedPaymentLimit(limit)) +} + +func boundedPaymentLimit(limit int) int { + if limit < 1 { + return 1 + } + if limit > 500 { + return 500 + } + return limit +} + +func (db *Database) UpdatePaymentOrder(ctx context.Context, id, status, codeURL string) (payments.Order, error) { + q, err := db.paymentQuerier() + if err != nil { + return payments.Order{}, err + } + if id == "" || len(codeURL) > 2048 || (status != payments.StatusPending && status != payments.StatusClosed) { + return payments.Order{}, payments.ErrConflict + } + statement := closePaymentOrderSQL + args := []any{id} + if status == payments.StatusPending { + statement = updatePendingPaymentOrderSQL + args = append(args, codeURL) + } + order, found, err := queryPaymentOrder(ctx, q, statement, args...) + if err != nil { + return payments.Order{}, paymentSQLError("update payment order", err) + } + if found { + return order, nil + } + return db.GetPaymentOrder(ctx, id) +} + +func (db *Database) SettlePaymentOrder(ctx context.Context, transaction payments.Transaction) (payments.Order, error) { + if _, err := db.paymentQuerier(); err != nil || db.transactions == nil { + return payments.Order{}, payments.ErrUnavailable + } + if transaction.OrderID == "" || transaction.MchID == "" || transaction.AppID == "" || + transaction.TransactionID == "" || transaction.TradeState != "SUCCESS" || + transaction.Currency != "CNY" || transaction.AmountFen < 1 || transaction.AmountFen > 1_000_000 { + return payments.Order{}, payments.ErrVerification + } + tx, err := db.transactions.Begin(ctx) + if err != nil { + return payments.Order{}, paymentSQLError("begin payment settlement", err) + } + committed := false + defer func() { + if !committed { + _ = tx.Rollback(ctx) + } + }() + order, found, err := queryPaymentOrder(ctx, tx, lockPaymentOrderSQL, transaction.OrderID) + if err != nil { + return payments.Order{}, paymentSQLError("lock payment order", err) + } + if !found { + return payments.Order{}, payments.ErrNotFound + } + if order.MchID != transaction.MchID || order.AppID != transaction.AppID || + order.AmountFen != transaction.AmountFen || order.Currency != transaction.Currency { + return payments.Order{}, payments.ErrVerification + } + if order.Status == payments.StatusPaid { + if order.TransactionID != transaction.TransactionID { + return payments.Order{}, payments.ErrConflict + } + if err := tx.Commit(ctx); err != nil { + return payments.Order{}, paymentSQLError("commit payment replay", err) + } + committed = true + return order, nil + } + if order.Status != payments.StatusPending && order.Status != payments.StatusClosed { + return payments.Order{}, payments.ErrConflict + } + paidAt := transaction.SuccessTime + if paidAt.IsZero() { + paidAt = time.Now().UTC() + } + paid, found, err := queryPaymentOrder(ctx, tx, paidPaymentOrderSQL, order.ID, transaction.TransactionID, paidAt) + if err != nil { + return payments.Order{}, paymentSQLError("record payment transaction", err) + } + if !found { + return payments.Order{}, payments.ErrConflict + } + metadata, err := json.Marshal(map[string]string{ + "source": "wechat_native", "paymentOrderId": order.ID, + "transactionId": transaction.TransactionID, "mchId": transaction.MchID, + "appId": transaction.AppID, "initiatedByAccountId": order.AccountID, + }) + if err != nil { + return payments.Order{}, err + } + rows, err := tx.Query(ctx, PostWalletEntrySQL, + "wechat-native-entry:"+order.ID, order.OrganizationID, nil, nil, + "recharge", order.AmountFen, "CNY", "wechat-native:"+order.MchID+":"+order.ID, + "微信扫码充值", json.RawMessage(metadata)) + if err != nil { + return payments.Order{}, paymentSQLError("post payment wallet credit", err) + } + if !rows.Next() { + rowErr := rows.Err() + rows.Close() + if rowErr != nil { + return payments.Order{}, paymentSQLError("read payment wallet credit", rowErr) + } + return payments.Order{}, fmt.Errorf("payment wallet credit returned no row") + } + var posting WalletEntry + if err := rows.Scan(&posting.LedgerID, &posting.BalanceAfterFen, &posting.BalanceFen, + &posting.TotalRechargedFen, &posting.TotalChargedFen, &posting.CreatedAt, + &posting.UpdatedAt, &posting.DeltaFen); err != nil { + rows.Close() + return payments.Order{}, paymentSQLError("scan payment wallet credit", err) + } + rowErr := rows.Err() + rows.Close() + if rowErr != nil { + return payments.Order{}, paymentSQLError("complete payment wallet credit", rowErr) + } + if posting.DeltaFen != order.AmountFen || posting.LedgerID != "wechat-native-entry:"+order.ID { + return payments.Order{}, payments.ErrConflict + } + if err := tx.Commit(ctx); err != nil { + // The commit result can be ambiguous. A replay with this transaction ID + // resolves it safely because paid status and wallet entry commit together. + return payments.Order{}, paymentSQLError("commit payment settlement; query or replay the order", err) + } + committed = true + return paid, nil +} + +func queryPaymentOrder(ctx context.Context, q Querier, statement string, args ...any) (payments.Order, bool, error) { + rows, err := q.Query(ctx, statement, args...) + if err != nil { + return payments.Order{}, false, err + } + defer rows.Close() + if !rows.Next() { + return payments.Order{}, false, rows.Err() + } + order, err := scanPaymentOrder(rows) + if err != nil { + return payments.Order{}, false, err + } + return order, true, rows.Err() +} + +func queryPaymentOrders(ctx context.Context, q Querier, statement string, args ...any) ([]payments.Order, error) { + rows, err := q.Query(ctx, statement, args...) + if err != nil { + return nil, paymentSQLError("list payment orders", err) + } + defer rows.Close() + out := make([]payments.Order, 0) + for rows.Next() { + order, err := scanPaymentOrder(rows) + if err != nil { + return nil, paymentSQLError("scan payment order", err) + } + out = append(out, order) + } + return out, paymentSQLError("read payment orders", rows.Err()) +} + +func scanPaymentOrder(rows Rows) (payments.Order, error) { + var order payments.Order + var paidAt sql.NullTime + err := rows.Scan(&order.ID, &order.OrganizationID, &order.AccountID, &order.RequestKey, + &order.MchID, &order.AppID, &order.AmountFen, &order.Currency, &order.Status, + &order.CodeURL, &order.TransactionID, &order.CreatedAt, &order.UpdatedAt, + &order.ExpiresAt, &paidAt) + if err != nil { + return payments.Order{}, err + } + if paidAt.Valid { + order.PaidAt = &paidAt.Time + } + if order.Status != payments.StatusPending { + order.CodeURL = "" + } + return order, nil +} + +func paymentSQLError(action string, err error) error { + if err == nil { + return nil + } + var pgErr *pgconn.PgError + if errors.As(err, &pgErr) && (pgErr.Code == "23505" || pgErr.Code == "23503" || pgErr.Code == "23514") { + return fmt.Errorf("%w: %s: %v", payments.ErrConflict, action, err) + } + return fmt.Errorf("%s: %w", action, err) +} + +var _ payments.Repository = (*Database)(nil) diff --git a/backend/internal/postgres/payments_integration_test.go b/backend/internal/postgres/payments_integration_test.go new file mode 100644 index 0000000..c333314 --- /dev/null +++ b/backend/internal/postgres/payments_integration_test.go @@ -0,0 +1,116 @@ +package postgres + +import ( + "context" + "errors" + "os" + "sync" + "testing" + "time" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" + "github.com/jackc/pgx/v5/pgxpool" +) + +// Run only against a disposable PostgreSQL instance. The test never reads the +// application's DATABASE_URL or local credentials. +func TestPaymentSettlementInDisposablePostgres(t *testing.T) { + databaseURL := os.Getenv("NIAN_TEST_PAYMENT_DATABASE_URL") + if databaseURL == "" { + t.Skip("set NIAN_TEST_PAYMENT_DATABASE_URL to a disposable PostgreSQL database") + } + ctx := context.Background() + pool, err := pgxpool.New(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer pool.Close() + db := NewDatabase(Config{Backend: BackendPostgres}, &pgxPoolAdapter{pool: pool}) + if err := db.Readiness(ctx); err != nil { + t.Fatalf("migrations/readiness: %v", err) + } + _, err = pool.Exec(ctx, `INSERT INTO public.platform_organizations(id, name, archive_owner_id) VALUES ('pay_test_org', 'payment test org', 'pay_test_archive'); +INSERT INTO public.platform_users(id, phone, display_name, role, organization_id, status, password_hash, password_salt) +VALUES ('pay_test_admin', '13900000123', 'Payment Test', 'organization_admin', 'pay_test_org', 'active', 'hash', 'salt')`) + if err != nil { + t.Fatal(err) + } + makeOrder := func(id, requestKey string, amount int64) payments.Order { + return payments.Order{ID: id, OrganizationID: "pay_test_org", AccountID: "pay_test_admin", + RequestKey: requestKey, MchID: "test_mch", AppID: "test_app", AmountFen: amount, + Currency: "CNY", ExpiresAt: time.Now().Add(15 * time.Minute)} + } + first, err := db.CreatePaymentOrder(ctx, makeOrder("pay_test_order_1", "pay_test_request_1", 5200)) + if err != nil || first.Status != payments.StatusPending { + t.Fatalf("create first: %+v %v", first, err) + } + replayed, err := db.CreatePaymentOrder(ctx, makeOrder("pay_test_order_new", "pay_test_request_1", 5200)) + if err != nil || replayed.ID != first.ID { + t.Fatalf("idempotent create: %+v %v", replayed, err) + } + if _, err := db.CreatePaymentOrder(ctx, makeOrder("pay_test_order_new", "pay_test_request_1", 5201)); !errors.Is(err, payments.ErrConflict) { + t.Fatalf("changed request payload: %v", err) + } + txn := payments.Transaction{OrderID: first.ID, MchID: "test_mch", AppID: "test_app", + TransactionID: "wx_test_transaction_1", TradeState: "SUCCESS", Currency: "CNY", + AmountFen: 5200, SuccessTime: time.Now().UTC()} + var wg sync.WaitGroup + errorsOut := make(chan error, 12) + for i := 0; i < 12; i++ { + wg.Add(1) + go func() { + defer wg.Done() + order, err := db.SettlePaymentOrder(ctx, txn) + if err == nil && order.Status != payments.StatusPaid { + err = payments.ErrConflict + } + errorsOut <- err + }() + } + wg.Wait() + close(errorsOut) + for err := range errorsOut { + if err != nil { + t.Fatalf("concurrent settlement: %v", err) + } + } + var balance, recharged int64 + if err := pool.QueryRow(ctx, `SELECT balance_fen, total_recharged_fen FROM public.billing_wallets WHERE organization_id = 'pay_test_org'`).Scan(&balance, &recharged); err != nil { + t.Fatal(err) + } + var ledgerCount int + if err := pool.QueryRow(ctx, `SELECT count(*) FROM public.billing_ledger WHERE organization_id = 'pay_test_org' AND idempotency_key = 'wechat-native:test_mch:pay_test_order_1'`).Scan(&ledgerCount); err != nil { + t.Fatal(err) + } + if balance != 5200 || recharged != 5200 || ledgerCount != 1 { + t.Fatalf("after 12 deliveries: balance=%d recharged=%d ledger=%d", balance, recharged, ledgerCount) + } + second, err := db.CreatePaymentOrder(ctx, makeOrder("pay_test_order_2", "pay_test_request_2", 300)) + if err != nil { + t.Fatal(err) + } + if _, err := db.UpdatePaymentOrder(ctx, second.ID, payments.StatusClosed, ""); err != nil { + t.Fatal(err) + } + collision := txn + collision.OrderID = second.ID + collision.AmountFen = 300 + if _, err := db.SettlePaymentOrder(ctx, collision); !errors.Is(err, payments.ErrConflict) { + t.Fatalf("reused WeChat transaction: %v", err) + } + stillClosed, err := db.GetPaymentOrder(ctx, second.ID) + if err != nil || stillClosed.Status != payments.StatusClosed { + t.Fatalf("transaction collision changed order: %+v %v", stillClosed, err) + } + late := collision + late.TransactionID = "wx_test_transaction_2" + if _, err := db.SettlePaymentOrder(ctx, late); err != nil { + t.Fatalf("valid late success: %v", err) + } + if err := pool.QueryRow(ctx, `SELECT balance_fen, total_recharged_fen FROM public.billing_wallets WHERE organization_id = 'pay_test_org'`).Scan(&balance, &recharged); err != nil { + t.Fatal(err) + } + if balance != 5500 || recharged != 5500 { + t.Fatalf("after late success: balance=%d recharged=%d", balance, recharged) + } +} diff --git a/backend/internal/postgres/payments_test.go b/backend/internal/postgres/payments_test.go new file mode 100644 index 0000000..bf2efd6 --- /dev/null +++ b/backend/internal/postgres/payments_test.go @@ -0,0 +1,177 @@ +package postgres + +import ( + "context" + "encoding/json" + "errors" + "strings" + "testing" + "time" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" + "github.com/jackc/pgx/v5/pgconn" +) + +func paymentTestOrder(status, transactionID string) payments.Order { + now := time.Now().UTC() + order := payments.Order{ + ID: "pmt_123", OrganizationID: "org_1", AccountID: "account_1", RequestKey: "request_1", + MchID: "mch_1", AppID: "wx_app_1", AmountFen: 5200, Currency: "CNY", + Status: status, CodeURL: "weixin://qr", TransactionID: transactionID, + CreatedAt: now, UpdatedAt: now, ExpiresAt: now.Add(15 * time.Minute), + } + if status == payments.StatusPaid { + order.PaidAt = &now + } + return order +} + +func paymentTestRow(order payments.Order) []any { + var paidAt any + if order.PaidAt != nil { + paidAt = *order.PaidAt + } + return []any{order.ID, order.OrganizationID, order.AccountID, order.RequestKey, + order.MchID, order.AppID, order.AmountFen, order.Currency, order.Status, + order.CodeURL, order.TransactionID, order.CreatedAt, order.UpdatedAt, order.ExpiresAt, paidAt} +} + +func paymentTestTransaction() payments.Transaction { + return payments.Transaction{ + OrderID: "pmt_123", MchID: "mch_1", AppID: "wx_app_1", + TransactionID: "wx_transaction_1", TradeState: "SUCCESS", Currency: "CNY", + AmountFen: 5200, SuccessTime: time.Now().UTC(), + } +} + +func TestPaymentSettlementAtomicallyPostsExactAmountAndMarksPaid(t *testing.T) { + order := paymentTestOrder(payments.StatusPending, "") + paid := paymentTestOrder(payments.StatusPaid, "wx_transaction_1") + now := time.Now().UTC() + tx := &generationStateTransaction{results: []*jobRows{ + {rows: [][]any{paymentTestRow(order)}}, + {rows: [][]any{paymentTestRow(paid)}}, + {rows: [][]any{{"wechat-native-entry:pmt_123", int64(5200), int64(5200), int64(5200), int64(0), now, now, int64(5200)}}}, + }} + db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx}) + got, err := db.SettlePaymentOrder(context.Background(), paymentTestTransaction()) + if err != nil || got.Status != payments.StatusPaid || tx.commits != 1 || tx.rollbacks != 0 { + t.Fatalf("got=%+v err=%v commits=%d rollbacks=%d", got, err, tx.commits, tx.rollbacks) + } + if len(tx.queries) != 3 || tx.queries[0].sql != lockPaymentOrderSQL || + tx.queries[1].sql != paidPaymentOrderSQL || tx.queries[2].sql != PostWalletEntrySQL { + t.Fatalf("queries=%+v", tx.queries) + } + args := tx.queries[2].args + if args[0] != "wechat-native-entry:pmt_123" || args[1] != "org_1" || args[2] != nil || args[3] != nil || + args[4] != "recharge" || args[5] != int64(5200) || args[7] != "wechat-native:mch_1:pmt_123" { + t.Fatalf("wallet args=%#v", args) + } + var metadata map[string]string + if err := json.Unmarshal(args[9].(json.RawMessage), &metadata); err != nil || metadata["initiatedByAccountId"] != "account_1" { + t.Fatalf("metadata=%#v err=%v", metadata, err) + } +} + +func TestPaymentSettlementRejectsMismatchedAmountBeforeWalletWrite(t *testing.T) { + tx := &generationStateTransaction{results: []*jobRows{{rows: [][]any{paymentTestRow(paymentTestOrder(payments.StatusPending, ""))}}}} + db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx}) + transaction := paymentTestTransaction() + transaction.AmountFen-- + _, err := db.SettlePaymentOrder(context.Background(), transaction) + if !errors.Is(err, payments.ErrVerification) || tx.commits != 0 || tx.rollbacks != 1 || len(tx.queries) != 1 { + t.Fatalf("err=%v commits=%d rollbacks=%d queries=%d", err, tx.commits, tx.rollbacks, len(tx.queries)) + } +} + +func TestPaymentSettlementReplaysSamePaidTransactionWithoutRecredit(t *testing.T) { + tx := &generationStateTransaction{results: []*jobRows{{rows: [][]any{paymentTestRow(paymentTestOrder(payments.StatusPaid, "wx_transaction_1"))}}}} + db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx}) + _, err := db.SettlePaymentOrder(context.Background(), paymentTestTransaction()) + if err != nil || tx.commits != 1 || len(tx.queries) != 1 { + t.Fatalf("err=%v commits=%d queries=%d", err, tx.commits, len(tx.queries)) + } +} + +func TestPaymentSettlementAllowsVerifiedLateSuccessAfterClose(t *testing.T) { + closed := paymentTestOrder(payments.StatusClosed, "") + paid := paymentTestOrder(payments.StatusPaid, "wx_transaction_1") + now := time.Now().UTC() + tx := &generationStateTransaction{results: []*jobRows{ + {rows: [][]any{paymentTestRow(closed)}}, + {rows: [][]any{paymentTestRow(paid)}}, + {rows: [][]any{{"wechat-native-entry:pmt_123", int64(5200), int64(5200), int64(5200), int64(0), now, now, int64(5200)}}}, + }} + db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx}) + got, err := db.SettlePaymentOrder(context.Background(), paymentTestTransaction()) + if err != nil || got.Status != payments.StatusPaid || tx.commits != 1 { + t.Fatalf("got=%+v err=%v commits=%d", got, err, tx.commits) + } +} + +func TestPaymentSettlementRollsBackOrderWhenWalletFails(t *testing.T) { + tx := &generationStateTransaction{results: []*jobRows{ + {rows: [][]any{paymentTestRow(paymentTestOrder(payments.StatusPending, ""))}}, + {rows: [][]any{paymentTestRow(paymentTestOrder(payments.StatusPaid, "wx_transaction_1"))}}, + {err: &pgconn.PgError{Code: "P0001", Message: "wallet failed"}}, + }} + db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx}) + _, err := db.SettlePaymentOrder(context.Background(), paymentTestTransaction()) + if err == nil || tx.commits != 0 || tx.rollbacks != 1 { + t.Fatalf("err=%v commits=%d rollbacks=%d", err, tx.commits, tx.rollbacks) + } +} + +func TestPaymentSettlementRejectsReusedProviderTransactionAndRollsBack(t *testing.T) { + tx := &generationStateTransaction{results: []*jobRows{ + {rows: [][]any{paymentTestRow(paymentTestOrder(payments.StatusPending, ""))}}, + {err: &pgconn.PgError{Code: "23505", ConstraintName: "payment_orders_provider_transaction_unique"}}, + }} + db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx}) + _, err := db.SettlePaymentOrder(context.Background(), paymentTestTransaction()) + if !errors.Is(err, payments.ErrConflict) || tx.commits != 0 || tx.rollbacks != 1 || len(tx.queries) != 2 { + t.Fatalf("err=%v commits=%d rollbacks=%d queries=%d", err, tx.commits, tx.rollbacks, len(tx.queries)) + } +} + +func TestPaymentSettlementRejectsDifferentTransactionForPaidOrder(t *testing.T) { + tx := &generationStateTransaction{results: []*jobRows{{rows: [][]any{paymentTestRow(paymentTestOrder(payments.StatusPaid, "other_transaction"))}}}} + db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx}) + _, err := db.SettlePaymentOrder(context.Background(), paymentTestTransaction()) + if !errors.Is(err, payments.ErrConflict) || tx.commits != 0 || tx.rollbacks != 1 || len(tx.queries) != 1 { + t.Fatalf("err=%v commits=%d rollbacks=%d queries=%d", err, tx.commits, tx.rollbacks, len(tx.queries)) + } +} + +func TestPaymentCreateRejectsInvalidMoneyAndIdentifiersBeforeWrite(t *testing.T) { + for _, mutate := range []func(*payments.Order){ + func(o *payments.Order) { o.AmountFen = 0 }, + func(o *payments.Order) { o.AmountFen = 1_000_001 }, + func(o *payments.Order) { o.Currency = "USD" }, + func(o *payments.Order) { o.RequestKey = "request:key" }, + func(o *payments.Order) { o.ID = strings.Repeat("a", 33) }, + } { + q := &fakeQuerier{} + db := NewDatabase(Config{Backend: BackendPostgres}, q) + order := paymentTestOrder(payments.StatusPending, "") + mutate(&order) + if _, err := db.CreatePaymentOrder(context.Background(), order); err == nil || q.sql != "" { + t.Fatalf("order=%+v err=%v sql=%s", order, err, q.sql) + } + } +} + +func TestPaymentCreateUsesAccountOrganizationAndRequestUniqueness(t *testing.T) { + if !strings.Contains(createPaymentOrderSQL, "account.organization_id = organization.id") || + !strings.Contains(createPaymentOrderSQL, "account.role IN ('organization_admin', 'super_admin')") || + !strings.Contains(createPaymentOrderSQL, "ON CONFLICT DO NOTHING") { + t.Fatalf("create SQL lacks account relation or conflict control: %s", createPaymentOrderSQL) + } + order := paymentTestOrder(payments.StatusPending, "") + q := &fakeQuerier{rows: [][]any{paymentTestRow(order)}} + db := NewDatabase(Config{Backend: BackendPostgres}, q) + created, err := db.CreatePaymentOrder(context.Background(), order) + if err != nil || created.ID != order.ID || q.sql != createPaymentOrderSQL { + t.Fatalf("created=%+v err=%v sql=%s", created, err, q.sql) + } +} diff --git a/backend/internal/postgres/refunds.go b/backend/internal/postgres/refunds.go new file mode 100644 index 0000000..7333b65 --- /dev/null +++ b/backend/internal/postgres/refunds.go @@ -0,0 +1,533 @@ +package postgres + +import ( + "context" + "database/sql" + "encoding/json" + "strings" + "time" + "unicode" + "unicode/utf8" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" +) + +const refundColumns = `r.id, r.order_id, r.organization_id, r.operator_id, + COALESCE(u.display_name, ''), r.request_key, r.mch_id, r.transaction_id, + COALESCE(r.provider_id, ''), r.amount_fen, r.total_fen, r.currency, r.reason, + r.status, r.failure_reason, r.created_at, r.updated_at, r.succeeded_at` + +const refundSelect = `SELECT ` + refundColumns + ` FROM public.payment_refunds r + LEFT JOIN public.platform_users u ON u.id = r.operator_id ` + +const adminOrdersSQL = `SELECT payment_orders.id, payment_orders.organization_id, + payment_orders.account_id, payment_orders.request_key, payment_orders.mch_id, + payment_orders.app_id, payment_orders.amount_fen, payment_orders.currency, + payment_orders.status, COALESCE(payment_orders.code_url, ''), + COALESCE(payment_orders.transaction_id, ''), payment_orders.created_at, + payment_orders.updated_at, payment_orders.expires_at, payment_orders.paid_at, + COALESCE(org.name, ''), COALESCE(account.display_name, ''), + COALESCE(refunds.refunded_fen, 0), COALESCE(refunds.refunding_fen, 0) +FROM public.payment_orders +JOIN public.platform_organizations org ON org.id = payment_orders.organization_id +JOIN public.platform_users account ON account.id = payment_orders.account_id +LEFT JOIN LATERAL ( + SELECT sum(amount_fen) FILTER (WHERE status = 'success') AS refunded_fen, + sum(amount_fen) FILTER (WHERE status IN ('pending', 'processing', 'abnormal')) AS refunding_fen + FROM public.payment_refunds WHERE order_id = payment_orders.id +) refunds ON true +WHERE ($1::text = '' OR payment_orders.organization_id = $1::text) +ORDER BY payment_orders.created_at DESC, payment_orders.id DESC +LIMIT $2::integer OFFSET $3::integer` + +// The caller requests limit+1 to discover whether another page exists. +func (db *Database) ListAdminPaymentOrders(ctx context.Context, organizationID string, limit, offset int) ([]payments.AdminOrder, error) { + q, err := db.paymentQuerier() + if err != nil { + return nil, err + } + if offset < 0 { + return nil, payments.ErrConflict + } + rows, err := q.Query(ctx, adminOrdersSQL, organizationID, boundedAdminOrdersLimit(limit), offset) + if err != nil { + return nil, paymentSQLError("list admin payment orders", err) + } + defer rows.Close() + out := make([]payments.AdminOrder, 0) + for rows.Next() { + var item payments.AdminOrder + var paidAt sql.NullTime + if err := rows.Scan(&item.ID, &item.OrganizationID, &item.AccountID, &item.RequestKey, + &item.MchID, &item.AppID, &item.AmountFen, &item.Currency, &item.Status, + &item.CodeURL, &item.TransactionID, &item.CreatedAt, &item.UpdatedAt, + &item.ExpiresAt, &paidAt, &item.OrganizationName, &item.AccountName, + &item.RefundedFen, &item.RefundingFen); err != nil { + return nil, paymentSQLError("scan admin payment order", err) + } + if paidAt.Valid { + item.PaidAt = &paidAt.Time + } + item.CodeURL = "" + item.RefundableFen = item.AmountFen - item.RefundedFen - item.RefundingFen + if item.Status != payments.StatusPaid || item.RefundableFen < 0 { + item.RefundableFen = 0 + } + out = append(out, item) + } + return out, paymentSQLError("read admin payment orders", rows.Err()) +} + +func boundedAdminOrdersLimit(limit int) int { + if limit < 1 { + return 1 + } + if limit > 101 { + return 101 + } + return limit +} + +func (db *Database) CreatePaymentRefund(ctx context.Context, input payments.Refund) (payments.Refund, error) { + if _, err := db.paymentQuerier(); err != nil || db.transactions == nil { + return payments.Refund{}, payments.ErrUnavailable + } + if !validPaymentKey(input.ID, 32) || !validPaymentKey(input.RequestKey, 64) || + !validPaymentKey(input.OrderID, 32) || input.OperatorID == "" || input.AmountFen <= 0 || + len(input.Reason) > 80 { + return payments.Refund{}, payments.ErrConflict + } + tx, err := db.transactions.Begin(ctx) + if err != nil { + return payments.Refund{}, paymentSQLError("begin refund reservation", err) + } + defer tx.Rollback(ctx) + order, found, err := queryPaymentOrder(ctx, tx, lockPaymentOrderSQL, input.OrderID) + if err != nil { + return payments.Refund{}, paymentSQLError("lock original payment", err) + } + if !found { + return payments.Refund{}, payments.ErrNotFound + } + if order.Status != payments.StatusPaid { + return payments.Refund{}, payments.ErrConflict + } + operatorOK, err := queryRefundOperator(ctx, tx, input.OperatorID) + if err != nil { + return payments.Refund{}, paymentSQLError("verify refund operator", err) + } + if !operatorOK { + return payments.Refund{}, payments.ErrConflict + } + previous, found, err := queryRefund(ctx, tx, refundSelect+` WHERE r.order_id = $1 AND r.request_key = $2`, order.ID, input.RequestKey) + if err != nil { + return payments.Refund{}, paymentSQLError("read refund request", err) + } + if found { + if previous.OperatorID != input.OperatorID || previous.AmountFen != input.AmountFen || previous.Reason != input.Reason { + return payments.Refund{}, payments.ErrConflict + } + if err := tx.Commit(ctx); err != nil { + return payments.Refund{}, paymentSQLError("commit refund replay", err) + } + return previous, nil + } + used, err := queryRefundUsed(ctx, tx, order.ID, "") + if err != nil { + return payments.Refund{}, paymentSQLError("check refundable balance", err) + } + if used > order.AmountFen || input.AmountFen > order.AmountFen-used { + return payments.Refund{}, payments.ErrInvalidAmount + } + created, found, err := queryRefund(ctx, tx, `INSERT INTO public.payment_refunds + (id, order_id, organization_id, operator_id, request_key, mch_id, transaction_id, + amount_fen, total_fen, currency, reason) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + RETURNING `+refundColumnsNoJoin, + input.ID, order.ID, order.OrganizationID, input.OperatorID, input.RequestKey, + order.MchID, order.TransactionID, input.AmountFen, order.AmountFen, order.Currency, input.Reason) + if err != nil { + return payments.Refund{}, paymentSQLError("create refund reservation", err) + } + if !found { + return payments.Refund{}, payments.ErrConflict + } + if err := tx.Commit(ctx); err != nil { + return payments.Refund{}, paymentSQLError("commit refund reservation", err) + } + return created, nil +} + +const refundColumnsNoJoin = `id, order_id, organization_id, operator_id, ''::text, request_key, + mch_id, transaction_id, COALESCE(provider_id, ''), amount_fen, total_fen, + currency, reason, status, failure_reason, created_at, updated_at, succeeded_at` + +func queryRefundOperator(ctx context.Context, q Querier, operatorID string) (bool, error) { + rows, err := q.Query(ctx, `SELECT 1 FROM public.platform_users WHERE id = $1 AND role = 'super_admin' AND status = 'active'`, operatorID) + if err != nil { + return false, err + } + defer rows.Close() + if !rows.Next() { + return false, rows.Err() + } + var one int + if err := rows.Scan(&one); err != nil { + return false, err + } + return one == 1, rows.Err() +} + +func queryRefundUsed(ctx context.Context, q Querier, orderID, excludeID string) (int64, error) { + rows, err := q.Query(ctx, `SELECT COALESCE(sum(amount_fen), 0)::bigint FROM public.payment_refunds + WHERE order_id = $1 AND id <> $2 AND status IN ('pending', 'processing', 'abnormal', 'success')`, orderID, excludeID) + if err != nil { + return 0, err + } + defer rows.Close() + if !rows.Next() { + return 0, rows.Err() + } + var used int64 + if err := rows.Scan(&used); err != nil { + return 0, err + } + return used, rows.Err() +} + +func (db *Database) GetPaymentRefund(ctx context.Context, id string) (payments.Refund, error) { + q, err := db.paymentQuerier() + if err != nil { + return payments.Refund{}, err + } + item, found, err := queryRefund(ctx, q, refundSelect+` WHERE r.id = $1`, id) + if err != nil { + return payments.Refund{}, paymentSQLError("get refund", err) + } + if !found { + return payments.Refund{}, payments.ErrNotFound + } + return item, nil +} + +func (db *Database) ListPaymentRefunds(ctx context.Context, orderID string) ([]payments.Refund, error) { + q, err := db.paymentQuerier() + if err != nil { + return nil, err + } + return queryRefunds(ctx, q, refundSelect+` WHERE r.order_id = $1 ORDER BY r.created_at DESC, r.id DESC`, orderID) +} + +func (db *Database) PendingPaymentRefunds(ctx context.Context, limit int) ([]payments.Refund, error) { + q, err := db.paymentQuerier() + if err != nil { + return nil, err + } + return queryRefunds(ctx, q, refundSelect+` WHERE r.status IN ('pending', 'processing', 'abnormal') + ORDER BY r.updated_at, r.created_at, r.id LIMIT $1`, boundedPaymentLimit(limit)) +} + +func (db *Database) TouchPaymentRefund(ctx context.Context, id string) (payments.Refund, error) { + q, err := db.paymentQuerier() + if err != nil { + return payments.Refund{}, err + } + item, found, err := queryRefund(ctx, q, `UPDATE public.payment_refunds + SET updated_at = now() WHERE id = $1 AND status IN ('pending', 'processing', 'abnormal') + RETURNING `+refundColumnsNoJoin, id) + if err != nil { + return payments.Refund{}, paymentSQLError("touch refund", err) + } + if found { + return item, nil + } + return db.GetPaymentRefund(ctx, id) +} + +// Reject only an unsubmitted request. The original payment lock serializes +// reservation release with new requests and late provider notifications. +func (db *Database) RejectPaymentRefund(ctx context.Context, id, reason string) (payments.Refund, error) { + if _, err := db.paymentQuerier(); err != nil || db.transactions == nil { + return payments.Refund{}, payments.ErrUnavailable + } + if !validPaymentKey(id, 32) || reason == "" || len(reason) > 160 || !utf8.ValidString(reason) || + strings.IndexFunc(reason, unicode.IsControl) >= 0 { + return payments.Refund{}, payments.ErrConflict + } + tx, err := db.transactions.Begin(ctx) + if err != nil { + return payments.Refund{}, paymentSQLError("begin refund rejection", err) + } + defer tx.Rollback(ctx) + initial, found, err := queryRefund(ctx, tx, refundSelect+` WHERE r.id = $1`, id) + if err != nil { + return payments.Refund{}, paymentSQLError("read refund for rejection", err) + } + if !found { + return payments.Refund{}, payments.ErrNotFound + } + if _, found, err := queryPaymentOrder(ctx, tx, lockPaymentOrderSQL, initial.OrderID); err != nil { + return payments.Refund{}, paymentSQLError("lock original payment for rejection", err) + } else if !found { + return payments.Refund{}, payments.ErrNotFound + } + item, found, err := queryRefund(ctx, tx, refundSelect+` WHERE r.id = $1 FOR UPDATE OF r`, id) + if err != nil { + return payments.Refund{}, paymentSQLError("lock refund for rejection", err) + } + if !found { + return payments.Refund{}, payments.ErrNotFound + } + if item.OrderID != initial.OrderID { + return payments.Refund{}, payments.ErrConflict + } + if item.Status == payments.RefundRejected { + if err := tx.Commit(ctx); err != nil { + return payments.Refund{}, paymentSQLError("commit rejected refund replay", err) + } + return item, nil + } + if item.Status != payments.RefundPending || item.ProviderID != "" { + return payments.Refund{}, payments.ErrConflict + } + item, found, err = queryRefund(ctx, tx, `UPDATE public.payment_refunds + SET status = 'rejected', failure_reason = $2, updated_at = now() + WHERE id = $1 AND status = 'pending' AND provider_id IS NULL + RETURNING `+refundColumnsNoJoin, id, reason) + if err != nil { + return payments.Refund{}, paymentSQLError("reject refund", err) + } + if !found { + return payments.Refund{}, payments.ErrConflict + } + if err := tx.Commit(ctx); err != nil { + return payments.Refund{}, paymentSQLError("commit refund rejection", err) + } + return item, nil +} + +func (db *Database) RecordPaymentRefund(ctx context.Context, remote payments.RefundTransaction) (payments.Refund, error) { + if _, err := db.paymentQuerier(); err != nil || db.transactions == nil { + return payments.Refund{}, payments.ErrUnavailable + } + if !validPaymentKey(remote.ID, 32) || !validPaymentKey(remote.OrderID, 32) || + remote.MchID == "" || remote.TransactionID == "" || remote.ProviderID == "" || + remote.Currency != "CNY" || remote.AmountFen <= 0 || remote.TotalFen <= 0 || + (remote.Status != payments.RefundPending && remote.Status != payments.RefundProcessing && + remote.Status != payments.RefundSuccess && remote.Status != payments.RefundClosed && remote.Status != payments.RefundAbnormal) { + return payments.Refund{}, payments.ErrVerification + } + tx, err := db.transactions.Begin(ctx) + if err != nil { + return payments.Refund{}, paymentSQLError("begin refund reconciliation", err) + } + defer tx.Rollback(ctx) + order, found, err := queryPaymentOrder(ctx, tx, lockPaymentOrderSQL, remote.OrderID) + if err != nil { + return payments.Refund{}, paymentSQLError("lock original payment", err) + } + if !found { + return payments.Refund{}, payments.ErrNotFound + } + item, found, err := queryRefund(ctx, tx, refundSelect+` WHERE r.id = $1 FOR UPDATE OF r`, remote.ID) + if err != nil { + return payments.Refund{}, paymentSQLError("lock refund", err) + } + if !found { + return payments.Refund{}, payments.ErrNotFound + } + if order.Status != payments.StatusPaid || item.OrderID != order.ID || item.OrganizationID != order.OrganizationID || + item.MchID != order.MchID || item.TransactionID != order.TransactionID || item.TotalFen != order.AmountFen || + item.ID != remote.ID || item.OrderID != remote.OrderID || item.MchID != remote.MchID || + item.TransactionID != remote.TransactionID || item.AmountFen != remote.AmountFen || + item.TotalFen != remote.TotalFen || item.Currency != remote.Currency || + (item.ProviderID != "" && item.ProviderID != remote.ProviderID) { + return payments.Refund{}, payments.ErrVerification + } + if item.Status == payments.RefundSuccess { + if err := tx.Commit(ctx); err != nil { + return payments.Refund{}, paymentSQLError("commit refund replay", err) + } + return item, nil + } + if remote.Status == payments.RefundSuccess { + // A provider-confirmed refund can arrive after a former CLOSED + // reservation was released and another refund was requested. Pending + // requests are only local reservations; they cannot invalidate money + // already returned by WeChat. Count completed refunds for this check. + used, err := queryRefundSucceeded(ctx, tx, order.ID, item.ID) + if err != nil { + return payments.Refund{}, paymentSQLError("check total refunded", err) + } + if used > order.AmountFen || item.AmountFen > order.AmountFen-used { + return payments.Refund{}, payments.ErrConflict + } + if err := debitRefundWallet(ctx, tx, item, remote.ProviderID); err != nil { + return payments.Refund{}, err + } + } + // Once closed, a delayed genuine success may still arrive. Other stale states + // never reopen it; success itself can never be reversed locally. + status := remote.Status + if item.Status == payments.RefundClosed && status != payments.RefundSuccess { + status = payments.RefundClosed + } + if item.Status == payments.RefundRejected && status != payments.RefundSuccess && + status != payments.RefundProcessing && status != payments.RefundAbnormal { + status = payments.RefundRejected + } + if item.Status == payments.RefundProcessing && status == payments.RefundPending { + status = payments.RefundProcessing + } + if item.Status == payments.RefundAbnormal && status == payments.RefundPending { + status = payments.RefundAbnormal + } + when := remote.SuccessTime + if status == payments.RefundSuccess && when.IsZero() { + when = time.Now().UTC() + } + item, found, err = queryRefund(ctx, tx, `UPDATE public.payment_refunds SET + status = $2, provider_id = $3, succeeded_at = CASE WHEN $2 = 'success' THEN $4::timestamptz ELSE NULL END, + failure_reason = CASE WHEN $2 = 'rejected' THEN failure_reason ELSE '' END, + updated_at = now() WHERE id = $1 RETURNING `+refundColumnsNoJoin, + item.ID, status, remote.ProviderID, nullableRefundTime(status, when)) + if err != nil { + return payments.Refund{}, paymentSQLError("record refund status", err) + } + if !found { + return payments.Refund{}, payments.ErrConflict + } + if err := tx.Commit(ctx); err != nil { + return payments.Refund{}, paymentSQLError("commit refund reconciliation", err) + } + return item, nil +} + +func queryRefundSucceeded(ctx context.Context, q Querier, orderID, excludeID string) (int64, error) { + rows, err := q.Query(ctx, `SELECT COALESCE(sum(amount_fen), 0)::bigint FROM public.payment_refunds + WHERE order_id = $1 AND id <> $2 AND status = 'success'`, orderID, excludeID) + if err != nil { + return 0, err + } + defer rows.Close() + if !rows.Next() { + return 0, rows.Err() + } + var amount int64 + if err := rows.Scan(&amount); err != nil { + return 0, err + } + return amount, rows.Err() +} + +func nullableRefundTime(status string, when time.Time) any { + if status == payments.RefundSuccess { + return when + } + return nil +} + +func debitRefundWallet(ctx context.Context, tx Transaction, item payments.Refund, providerID string) error { + metadata, err := json.Marshal(map[string]string{ + "source": "wechat_refund", "paymentOrderId": item.OrderID, "refundId": item.ID, + "transactionId": item.TransactionID, "providerRefundId": providerID, + }) + if err != nil { + return err + } + rows, err := tx.Query(ctx, `INSERT INTO public.billing_wallets(organization_id) VALUES ($1) + ON CONFLICT (organization_id) DO NOTHING RETURNING organization_id`, item.OrganizationID) + if err != nil { + return paymentSQLError("ensure refund wallet", err) + } + rows.Close() + rows, err = tx.Query(ctx, `UPDATE public.billing_wallets SET balance_fen = balance_fen - $2, + updated_at = now() WHERE organization_id = $1 RETURNING balance_fen`, item.OrganizationID, item.AmountFen) + if err != nil { + return paymentSQLError("debit refund wallet", err) + } + if !rows.Next() { + rows.Close() + return payments.ErrConflict + } + var balance int64 + if err := rows.Scan(&balance); err != nil { + rows.Close() + return paymentSQLError("scan refund wallet", err) + } + rows.Close() + key := "wechat-refund:" + item.MchID + ":" + item.ID + rows, err = tx.Query(ctx, `INSERT INTO public.billing_ledger + (id, organization_id, kind, delta_fen, balance_after_fen, currency, + idempotency_key, description, metadata) + VALUES ($1, $2, 'recharge_refund', $3, $4, 'CNY', $5, '微信充值退款', $6::jsonb) + RETURNING id`, "wechat-refund-entry:"+item.ID, item.OrganizationID, -item.AmountFen, + balance, key, json.RawMessage(metadata)) + if err != nil { + return paymentSQLError("record refund wallet ledger", err) + } + if !rows.Next() { + rows.Close() + return payments.ErrConflict + } + var id string + if err := rows.Scan(&id); err != nil { + rows.Close() + return paymentSQLError("scan refund ledger", err) + } + rows.Close() + if id != "wechat-refund-entry:"+item.ID { + return payments.ErrConflict + } + return nil +} + +func queryRefund(ctx context.Context, q Querier, statement string, args ...any) (payments.Refund, bool, error) { + rows, err := q.Query(ctx, statement, args...) + if err != nil { + return payments.Refund{}, false, err + } + defer rows.Close() + if !rows.Next() { + return payments.Refund{}, false, rows.Err() + } + item, err := scanRefund(rows) + if err != nil { + return payments.Refund{}, false, err + } + return item, true, rows.Err() +} + +func queryRefunds(ctx context.Context, q Querier, statement string, args ...any) ([]payments.Refund, error) { + rows, err := q.Query(ctx, statement, args...) + if err != nil { + return nil, paymentSQLError("list refunds", err) + } + defer rows.Close() + out := make([]payments.Refund, 0) + for rows.Next() { + item, err := scanRefund(rows) + if err != nil { + return nil, paymentSQLError("scan refund", err) + } + out = append(out, item) + } + return out, paymentSQLError("read refunds", rows.Err()) +} + +func scanRefund(rows Rows) (payments.Refund, error) { + var item payments.Refund + var succeeded sql.NullTime + if err := rows.Scan(&item.ID, &item.OrderID, &item.OrganizationID, &item.OperatorID, + &item.OperatorName, &item.RequestKey, &item.MchID, &item.TransactionID, + &item.ProviderID, &item.AmountFen, &item.TotalFen, &item.Currency, &item.Reason, + &item.Status, &item.FailureReason, &item.CreatedAt, &item.UpdatedAt, &succeeded); err != nil { + return payments.Refund{}, err + } + if succeeded.Valid { + item.SucceededAt = &succeeded.Time + } + return item, nil +} + +var _ payments.RefundRepository = (*Database)(nil) diff --git a/backend/internal/postgres/refunds_integration_test.go b/backend/internal/postgres/refunds_integration_test.go new file mode 100644 index 0000000..0af4351 --- /dev/null +++ b/backend/internal/postgres/refunds_integration_test.go @@ -0,0 +1,285 @@ +package postgres + +import ( + "context" + "errors" + "os" + "sync" + "testing" + "time" + + "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/payments" + "github.com/jackc/pgx/v5/pgxpool" +) + +// Run against a disposable, migrated database only. Never uses DATABASE_URL. +func TestRefundSettlementInDisposablePostgres(t *testing.T) { + url := os.Getenv("NIAN_TEST_REFUND_DATABASE_URL") + if url == "" { + t.Skip("set NIAN_TEST_REFUND_DATABASE_URL to a disposable migrated database") + } + ctx := context.Background() + pool, err := pgxpool.New(ctx, url) + if err != nil { + t.Fatal(err) + } + defer pool.Close() + db := NewDatabase(Config{Backend: BackendPostgres}, &pgxPoolAdapter{pool: pool}) + if err := db.Readiness(ctx); err != nil { + t.Fatal(err) + } + _, err = pool.Exec(ctx, `INSERT INTO public.platform_organizations(id,name,archive_owner_id) + VALUES ('refund_test_org','refund test org','refund_test_archive'); + INSERT INTO public.platform_users(id,phone,display_name,role,organization_id,status,password_hash,password_salt) + VALUES ('refund_test_admin','13900000901','Refund Admin','super_admin',NULL,'active','hash','salt'), + ('refund_test_orgadmin','13900000902','Org Admin','organization_admin','refund_test_org','active','hash','salt')`) + if err != nil { + t.Fatal(err) + } + order, err := db.CreatePaymentOrder(ctx, payments.Order{ID: "refund_test_order", OrganizationID: "refund_test_org", AccountID: "refund_test_orgadmin", RequestKey: "refund_test_pay_key", MchID: "refund_test_mch", AppID: "refund_test_app", AmountFen: 500, Currency: "CNY", ExpiresAt: time.Now().Add(15 * time.Minute)}) + if err != nil { + t.Fatal(err) + } + _, err = db.SettlePaymentOrder(ctx, payments.Transaction{OrderID: order.ID, MchID: order.MchID, AppID: order.AppID, TransactionID: "refund_test_payment_tx", TradeState: "SUCCESS", Currency: "CNY", AmountFen: 500, SuccessTime: time.Now()}) + if err != nil { + t.Fatal(err) + } + // Spend 400 before refund; successful refund must leave a negative balance. + rows, err := pool.Query(ctx, PostWalletEntrySQL, "refund_test_charge", "refund_test_org", nil, nil, "charge", int64(-400), "CNY", "refund_test_charge_key", "consumption", nil) + if err != nil { + t.Fatal(err) + } + for rows.Next() { + } // consume the SQL function result + if err := rows.Err(); err != nil { + t.Fatal(err) + } + rows.Close() + create := func(id, key string, amount int64, actor string) (payments.Refund, error) { + return db.CreatePaymentRefund(ctx, payments.Refund{ID: id, OrderID: order.ID, OperatorID: actor, RequestKey: key, AmountFen: amount, Reason: "customer request"}) + } + if _, err := create("refund_test_bad", "refund_test_bad_key", 100, "refund_test_orgadmin"); !errors.Is(err, payments.ErrConflict) { + t.Fatalf("non-super-admin refund: %v", err) + } + first, err := create("refund_test_refund", "refund_test_refund_key", 500, "refund_test_admin") + if err != nil { + t.Fatal(err) + } + if first.TransactionID != "refund_test_payment_tx" || first.MchID != "refund_test_mch" { + t.Fatalf("refund snapshot: %+v", first) + } + second, err := create("refund_test_replay", "refund_test_refund_key", 500, "refund_test_admin") + if err != nil || second.ID != first.ID { + t.Fatalf("idempotent refund: %+v %v", second, err) + } + if _, err := create("refund_test_other", "refund_test_other_key", 1, "refund_test_admin"); !errors.Is(err, payments.ErrInvalidAmount) { + t.Fatalf("over-refund reserved: %v", err) + } + remote := payments.RefundTransaction{ID: first.ID, OrderID: order.ID, MchID: order.MchID, TransactionID: "refund_test_payment_tx", ProviderID: "wx_refund_test_id", Status: payments.RefundSuccess, Currency: "CNY", AmountFen: 500, TotalFen: 500, SuccessTime: time.Now()} + var wg sync.WaitGroup + result := make(chan error, 8) + for i := 0; i < 8; i++ { + wg.Add(1) + go func() { defer wg.Done(); _, err := db.RecordPaymentRefund(ctx, remote); result <- err }() + } + wg.Wait() + close(result) + for err := range result { + if err != nil { + t.Fatalf("concurrent callback: %v", err) + } + } + var balance, gross, charged int64 + if err := pool.QueryRow(ctx, `SELECT balance_fen,total_recharged_fen,total_charged_fen FROM public.billing_wallets WHERE organization_id='refund_test_org'`).Scan(&balance, &gross, &charged); err != nil { + t.Fatal(err) + } + if balance != -400 || gross != 500 || charged != 400 { + t.Fatalf("balance=%d gross=%d charged=%d", balance, gross, charged) + } + var count int + if err := pool.QueryRow(ctx, `SELECT count(*) FROM public.billing_ledger WHERE organization_id='refund_test_org' AND kind='recharge_refund'`).Scan(&count); err != nil { + t.Fatal(err) + } + if count != 1 { + t.Fatalf("refund ledger count=%d", count) + } + // Ordinary debits remain guarded even after the refund debit caused debt. + rows, err = pool.Query(ctx, PostWalletEntrySQL, "refund_test_charge2", "refund_test_org", nil, nil, "charge", int64(-1), "CNY", "refund_test_charge_key2", "consumption", nil) + if err == nil { + for rows.Next() { + } + err = rows.Err() + rows.Close() + } + if err == nil { + t.Fatal("ordinary charge accepted negative balance") + } + admin, err := db.ListAdminPaymentOrders(ctx, "", 10, 0) + if err != nil || len(admin) != 1 || admin[0].RefundedFen != 500 || admin[0].RefundableFen != 0 { + t.Fatalf("admin orders: %+v %v", admin, err) + } + // A confirmed close frees the reservation. A genuine delayed SUCCESS still + // settles, provided the total of settled and reserved refunds fits the payment. + order2, err := db.CreatePaymentOrder(ctx, payments.Order{ID: "refund_test_order2", OrganizationID: "refund_test_org", AccountID: "refund_test_orgadmin", RequestKey: "refund_test_pay_key2", MchID: "refund_test_mch", AppID: "refund_test_app", AmountFen: 500, Currency: "CNY", ExpiresAt: time.Now().Add(15 * time.Minute)}) + if err != nil { + t.Fatal(err) + } + _, err = db.SettlePaymentOrder(ctx, payments.Transaction{OrderID: order2.ID, MchID: order2.MchID, AppID: order2.AppID, TransactionID: "refund_test_payment_tx2", TradeState: "SUCCESS", Currency: "CNY", AmountFen: 500, SuccessTime: time.Now()}) + if err != nil { + t.Fatal(err) + } + late, err := db.CreatePaymentRefund(ctx, payments.Refund{ID: "refund_test_late", OrderID: order2.ID, OperatorID: "refund_test_admin", RequestKey: "refund_test_late_key", AmountFen: 350, Reason: "late success"}) + if err != nil { + t.Fatal(err) + } + lateRemote := payments.RefundTransaction{ID: late.ID, OrderID: order2.ID, MchID: order2.MchID, TransactionID: "refund_test_payment_tx2", ProviderID: "wx_refund_test_late", Status: payments.RefundClosed, Currency: "CNY", AmountFen: 350, TotalFen: 500} + if closed, err := db.RecordPaymentRefund(ctx, lateRemote); err != nil || closed.Status != payments.RefundClosed { + t.Fatalf("close refund: %+v %v", closed, err) + } + replacement, err := db.CreatePaymentRefund(ctx, payments.Refund{ID: "refund_test_replacement", OrderID: order2.ID, OperatorID: "refund_test_admin", RequestKey: "refund_test_replacement_key", AmountFen: 200, Reason: "replacement"}) + if err != nil { + t.Fatalf("reserve after close: %v", err) + } + lateRemote.Status = payments.RefundSuccess + if settled, err := db.RecordPaymentRefund(ctx, lateRemote); err != nil || settled.Status != payments.RefundSuccess { + t.Fatalf("late refund success: %+v %v", settled, err) + } + if _, err := db.RecordPaymentRefund(ctx, lateRemote); err != nil { + t.Fatalf("late refund replay: %v", err) + } + if err := pool.QueryRow(ctx, `SELECT balance_fen FROM public.billing_wallets WHERE organization_id='refund_test_org'`).Scan(&balance); err != nil { + t.Fatal(err) + } + if balance != -250 { + t.Fatalf("late success wallet balance=%d, want -250", balance) + } + if _, err := db.RejectPaymentRefund(ctx, late.ID, "明确拒绝"); !errors.Is(err, payments.ErrConflict) { + t.Fatalf("successful refund was rejected: %v", err) + } + rejectedReplacement, err := db.RejectPaymentRefund(ctx, replacement.ID, "微信明确拒绝退款") + if err != nil || rejectedReplacement.Status != payments.RefundRejected || rejectedReplacement.FailureReason != "微信明确拒绝退款" { + t.Fatalf("reject unsubmitted refund: %+v %v", rejectedReplacement, err) + } + if again, err := db.RejectPaymentRefund(ctx, replacement.ID, "different reason"); err != nil || again.FailureReason != "微信明确拒绝退款" { + t.Fatalf("rejected replay: %+v %v", again, err) + } + if replay, err := db.CreatePaymentRefund(ctx, payments.Refund{ID: "refund_test_replacement_again", OrderID: order2.ID, OperatorID: "refund_test_admin", RequestKey: "refund_test_replacement_key", AmountFen: 200, Reason: "replacement"}); err != nil || replay.ID != replacement.ID || replay.Status != payments.RefundRejected { + t.Fatalf("same request after rejection: %+v %v", replay, err) + } + var createWG sync.WaitGroup + createResults := make(chan error, 2) + for _, n := range []string{"a", "b"} { + createWG.Add(1) + go func(n string) { + defer createWG.Done() + _, err := db.CreatePaymentRefund(ctx, payments.Refund{ID: "refund_test_concurrent_" + n, OrderID: order2.ID, OperatorID: "refund_test_admin", RequestKey: "refund_test_concurrent_key_" + n, AmountFen: 100, Reason: "concurrent"}) + createResults <- err + }(n) + } + createWG.Wait() + close(createResults) + var accepted, rejected int + for err := range createResults { + if err == nil { + accepted++ + } else if errors.Is(err, payments.ErrInvalidAmount) { + rejected++ + } else { + t.Fatalf("concurrent reservation: %v", err) + } + } + if accepted != 1 || rejected != 1 { + t.Fatalf("concurrent accepted=%d rejected=%d", accepted, rejected) + } + all, err := db.ListPaymentRefunds(ctx, order2.ID) + if err != nil { + t.Fatal(err) + } + for _, item := range all { + if item.Status != payments.RefundPending { + continue + } + processing := payments.RefundTransaction{ID: item.ID, OrderID: order2.ID, MchID: order2.MchID, + TransactionID: "refund_test_payment_tx2", ProviderID: "wx_refund_test_processing", Status: payments.RefundProcessing, + Currency: "CNY", AmountFen: item.AmountFen, TotalFen: 500} + if _, err := db.RecordPaymentRefund(ctx, processing); err != nil { + t.Fatalf("processing refund: %v", err) + } + if _, err := db.RejectPaymentRefund(ctx, item.ID, "明确拒绝"); !errors.Is(err, payments.ErrConflict) { + t.Fatalf("processing refund was rejected: %v", err) + } + break + } + order3, err := db.CreatePaymentOrder(ctx, payments.Order{ID: "refund_test_order3", OrganizationID: "refund_test_org", AccountID: "refund_test_orgadmin", RequestKey: "refund_test_pay_key3", MchID: "refund_test_mch", AppID: "refund_test_app", AmountFen: 100, Currency: "CNY", ExpiresAt: time.Now().Add(15 * time.Minute)}) + if err != nil { + t.Fatal(err) + } + _, err = db.SettlePaymentOrder(ctx, payments.Transaction{OrderID: order3.ID, MchID: order3.MchID, AppID: order3.AppID, TransactionID: "refund_test_payment_tx3", TradeState: "SUCCESS", Currency: "CNY", AmountFen: 100, SuccessTime: time.Now()}) + if err != nil { + t.Fatal(err) + } + unexpected, err := db.CreatePaymentRefund(ctx, payments.Refund{ID: "refund_test_unexpected", OrderID: order3.ID, OperatorID: "refund_test_admin", RequestKey: "refund_test_unexpected_key", AmountFen: 100, Reason: "unexpected success"}) + if err != nil { + t.Fatal(err) + } + if _, err := db.RejectPaymentRefund(ctx, unexpected.ID, "微信明确拒绝退款"); err != nil { + t.Fatal(err) + } + confirmed := payments.RefundTransaction{ID: unexpected.ID, OrderID: order3.ID, MchID: order3.MchID, TransactionID: "refund_test_payment_tx3", ProviderID: "wx_refund_test_unexpected", Status: payments.RefundSuccess, Currency: "CNY", AmountFen: 100, TotalFen: 100} + if recovered, err := db.RecordPaymentRefund(ctx, confirmed); err != nil || recovered.Status != payments.RefundSuccess || recovered.FailureReason != "" { + t.Fatalf("trusted success after rejection: %+v %v", recovered, err) + } + order4, err := db.CreatePaymentOrder(ctx, payments.Order{ID: "refund_test_order4", OrganizationID: "refund_test_org", AccountID: "refund_test_orgadmin", RequestKey: "refund_test_pay_key4", MchID: "refund_test_mch", AppID: "refund_test_app", AmountFen: 100, Currency: "CNY", ExpiresAt: time.Now().Add(15 * time.Minute)}) + if err != nil { + t.Fatal(err) + } + _, err = db.SettlePaymentOrder(ctx, payments.Transaction{OrderID: order4.ID, MchID: order4.MchID, AppID: order4.AppID, TransactionID: "refund_test_payment_tx4", TradeState: "SUCCESS", Currency: "CNY", AmountFen: 100, SuccessTime: time.Now()}) + if err != nil { + t.Fatal(err) + } + recoveredRefund, err := db.CreatePaymentRefund(ctx, payments.Refund{ID: "refund_test_recovered", OrderID: order4.ID, OperatorID: "refund_test_admin", RequestKey: "refund_test_recovered_key", AmountFen: 100, Reason: "remote recovery"}) + if err != nil { + t.Fatal(err) + } + if _, err := db.RejectPaymentRefund(ctx, recoveredRefund.ID, "微信明确拒绝退款"); err != nil { + t.Fatal(err) + } + progress := payments.RefundTransaction{ID: recoveredRefund.ID, OrderID: order4.ID, MchID: order4.MchID, TransactionID: "refund_test_payment_tx4", ProviderID: "wx_refund_test_recovered", Status: payments.RefundProcessing, Currency: "CNY", AmountFen: 100, TotalFen: 100} + if resumed, err := db.RecordPaymentRefund(ctx, progress); err != nil || resumed.Status != payments.RefundProcessing || resumed.FailureReason != "" { + t.Fatalf("trusted processing after rejection: %+v %v", resumed, err) + } + pending, err := db.PendingPaymentRefunds(ctx, 100) + if err != nil { + t.Fatal(err) + } + var queued bool + for _, item := range pending { + if item.ID == recoveredRefund.ID { + queued = true + } + } + if !queued { + t.Fatal("recovered processing refund missing from reconciliation queue") + } + progress.Status = payments.RefundAbnormal + if resumed, err := db.RecordPaymentRefund(ctx, progress); err != nil || resumed.Status != payments.RefundAbnormal || resumed.FailureReason != "" { + t.Fatalf("trusted abnormal after rejection: %+v %v", resumed, err) + } + _, err = pool.Exec(ctx, `INSERT INTO public.payment_orders + (id, organization_id, account_id, request_key, mch_id, app_id, amount_fen, currency, status, transaction_id, paid_at, expires_at) + SELECT 'refund_page_' || lpad(i::text, 3, '0'), 'refund_test_org', 'refund_test_orgadmin', + 'refund_page_key_' || i, 'refund_test_mch', 'refund_test_app', 100, 'CNY', 'paid', + 'refund_page_tx_' || i, now(), now() + interval '15 minutes' + FROM generate_series(1,105) AS i`) + if err != nil { + t.Fatal(err) + } + firstPage, err := db.ListAdminPaymentOrders(ctx, "", 101, 0) + if err != nil || len(firstPage) != 101 { + t.Fatalf("admin page limit+1: len=%d err=%v", len(firstPage), err) + } + nextPage, err := db.ListAdminPaymentOrders(ctx, "", 101, 100) + if err != nil || len(nextPage) != 9 { + t.Fatalf("admin page offset: len=%d err=%v", len(nextPage), err) + } +} diff --git a/components/admin-wechat-payments.module.css b/components/admin-wechat-payments.module.css new file mode 100644 index 0000000..e03bc2a --- /dev/null +++ b/components/admin-wechat-payments.module.css @@ -0,0 +1,40 @@ +.section { margin: 22px 0; padding: 24px; border: 1px solid #e5eaf1; border-radius: 20px; background: #fff; color: #20334b; } +.header, .toolbar, .subheading, .pagination { display: flex; align-items: center; justify-content: space-between; gap: 16px; } +.header h2 { margin: 0; font-size: 20px; } +.header p, .form p { margin: 6px 0 0; color: #617187; font-size: 14px; line-height: 1.6; } +.toolbar { margin: 22px 0 16px; flex-wrap: wrap; } +.toolbar label, .field { display: grid; gap: 7px; color: #42576e; font-size: 14px; } +.toolbar select, .field input { min-width: 180px; padding: 9px 11px; border: 1px solid #ced9e5; border-radius: 9px; background: #fff; color: #20334b; font: inherit; } +.secondary, .link, .icon { display: inline-flex; align-items: center; justify-content: center; gap: 5px; border: 1px solid #d8e3ed; border-radius: 8px; padding: 8px 11px; background: #fff; color: #146e69; cursor: pointer; font: inherit; font-size: 13px; } +.link, .icon { border: 0; } +.secondary:disabled, .icon:disabled, .primary:disabled { opacity: .5; cursor: not-allowed; } +.hint, .empty { color: #718096; font-size: 14px; } +.empty { padding: 36px; border: 1px dashed #d7e1ea; border-radius: 10px; text-align: center; } +.error { color: #ad3030; font-size: 14px; } +.notice { color: #116d58; font-size: 14px; } +.tableWrap { overflow-x: auto; } +.table { width: 100%; min-width: 920px; border-collapse: collapse; text-align: left; font-size: 13px; } +.table th { padding: 11px 10px; border-bottom: 1px solid #dfe8ef; color: #617187; font-weight: 500; } +.table td { padding: 14px 10px; border-bottom: 1px solid #ecf0f4; vertical-align: top; } +.table td strong { display: block; font-weight: 600; } +.table small { display: block; margin-top: 4px; color: #708096; } +.ids span, .ids small { display: block; max-width: 225px; overflow-wrap: anywhere; } +.pagination { justify-content: flex-end; margin-top: 16px; font-size: 13px; color: #617187; } +.backdrop { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 20px; background: rgba(15, 27, 43, .55); } +.dialog { width: min(100%, 620px); max-height: 90vh; overflow: auto; padding: 24px; border-radius: 18px; background: #fff; box-shadow: 0 18px 65px rgba(0, 0, 0, .22); } +.details { display: grid; gap: 8px; margin: 20px 0; } +.details > div { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 12px; align-items: baseline; font-size: 13px; } +.details span { color: #718096; } +.details code { overflow-wrap: anywhere; } +.subheading { border-top: 1px solid #e8eef3; padding-top: 15px; } +.subheading h3, .form h3 { margin: 0; font-size: 16px; } +.refund { padding: 12px 0; border-bottom: 1px solid #edf1f5; font-size: 13px; } +.refund small { display: block; margin-top: 5px; color: #718096; overflow-wrap: anywhere; } +.refund .failure { color: #ad3030; } +.form { display: grid; gap: 14px; margin-top: 20px; padding-top: 18px; border-top: 1px solid #e8eef3; } +.form p { margin: 0; } +.mode { display: flex; gap: 18px; flex-wrap: wrap; font-size: 14px; } +.mode label { display: inline-flex; align-items: center; gap: 6px; } +.field input { width: 100%; } +.primary { padding: 11px 15px; border: 0; border-radius: 9px; background: #087b72; color: #fff; font: inherit; font-weight: 600; cursor: pointer; } +@media (max-width: 620px) { .section, .dialog { padding: 18px; } .details > div { grid-template-columns: 100px minmax(0,1fr); } .header { align-items: flex-start; } } diff --git a/components/admin-wechat-payments.tsx b/components/admin-wechat-payments.tsx new file mode 100644 index 0000000..00fd043 --- /dev/null +++ b/components/admin-wechat-payments.tsx @@ -0,0 +1,193 @@ +"use client"; + +import { useCallback, useEffect, useRef, useState, type FormEvent } from "react"; +import { RefreshCw, X } from "lucide-react"; +import { + createPaymentRefund, getPaymentRefund, listAdminPaymentOrders, listPaymentRefunds, + parseYuanToFen, type AdminPaymentOrder, type PaymentRefund +} from "@/lib/client/payment-api"; +import { formatBillingAmount } from "@/lib/billing"; +import styles from "./admin-wechat-payments.module.css"; + +type Organization = { id: string; name: string }; + +function refundLabel(status: PaymentRefund["status"]): string { + return ({ pending: "已受理,等待微信处理", processing: "微信处理中", success: "退款成功", closed: "退款关闭", abnormal: "退款异常", rejected: "申请被拒绝" })[status]; +} + +function orderLabel(status: AdminPaymentOrder["status"]): string { + return ({ pending: "待支付", paid: "已支付", closed: "已关闭" })[status]; +} + +function displayTime(value: string | undefined): string { + if (!value) return "—"; + const date = new Date(value); + return Number.isNaN(date.getTime()) ? value : date.toLocaleString("zh-CN", { hour12: false }); +} + +export function AdminWechatPayments({ organizations, onChanged }: { organizations: Organization[]; onChanged: () => void }) { + const [organizationId, setOrganizationId] = useState(""); + const [offset, setOffset] = useState(0); + const [page, setPage] = useState<{ orders: AdminPaymentOrder[]; hasMore: boolean; enabled: boolean } | null>(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [refreshIndex, setRefreshIndex] = useState(0); + const [selected, setSelected] = useState(null); + const [refunds, setRefunds] = useState([]); + const [detailLoading, setDetailLoading] = useState(false); + const [detailError, setDetailError] = useState(null); + const [mode, setMode] = useState<"full" | "partial">("full"); + const [amountYuan, setAmountYuan] = useState(""); + const [reason, setReason] = useState(""); + const [submitting, setSubmitting] = useState(false); + const [notice, setNotice] = useState(null); + const attempt = useRef<{ intent: string; key: string } | null>(null); + const selectedRef = useRef(null); + selectedRef.current = selected; + + const reload = useCallback(() => setRefreshIndex((current) => current + 1), []); + + useEffect(() => { + const controller = new AbortController(); + setLoading(true); + setError(null); + listAdminPaymentOrders(organizationId, offset, controller.signal) + .then((result) => { + if (!controller.signal.aborted) { + setPage(result); + const current = selectedRef.current; + if (current) { + const fresh = result.orders.find((order) => order.id === current.id); + if (fresh) setSelected(fresh); + } + } + }) + .catch((cause) => { if (!controller.signal.aborted) setError(cause instanceof Error ? cause.message : String(cause)); }) + .finally(() => { if (!controller.signal.aborted) setLoading(false); }); + return () => controller.abort(); + }, [organizationId, offset, refreshIndex]); + + useEffect(() => { + if (!selected) return; + const controller = new AbortController(); + setDetailLoading(true); + setDetailError(null); + listPaymentRefunds(selected.id, controller.signal) + .then((entries) => { if (!controller.signal.aborted) setRefunds(entries); }) + .catch((cause) => { if (!controller.signal.aborted) setDetailError(cause instanceof Error ? cause.message : String(cause)); }) + .finally(() => { if (!controller.signal.aborted) setDetailLoading(false); }); + return () => controller.abort(); + }, [selected?.id]); + + function openOrder(order: AdminPaymentOrder) { + setSelected(order); + setRefunds([]); + setMode("full"); + setAmountYuan(""); + setReason(""); + setNotice(null); + setDetailError(null); + attempt.current = null; + } + + async function refreshDetail() { + if (!selected) return; + setDetailLoading(true); + setDetailError(null); + try { + const entries = await listPaymentRefunds(selected.id); + const updated = await Promise.all(entries.map(async (entry) => { + if (entry.status === "pending" || entry.status === "processing" || entry.status === "abnormal") { + return getPaymentRefund(entry.id); + } + return entry; + })); + setRefunds(updated); + reload(); + onChanged(); + } catch (cause) { + setDetailError(cause instanceof Error ? cause.message : String(cause)); + } finally { + setDetailLoading(false); + } + } + + async function submit(event: FormEvent) { + event.preventDefault(); + if (!selected || submitting) return; + const amountFen = mode === "full" ? selected.refundableFen : parseYuanToFen(amountYuan, 1, selected.refundableFen); + const cleanReason = reason.trim(); + if (!amountFen || !cleanReason || new TextEncoder().encode(cleanReason).length > 80) { + setDetailError("请填写有效退款金额和原因(原因不超过 80 字节)。"); + return; + } + const intent = `${selected.id}:${amountFen}:${cleanReason}`; + if (attempt.current?.intent !== intent) attempt.current = { intent, key: crypto.randomUUID() }; + setSubmitting(true); + setDetailError(null); + setNotice(null); + try { + const refund = await createPaymentRefund(selected.id, amountFen, cleanReason, attempt.current.key); + setRefunds((current) => [refund, ...current.filter((entry) => entry.id !== refund.id)]); + if (refund.status === "pending" || refund.status === "processing" || refund.status === "success") { + setSelected((current) => current?.id === selected.id ? { + ...current, + refundableFen: Math.max(0, current.refundableFen - refund.amountFen), + refundingFen: current.refundingFen + (refund.status === "success" ? 0 : refund.amountFen), + refundedFen: current.refundedFen + (refund.status === "success" ? refund.amountFen : 0) + } : current); + } + if (refund.status === "rejected") { + setDetailError(`退款申请被拒绝${refund.failureReason ? `:${refund.failureReason}` : ",请核对后重试"}。`); + } else if (refund.status === "closed") { + setDetailError("退款已关闭,款项未退回;请刷新可退金额后重试。"); + } else { + setNotice(refund.status === "success" ? "微信退款成功,组织余额已扣减。" : `退款申请已提交:${refundLabel(refund.status)}。请稍后刷新查看最终结果。`); + } + attempt.current = null; + reload(); + onChanged(); + } catch (cause) { + setDetailError(cause instanceof Error ? cause.message : String(cause)); + } finally { + setSubmitting(false); + } + } + + return
+

微信充值记录

查看所有组织的扫码充值与原路退款。

+
+ + {page && !page.enabled ? 支付服务当前未启用,仍可查看已有记录。 : null} +
+ {error ?

读取充值记录失败:{error}

: null} + {loading ?

正在读取充值记录…

: null} + {!loading && !error && page?.orders.length === 0 ?

暂无微信充值记录。

: null} + {!error && page?.orders.length ?
{page.orders.map((order) => + + + + + + + )}
组织 / 充值人订单 / 微信交易号充值金额状态 / 退款时间
{order.organizationName || order.organizationId}{order.accountName || order.accountId}{order.id}{order.transactionId || "暂无微信交易号"}{formatBillingAmount(order.amountFen)}{orderLabel(order.status)}已退 {formatBillingAmount(order.refundedFen)} · 处理中 {formatBillingAmount(order.refundingFen)}可退 {formatBillingAmount(order.refundableFen)}{displayTime(order.paidAt || order.createdAt)}
: null} +
第 {Math.floor(offset / 50) + 1} 页
+ {selected ?
{ if (event.target === event.currentTarget && !submitting) setSelected(null); }}>
+

充值与退款详情

+
组织{selected.organizationName || selected.organizationId}
充值人{selected.accountName || selected.accountId}
充值金额{formatBillingAmount(selected.amountFen)}
已退 / 处理中 / 可退{formatBillingAmount(selected.refundedFen)} / {formatBillingAmount(selected.refundingFen)} / {formatBillingAmount(selected.refundableFen)}
订单号{selected.id}
微信交易号{selected.transactionId || "—"}
+

退款记录

+ {detailError ?

{detailError}

: null} + {notice ?

{notice}

: null} + {detailLoading ?

正在查询退款记录…

: null} + {!detailLoading && refunds.length === 0 ?

暂无退款记录。

: null} + {refunds.map((refund) =>
{formatBillingAmount(refund.amountFen)} · {refundLabel(refund.status)}{displayTime(refund.createdAt)} · 操作人:{refund.operatorName || refund.operatorId}原因:{refund.reason}{refund.status === "rejected" && refund.failureReason ? 拒绝原因:{refund.failureReason} : null}退款单号:{refund.id}{refund.providerId ? ` · 微信退款单号:${refund.providerId}` : ""}
)} + {selected.status === "paid" && selected.refundableFen > 0 && page?.enabled ?
void submit(event)}> +

发起原路退款

退款成功后会从「{selected.organizationName || selected.organizationId}」的余额扣除本次退款金额;余额不足时将变为负数。

+
+ {mode === "partial" ? : 本次退款:{formatBillingAmount(selected.refundableFen)}} + + +
: null} +
: null} +
; +} diff --git a/components/billing-manager.tsx b/components/billing-manager.tsx index 2a27d5c..7ae4b0d 100644 --- a/components/billing-manager.tsx +++ b/components/billing-manager.tsx @@ -21,6 +21,8 @@ import { } from "lucide-react"; import { billingUnitLabel, formatBillingAmount } from "@/lib/billing"; import { parseAdminBillingPayload, parseMemberBillingPayload } from "@/lib/client/billing-api"; +import { WechatRecharge } from "@/components/wechat-recharge"; +import { AdminWechatPayments } from "@/components/admin-wechat-payments"; import { groupedPriceRuleSections, priceCatalogBulkTarget, priceTierEditTarget, type PriceEditTarget } from "@/lib/client/billing-price-catalog"; import { pulseFeedback, revealChildren, runScopedMotion } from "@/lib/ui/motion"; import type { BillingAccountConfig, BillingParameterDimension, BillingParameterTier, BillingPriceRule, OrganizationWallet } from "@/lib/types"; @@ -39,7 +41,7 @@ type LedgerEntry = { organizationId: string; accountId?: string; jobId?: string; - kind: "recharge" | "charge" | "refund" | "adjustment"; + kind: "recharge" | "charge" | "refund" | "recharge_refund" | "adjustment"; deltaFen: number; balanceAfterFen: number; description: string; @@ -76,7 +78,7 @@ type AdminPayload = { priceRules: BillingPriceRule[]; }; -type BillingTabId = "overview" | "ledger" | "pricing" | "balance" | "account"; +type BillingTabId = "overview" | "ledger" | "pricing" | "balance" | "account" | "wechat"; type BillingTabDefinition = { id: BillingTabId; @@ -129,6 +131,7 @@ export function BillingManager({ isSuperAdmin }: { isSuperAdmin: boolean }) { { id: "overview", label: "概览" }, { id: "pricing", label: "价格与计费" }, { id: "balance", label: "余额与上账" }, + { id: "wechat", label: "微信充值" }, { id: "account", label: "收款设置" } ] : [ { id: "overview", label: "概览" }, @@ -300,6 +303,7 @@ export function BillingManager({ isSuperAdmin }: { isSuperAdmin: boolean }) { {!isSuperAdmin && billing ? ( <> {activeTab === "overview" ? <> + void load()} /> setActiveTab("ledger")} />} /> : null} {activeTab === "ledger" ? 最近 {Math.min(billing.ledger.length, 100)} 条} /> : null} @@ -311,6 +315,7 @@ export function BillingManager({ isSuperAdmin }: { isSuperAdmin: boolean }) { {activeTab === "overview" ? : null} {activeTab === "pricing" ? setPriceEditState({ rule, target })} onBulkEdit={() => { setError(null); setBulkPriceEditOpen(true); }} /> : null} {activeTab === "balance" ? : null} + {activeTab === "wechat" ? void load()} /> : null} {activeTab === "account" ? setEditingAccount(true)} onCancel={() => { setEditingAccount(false); setAccountDraft({ ...emptyAccountDraft, ...admin.billingAccount }); }} onChange={(key, value) => setAccountDraft((current) => ({ ...current, [key]: value }))} onSubmit={saveBillingAccount} /> : null} ) : null} diff --git a/components/wechat-recharge.module.css b/components/wechat-recharge.module.css new file mode 100644 index 0000000..01b0031 --- /dev/null +++ b/components/wechat-recharge.module.css @@ -0,0 +1,37 @@ +.section { margin: 22px 0; padding: 24px; border: 1px solid #e5eaf1; border-radius: 20px; background: #fff; } +.heading, .orderHeading, .dialogHead { display: flex; align-items: center; justify-content: space-between; gap: 16px; } +.heading h2, .orderHeading h3, .dialogHead h2 { margin: 0; color: #17263c; } +.heading h2 { font-size: 20px; } +.heading p, .dialogHead p { margin: 6px 0 0; color: #66758b; font-size: 14px; } +.orderHeading { margin: 22px 0 10px; } +.orderHeading h3 { font-size: 15px; } +.orderHeading button, .dialogHead button { display: inline-flex; align-items: center; gap: 5px; border: 0; background: transparent; color: #48617d; cursor: pointer; } +.orders { display: grid; gap: 8px; } +.order { width: 100%; padding: 12px 14px; display: flex; justify-content: space-between; align-items: center; gap: 12px; text-align: left; border: 1px solid #e7edf3; border-radius: 12px; background: #fbfcfe; cursor: pointer; } +.order:hover { border-color: #95acc7; } +.order span:first-child { display: grid; gap: 3px; } +.order strong { color: #1b2c43; } +.order small, .note { color: #718096; font-size: 13px; } +.status { color: #315b86; font-size: 13px; } +.backdrop { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 20px; background: rgba(15, 27, 43, .55); } +.dialog { width: min(100%, 460px); max-height: min(90vh, 850px); overflow: auto; padding: 24px; border-radius: 18px; background: #fff; box-shadow: 0 18px 65px rgba(0, 0, 0, .22); } +.dialogHead { align-items: flex-start; border-bottom: 1px solid #e9eef4; padding-bottom: 18px; } +.dialogHead h2 { font-size: 20px; } +.form { display: grid; gap: 15px; padding-top: 20px; } +.label { font-weight: 600; color: #263c55; } +.presets { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } +.presets button { padding: 11px 5px; border: 1px solid #dce5ef; border-radius: 10px; background: #f8fafc; color: #294867; font-weight: 600; cursor: pointer; } +.presets button.selected { border-color: #327bd1; background: #eaf4ff; color: #1764ae; } +.custom { display: grid; gap: 7px; font-size: 14px; color: #3a4e65; } +.custom input { width: 100%; padding: 11px 12px; border: 1px solid #cedae8; border-radius: 9px; font: inherit; } +.custom input[aria-invalid="true"] { border-color: #c64848; } +.form small, .payment small { color: #718096; } +.form :global(.billing-action-button) { justify-content: center; } +.payment { display: grid; justify-items: center; gap: 10px; padding-top: 20px; text-align: center; } +.payment p { margin: 2px 0; color: #455b73; } +.payment .amount { font-size: 30px; color: #172d47; } +.qr { padding: 12px; border: 1px solid #e2e9f1; border-radius: 10px; background: #fff; } +.payment small { line-height: 1.6; } +.payment :global(.billing-secondary-button) { margin-top: 6px; } +.error { margin: 12px 0 0; color: #b12929; font-size: 13px; } +@media (max-width: 600px) { .section { padding: 18px; } .heading { align-items: flex-start; flex-direction: column; } .presets { grid-template-columns: repeat(2, 1fr); } } diff --git a/components/wechat-recharge.tsx b/components/wechat-recharge.tsx new file mode 100644 index 0000000..d9dc352 --- /dev/null +++ b/components/wechat-recharge.tsx @@ -0,0 +1,241 @@ +"use client"; + +import { useCallback, useEffect, useRef, useState, type FormEvent } from "react"; +import { QRCodeSVG } from "qrcode.react"; +import { Loader2, RefreshCw, WalletCards, X } from "lucide-react"; +import { + createPaymentOrder, + formatYuan, + getPaymentOptions, + getPaymentOrder, + listPaymentOrders, + parseYuanToFen, + type PaymentOptions, + type PaymentOrder +} from "@/lib/client/payment-api"; +import styles from "./wechat-recharge.module.css"; + +function errorMessage(error: unknown): string { + return error instanceof Error ? error.message : "支付服务暂时不可用"; +} + +function orderState(order: PaymentOrder): string { + if (order.status === "paid") return "已支付"; + if (order.status === "closed") return "已关闭"; + return Date.parse(order.expiresAt) <= Date.now() ? "确认中" : "待支付"; +} + +function preferSettledOrder(current: PaymentOrder, incoming: PaymentOrder): PaymentOrder { + return current.status !== "pending" && incoming.status === "pending" ? current : incoming; +} + +function updateOrderList(current: PaymentOrder[], incoming: PaymentOrder): PaymentOrder[] { + const existing = current.find((order) => order.id === incoming.id); + return [existing ? preferSettledOrder(existing, incoming) : incoming, ...current.filter((order) => order.id !== incoming.id)]; +} + +export function WechatRecharge({ organizationName, onPaid }: { organizationName: string; onPaid: () => void }) { + const [options, setOptions] = useState(null); + const [orders, setOrders] = useState([]); + const [selectedFen, setSelectedFen] = useState(null); + const [customYuan, setCustomYuan] = useState(""); + const [open, setOpen] = useState(false); + const [activeOrder, setActiveOrder] = useState(null); + const [loading, setLoading] = useState(true); + const [submitting, setSubmitting] = useState(false); + const [error, setError] = useState(null); + const attemptRef = useRef<{ amountFen: number; requestKey: string } | null>(null); + const activeRef = useRef(false); + const modalGenerationRef = useRef(0); + const paidNotifiedRef = useRef(new Set()); + const onPaidRef = useRef(onPaid); + const closeButtonRef = useRef(null); + + useEffect(() => { onPaidRef.current = onPaid; }, [onPaid]); + + const refreshOrders = useCallback(async () => { + const next = await listPaymentOrders(); + setOrders(next); + setError(null); + }, []); + + useEffect(() => { + const controller = new AbortController(); + getPaymentOptions(controller.signal) + .then(async (nextOptions) => { + if (controller.signal.aborted) return; + setOptions(nextOptions); + setSelectedFen(nextOptions.presetAmountsFen[0] ?? null); + setLoading(false); + if (!nextOptions.enabled || !nextOptions.canRecharge) return; + try { + const nextOrders = await listPaymentOrders(controller.signal); + if (!controller.signal.aborted) setOrders(nextOrders); + } catch (cause) { + if (!controller.signal.aborted) setError(errorMessage(cause)); + } + }) + .catch((cause) => { if (!controller.signal.aborted) setError(errorMessage(cause)); }) + .finally(() => { if (!controller.signal.aborted) setLoading(false); }); + return () => { controller.abort(); activeRef.current = false; modalGenerationRef.current += 1; }; + }, []); + + useEffect(() => { + activeRef.current = open; + }, [open]); + + function closeDialog() { + modalGenerationRef.current += 1; + activeRef.current = false; + setSubmitting(false); + setOpen(false); + } + + function openNew() { + modalGenerationRef.current += 1; + activeRef.current = true; + setActiveOrder(null); + setError(null); + setOpen(true); + } + + useEffect(() => { + if (!open) return; + const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null; + closeButtonRef.current?.focus(); + function onKeyDown(event: KeyboardEvent) { + if (event.key === "Escape") closeDialog(); + if (event.key !== "Tab") return; + const dialog = document.getElementById("wechat-recharge-dialog"); + const focusable = [...(dialog?.querySelectorAll("button:not(:disabled), input:not(:disabled)") || [])]; + const first = focusable[0]; + const last = focusable.at(-1); + if (!first || !last) return; + if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); } + else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); } + } + document.addEventListener("keydown", onKeyDown); + return () => { document.removeEventListener("keydown", onKeyDown); previousFocus?.focus(); }; + }, [open]); + + useEffect(() => { + if (!open || activeOrder?.status !== "pending") return; + const controller = new AbortController(); + let timer: ReturnType | undefined; + const orderId = activeOrder.id; + const generation = modalGenerationRef.current; + async function poll() { + try { + const next = await getPaymentOrder(orderId, controller.signal); + if (controller.signal.aborted || !activeRef.current || generation !== modalGenerationRef.current) return; + setActiveOrder((current) => current?.id === orderId ? preferSettledOrder(current, next) : current); + setOrders((current) => updateOrderList(current, next)); + if (next.status === "paid" && !paidNotifiedRef.current.has(next.id)) { + paidNotifiedRef.current.add(next.id); + onPaidRef.current(); + } + if (next.status === "pending") timer = setTimeout(poll, 3000); + } catch (cause) { + if (controller.signal.aborted || !activeRef.current || generation !== modalGenerationRef.current) return; + setError(errorMessage(cause)); + timer = setTimeout(poll, 3000); + } + } + timer = setTimeout(poll, 3000); + return () => { controller.abort(); if (timer) clearTimeout(timer); }; + }, [activeOrder?.id, activeOrder?.status, open]); + + if (loading) return null; + if (!options?.enabled || !options.canRecharge) return null; + + const customFen = options ? parseYuanToFen(customYuan, options.minAmountFen, options.maxAmountFen) : null; + const amountFen = selectedFen === null ? customFen : selectedFen; + + function choosePreset(fen: number) { + modalGenerationRef.current += 1; + setSubmitting(false); + setSelectedFen(fen); + setCustomYuan(""); + setError(null); + } + + function chooseCustom(value: string) { + modalGenerationRef.current += 1; + setSubmitting(false); + setSelectedFen(null); + setCustomYuan(value); + setError(null); + } + + async function startPayment(event: FormEvent) { + event.preventDefault(); + if (amountFen === null || !options?.canRecharge || submitting) return; + const generation = modalGenerationRef.current; + setError(null); + setSubmitting(true); + try { + if (!attemptRef.current || attemptRef.current.amountFen !== amountFen) { + attemptRef.current = { amountFen, requestKey: crypto.randomUUID() }; + } + const order = await createPaymentOrder(amountFen, attemptRef.current.requestKey); + if (!activeRef.current || generation !== modalGenerationRef.current) return; + setActiveOrder(order); + setOrders((current) => updateOrderList(current, order)); + if (order.status === "paid" && !paidNotifiedRef.current.has(order.id)) { + paidNotifiedRef.current.add(order.id); + onPaidRef.current(); + } + attemptRef.current = null; + } catch (cause) { + if (activeRef.current && generation === modalGenerationRef.current) setError(errorMessage(cause)); + } finally { + if (generation === modalGenerationRef.current) setSubmitting(false); + } + } + + function openOrder(order: PaymentOrder) { + modalGenerationRef.current += 1; + activeRef.current = true; + setError(null); + setActiveOrder(order); + setOpen(true); + } + + return
+
+

微信扫码充值

充值到账后计入「{organizationName}」的共享余额。

+ +
+ {error && !open ?

{error}

: null} +

最近支付订单

+ {orders.length ?
{orders.slice(0, 8).map((order) => )}
:

暂无支付订单。

} + + {open ?
{ if (event.target === event.currentTarget) closeDialog(); }}> + +
: null} +
; +} diff --git a/contracts/http/route-surface.v1.json b/contracts/http/route-surface.v1.json index 6fc93db..5a334dd 100644 --- a/contracts/http/route-surface.v1.json +++ b/contracts/http/route-surface.v1.json @@ -71,6 +71,16 @@ { "method": "POST", "path": "/api/v1/jobs/{id}/cancel" }, { "method": "GET", "path": "/api/v1/openapi.json" }, { "method": "GET", "path": "/generated-results/{path...}" }, - { "method": "GET", "path": "/uploads/{path...}" } + { "method": "GET", "path": "/uploads/{path...}" }, + { "method": "GET", "path": "/api/payments/options" }, + { "method": "GET", "path": "/api/payments/orders" }, + { "method": "POST", "path": "/api/payments/orders" }, + { "method": "GET", "path": "/api/payments/orders/{id}" }, + { "method": "POST", "path": "/api/payments/wechat/notify" }, + { "method": "GET", "path": "/api/payments/admin/orders" }, + { "method": "GET", "path": "/api/payments/admin/orders/{id}/refunds" }, + { "method": "POST", "path": "/api/payments/admin/orders/{id}/refunds" }, + { "method": "GET", "path": "/api/payments/admin/refunds/{id}" }, + { "method": "POST", "path": "/api/payments/wechat/refund-notify" } ] } diff --git a/database/migrations/0007_wechat_native_payments.sql b/database/migrations/0007_wechat_native_payments.sql new file mode 100644 index 0000000..21d0f74 --- /dev/null +++ b/database/migrations/0007_wechat_native_payments.sql @@ -0,0 +1,32 @@ +-- Orders are written before calling WeChat. Keep them when a user or +-- organization is deleted so paid money cannot lose its audit trail. +create table if not exists public.payment_orders ( + id text primary key check (length(id) between 1 and 32 and id ~ '^[A-Za-z0-9_-]+$'), + organization_id text not null references public.platform_organizations(id) on delete restrict, + account_id text not null references public.platform_users(id) on delete restrict, + request_key text not null check (length(request_key) between 1 and 64 and request_key ~ '^[A-Za-z0-9_-]+$'), + mch_id text not null check (length(mch_id) between 1 and 64), + app_id text not null check (length(app_id) between 1 and 64), + amount_fen bigint not null check (amount_fen between 1 and 1000000), + currency text not null check (currency = 'CNY'), + status text not null default 'pending' check (status in ('pending', 'paid', 'closed')), + code_url text, + transaction_id text, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + expires_at timestamptz not null, + paid_at timestamptz, + constraint payment_orders_paid_fields_check check ( + (status = 'paid' and transaction_id is not null and length(transaction_id) > 0 and paid_at is not null) + or (status <> 'paid' and transaction_id is null and paid_at is null) + ), + constraint payment_orders_expiry_check check (expires_at > created_at), + constraint payment_orders_org_request_unique unique (organization_id, request_key) +); + +create unique index if not exists payment_orders_provider_transaction_unique + on public.payment_orders(mch_id, transaction_id) where transaction_id is not null; +create index if not exists payment_orders_org_created_idx + on public.payment_orders(organization_id, created_at desc); +create index if not exists payment_orders_pending_check_idx + on public.payment_orders(updated_at, created_at) where status = 'pending'; diff --git a/database/migrations/0008_wechat_refunds.sql b/database/migrations/0008_wechat_refunds.sql new file mode 100644 index 0000000..4a573fb --- /dev/null +++ b/database/migrations/0008_wechat_refunds.sql @@ -0,0 +1,34 @@ +-- Reserve each requested refund against its original, successful payment. +-- A successful external refund can exceed the current wallet balance. +alter table public.billing_wallets drop constraint if exists billing_wallets_balance_fen_check; +alter table public.billing_ledger drop constraint if exists billing_ledger_balance_after_fen_check; +alter table public.billing_ledger drop constraint if exists billing_ledger_kind_check; +alter table public.billing_ledger add constraint billing_ledger_kind_check + check (kind in ('recharge', 'charge', 'refund', 'adjustment', 'recharge_refund')); + +create table public.payment_refunds ( + id text primary key check (length(id) between 1 and 32 and id ~ '^[A-Za-z0-9_-]+$'), + order_id text not null references public.payment_orders(id) on delete restrict, + organization_id text not null references public.platform_organizations(id) on delete restrict, + operator_id text not null references public.platform_users(id) on delete restrict, + request_key text not null check (length(request_key) between 1 and 64 and request_key ~ '^[A-Za-z0-9_-]+$'), + mch_id text not null check (length(mch_id) between 1 and 64), + transaction_id text not null check (length(transaction_id) > 0), + provider_id text, + amount_fen bigint not null check (amount_fen > 0), + total_fen bigint not null check (total_fen > 0 and total_fen >= amount_fen), + currency text not null check (currency = 'CNY'), + reason text not null, + status text not null default 'pending' check (status in ('pending', 'processing', 'success', 'closed', 'abnormal', 'rejected')), + failure_reason text not null default '', + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + succeeded_at timestamptz, + constraint payment_refunds_request_unique unique (order_id, request_key), + constraint payment_refunds_success_check check ((status = 'success') = (succeeded_at is not null)) +); +create unique index payment_refunds_provider_unique on public.payment_refunds(mch_id, provider_id) + where provider_id is not null; +create index payment_refunds_order_idx on public.payment_refunds(order_id, created_at desc, id desc); +create index payment_refunds_pending_idx on public.payment_refunds(updated_at, created_at, id) + where status in ('pending', 'processing', 'abnormal'); diff --git a/deploy/ack/configmap.yaml b/deploy/ack/configmap.yaml index 7c2ff25..a67f8f8 100644 --- a/deploy/ack/configmap.yaml +++ b/deploy/ack/configmap.yaml @@ -10,6 +10,11 @@ data: GO_BACKEND_HOST: 0.0.0.0 GO_BACKEND_PORT: "8080" ZHINIAN_DATA_BACKEND: postgres + # Run the checked-in Go migration bundle before the API starts listening. + DATABASE_AUTO_MIGRATE: "true" + DATABASE_MIGRATION_TIMEOUT_SECONDS: "180" + # PostgreSQL role named by zhinian-go-db's APP_USER; replace before deploy. + DATABASE_APP_ROLE: REPLACE_WITH_APP_DB_ROLE ZHINIAN_AUTH_REQUIRED: "true" ZHINIAN_AUTH_COOKIE_SECURE: "true" ZHINIAN_PUBLIC_BASE_URL: https://REPLACE_WITH_PUBLIC_HOST @@ -17,3 +22,8 @@ data: ZHINIAN_RUNTIME_DIR: /var/lib/zhinian/runtime ZHINIAN_LOG_DIR: /var/lib/zhinian/logs ZHINIAN_SETTINGS_FILE: /var/lib/zhinian/settings.env + WECHAT_PAY_ENABLED: "false" + WECHAT_PAY_NOTIFY_URL: https://REPLACE_WITH_PUBLIC_HOST/api/payments/wechat/notify + WECHAT_PAY_MIN_AMOUNT_FEN: "100" + WECHAT_PAY_MAX_AMOUNT_FEN: "1000000" + WECHAT_PAY_PRESET_AMOUNTS_FEN: "10000,50000,100000" diff --git a/deploy/ack/go-api.yaml b/deploy/ack/go-api.yaml index 4bd65db..60e7958 100644 --- a/deploy/ack/go-api.yaml +++ b/deploy/ack/go-api.yaml @@ -42,12 +42,22 @@ spec: - secretRef: name: zhinian-go-providers optional: true + - secretRef: + name: zhinian-go-wechat-pay + optional: true env: - name: DATABASE_URL valueFrom: secretKeyRef: name: zhinian-go-db key: DATABASE_URL + # Migration credentials stay separate from the least-privilege + # application DATABASE_URL above. Never inject this Secret via envFrom. + - name: DATABASE_MIGRATION_URL + valueFrom: + secretKeyRef: + name: zhinian-migration-db + key: DATABASE_URL # Go alone creates and verifies the browser session cookie. The # static Web workload must never receive this signing secret. - name: ZHINIAN_AUTH_SESSION_SECRET @@ -75,7 +85,8 @@ spec: path: /api/health port: http periodSeconds: 5 - failureThreshold: 24 + # 180s migration deadline plus DB/bootstrap and startup headroom. + failureThreshold: 60 readinessProbe: httpGet: path: /api/ready diff --git a/deploy/ack/secrets.example.yaml b/deploy/ack/secrets.example.yaml index 92d9e16..c608ce6 100644 --- a/deploy/ack/secrets.example.yaml +++ b/deploy/ack/secrets.example.yaml @@ -8,7 +8,9 @@ metadata: namespace: zhinian type: Opaque stringData: - # Manual schema execution only. This connection intentionally uses plaintext. + # Startup migration connection, also usable for manual migrations. This + # account needs schema ownership/DDL and grant permissions. Plaintext RDS + # transport is limited to the private VPC by this deployment's DB policy. DATABASE_URL: "postgresql://MIGRATION_USER:MIGRATION_PASSWORD@RDS_INTERNAL_HOST:5432/APP_DATABASE?sslmode=disable" --- apiVersion: v1 @@ -46,7 +48,9 @@ metadata: namespace: zhinian type: Opaque stringData: - # Application role (least privilege). PostgreSQL transport is plaintext. + # Least-privilege application role. Set DATABASE_APP_ROLE in configmap.yaml + # to this connection's PostgreSQL user (APP_USER) so migrations grant it + # access to new tables/functions. PostgreSQL transport is plaintext. DATABASE_URL: "postgresql://APP_USER:APP_PASSWORD@RDS_INTERNAL_HOST:5432/APP_DATABASE?sslmode=disable" --- apiVersion: v1 @@ -60,3 +64,21 @@ stringData: # administrator exists. Password must be at least 8 characters. ZHINIAN_BOOTSTRAP_ADMIN_PHONE: REPLACE_WITH_ADMIN_PHONE ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD: REPLACE_WITH_STRONG_PASSWORD +--- +# Optional. Apply only when enabling WeChat Native payments; Go-only envFrom. +apiVersion: v1 +kind: Secret +metadata: + name: zhinian-go-wechat-pay + namespace: zhinian +type: Opaque +stringData: + WECHAT_PAY_MCH_ID: REPLACE_WITH_MERCHANT_ID + WECHAT_PAY_APP_ID: REPLACE_WITH_BOUND_APP_ID + WECHAT_PAY_MERCHANT_SERIAL: REPLACE_WITH_MERCHANT_CERT_SERIAL + WECHAT_PAY_API_V3_KEY: REPLACE_WITH_32_BYTE_API_V3_KEY + WECHAT_PAY_PUBLIC_KEY_ID: REPLACE_WITH_WECHAT_PUBLIC_KEY_ID + WECHAT_PAY_PRIVATE_KEY_PEM: | + REPLACE_WITH_PKCS8_MERCHANT_PRIVATE_KEY_PEM + WECHAT_PAY_PUBLIC_KEY_PEM: | + REPLACE_WITH_WECHAT_PAYMENT_PUBLIC_KEY_PEM diff --git a/docs/API.md b/docs/API.md index 929962a..eb2ec49 100644 --- a/docs/API.md +++ b/docs/API.md @@ -86,7 +86,18 @@ curl -X POST https://你的域名/api/v1/jobs \ 开放 API 仍按 API Key 和账号分区运行。当前未绑定组织的开放 API 任务保持兼容,不从组织钱包扣费;平台浏览器用户的真实图片/视频任务会按超级管理员配置的服务商标准单价、计费单位和上浮倍率,从所属组织余额冻结。普通用户余额不足时不会提交服务商并返回余额不足错误;超级管理员仍保存计算费用,但不检查、冻结或扣减组织额度,也不产生钱包扣费、退款流水。计费规则与最终金额会随任务保存,任务失败、取消或过期后由 Worker 在最终终态退款;Seedance 成功后按 `usage.completion_tokens` 多退少补,缺少该字段时保留冻结金额。MiniMax H3 按实际输出秒数及输入图片数结算;Wan 3.0 按 `usage.output_video_duration` 的实际时长结算(无视频输入时可回退 `usage.duration`),缺少有效用量时保留预扣并标记为估算。 -组织余额当前只能由超级管理员通过 `/billing` 的“余额与上账”直接入账。所有充值和人工余额调整都只记入组织账本,不存在个人上账归属;组织管理员和员工共同使用组织额度。未来接入支付时,支付成功回调应使用同一幂等上账逻辑自动入账,不产生待审核申请。余额不足时,平台会拒绝创建真实计费任务并返回错误;未配置真实服务商凭据时也不会生成占位结果。 +组织余额可由超级管理员通过 `/billing` 的“余额与上账”手工入账,也可在启用微信 Native 支付后由组织管理员扫码充值。所有充值和人工余额调整均计入组织账本,组织管理员和员工共同使用额度。支付回调和补单经核验后,在一个数据库事务中更新支付状态并幂等入账。超级管理员还能在「计费 → 微信充值」查看所有组织的订单并发起部分或剩余金额的微信原路退款;微信确认成功后,组织余额才会扣除,必要时允许变为负数。退款写入独立的 `recharge_refund` 账本类型,与生成失败返还余额区分。余额不足时,平台会拒绝创建真实计费任务并返回错误;未配置真实服务商凭据时也不会生成占位结果。 + +支付后台接口使用平台登录会话,不接受本页开放 API 的 API Key。只有超级管理员可以调用: + +| 接口 | 用途 | +| --- | --- | +| `GET /api/payments/admin/orders?organizationId=&limit=50&offset=0` | 分页查看跨组织充值订单;可按组织筛选,返回已退、退款中和可退金额 | +| `GET /api/payments/admin/orders/{id}/refunds` | 查看指定订单的退款记录 | +| `POST /api/payments/admin/orders/{id}/refunds` | 发起退款,请求体 `{ "amountFen": 5000, "requestKey": "唯一请求ID", "reason": "客户申请" }` | +| `GET /api/payments/admin/refunds/{id}` | 查询退款状态 | + +退款原因必填、最多 80 个 UTF-8 字节;同一 `requestKey` 重试不会创建第二笔退款。`pending` 和 `processing` 状态占用可退额度,但不会立即扣除余额;`success` 才扣除,`closed` 释放额度,`abnormal` 保留占用等待核对。关闭充值开关后仍可查看历史订单和退款,不能发起新退款。微信退款通知走无需登录的 `POST /api/payments/wechat/refund-notify`,由后端验签、解密和核对;回调 URL 从支付回调域名派生,无需另设环境变量。接口、配置和财务处理见 [微信支付说明](PAYMENTS.md)。 创作页通过 `GET /api/billing/balance` 展示当前组织的可用余额。接口仅接受平台会话认证,从服务端刷新后的会话确定组织,忽略客户端组织参数,返回 `organization` 和 `wallet`,不加载账本或价格目录,并设置 `Cache-Control: no-store`。未绑定组织返回 422。页面支持手动刷新,并在提交任务、任务计费状态变化、重新切回页面及可见状态下每 30 秒刷新;超级管理员显示“超管不计额度”。余额提示供用户参考,实际扣费及余额校验仍由服务端执行。 diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 8a9c453..5717b15 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -47,29 +47,35 @@ docker build -f backend/Dockerfile.alpine \ 生产固定使用 PostgreSQL。数据库连接只通过 Go Deployment 的 Secret 注入,不得进入 Web 镜像或 ConfigMap。优先使用 RDS 内网地址,并仅对白名单中的 ACK 工作负载网段放行。 -`DATABASE_URL` 必须使用 `sslmode=disable`。Go 和手工迁移使用的 Node 客户端都会强制 +`DATABASE_URL` 和 `DATABASE_MIGRATION_URL` 必须使用 `sslmode=disable`。Go 和手工迁移使用的 Node 客户端都会强制 归一化为该值;即使旧 Secret 仍包含 TLS 参数,客户端也不会读取 CA 或协商 TLS。 这表示 ACK 到 RDS 的数据库流量不使用 TLS、链路内容为明文。只应使用 RDS 内网地址, 并通过 VPC、安全组和白名单严格限制访问;若未来需要链路加密,必须同时修改客户端策略 和 RDS 配置后再部署。 -首次发布前,部署负责人按顺序手工执行: +ACK 模板设置 `DATABASE_AUTO_MIGRATE=true`。Go API 启动时先连接 +`DATABASE_MIGRATION_URL`(`zhinian-migration-db` Secret),按版本顺序执行镜像内已 +同步的 `database/migrations/*.sql`,并用 `DATABASE_APP_ROLE` 给应用账号授权;全部成功后 +才启动 HTTP 服务。该变量未提供时,启动器会回退使用 `DATABASE_URL`,但 ACK 明确使用 +独立迁移账号。`DATABASE_APP_ROLE` 必须填写为 `zhinian-go-db` 连接串中的 PostgreSQL +用户名,且迁移账号须具备建表、修改表和授权权限。`DATABASE_MIGRATION_URL` 与 +`DATABASE_URL` 的主机、端口和数据库名必须相同,连接用户名可以不同;启动器会检查。 +默认启动迁移超时 180 秒;对应的 startupProbe 提供约 300 秒预算。每个迁移版本的 DDL +与版本记录在同一事务中;失败的版本会回滚,之前已成功提交的版本保留。迁移失败时 Pod +不监听端口,查看 Go Pod 日志并修复原因后再重启。回滚镜像不会逆向撤销数据库迁移。 +遇到历史重复数据,先人工审计,不能跳过或 +自动删除计费与用量记录。 -1. `database/migrations/0001_initial_schema.sql` -2. `database/migrations/0002_generation_lifecycle_fencing.sql` -3. `database/migrations/0003_platform_runtime_settings.sql` -4. `database/migrations/0004_seedream_billing_provider.sql` -5. `database/migrations/0005_seedream_layer_compositions.sql` -6. `database/migrations/0006_minimax_h3_billing_provider.sql` -7. 应用角色授权语句(参考 `scripts/migrate-postgres.mjs`) +每次新增迁移,在仓库根目录运行 `npm run db:bundle`,把根目录 SQL 同步成提交到 Git 的 +Go 迁移包,然后构建 Go 镜像;不能修改已应用的历史 SQL。新镜像启动时会核对版本记录, +只执行未应用的迁移,重启不会重复建表。手工处理仍可从仓库根目录执行 +`npm run db:migrate`;其连接账号也应具备上述权限。生产不部署迁移 Job 或 Node Worker, +Go 镜像运行时不需要 Node/npm,也不用在 ACK「启动执行」中填写命令。 -升级已有生产库接入 MiniMax H3 时,只需在发布新 Go 镜像前执行尚未应用的 `0006`; -新版本 `/api/ready` 会同时检查计费服务商约束中已包含 `seedream` 和 `minimax`,未迁移的 -Pod 不会进入 Ready,避免运行后才在报价阶段返回 500。 - -生产不部署迁移 Job。遇到历史重复数据时迁移会失败,需先人工审计,不能跳过或自动删除 -计费与用量记录。仓库不再提供可误执行的 Node Migration Job 或 Node Worker 清单;后台 -任务由 Go API 内嵌 WorkerLoop 处理。 +虽然当前 `replicas: 1`,RollingUpdate 的 `maxSurge: 1` 可能短暂同时运行新旧两个 Go +Pod。迁移器使用 PostgreSQL 锁串行化迁移,不能以单副本假定没有并发。旧版 Pod 可能在 +新版迁移期间继续接流量,因此新增 SQL 需兼容滚动期间的新旧程序。数据库迁移不能靠 +回滚镜像自动撤销。 Go 首次启动会读取 `zhinian-go-bootstrap` Secret 中的 `ZHINIAN_BOOTSTRAP_ADMIN_PHONE` 和 `ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD`,仅在不存在 @@ -82,6 +88,11 @@ Go 首次启动会读取 `zhinian-go-bootstrap` Secret 中的 Git 的 `deploy/ack/secrets.production.yaml`,替换所有占位值。Web 不需要任何运行时 Secret;会话密钥只属于 Go。 +将 `configmap.yaml` 中 `DATABASE_APP_ROLE: REPLACE_WITH_APP_DB_ROLE` 替换为应用数据库 +用户(`zhinian-go-db` 的 `APP_USER`),并确认 `zhinian-migration-db` 的连接串指向同一 +数据库;两条连接串的主机、端口和数据库名须一致。先发布 Secret/ConfigMap 再更新 Go Deployment。ACK 控制台的「启动执行」命令 +与参数保持空白,镜像原本的 `zhinian-api` 启动入口会自行迁移。 + 仓库内静态检查: ```bash @@ -126,6 +137,7 @@ Pod 的 `emptyDir`,Pod 重建或滚动升级同样会永久丢失上传文件 Kubernetes Secret: - `DATABASE_URL` +- `DATABASE_MIGRATION_URL`(独立迁移账号,来自 `zhinian-migration-db`) - `ZHINIAN_AUTH_SESSION_SECRET`(Secret 名 `zhinian-go-auth`,仅注入 Go) - `ZHINIAN_BOOTSTRAP_ADMIN_PHONE`、`ZHINIAN_BOOTSTRAP_ADMIN_PASSWORD` - OSS 凭据;服务商凭据也可以先放 Secret 作为数据库尚未配置时的回退值 @@ -141,7 +153,7 @@ Secret/ConfigMap 为事实来源。设置页全部 27 项配置由超级管理 ## 探针与验收 - Web `/healthz`:Nginx 静态进程存活检查。 -- Go `/api/health`:Go 进程存活检查;以 250ms 上限刷新服务商状态,失败时使用进程内缓存并仍返回存活状态。 +- Go `/api/health`:迁移完成且服务开始监听后的进程存活检查;以 250ms 上限刷新服务商状态,失败时使用进程内缓存并仍返回存活状态。 - Go `/api/ready`:检查 PostgreSQL schema、表权限和业务函数权限。 发布后执行: @@ -176,6 +188,10 @@ cp .env.example .env.local ./scripts/deploy.sh ``` +ACK 和 Compose 会向 Go 进程注入环境变量。若直接在本地执行 `go run` 或 Go 二进制, +需显式导出 `DATABASE_AUTO_MIGRATE`、`DATABASE_MIGRATION_URL`、`DATABASE_URL` 等 +数据库启动参数;仅填写 `.env.local` 不等于已向 Go 进程注入这些变量。 + 根目录 Compose 会启动 `zhinian-web` 与 `zhinian-go-api`,挂载 `deploy/nginx-compose.conf` 将 `/api`、`/uploads`、`/generated-results` 转发给 Go;Go 内嵌 WorkerLoop,不再启动独立 Node Worker。ACK 生产仍使用上面的两镜像 + Ingress 拓扑, diff --git a/docs/PAYMENTS.md b/docs/PAYMENTS.md new file mode 100644 index 0000000..76c8b6f --- /dev/null +++ b/docs/PAYMENTS.md @@ -0,0 +1,79 @@ +# 微信 Native 扫码充值 + +电脑账单页面生成支付二维码,用户用手机微信扫码,支付确认后金额进入当前组织钱包。支持固定档位和自定义金额;组织管理员可以发起和查看本组织的支付订单,普通成员继续共用组织额度。超级管理员可在计费页查看所有组织的充值订单、按订单发起微信原路退款,也保留原有人工上账入口。 + +## 微信商户侧准备 + +- 公司商户号已开通 **Native 支付**。小程序支付权限不能替代 Native 权限。 +- 已认证的小程序或服务号 AppID 已绑定此商户号。已有小程序 AppID 可用,网页无需跳转小程序,也不需要用户微信登录。 +- 商户经营资料、网站和实际 AI 服务相符,并完成适用的审核及网站运营手续。 +- 取得商户 API 证书序列号、商户私钥、32 字节 APIv3 密钥,以及微信支付公钥和公钥 ID。这里使用微信支付公钥模式。 + +参考:[Native 接入准备](https://pay.wechatpay.cn/doc/v3/merchant/4015614538)、[开发参数](https://pay.wechatpay.cn/doc/v3/merchant/4013070756)。 + +## 部署配置 + +1. ACK 发布的新 Go 镜像开启了启动前迁移,会自动应用尚未执行的 `0007_wechat_native_payments.sql` 和 `0008_wechat_refunds.sql`,并通过 `DATABASE_APP_ROLE` 给应用账号授权。构建镜像前运行 `npm run db:bundle` 并提交同步后的 Go 迁移包;不要修改已执行的历史迁移。其他部署方式可手工运行 `npm run db:migrate`,或按 [`部署说明`](./DEPLOYMENT.md) 配置同一启动迁移流程。 +2. 在 **Go 后端** 配置下表变量;配置项不进入前端静态构建或网页设置接口。私钥文件来自微信商户平台的商户 API 证书生成流程,格式为 PKCS#8 `-----BEGIN PRIVATE KEY-----`。 +3. 将公开网站地址 `ZHINIAN_PUBLIC_BASE_URL`(或已设置的 `NEXT_PUBLIC_APP_URL`)配置为正确的 HTTPS 网站地址。回调路径由已有 `/api` 反向代理转发给 Go,公网微信服务器应能访问,且该路径不应被网站登录网关、验证码或 WAF 挑战页拦截。 +4. 配置完整后设置 `WECHAT_PAY_ENABLED=true` 并重启 Go。支付开启时强制要求 PostgreSQL 持久化和有效的强制登录配置;缺少密钥会启动失败。默认关闭时不展示充值入口。 + +| 变量 | 含义 | +| --- | --- | +| `WECHAT_PAY_MCH_ID` | 普通商户号 | +| `WECHAT_PAY_APP_ID` | 已认证且绑定商户号的小程序/服务号 AppID | +| `WECHAT_PAY_NOTIFY_URL` | `https://正式域名/api/payments/wechat/notify` | +| `WECHAT_PAY_MERCHANT_SERIAL` | 商户 API 证书序列号 | +| `WECHAT_PAY_PRIVATE_KEY_FILE` | 商户 PKCS#8 私钥 PEM 文件路径 | +| `WECHAT_PAY_API_V3_KEY` | 32 字节 APIv3 密钥,用于回调解密 | +| `WECHAT_PAY_PUBLIC_KEY_ID` | 微信支付公钥 ID,通常以 `PUB_KEY_ID_` 开头 | +| `WECHAT_PAY_PUBLIC_KEY_FILE` | 微信支付公钥 PEM 文件路径 | +| `WECHAT_PAY_MIN_AMOUNT_FEN` | 自定义充值最低金额,默认 `100`(1 元) | +| `WECHAT_PAY_MAX_AMOUNT_FEN` | 自定义充值最高金额,默认 `1000000`(10000 元),不得超过此上限 | +| `WECHAT_PAY_PRESET_AMOUNTS_FEN` | 固定档位,默认 `10000,50000,100000`(100、500、1000 元) | + +文件变量也支持对应的 `WECHAT_PAY_PRIVATE_KEY_PEM` / `WECHAT_PAY_PUBLIC_KEY_PEM`,同时配置时文件优先。金额均为整数分,最多配置 8 个不重复且在上下限内的固定档位。 + +ACK 的 `secrets.example.yaml` 已提供 `zhinian-go-wechat-pay` 模板,只有 Go 工作负载加载它。模板保留占位符;实际 Secret 通过部署环境注入。Docker Compose 可通过已有 `.env.local` 注入 PEM 字符串(换行可写作 `\n`),或在 Go 容器挂载只读密钥文件并填写容器内路径。若同时配置两个公开网站地址,`NEXT_PUBLIC_APP_URL` 优先,需确保它不是旧的 localhost 地址。 + +微信退款通知使用 `https://正式域名/api/payments/wechat/refund-notify`。后端从已配置的 `WECHAT_PAY_NOTIFY_URL` 派生同一 HTTPS 域名,无需新增环境变量。两个回调路径都需由公网 `/api` 路由转发给 Go。 + +## 订单与到账 + +- 服务端从会话确定组织和发起人,校验整数金额及范围。每次充值尝试带 `requestKey`,重试返回同一订单;更换金额应创建新尝试。 +- 默认支付有效期 15 分钟。二维码在浏览器本地生成,不向第三方二维码服务传递支付链接。 +- 回调通过官方 SDK 验签、检查时间戳并解密,然后核对商户、AppID、订单、币种、金额和支付状态。 +- 支付成功状态、交易号和钱包账本在同一 PostgreSQL 事务提交。重复回调、页面查单和后台补单并发到达仍只入账一次。 +- 每 30 秒后台扫描待支付订单,结合微信查单补齐漏通知。超时订单查询后向微信关单;回调晚到仍可确认有效付款。网络失败保留待确认状态继续重试。 +- 钱包流水的充值类型为 `recharge`,发起人在支付订单和账本 metadata 里记录。财务可使用本地订单号及微信交易号与微信商户平台核对。 + +## 原路退款与余额 + +只有超级管理员可在「计费 → 微信充值」查看跨组织订单并发起退款;组织管理员和普通成员不能发起或读取后台退款接口。订单列表可按组织筛选,展示已退款、退款中、可退金额。仅已支付且属于当前商户号的订单可退,单次可退一部分或整笔剩余可退金额,累计不得超过原支付金额。退款原因必填,去除首尾空白后最多 80 个 UTF-8 字节。 + +创建退款时,系统先为该笔订单保留可退额度,并以 `requestKey` 保证重复提交仍指向同一笔退款。微信受理或退款处理中**不会立即扣除组织余额**;只有经微信退款查询或签名通知确认成功,才在同一数据库事务中写入成功状态并从组织钱包扣款。该笔扣款允许钱包变为负数,避免已消费充值金额阻止真实原路退款;后续计费仍按原余额规则处理。退款账本流水使用独立的 `recharge_refund` 类型,不与生成任务失败返还的退款流水混用。 + +退款状态包括 `pending`、`processing`、`success`、`closed`、`abnormal`、`rejected`。微信明确拒绝申请时,记录 `rejected` 和可读原因,释放可退额度;网络超时、限流或服务端错误仍保留待确认,沿用同一微信商户退款单号查询及重试。已关闭退款也会释放预留额度,可重新申请;异常退款继续占用额度,需核对微信商户平台及后台查询结果,避免重复退款。后台定期查询处理中订单,修复遗漏回调。退款通知无需用户登录,但必须经过微信官方签名验证、解密,以及商户号、交易号、金额和订单核对。关闭充值开关后仍可查看历史订单和退款记录,不能新建退款;待处理退款的通知和对账需保持微信支付配置开启。 + +## API + +| 接口 | 用途 | +| --- | --- | +| `GET /api/payments/options` | 登录后读取开启状态、权限、固定金额和上下限 | +| `GET /api/payments/orders` | 组织管理员读取本组织最近 100 个订单 | +| `POST /api/payments/orders` | `{ "amountFen": 10000, "requestKey": "客户端生成的UUID" }` 创建或重试订单 | +| `GET /api/payments/orders/{id}` | 本组织订单状态;适时向微信补查 | +| `POST /api/payments/wechat/notify` | 微信签名通知,成功持久化后返回 204;不依赖用户 Cookie | +| `GET /api/payments/admin/orders?organizationId=&limit=50&offset=0` | 超管分页查看全部组织订单;组织筛选可选,包含可退与已退金额 | +| `GET /api/payments/admin/orders/{id}/refunds` | 超管查看指定订单的退款记录 | +| `POST /api/payments/admin/orders/{id}/refunds` | 超管发起部分或剩余金额退款;请求体 `{ "amountFen": 5000, "requestKey": "客户端生成的UUID", "reason": "客户申请" }` | +| `GET /api/payments/admin/refunds/{id}` | 超管查询单笔退款状态 | +| `POST /api/payments/wechat/refund-notify` | 微信退款签名通知;不依赖用户 Cookie | + +## 上线联调 + +在测试商户或受控正式环境中先核对配置和回调可达性,再由业务负责人发起一笔小额支付,确认网页成功状态、组织余额、唯一充值流水及微信商户平台交易号一致。必要时可暂时把最低金额设为 `1` 分,并同时调整固定档位。检查重复回调不重复加钱、关闭网页后仍自动到账、刷新后能恢复待支付订单以及二维码失效后可新建订单。退款需另行用受控小额订单核对微信成功状态、退款通知、组织余额只扣一次和 `recharge_refund` 流水;切勿为测试而对真实客户订单发起退款。 + +此版本提供收款充值、查询、关单、自动补单和超管原路退款;尚无普通用户自助退款或微信账单下载。正式收款前仍应确定退款审批与财务核对流程。若绕过平台直接在微信商户平台退款,平台余额不会自动同步,需要人工核对并处理账本。现有生成任务失败退回平台余额的逻辑继续独立运行。 + +真实商户权限、证书和线上微信回调需要部署后联调,本地模拟测试不能确认这些外部条件。 diff --git a/docs/manual-images/billing-overview.jpg b/docs/manual-images/billing-overview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d19243a40078d7661babecb8cd249fd8da6f9f0f GIT binary patch literal 56591 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¡*tD-I+WBMD%?bb_9NfS#eEue6Up( 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

>95?N&EAX-@6zDjWRJb2qYrKnb6;Hl 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 NT%&$0^{1~x{|PlU(f$Ac literal 0 HcmV?d00001 diff --git a/docs/manual-images/image-create.jpg b/docs/manual-images/image-create.jpg new file mode 100644 index 0000000000000000000000000000000000000000..46588874fafd39d5adc3d85bb97aae82f302fb4e GIT binary patch literal 73283 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�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 JQ2G6s_%}=2Zz%u( literal 0 HcmV?d00001 diff --git a/docs/manual-images/organization-members.jpg b/docs/manual-images/organization-members.jpg new file mode 100644 index 0000000000000000000000000000000000000000..16683f0b624cd79cc1938983a95929ee0b72e2c7 GIT binary patch literal 70883 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 Hb?AQqLp=Q$ literal 0 HcmV?d00001 diff --git a/docs/manual-images/task-failure.jpg b/docs/manual-images/task-failure.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a25eae890b554df33fc56f8a6c3bf912148ec727 GIT binary patch literal 48412 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 f?%; literal 0 HcmV?d00001 diff --git a/docs/manual-images/task-result.jpg b/docs/manual-images/task-result.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c45259eb7e844071c64fa4e2a80c0b4f4dfbd9e7 GIT binary patch literal 35680 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�IE5`xs zZ_lx^oqgc^jTLbG>wJiNL<@qa%A0K;@Sds*a-4g5+9JsY(rvPBw`4}&;RxZDwTc+m zjL=t2B1hu*psC^Cs}{{SGmdo5`Hy$`yF5aEK1RObUk`$tT7sIjQ)kMJ+9{7+qbN#Crc^7eZY8;R$-S_xq##IC)J|DdpHe~ zAkC`L_{Dgp?mxqH0$8RAKPnHZPc>LYIv<|X<}|w;$zIB#doALU%+H~PofPSHJa{#H zLc6;}eJEkAj)vQNy3-PTW8qIp$lfk63;OdHZPcnt!p`b?xVLy&@%%B$2 z1V0?7CGM8@sIfSqws70M2|H2JSEL19P&djF(BU#`$x3xW^Us#(VOJ1pS&~Xs*xrFF zs%wrbZaQ=D;F8;eNWF%*_SP0Ju~Uhs zfz#lf!F6wx#SDnLK1Wvh$T(Thx|U{lL*H_St}04l*yt?;RA=~ZhpC;U2XrOduQEel zS6|VBj2w4L#MbO)0u!;wRFZ3P7R{q5UaSwgw7bN35h0ka&G{uvr2n9D>a6p*=sO(O z9U`428srWIUXCnanvFk)1ZERx`+!F5KH$|pK>k8fP`rp_Sc%>4uUpSnzYcxg)(qd) z{LFf?^XTVuhnVr_2TZwfbmAZ=CC+RzL(MG0(?3YX#?HJ)aLoLc+DAYeQw9CQ@^9g} z9lPiq`eq+s6;m@V9gn#rMaV>7-4hQgs6E+jmUHZP zyNmGQpRW@( zKmz4!s*7I(S6GvmfToL&QjGO5;e!RvaRb|^(WWodpj*%~OUIdV>RfP`{63)4ixy;7 z6k+llUE0#8rrKdppOP7pfhxJ+7aGKKITE`R^fgR`=~>_!KOcA-|D(Mx4Qndf(vBhy zAYMfgji|_^gh@a^Kpc<|AdG<|5CSNJKmw=I%-y@{3b-e&X zn+4;{8`S{cFax7B-iVbHznXBRdR^G*e~26aK=`jC=fAq02j0JAbo`QS86pK|bvS;Z zr~J10LQh%$A64$`lm3>_@g)D3C}I5w?W6|;c%wU!^w%iicWwf(O;ky#28w>`Qx_u50R7p@h?WlxD7*LQiG+V89rTQ$;}rhJIE+P^hEkl z-wv^(_|hS?j~<&k$QNHqV0F~b)ynqpaikE027}qk$N@+L0Q-@OZx}O%ouTao`z^!o zf+2WpHzQ+hT;E#N$CE5I7H@M$``J#}C{;ILl+m=2+&UmYs(Pz4*e>Gn7Uo@75b_=} z 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 N;W@vqd+Cq4{{nJH(cl08 literal 0 HcmV?d00001 diff --git a/docs/智念AIGC平台操作手册.docx b/docs/智念AIGC平台操作手册.docx new file mode 100644 index 0000000000000000000000000000000000000000..c4d634a478e11665082082c0ba6c2689288d6bb1 GIT binary patch literal 340385 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�W}RRmK_{WEPy0%Y#Kj}_sa zDZOKZfM=c!se0)DA)LyC6h8EM9@slU%=7=1*~jL8C7e)cF1rEUo`RtBfTi6fYcmRF%yVC;$8w|957v6lQ2)zvY=JL%LIR!yglu{h& zc;}76a>AD$cc-6dCD@y5C*NJj-Zvr`_GX=VPR>XB?ukvD_svt$&K&Bj$)C5h2oDVl z9(7Vetckbo?O_r3&9fgK3ArJ<9YRG>Hv*S6+%}KjeFzk*Pb04P{GydzI5yRU&+WQbp1qfnuUw978NBpx#w1MmaVbcGJo2ycxBh6Lp zg@SDSCn)po#={T`t&(+Y?TGM5V2)bkY3Jmsb| zs7RzJmV+ZT(B7f%acHhwJU_^1h#h9&NY^&YW*@W%_Q!~|c78HwV=$PL0|!6dr4wMt z4=r^^XYxgQqj+r!CKxNPIqe|mK>}2}j-8biDQDGdLN-i%5-L+P(#Ry* z>M_xBosVXOXDWh+wF%r4#&p&sotP0ayj){rOsQnB$Ia*y1+sSY(o^z!r_9>P)W_H` zHp>Ei$lv&jmJVwV%`%sM*tm){#UE(Pj6<#mOA z3tR(!#?q(r>U$T~4z^Q9bWFu6E61passH|~ljt;#@PlveLW&JGlQv;2lE~LsI`?Sk zyfwCEUX@svi$P!_MlGh0dtsz@fxVp%pnXcs<&oT9>x)U5S2>9rr!J@VvF&k@P#vj2 zGe=)X3h=(i1b)|EmnTz0r%7&nEPl%InEl&Uc??vG%*O7SEiOCWx`5dM)^CyNG}6+q z6uZ_^R&guEmR?cnVWe_vVR;ZKi<{+s&Zf1fOaURAOJ^B?sKx-kFz{=O0GJMx)AJ|m zHNco*SBeqnGtlj+@#D)DT<6+;8nLx<7+vJQX2Ga$75wR+aec zC#u?q1tGLY!v#Gi!28f#c-6qn}}}y!CE;ria>(OHtL+*$mG6&ldw^~fH{vJfARmo z=~rIUmc^ZvwaCp#&wzw)N|3G4Sb`#|6!5I))E6a@T#=F;V}cwxvS$%-uu#YX^bD7y z`XmMIgH5=3x+d4e!n@s8 z2nCE7HlWf4Da@PQ6 znkOJ_;)H-P)>-?Qn1pQpeFi;S|94`B`uvT%-L9qfDJ7np>583)#qK7*YP7MW$qlp? ze*@s`U^H2p%oK{-_^+HQky4$|Ta7eOlsyLP7*2j{_CiA|_6)^N)6u|iFu0j{x0u13 zKUz1@<8z#j0%?^}|G~Fid@95OIP_eV1THNE=t=XgV<7S;k2s)UUl7r5((5@-bDx(@ z2rOyAr?sx59q$JS0Hy%cMnqKce&6Y9z|ab7yZgs7HieY}%1EBFV1x57QW5`R$vl$^ z2q@qUqjN6)859lK_|qw+&%3zGs8-GY(+U3ZR>Lg)A9jnV)b7#YHDG7pidNBXWxw7F zQ6^gj+Z0HJ45WHSrKqUa?NTX95l__?5@yz9kz-1BnL&5KXu+cpUBuO`b}sknLWCRQ zQDc4$FdMiA1ejn?7+r88K#VM|G%LKz*SvqQ1@;+CQxF_;^MvA~A(8nRjgEBe7K_Kb5|6N))zM`+4&L-eFLGQ`11Y@oI^exRCw)9xxK_2_&3@XQ**;A21#WUd*xC{#RLY;ND9|I+Fhn zfpBb#Yows1XgALK3SDgnU&dMZE`IL+6|immYG8BA!&TH5$R^oN*oH{Cu|9M0>EBT! z_{5B{P|zPxush zNic^PaWafzTS6}omm~Z~$JC&|KRZA`n(Ln_5QYiX*76KSm)Fyb^Q9jZ=;@KzZE!!) zkrD)Uc9wl%7-4Mev=MXTijFU-DvUa}l@0l3nL6!b7OVgOz`f`1%BT4|x98o|@4a?J zR+(mZ;P-{aW_Bar@UkK`zVa{U_*!^dViZ#ln6J~g3#!4^utO(zQ;raLArok5@lB*7 zC7R+n;iek-I~~=40Lb6!;M!ZT`g942+@yt7w|+UY9KX2@S~iWePa@xaJ^>2j_9H2i z8dBeV(kdd{W(s+RXWd08pW)E*N0RC{AgV~oQ+}GTX+p>i2yDr{D@UmTLGM#$YCz>( zkYZP5&rcqp+MsWIx(w=XEE)Vxu_R;CNc zT?9}j!SyM)&ZVBb!Ici$24Zi=q_HDsxd&iuqUj;=G$Fdqfg5=Gli#_Bx*H8kX9jl~ zEF^=KaN5}latNY*_E47tT>*5EWTRg zCTuGzj1!w4g*u0EBNQ>-p&Cff5e!Ht*#Zutp@eN)CP_)FYGVw7%t}W3Lp`1AOEEMS z>>;hj@Db7D-GcP(OXpqWbc}MrgoD?B*FrsE*8rA$D^sC03~$}fpv3XB`fC8I&_!Ee zR@yZnP4v=>%Izxkq<&8RNT|iIIote$pUmhaCZeq>qKmM7F7V0Me_OZ*ywbQ$oSlk> zq&~!j6%94L?v~upQig{6DiR6-3|x>NIvwP=@fzREGPu}|+TK_r zLBw-DQm47`YPiEFgcK8U%;P2qBnCaM5spbgnBQT-HkniT`Lyfn6~3+-hN#wVtj-L& z+bO}%sv`q=Ej9Sb;kH|Bi#)pnsR3s71VDv}6Rv%3eH%a#t zp@XsyeotWpDdYibX@LpjkDF;%dTdG}%#9k!onL` zF%2B)>NCnE!*11wYIQZDB?rK<+r3&#q;LzuU9rokRJOt+$fecmu%TsZA&lx_Rn0%{ z7xTU%tMCpq!ET-u)I3x-UVqKdTg_V;U(N^!{3JDqk1$Vcxs-~&DX2h<#%D=x$rJNllbk;!N2vcE9Hj7jhw?8d zp_-H#z~Z*yK1uwmI1K;*K=}TxC5Qk1!KfA?gz0iW6F?ZA!u0(;=)RkUOc?@b~*okx17VS2&ri&(%vNp6^GL| z7t=SR`226L=BlDq4`mQ0>Ezuqk4|OP4v^-}zp4MEg095dQoey&`zS!Xg40?(74Gf1w(ftSHp;!p7{8-3qA$L$W+lC+aSY4 zBg$y(;ZZdyZNdstWyVSz?H`i3g$w3>{J)Lc-O=WzhV2L<#nU(GO~#6PS+N# zh5Dy-txH~ZVVM!ElW9}D(hSFWPE#62BRM}OR{5Op zOBqdLY*B-nN4wXCzB+i9ho@t;?HceVVc5P}Ws<6PLy!j+A>gwp0Glx0I!vw5d}>Og5>K1a-K-6(l9 z>N{)4*Qh9qDJpBN9nYqz_oOVgpstg}d}zVcOKlYM*V(~9CG%bi4vtcZfK{2;$a#Ca zfxixSCp9#_0y$&8r$}wsJ!Y%M4dyhK_=ScH*zndu%!d53oX%1a)%Ms^>_cWR8H}xo zsN)%Twd?LA447e-<5h`a>2B}L7)GYN`9C+j%C!sc)(9O4JpbW1q6V6B**>a}FUV!z9*f@XE3iUrLA6kyIOvn? znBkem{k2j%r%7i~#EUAgqM|-+Wd!_7L>XH@omoy8)s=hCuFqpL!}LWOrq*kipkr=& zrM!y1W0j;Rm90>nT`23ARHKKI<|?26>)8~eDhm-1!2ta0M);l*?UU*TO zq>g))PLe4{G?j0x?_J(tSm!I#nfk7j$e`u!$DT%!VxpY7Pl3gWAd z@v34T^FJF~$-KA*@DK~VYfm5KJ7VzU(BhJIr_-P^Sot!{v+d15LB!mv9~K8*BJ!+X zUw^f7qLJh5#+MQ}xw#HWmX~Gd641ybM`A9oCyEVbU&%>gMALo=wGuE$^yJ+eD}8Q%M!IAoFiRY<4sIS|zEhNUuKp*~mRP_cebbr}#BM z3w%(h!sw#~D{Yn4)D{)hkfCC)z-FoGH^{VO90Lc8S);Lh=s~l`iJ@WS->r1yZw`8G zs%w#3evvHGJgKdESr~`b2sfz54NC(TIvhEJK-1+M4reS+IVZ?-6RZN&P&GI%8evXf z`wMMy%gwVbWD|TAH`Hkh50FV^rL>Oa@DE+VRl$5{WH3t9P3lh5qEpp9ZFegSjy(}1 z3OSfSZSZ)X^n2I}+Lr5=v9sw=AAEx>)@yhr_~T79s1oR z7lx3azScd{F`KkmU%j#%^27Q$4KZE!b687s9f1IIr2K)2aY(w9bh0Xunb{QWk|3Y- zPYM8`KLP*r49-hBDE65maQ9G3Ozvbc#{C;lin@^zn=V9$XwH_nVT+i)ELIejD6(8d z;O>C;mm}yTX}?!TF_fDTv4z){!s{1T!ISOBMfKv^qK<_*p+7Z&XI;K>vt~LM8*Kwx z%wrWHVf@QUAuY+p^*q+K$r#Z5nzhmIweu6x%8JjTn>lf-kldXyC1%5Trwcs;3H=0W z!e_H{QnFdqsXq99*e3c>)nnK9XveQu-8uCya`J%x`8!qGU1gaL(C6*HsqfNeUFlz- z38(lygKUk@cqQCc%Z8RR3d!E?ZnT4fM-S&TkP0rIOcknd#R%V4%R*Fq0-cGC#fE*h zBE{p-uK_Ql{`luXz{!P!AI)xBtez_mH5+n|&l&7sJRZP$%TvyOu0jct_`k7GrX}@$&sS9A;`Z?Ok!FMWg4Ioq<>tANMjSuh@MO*_G#ZRWHoV;HIon1)PbIS>4aK&1CFOs!;Dgf!U7A%iF-LIikRSZcS=% z?a=Ay)95QTc4 z!jxla+qhc%V0PP?5H43;&TYKZV^1}wqir2DC`ZK^9|{y|S7-*-h0dxO(5O+2l$<4J zh3xM+{D$T!M9ZWvr%!?SldmRE5FwhHJiTlkXRvuZZ=`*wj;_C9k)@)bcuk>&upKxQ z0N*Dc$3$J{qE%QWIE`{>DCpKfnTr_RCNa}i&o0O%N_dp8<%5iR1U4C?0plZtelg}O zk44qC47Qnt>5`cx1BZF%C@P1i)3HPI{6pzATt3QDy)87OBtEMXeBDTJ(SkDBX5r`V zF^7l1i)GqS+sYnR~VBH^v0tRl5|7YrpyhHm?M27gbwwj6VjAiI#G5cFJAJ!oXr2KMRi! zT*sM+88n7Kf!PXLOBEyXD66?KDPQ}t1LpC%RzKuN#Fpz%C$afKOE?Z=V%HBVgMN&; z3x>_?;&E#{9SR^A#3FYO=(KZkEFRZ0aD{i#sAS-;oSAfU)MoHZ(wOL^yHYZs7_pdw z!7tWK7Y|>?esPgV^C@c1Y8+7#1-4Doau6%(C%{7XPctYK4ovv30fX#l{t5KrAJ=B3 z#ZlSJ%(9+FcAdG{Pb@phvVV-Khwrc7Ri>sFMBn$xVjq139ilZh3mHVFq2vimVn$lX zENK=nnLqX4v8_Az{`i?@V+RcTezRg?W|QHg)V129MEuHfr2H%$9!|-4E4wfs+PkScx%I(9Hf>w(>K1ftQAPtd1meKSF3Gau2q}wa)A0-cw0$N*q2x>qd1GB8IiC! zzs*k)^sW4nUVSstiS`pBtTVN*mdpsR!up4@Qa=o)k83jG;6(p^NmB(>YL|W)N}ENY znu(EYY|z6~RT$V65ZKPYX)ZSF?D~5iT|?N7UdVg2b&hl>wP9m%7kypW4f8f03sdEQ zX)1|r@bxy3odssLXbdtR@SI-*(rETyW5(JTDsemPkYXm>$0H2MpSRzKb7=2F7OHPv z1be#jeiqnX{2x&0R{4dvJ1CMce6YKa+o=6ok|KvUnuH=zM*p)=^Pgvp!`wqaqaz>v zKENDUe0mqq2<(0;j=FACxbSd0w?EX%(t5zbz zkcE|dija_iU@VN8sL4JBQ#(kM>!5wXeq+CS7rC!BA@OqF3y*gB3TOS-HGq4bW6UVM zl8$a{q^n)R0CBL~)59e*l@sk6uvS5oGgW2=#b}Y4NS4J8#l(vZ=P1?;wjr_h2K{Ou zgnpdMrAeU8HhL>>Su(;?pl1u7ViuG3XL}EBaOI0GY*3OJ#*tw%wD}zIT_W!3Cp5&~ zIWIGkjB3yP*VeCIxy!OY2ctY94AH7i3M;oJ`5ML>shMdnv(Cxugk;ic@EWkQI(zI5 z4yG?y5z@KQ zB*wjxQ{GlO*I1uA;dQb;BJB|RoIjwJc*5yr!y&W-+v9L!RI6LR2KY7|k@h;N;IQUJ z&o%`)>%W z)BB(_|4-vDT66dD7o7aWKk*lNtGmL|ktgmpcgImc*ak6-zBY0{yG_b30E6pmIyB`gE;)`rd$&bGcUx=igpOk; z!0N=SE9P5=TrzaVPCTJLEprV3F*YqGKD2RehJUB8jK3<^_HE_7Z$s_@wz+3Z>FZWhbQ9PP5o%_j+pZfiS|?G`5pMU-h(;mZiRk=dJne3I=p>#8oJ~$-Tm!Wy1gw54`9;=k>&5fvVnJc z`QC#Q-`-0+@;k|6n02Sv_UL4CSl+o*YQch{m#KlmCwIb{}_Uh zoQEx4+JB!8rzAD4a&Hl`&=Xzt+5w~W={^<`UtI&_Ednb1%2c8t6QHedH|+tgFi?{< z*V`gWN9DJD>tu0B8TKIz(zqgx6s>5t>+H4~)& z@M3P)`%uR_H!)0Y=x5CAk!?(}m;~{V&f^otSYhK8V$Fs)wrhaWlKGB9q;f6y{D;ss z7)K^w5^48hEz_gO{m|;&Rg7!EhSmkY_rAEUz%`&<=l!HOTePd#rC!O6-TE!IsjZ%^ z^PQ{7tpEAgM$ z?Hdob27eo0qQuqtGG%$?=dpYE?bS3-e=r>ByW~u6Loj(aB%S=_jrTq!pJ8_pTPHLS zaY`Rup8D3a>WbWlz7=d0lQ8wWxMND4lt+)75!K8|s8nM!5nMi~R^rb&`nt0PxziLZ zQgS(to)w{WIMm`qz@kQl*fy)EY{M*b(WK5HqB9;=PKqGIZa2%$*kVecs6pk} zyrd{=^X%eR1XUJ&0kY#N(ls;=vuBKz27l6Z<<6zecAAqDdB(dsq@yt;(l9eqO8t+;d7Q;*L zRXo@#PaQF=*8gf`l(*p6rud%Mc3*oO+)+$j^GC3fZn+@L>T4mi8YQN0&1}Wi zVu86w!lf_G)G3dVf((5vE;t{_PXOopY#u}9d9Zwb9u5L~H|gh2KA?|C)us*D5gg;= z>eF0%@@~+=DBmXjC{oOvIvdrW^IPklWbXFDR7MiFp$}-@t^wuafHu)LzUD{a!(&5Q zJjCj0`Ajv+)oqhxV8_q`3a$6{9FBG$lAw&I=@A#nCK+W4lC&|9{f+R>9=Dzxh=n@L znqg0P&Tg>57PN__t7tmA6DCpkY-T%KO-V*Ocb(!D4T5j=Wm>^hSSnK0H6W||<1ggc zlUL<3i~Fa^d^6ezdd_Ti##6+3D18%Y zo+;~h&MZ?}mb43{t`1`(_#L%}H1eb??5$<9IyHM*0O&bIf8Yh0GrABArd1;g^>p{( zm_nw4rpMLB5KFD1&)I*{m@9U}(}Z*NHzH4-CssFdMWh8bSp7Xf%X2%u!7T32cc*WgB2HgH6+x58g zEpF9ymA`ashTLGW=lmI8@zs&DqQqi+f!*iNL zp{5pdUHnvMgXk@Bsk^o8@w|Zxl6(!gnz^DblJ08C9Q`~s$jXVy5>t#=5~!8}zKqRi zzhonkXFA#+ag`}p<-bf>v3e^T$;AyI8BA`$M=5}+a&S>x1ziI^lP;lno9;hvDEa|) zTl60MbU<;T@4y*$7jqa+x{{5;-a2^s{KkY5fBRJn=d0E;9h^65Dv$r|yE#_(Yi^IU z9JsNg)Nbvl5<0&><`bf!rdNWuvNwC)ZxeFz5ROr~F^HFIynmRJH%Bxgp9q`_VtYED?s$tc^ zhA-KcO@dDL`mFiSYK9N4##0?Jhz~mw^SXHC_8P-;HajQTR&&#t) zcc0oxM8~Bim~2J>lKWY|?5+DuJ4HYq6qBs3>OL!8-JV!{UD0e|u)JL9v|Kc$(v) zSP=B7FX-$_`Z{korlg;tZWvd4Qp&9?4WCMzAE4B5oF69?4Uh0Q&cfi)@+RZ#aDwSreywt{8bwFi6vtu%| zB?GWsF#ZfCvX;s42*Mn<&8i(}*RY9`m8CAWXr$n#%1KT05lZjAJ@e#Gz)fr0IClD7 zeq`k53N@+R?=kcq)Yj5dwtK?oY^fzClSP%&-MagZ%2bg;nE@-2;>SFn&}@#LEOMF_ z?~L>E$znlv*eahm)f6(>(ztTNJ4@1wIs6tAAvtggV2MYw3pueVvNs}r!$90GwN=># z8yr{Tq>Ewa8QkFc0pFYSSH5%>r+Mv@vnjXL?+G9LrD7lPv6TO{6%l;!moq|Bo#@xX zp>tGXv3`L*;+)o=r-=KgdXKvakO>3$yUmnsGqWJs*(pw}ZpqeSYzL_j)-Cj6>Zh6N zV;dV5(NA%{uyLAeOpy|WtlH93iQf21+H#KO8lfgDIkTyqpnSY9P1~f+3YH4#I5BZ} zq}jK*c&~H*1o8~%^DatBHBNBKLA4JNJ=Z$@i0^`Cf@CSDRWBX3F+LR1$r0AN6k zv-L@qW1W$ZE}kV*N>1M8Vd6C);6g2{oAP~h>rA<-hIuL#(UzqR)l?W#>yf@er+b}? z;X)zx@NvX9-J}) z)MR+Nk=>RRH1R33Bc)NMMahcbWmjJRpUmYbE|~P zb2uKWjn5cFN!kG0QXmpM+=UFuX&e(XtIggu{Zjdd{^#;vj}tmA^aIl+%@KyiM2PGK zLfk*PmDCIdhZDjGs|vRTQY9EFIIaOyYEzYL+pCrtVUMIzJ*_ee^*QccSa*y&>o9iUY$F^4I@^Uv!%?vYA#7gQv&Sb=6O&82x1LAx8 zcyTY*tVD_DrHwri1+ZG_wY!81+23I`C>$8I*ipS3F-6qcV;1~1e;V>S|8iK`(Zs3T zpCzP^LZ!xz3{C&bVZV-R$npD8)iHIM*e4U4K_)TW8_%0(ohnuu#$Curx#1ig+Ffmq zwEFxt%(pnJ6jfC#3xjPf2_iNgFIs>GScYsR1t_5j@%1}bfod7;H5@-dyz)|I9& zEi`314SUimawyR7c_^GGk6$s64$)^;1r<0yf%vRZM1;39`=CD;BmGV$-Cc9~82~;V zm&{6d#qP6UodU{>$6=3mkPR<}gKX7g+KhFY7k+@v`tB(hGRPi?ZB;E{6>-+`j<-e-t_JY*ASEGz zKWu1<36yfZvZdHkBQIf4?IIM#dbtgBI0P2VO_(h`H5CMZfN7WpynH@Z(}!vb{%!~F zdIWi#f$*%&hi!EorbZ5b=YetousKKt(QU2)(qFoXcQAW;MPiC0C06@b!gdttME}J| z6{aI6FQL9qX;oCUxi162F#u`16wGXP@(e`I4*77*|X1CX}>U zFm7&}KwQ?SlsBncb)v$1kVn#B<>`CeRn<>PZO-O9gq@0}Ua49|oO~-PO~)s6rg=3I zOV8rk>ViXp@$j{fsaa8+pE=uT7SauWmEri*OB+PC3A2Xb1 zLFT%T_6G;XhlbUL;MmKp10`uI_Q{eD@T3M_yNA|T!@;8xj%&Cq8jTQeWvda?&89z@ zI$6$v7z8&kxy+rHiA!dO1rJ3QU>H{{A;Y< zJW1~$PLT;8LRO)5L>poZUZ}ZDwFc>G^YG5PZv2^;;Pw7`< z!}RlykRE47oPR7uwOnSe*Rw{PuK7|hslK2s1|+F^qz*LauWA z6sO+h;hvl zskt}2p3C-`7TlZlVvp^3vvSllDM-!ZPM9!7Wlo_XRw`8d%*_)MSCXy4aIL3KRUyGH zwbigW)wzYQrLxW(BRIe>%at?&rOoTE8XDa$eVv^MUBkhQ zr(Obq3au@jMqDx1O5dlx*)bM5EJW0V;7263m*ZL8`xk|KD?IL@Tp>%{^oFf`{9TV| zCs$R<|BFsV=e<*5cpscCp$l|(9+uy*Sxr-({(k3E;CBS1S8#YKDsGZ~WGEdOJrxx% z@OoC+HFA3j_fkETsIUNWO|)1gXhDfoR8m}FEtNmyr;qS+Qy7yFyA1+~SF0KOCoxl| zp(ZM`T!VCrbpDUof=XO^wOmWdIY8@k0rNK3ZkJ_O6?dmj!y)>fqfz!3(+t|8&s>ev z!Jp3f8Av%FMSK_WIS5BP+6KPC9c-k{SWd$z7bnTi&bO;JPcne-T~!m6e+u04d6{8| zQO*%jk;ah*1_-v2YZm-k7+pxgx7b`662tp(@^ZVRp4BwYF_ZOiClZ700eFeTa{1ZU zDp^+&l*7OYd?IF%BFXr*ZHYH;YCEa2D>Y2xbEj$}C)cL%!#m;# zL_#H&E^!8kUym&V*>IT)|CLR7zRBP;)!S@PkU*`51mL@rF;6=@ zyelyPVJr2keYcLIZAQ-5fy5}XoZ`W*vsygTC_3$zWWe?%p%j`WDvKBnp@F=bcrd5Jh8G+pU8{;BIioe>xrY-UBv|ZQviQgK9fX105epGmud6# zm0qc}uHap#0zW_c_SZ>Qyfcm4cnyf=VTfWFTk*1X^oM%y>Kos9Mu;3kKLv0sJ+kkKmX?~}eLa1~UJ9vki3T5__jjF}DN(8QxC>Q2sx+_dE= zJ6?KHK6bLcorq!#@o)<@p`{X;Wkhq{|F~)5wUiXn)y?f;NtqYG^r`jwBc@c`l z%S_T<&(fUyv!!SIN3iQy$sVi!bcu{XD7UpolwoAZm!gRDRLbfu`^UUF2v6-lxsCxm zsStezIj_`B^r|Il0YbxFmgY7B;5h16X3QG zKYa3=w?-b`UYyDI3?6$Xo0PG*<+c7e4LlGI)_+7_sW3RyBrZ2WOK!+qMOC2Jh|k0K z%`h*9sW$y)>A5?&KQt3w{-v!MLC%YrnK?&tvVB5^F-Vh@51*%8yA4<}KprK3Z8jy_ zw0Lhzf^8MWF`Zn)p{YWRg}C&JwdGp?8*;&ABAiqOXc;s+R5>MrEhMSs)&8 z3PQ;fBkhq*qQ-yLOF}DT%{HLw8QE%8Dt0_=rh&E06R9M<{N?Z)jM45WI^TeM$VCo~ zmq!kt!oazU-Nii=UY@ac#iig2wZ8zB1@!-8@2$h)>biVE2p$341S2&X)ohmlFAi;+**yRCn`9nInKw#o>kam_DknI-oR7XS$CMw0GXfR!*9 zXdfy}n4=Fr#(`-p8;M&iejpXdOEURf_Kf?Q=d^rKuAbK%_yW?MovM@9b+Fl{Rgqe7 zcB{sc>_MI&B>cqp8l&wMVro`zlvuV-Nf*m1gQCOoeP3$)=|1knPOCpaFLgm*e%`4d z_bFe{C3^dSFxtwXNY};<>)!Oe_`A_3sc;NA?y{taY*@`aV>1KAC#AtEG13cV=2fQ` zqA;ThhNej`C(7}LA!D<0^{FjNS;}*(<`cWV0io)VTMZM1(uRck^#bUg8Ff*7RmomF z5f5tG6Opzm7F~=%8dZP8I5q?L@L)#YCWY!RSsNinu$ulS* z>dG>;N*&jHqNA&74U83--GENNPi@MoI zf4+hce))~BUsT$iRZ0H#pNloX_+5$CfBfewNcr3!fUODFeRS+=ECijwX!TWDHv9tU z#kKFoMx@p?^-CMEK@FpP54eO!2A@-9ZcSEw)Grhq-k(ljSUqrGMtU(|s_!`h>JEcS!T!H0Zt77k}`hjv6@pm;{Qm>F=FW zmMhd>T&JW5*Y1O(v0V`n0)Ra9_%5{BNbJEi@WEtr8N5z$`Fr4Cv3YD^CXJn>A@fAg zJ0r|!1n&*_bExCN30h*5XOsyN#(;ZOh3{#~N} z!32sOE1z^d|TH9+F0Cr@w~#Ib5OAXjMqmPJf>HEDwe^IY@}77=4AU(WR2_!H^60|L4rB>u#p-nr|$r_4f&)*fnHLL>Eo>- za-qIE{M9aD?)KKa?*0c7R(9#niA`Sj{XiNj6!p6Lfut|=P2pQCec=mWep%j=R$Vn5 z3tziCF)OdK=sFCczk0tX6{4UfN@<&2~tOznp(3ec8}o|7SJUTV-<}>ZiPfV;0~(2pu4$NPUVIe35?ZbQRWd&Ok=icOr>>x1n?U11UnB z+-qGEtE#{9DpjpAu)lD--Ne%rFqfn|D{0P#E^Tg5+?4*Yc{zsNmx}XAH$(x?b3iD2 zr8aBlqgiB_0)cfI>Y0;D@V&S`%~-k5;LDP`T$aCB)Vq zP01t6FFDvgFG)4SJ};mwWehi*mRirLvk!cR(DzpeT}oM zR(y5&r!>^Zy&c{cW;I-Kil)8JpMTA)(WC#NI|pjk0Cl(kJM!uDA(|8vl)no4#kHuY zdS>~mNm1;?;e7u%681e(=Uav(md@M$9nTS+tWlCHim##9CX#>e*L}x@W_rI3e5ZX+ z{oDUggQS=G<-vCf;-7nTOY5Z_k{cu-lAHByRy8ljkn#V+yzda^Q_!^Uae|a4~ z?t`KZ=N?VrJzc)!fwIe1<(JNtwldi z8(9B+^8|EN)w38spN5^h3~7>!?6Vk$Ash2utycn?Yf<{^C%-0`zZxGMtwer;g2Fyk zO*nfkw<1o|0}G03w+k(6U=I(Pl$15A?>4Z_E#O|-4DHi)y!zFJ!0z|4z<;r0fTu8` z+*TwbjmAq7;98QNOFA$;gC$OE$}32`)jGVcbii)>>Y6oN{vX!q7bSnJ(?qWV=fi$G z706ZmsmK-)g5}N0ja_fDLW3U5Y8l>L;`&f)tbyGgMnJ=JO6M*_iBakQaZk4Y-Q~aS z!UffW8(P^PFvk5rQsoRrLc;0#6=4uY{F43kyN%c+rpwZMoUg4!()5=lzrywL|6;fM z+h6>r{kkYlNsUIQ`>j9)!kPKyr07o6`vOulLJ%& z=Aa6q8SEsB01**AZa{C0GY!E&$kVe1Fdfm&|r z&yB{h#NE%OZiY*u!98TML4Cl*F-cIrwZ1udH?t-wE5f-;cwHm=m6nf`0RD2ggg{M1 z(&SUex)w`_zj_4$y;AR3f%fzz#kNISaRNaOCcFzr0o3Zx)xWLB@;9Pvgl_V=PD2A# zhOS>xbf%7ga&ZPW^vr1PJO@fJr0#%NLq$cPV1{!Qh^r#w@$r{ylBPjyE4bA#u*;vv z{rQx>X6Hk5A_nkF&r zv)0jLC05<8-QZ8W$Hoq!6f)We&Xmc69e9$hhI^i!{FLwinw9yzg#LC%G#41D_c zDjWNIm3>Llo16A)r_mkb#cEjk>M;6I2gjoh+7|Y3DfqwRHjnlgq4t|vCBt~Q<4;;% z!khDwUu3URrOkl?-%Gv&`IDZ>8J~IDKfWw~^DMDEoS6WVp~v#&n;vYQbb~FP&@pDB zud1~5Sm8kgn4JHzVU<0&x~CdX6HT+?jnw0^|3P-s-y+}514<0&uX34S$jS*f`$eaF zv8t&Y^RJ0@3GoYJf7Lp?iR9B1XsxnL7XoH{yAP%L2w#N#1Ig$v`~%5ow7vTs2o7v? z{Zn}x`VaX0pA`Ln_TEYX<==aQxaBne?7e0GY{khGqY65{^blx_x`~b1!!Yc>832?F zxCr|%EJAtq+cUcTnBOjyw2lnZIX6`RyzwyC{Q^N5L6NJ`tB9TN=f|e4u1z072~f8T zEA#s+-p=@?d!`>qDKAbw21R_o|E^anN&%Mak~n=(?#=gpUg^Jb_x5P$L0vMUVZ-WL z=u7W4JfM{(|3fEDu_Gkh^se^YINut#fcMd> zyy_Myxyt9vvvZ>a6m&_q{+XnrgE;%2tv9&@L(H8$Nn)|#XWmwf3&yd+@RgEk%%L>UG);Q;;zNN`lOJD>_-44F*_5D86a>d8=2{==E3z%)Xw9om)5_ z?DdCJ7EQN3e^H=Vh=XI>S@GnQi)`US)miNJ%h`1ll2&dO`F$Pgzs=5V}|P#iRXW$MnoQ&W4Am%+BW zZ}SmxRnI~Tj!Ufeo7?a?)zx|6l5Bd7{T9yl9h$o$89u_U%NmZ3_M6f|v%LCuNMpER zuBXLschqTz%|8`3RM~&&8}c6((y@P~NG`hc4?%Br9wNS(#^fdW>PSQe7)O(&@c*J? z;QOiV|Ctc1|M*(sMs89_5?hj_WCnugM_>Ud6ll}OXp-21j9-BjuUruKJPmhZc`#|m z>c+gxd?u9X7a;l zTTZ_;u0c;5=B{jMyHL_$gB9d|>QF;5zEuIkzvfU?R8XK}T~P;AeTM?$5qp=7x_~*C z7E_>HGlBdTl>n~gp07A%n#isg%NUZ`GRJZT5A@Q^}Aht&2sc-2At zeAQ&fbjehWV6v&y@b;#_DCpP)H z;|i)Apfi3qlbM|9XLon9Is2r&<*JEqPi_}pL>1rs=a(?dygTIt#~|WzUCjs1o%66C zNSNArSFw5{I}WvThBYui5s8p{BPZ0)YmgBv$5_MF8yB*{+Xa4vf8yS<=IC)FMjUs9 zR@-B2s~{m`1rfG_=nL=lya=*VyhPet6${P-XLW-%O*ZG|LYj}&*Y0mvBJ#VyQH`Pg-K74zkkO%!O!fYo zU*&h9IX9HQm;DO`68X zz4uN}GB?N6&7L;Bpt-VJNBsg_to?+hL-r_LPfes>Cg_f9&`M!{^ze<>hz61 zKo#(N_jJEVYw)`M-s)4MVif&Owcl$QCwnKox{o9Ira&~2@OW@`*)7WQfjG~*#y6o< zH+Z;vfCP1?F9v2Xdk%Xl$5I>JZ8x%qmBvpdWnWOPo!5>HSdXV&BYVQ*x)^N$^L;JN zI@Vm?(^%lhXDtJs^;1|^TqSWwZ%7VSF`E&Zy$Xb2GImvSG4q*CDXUefd8G4!?F<4ABNpn)pW}$vrsxqf{~V$e6j7VdFh~h)D?~*? z;8V41o^dhUF>5u+b*+43Sz$k2Z9fDZIlzu-?~EhRg&$|2I?^UbB11J6i9f^4T$~{~ z<`rZ*3QC++A=|(xkEeX@){a37XNCmxu4whGct_uJ0!Z4}e?2sUIHSIE;`U zGZ(b$w5cXhlvD3iB*Wd&h2kiE>)(t>V3BYcmE4S|QP^Ap;oEtDXS2xyrpdwJ-~}8n zEZ~GXpX*a;;x^w!NIQf04#orl>v@vpGDo&s z9;EnM&qLjfArTHTVQ_Wp5J>uvn{CUA`OewfLCm^=7cpc7sE+}f!Bte>;FBw^^24Pj zMY;|+bW}=+Z>?}M>UzGcSvSZ~1F|_Q{b7nIUtMRm1G?~aFcf1mXC?kBm zT|G3~sMMSDY2eDYF-zzQ7u+iSHg*Eu!L`J8?YNe$V){+Wh8Gal@6EV`f?XeX{J!&Z zU2+dm3$WwMVHtO_=4?xovpO?K9t98!F-1q}S_MOeINo{zTQUL|mXCly5Vyy?ew#6T zElSDN!wp?b>x`RGJQzLS9s?C0ow( z3V!2dZ{16N`NNVqAmd&Fa&P9uBO3}v)6bF0hvx*76bw*g95k-(^YjJ*KG)0XtSgA> z!FUI|J#)sAhr3s|XHEfI4#jZ9^f-g5sVm}y_lnZqh*rmRXRipy<<+napY0wDTUt9H2(7l-jgq|=>% z^)Lx2;G(qEY06C~$+GJ7*+Vr(=~Y#H6;mDPI0=4WcevW%{S*t~$8Hj?!62b0LF5l) z3>0{WhYjmlfZmd$U?mEPtV&NHjaZybyR~s_p>Gs58ju2k739m9va@5>rBL3i;|5W- zmuXZ6l!2KS?V|Sv;jv5sH#cpmb*bbVg*m?Eo}>WEZykbmB87UTjPdIM%vy(v4a*`$ z0&TL(8CA8qqM$RCcX%OK^7?cOwPJLL5Ea)%ZFk@n-s z8`f~5kl&OKZ`nZ!v(m@jyZQPoYlh-~^W8TXxBRIn|4xGWpGQ2eM)x#+G1@V9>i$5o z{6Ioq#%QiPX}LjMAh)Obi&^GL(LagMUi|sMg>9=}=kkYELr$XosPwbYmF7P_c|F;c z)iS(z;QYS$jZ2$#=g#P%_N#G`tPgR{-1O|qetv-sq7%9VhQp(;=3eagS(Z{(kd4Z5 zwqm?(hi+ti=Vrg|96xIv+n;%863`#q^V;W_{rm21+w1 z^6fYa$ILfE9XXsd<@hI#F)4|c_<)X9booAjr|De=%ynGHCl85NH6{MO%mOxv3Zon##(-YqvXHvw` zI`v(y2oTHHk9Xgg0_W3VcwDbaX?22SnC|TS${SgCr-3~1=P*D150uBXGkg_Y65K0P z{bLc;C3dxq&*UNnOJ3o~WMN~Ie-!D$cqG;3y4v2Rfo{yCqJ$&HB|RP;A4j4_$A}#N zT}X6MCLa;y@d}3q!X{Tu_NIqh^J|~l$Z^Zm`QQ-J#_>M69efEZVlB zeGt|75`h_eIH@R(mWE*#@oNFcvl}kk;G&NmeC^p^xeh1g zj|*ExsAJ+@L^05LsZWEf;A`4eiOMHo&Kda6qWfNOLV}HX6mnULUk&FW$nuIxbD&DV zBRgn`sKUe*2J4p-sMSP8u$QMast^mZ80qCH`Skr>;Bxn6{EZ>pMVE$aVo+13JuwGa zgVH#!9t9_Peg5OJgyu*)7vr=+W~}L$lTAogIclgY5{i#__p2k^*pG?-cCGfwPQOpSFyy2fFd zJYq@@JI|vIyjNOkY-*RwE1Mo5Z^WfXMg^%qX4^A*KsHXrE6LZMy)#&K;5c#8ohM38 z&$=ykuCJ#Vn`hbILCGY$+B3TmzqzpWgiMSIG?h_ksCYMiBq8PjX;7Td4e3b=Dv;&z)G;&>H9wnC(v7+J?p z2NZ>%Caiy;&7xXEW?`U~+#F7n+u~jvk;vg?Vlwh6*^N*q>o_Jzo}6fWXUN(=a;^fJ zj)B?J#Xuh$kK8ng0-1%Mbv1T?XhARP}v$~qDPk0T_?zp+UzAn{YoTi)th5+Fb&95 zmCL%O2sfklOD3K&(OZCM8`ft!{Xb0Xf)ofFP^ z3S5vb&tQ`-()u{7gdo7H=Y(LK(ZhDzxRuj|w#)_-)s%Xk9x8$Jq*{5is^Nhd*MS3y z;49ql;0L7XBM=9BNpbeo{KRpzS)=ll=|?-{Y9ug=74_@Q?@^<9B;^&34McMh3N!sU zb?b{KOaa=d0xhYv)m*f~!nNT)*OSrsQYY~#W4Lv*IsDkJDizw6D(XInCH{(xvc|ch z$O04=GEj>_-qL;dXsrNo;uKmkDdkXpco0xWKqa%npbFvks<^5Y$_dz$QOR#|P;S?q zn;Iw7f9IvFKemPHLf181o+Yv?@tt>gUE}%nN2@VsB7D<;$5T@}q7m@clutUtIOf<( zRfa}1G1Dzjr2X6c(X9MDc*@P;v7=YpA!})e-lPh;NhWf?fmb1KON~qZ zR4f{iY_iTY-j~(qIE@D=& zyObxWSb1}AChlGr18EZr2Cdur@7mt%og-Y4BChaU0pL*S6Jm#!r;nEhQgfKi*%`{R z8XHp6+43^x!HvtO3~#NXkRqVxuqi%+OrR&%e(2%Rb()fy{Ki|5{n440mQMOkg-4(2 z0?E5$_jI&USFx3LufS^)R=K&=8^z~ZyqJR7(j)E`P>QO_IH+qaTZ7*UPFrWl+;|S8 z%@@v2pM}wQmeN0oN+YPjS64WGjp%>&sZ<)kRK4X^QPD7Qm!tp=Bv`kCqBr(;pROV^ z=sJ(q$DJF$C!Ve-iJxEMsHkd0ls0YJw41X36=4WBzUdSMOlM$%W3w?Q__u4c-vi^} zr(93!oZcpD$sW=|L#vGq_=FtxGU9u=E+|^A(ZZ>Nmjz>d9pE*dMNL|tlUN{Rpx&)n<>(Yl^bH)0qVsLsN)35N~T z_%sv(e47iM`E^R=lw74&G>p)+2Kj-=#_@}6_-djnmRN1lyJ-^~=6EBzCQa*}!RIfw z5zR*DzW$I3DIl3!7ZQ>XS`#g`TME(T8?81Rl<5(bu2klQCUb4&40;F|*-$^+itba` z_EypR{;p;+TC`>08qa$l?)UDR1`B-9gYABopPO87CJOTf=#gp9)WIVu--(KVEx(6$ zxvJC~qfGT-Ui5l+8drh#u-Kq_1FE=sL0a z^X*D#YD?=lPd6JMRtV-MA0&#FY$67%c0Z36;7uI#>^CC;dQqQ<1${m?fI0LQigNgs zLhRR_@Tc`#TiteTiWe5V74a3Qe;{=jSh-D&64@}my_k}d8F{pzA~mf+XHUwtVDa;( zr8DuE$|RZ)^*LdKtGenmr3xyTh^swo7PbdbBOe@y&DJJxH)`pbmE2ONVhj`Y%v!`$ zO9{!TPiry0xmU9-t=jS;m$Q4Qn!Q_*GaK1KtBY7u(tTBwE|0qJYq~%+=(7t`DC3Hw ze&V5>-9M!{-?u$5pu(-E##A*?;jJ{r=PJI$QP8+l=9Hq>DBvbij}U=mocrgPm30lo zLA{aIouL{cY``g#YuucOv-`IOo*{Z2k8B^|b@QL=TsjYLwnNY&7=3Z7_1}uemzoXW)cuKT7_%#hDXa#tB zC&P$X7BdrQ-v5DApp85dT@XV?M#4!^(GhXn;PAD7Wx}AvSe*KBzFq1?vW5 zlFCR&*86HueR5dqnbz>;fr10=E~xw%Wa%+8H#7n-XT%@5X^c>Kbb5vZ#F6aX?_O`L zSM^;8^8xM5zUORI(lVorh#HhkAcRCuw=@Y+*;1Y1lkm8ZV$iMBjsvL(4ravIiivRH zS%VBmHX#L~mi4V&_`v0<9`tuG5ijiUPe@3Qres*`c^Zro%vk{H#qdDhrbn83LA~c&F3ATQhb1Wia4_;0f5% zQ;$=tt*wNAcuMP8r7z~P`T?L7oaOEvm(*I=RGPyM^EoI_CMu0H+MJp+a~H z*&w>ECZ#hojqKS{Sf(ebG(kP+0Wzj;1D6{;vaK|CpY-IT0U30<>iJ;T#^*REIJ2iOD2 zd!{2qmdC}rAg=`t-q^2&LYv6pX^U{XR$axf!^P7fl#ZZb+@y}o&ug@(Eusp-*3Lk& zg?wNNckBwNW`QFJvUZqlq`18w3oM=sueu}6B(+~)VaYVja#o*IowO);Erij?A0Y)K{M-GY+p#J$HFU#-|JlJs~)ClM}eU(k3nDN}2#+ z8-KH7f?VCEB^Z0SUm?Grn_D`TVRxQ`_H`SHCzJxANngRHm(0lF<9{I?x3Rbkj-Oqx zLkmjU)u}Wz1ggrKO~|mUu-{Z$&!(a8WCd?3QZ7-kB_d8c@!6;hkLfHwkl#$$kF!S5 zKe*w&{ed)N1;!Nr?pnw6Da<8O;e@+>$~2!arK)*Ujl;^iz`(&O`z|=>qJ1>?wpMvQ!>{d6|F9P+cu2JkRNy(BBeE>tA-pWRfGE z#xSD+GXE`U{|gV*qx?fxBpBs)crUFlKFVQ^{H&f4Uu2T+zlOa_*4Tgk7~~{FA2aOP zg28V%thg9!(h*1H-EiQokPW;RQgb-JIq|pxt}WwK9H>(~3(p*y@KtkkJ~Y4p#!jwm z@x=`WxE7Q%Zy2&!IgT%h$fp}VIL^5{O_*+#VR@mL#R(HNe)25-ICIYku+3ZPW+r2ms9GsE~S$sb%kr&&h3*n z@l=d)`7oaEr8&-mhz8oojr|Z&_}gx>HsuK?R$*jn1rtII<|WDrc}zaE3;z zW9-+clQ!U04GlBzAfkH9~ak-;^FCy%J>NJu<43= z=PV8nx_oMb#5htSANi*5Jhz{UoE%lsbToVXc7ZUPtT0pe_+NjmE5wk_Z2LV*7Xr3Y ziOhH+ZF_>n7-8D^f=!=@KD3a9-m{}>gd}{p3-5fo+n8d+=`#H?x^aF z$vTZMjh@lltF{MAu^?r+uoylP0uyz#`6vn?R?KX;h%i|6q$L8*s#-{mFc`n4ANFQY z!p^wUk&rgxSHG$^0uG}(+WNO%G#xM7%caIAb~><@0xQe#d)SLW3|=(K10Qn5a^r9Y zGyGzVV(90NY}OD|)K#s6>g+GoyY~C6cYB9vk<7v%K>j#1Tp z6C0eJRhmP__f-_$NYJ#}%h|xO_fq8niH_AVZ9<|2O4z;WQ&c<8;A_3F*RXZ zJLnW#0t3apOx`x?Zc8C9-!8fV#V$rc7CYiggBg}nJ}+w06sm>T-&2;AdP)cYG_f2Q zKrD_S>BIKmj5LxRE)fuTGLcNjJSujiyn{`DZo{Ub8&p56Ig+XsP2Vy%jJ@wVk(bn9 z(@H8bOxk@Ye7HO7C7n3NRCbLx!lTZLZ zMHYVHVy$eH4yYR%sKZH_HjqEiRig6&lcRLJ0+_V8T)bD7V4Z3Ip3rp+&!%aHQNh`5 zRZp5qXOtHg4^VK)`8L(BLUKI%y@pyNUshiW-YuV;7DPZ`n2n2v)#BCdmq_+wPB<9i zw;XRGdnxv;T9wJk4Mdym;xFexJPlcoJf(&2yPn-J>n_yNZ%a-PHI~ZueI^vBTi@jj z;Mc1+rc|I?`!Miug6g}^v?i7+(cTjdg?~{~0;mdH%BF!)@F813e*8I_EFD!R)E>pFS+U`Sr{m% z_2zZj1jQHy*`w)EA%R=LKah00JLID6TV~8o8$RD0WlB)V0Jc-|g7>e_*BeCDinWae zAoKQxd7c6DZo`~a*3$!)7F-}x&($euaBWC(L>5Xok0)yjxte%Qnlg~H{&3z=XIOd3 zfmci2SE%J|ek`vwkMET?$TBZtvx1u%-~JHZkW>;1SFGHZcy(wUW{BsxR>fdEgG}+x zyLo^Ng?$fj$l7r?UOL~HO0lP>R)BfJS-W5K7(r@&Q(F^MxKim#eilG=-`Z^qIuCD) zy;6gTFFgC+Gg{mg`aMO!@>x=hQO$)A&Htxai56b_JDcGXlmTdwVZlTCzc54#D~2$+CvE3U-@!lM+;7 z$0ll^)>8$&D#nv`t(JA9iJENFl6F*c^&d!&4cr_&9gQXAM0R~`yNT57lfHAyP<#)s zsPv8aW;YpsGRw{a1DVzv_lwVqXSNa#T{8SdZ72LlYGS9Av)3r9;f^V&bOwY5m`G_0 zRkKxk=IRzB4_$bd)UwqTcYFKo#5Iq8pjDr5LxxK?Nmq5Ti|OsBHX~ehAwXX86sIZ&1NLNJ=(4O@WMn-MuUg~t|YoTiPHb9UAM7+ z0yvn3N1WEZCqa~;%mRPEC?B`xu(-^w%$tRJn!}`(! z;GSWNBxv6!%7xnQao6Xr3Zm^N&vpceV~*j0%x$yg+<;(nm`zG(c6=&&H@0 z6)n%H(TJp(Z0gpvSJf>lZUs4Sc*kF}Bl8ZaMC5})$i!+Paok|FkH*q&PBRWG6n5>V z*Dq~6-ttB&P-*(F9$u=yyD*)4nv1=BDXNDZOpA{!-Yb4oB8;5>sb0;&vY;5YWa9}V z_fm23E#XRPeCi7_9m8{ryACZce2z<>H|2LvG}BaFv>+$I7pXTap!(E*)O6qj*c2s% z5xL{F-g>XrlT)jFmU3!0`Lfn`f z1*(dClV-(ql9M2#-SPcho5Xk+6$mXM1ha4;_LSfvw*d?WySppVn}4pjo!V)Xewa-` zagS)(njAIjIPemx(g<6lXq&O8pzDyjS@Cej0y^=DAEY_f;WJW?am7d)xnJ+9@$Nk* zZ*VVFat-ntD~l{?ctMKvHW)f%KYAVT zu{xkpk1Wqj<9U^`l#!Z+R2>|dZ^s-ZBq0Hq9uV z<6FJs2HND4zLANTe~acOy=2EM=>Q5wF0sDULjCNSX;tcIByb_koA#D&Gwvh`h7vOD zEx6qV!>n$q5@}jFuF(?`Wp8_2zPfajXIr=f%@PQsbP}KW;AU39oPNRaP;IPoYBu1n z=YPt(re=L5x`A!&#-gJw6s=l^lHH~7fx*XklyaWX9QV9w z8Obmfj{LkB&_Eb45E}j&Ps6~dNz|)9S%Z*(%=ZN~=0r<$o-kz^*qLKNON?~;kiKoX zVSmL1{$6+W5PryB3brc=fh9ncU1y%SHC!n_^lNO1qU#=hCgkf|dKI|7yihxi0Kq_( zLktrhd9D=AR(==cm^EG} zfQc0aP`l`!hGw^;D@5V@C5beDZ2HkE`l%fOoWCmgW8(bvHiyV7tI=1*@b@bof*ee# z#<6DaFB`8`ZSk56QFU}4$=?F9C>c=<(&G}<&-jKlTnY=DWmLZ&?OOrqb5_tO`em=W z4R1ZwHz}Z2qZ8hM)s>h#A_7&P^%M=SqLx*7HL?9s)fepdO$98E>@xLp`~uyr!fTM* zD*fwBaW{E11b-lP%gI&Pv^ZY>6?)EO=BZjY>;h#OCV=mHSic`5U*|}d8Wz5CHjjz1 zkJpcxH?8mpiYd8Op<)`4w*^`uaO{T%P@3c7D5-XYIbuJ(cZQfiVhrYBk=nDXRHIFg z(e)ha?Xpf14R_);X?PHm!l-`A%oPXNfI4#jn|RgJh*<&tj?TyJYBEgm?PJD$%7_j; zDd!6LYAKO!Y@6aa?y{gv-ORZZBJ}E<925XQ6(!_}SBKW%urL|&YGa4 z2{ML`9qjoeHQw#Ud3+q&K-NM_ZtEMo6Rtq zMzic<;$!U0V+Jd>B^upw-i)WG*#NxomY^J*N?@0ynfNd<*V)a^U- zOwCSzoTr_bFlJ8c@hZirPfjEVN#qmP=96I0PvfA9h?M=PYMti01C}$B;MgiDjB44p z1Bra+nb<$UKX6&)Q}BsyvkJ{?jz?;j!9f$a1djV#hHo>IQ7LI7ngri>JvmlHyc6C5 zXC_}oQ^^&4A)46pE`a3t6g5pOG6n=Y44Dpe5GQJ6^tyH56VIDaIwqJTTNzbu@4$JX zzQgxAdI_E_Gs|U6RV^w*vvTp?$7xoK$SseQ7(+s4I`Xf-D4636U`vcIV>e@mm8tqQ zs+SFWvoC5S3|*!tYi`}`(6y`vhU1%(rpBf)t#1%Hb(-tLOpjX{8g}t9>ALWwQSs!x zIUD4VAJa+yFK-qyciN&Cvm1?vwkz9LH8Q6P4l3vvh;!mR_2qj-R>;^+>#{%h#qBwc zO(VjTwNL0IunCic!3hlj=qVf4B)_B_d~p|9TjiaZbvr~kx(+hZVq&Z;%t+KF-hw`V zu2m($)Jpc*niGepJ{Bz$y37JV$2+xG@$_6hAR$N){6aNqa>To9pjhc@k7oU7qagp? zx_wnoguECi1=>m6CVk&MKGO1SMqCdtFzwjvBR114qayRf_JIYq;R^e!aB`}O2WpnqP!f! zt=ev^`K30Gh7b<`hRVCctPTz{9hlAa(`2m!1@xd=89N~j-8D7kE>YB*wjf#cIUpCv zv%5FVv)F@zI1Z>c5OX9>czrF9IIVNJ%|_p+{xlPuS?NhRkoYv)PaH-!I@dZ+B3jOt z%cS2SLQ84~9J4s^s)(pJ6^h@qwC*kVGz>^BI1#G`=#Pl7q3p-EWWIzV{4>LLf)2qR zDgLCFlBjRTT8@~AG4N}b(1#PjoOO$X8h$lR`d`-iHRW( zNU!Jcz(d&t?+73o>E>saCU?cY|oo zZxYaT5h}B1&~Z5lD6DS7BZ69)*1;035(kK|L`tA+ccpRm6crN*f@m9adFV|e+IAE? zl6PT-nM3ciwKJ#@No82zt9VoE?9us`d7trT*I!l4kT0j1J>g3Ar46rZ628PXHbgYw z;~qHdb?gKY>Mo-I(B|fiJz_dTnQJfPDClAg_=JeXbj;=3xzO6{_>fVAfoi-nz-&{` zJAh+lXf?c!Je`7{1rDO%Sl+6{4nqP8Ker%Wa@~<;g2c+%TfEnx^is5Xvjsu7=p{pt z`rx=dOU;VJF=(+0GH|Wem6iLa5^3QT5R(4K2n?S6b3tP0oc~Z0D!e> zekt$oB!0gn8ar+5--8JL_t5{hhob3A6HrnP6@ntO1RfR1qW%|%8U>3Ql?aFeUb+-l zTF*SMRJv#a(vAkccAeU5WFQ*?Hhb1g5pMEH zN#YfjD^^0az_IZO4hIsRhj)fBXFpB%8k3uP*UZSa5+LpPf;a zTFG(C39~fbsl>G+zp54GDy(<}mbB*0 z3nmUM^vAt#yU6x#t?IV4yvOdk*C&eY*`u1tPmJaAH{;SQi5e7mieWSXQo86Ko_C`~ zX|cu^s&bA8nr-9Yrb6O$1{u!kR5)lj=U^B846yFpbt)bB3~$AD#JTu^PTn1M(VT%Y zEd3=VGjuyB&?63?cr(o*ikFtlf2Gnbahrz+(~icz@vJPWwdrq*YhSxTFQ{owe-26) z5`NaJlF;(#b={R;!V|*j=~-PlyRvj8sgWZT({BpUPe$1qyp|Ub_<{jnZ{WqizFQU^G`G?!X3{;K0SD}71G%p}VG+#?cE{o~*x6qyZDXLNLG z;;%|UMtd$xXWsFwsWIdvGbWk(4)pk~B~7HN7Qs?N1HqFt*mqVdje((tpy+TC6-V!E>4KO zl~te4Dm_HCeZ1m>*lj|V#Vuld9q-gl!6HyACZkzdqD@BN)S@I-*CCByGEG z{Hn+o&3#$$hKEb7L}bRgrYqIm#sZE%M>j4X8oUv6PHr80=ohFgvat$=TZdHrAMJf- zSd`0>@E}n#3KE74DnW8iB9a6g!oUy)P&j~u0R)C1L85|^WQL&RoRj2?1j!kOAxFsw zNRHy_0q)+t_w3zg&-eYnHt)Z2ejwfCQ0gXR07gK$zhQ%XNmgrU^WLgGwF1PzJg&!q&Dz+F8V(lx&_S~- zy8Jk(Y=gX{JR^#Fbc||DmmbKXVt_&2i2Fj?7@P+rG6cPh@-L`Hpdgw}W2~9>9dAFI zYb_AXnRDCVz4675j%yPZ_2#cM_YzQ4Qg?t(EJT?n#5>G}sU&AzUB5UEKe@A|M+8_YV0iMwyRTIoem6DrYavn%B$?Sq zxR~$X-8yNnDLFw1iL*(2q2;F%QHh_{nK%2^WHnR#esv!Eu5@}{%>DH|?cck^>4O9X24uN&#)Nwxm<)uIXxen*Y$pnS}i3 zc2gqWTRj4J^7C~+jHGzY5Hb7%!0U;VO>Tb-ditvpGJ^KA+#l*phL7@81WL42jjO<` z2m3TQCpbCSQ;<{O!4a{P7~P4eIGm{U8rExgckz{_3AMoLJ^Gr@Q5k}^d6^4VVmg)A z`bQUOk`xYM6`0(#r-#N*%7oV5)Gp1;vG4Z^I-;}g)YNBiSTF~cRwsa*mF^UMXvG`0 z=7$kIl)~2MbH5d9Yw$7^Js>-tMEj%%M z_N@@Rll{)E(TSTYX$2X>`L<5_ez|;hFk^dS++|TC2~Pz|nIt#UDUO&`jLeKcD6ZoB z!C@QH_7PtwbfJ8?=g;08e*2LV|KBCdZZoG)1Cqaeo2zO$*@hKJgL|)=XO0qd(8)ixZ zEn&RPQ>IW?tA%oWTTLz$%GMmaW@p!@cGj(pTKW}qK%a}Npg04{(W&CX;+&UB8%bbB z0?UYnB*Ci2lSJT7CEfjyaE*;eNy$DalwIR(xiX#*pMn?zSi9mjEr8#%;adE!Q=mr~ z(e+jE2f&5f?UM>)DH=66ZMl#cE0#j$xoe9H5aw#;H}%$AY8T_`00upd6i^uBTpa^} zk3K9njfu%nchwqN6C##dzwUDI=bQ(i58fU5R_W{P$xfKh<1b=R#vXy|N5=Qw$ysiM z-&jW9*Go1NNEi2|Rxr%jp5L->y}qsD@8qOP958M8G;KgrSloL|FK>*&Gdmi|*UjBU zwbH$4KG+DzT%15Ik_k}^M_GARpc-;?bh*bNMwUx*eA z;!otiG?OdpQc+%eUr%)#F`>emVBVHB@**kNIFqHt4l9n(NZzv^^rGxB`(5WS?dfHc ztSQbGRx){zCXmH3$tsT2l+mo0=`%@8Jjnea8ymF-9gzg5ndvYnB*l`dN1^U$I}RA` zt*XjzS5{H;#X6E#$?lb+WtdfmVd4BxNBm?`TVQifVH{@V7co6;v|5JW1k3r2;#;8| zj>zp??M|KM2dnlftN|qPF`?g=G9smd7DDlq>AQYq0sOvU8XUNF#k-mGt^#_}w;T1|U3HNLEPxN7M0 zQ6u3!7v2WAKVPlbSg+Orh^S0&jeR+Tf?owM8)LWIlxLj2t^uKYw-IJV4X)|!_Mi14 z&T7Oz0TCAsYU+TS<)%W5ksQ>PlS;wOKm&9siDu}zQ$KSx9~U`c*#x_Vag^n6nZa^x zz29A;LYldE<6O~D=ASAX+mcXAdXMEjF-w*Yv%&9H9-Zfm*5*7l{zSzKkjH15l0qbb!Pr@eL<3`SmvGOdPLb9__jE=mM-Q(B-&snZA@Jgz2NK z`^%eYQIF`E#8~GO}4Od~vEF@cZK4_9;> zMAiXqm9)DBMHBQq)B#mZM?|rSESS*~62g{X zGD;3fg-k{~4@nTY5AYI+E4{7oR;<6tk{hfEX@tit6E@wc6&fs8s7lX_v+A5%n(?iU z0Fi-J^r`(jvVX;P2-agug$Rnw9gk}`%fQC z3m*)^Jl=CUetU4x1|BK5px=Df-i9k8{p>;CXzdTcBTIePD*4+}70NpPRY;9C+Z*9g zvu_q*cy@PtRTX0icz9wB6W*bQ74`KjE0xV-qVuBICjpKKX-1fd^G7Z_R`@1oHn+QF zP^yK8Pc%%aRaJ!W_&rxDs*EQuuX?0u&D9FpZtT;Gc2qABMY9~eg}{EAyqYz0 z)6_%N!z@L?W9bGTB2iRZ;>98TQ`c_+?#Y8W%6G>ZL)ps4z^&*2g(t33hL&Q|l$r)N z-wCw3zSnWBnXy416@dF2Mq{y3+(Z-15XFQax@Z9-xBxPr5bI??K9{1OHbEqTrL7Bw zjWvWQ8@6bYV9031Y8D`VBtF&`OQkO!PgR)qvUWU&T9cxfU05`C(f)IvD6zYD2aJWA zi1zgOY~3?DJh2WY=%W05D+-?=j~pp}2SjIRO6)#!b3UX19)x9F)iut0z4y$V0Ac|#; z@f4^L)z397&IvtCbNW=xRe)q?#BMt>hDq8?R8(wCCd7s(7M>p1LELQIQUuBFYf2)E z*{6Yzn8FmsCdV-SdY5kr`r`7@vp04c?(M9CYzD+;3zAJXu{zYv0(p6zT6tHYvNF4y zy;Gfw(ZndGrKZnCo3TB%lp zttEP!bGs_27oMAj1}r}@$|p2Xhv;Qw{=&3A%PVu9`)t;>cUg38fjc!4&wQ&V(uF9< zOPx!sV+`Sf1s;*0;Kr<#aRXxhjg#@QMkct{6Z}mNKg+em2k0t9>oe10v4M)i6oYFb z?{R&Ced5n+R`2b2b=_ahs5s$bDAxk7p|sjNS2-R>^w`_>&JI--3*sz`F@^`*a;V`# zpL*2Iq$VdMN0!>RbgD_Pr(mZy9udRu*x7yqG%MY=6GMZZy`Eag@Rx#8cQIwXvO;wM zNMbxS1{d>LJ#d*wCVwkml8>5#`k!=xEwoK{Xaf3N%O9 z*4c?_m2OvN31;Ax;w~lN{C5EsL#!f{3~j$uu{?|H=s{e-HGVvutgMR=j6r*9@RI20 z(19Sf+pk25Q)&dEhUBJuQLq10m`8Z1X(+0NN{T7@(HrkP4~=#>tF`?p6u*vCzC;Gq zGJ5@Y_^V1t53VMq(VgGnuPPzGzlYf0VY(cdb-xpz^R){YNeTcM5t0;KElJV$w<*$ERj&8KC z7#z{~6p@krwnT3G?6DmdgS|={&O;uNZxeGI(zxYRhL74gcp$bdf;SdQ1wEE4uMy*l zh;~RD>ry1#gk?$MfLGJyg@BvkWicNCOP`mk4Gm0K&-&G*qxs+I$j^xj&2cuFjTfVi z1?h#y*ID0Grx$hj5VUtSa-U>!P9eMhgSmiBo1m$5)_g>prqQt|nAk1t(;kdsdrkM3 z4~A3BB>=P4HX@0%>};_2LVdRDeR?gfi6t1^Zl|U_!sSAtr!jCrvxE7liXuI!O1_8) z3R@Fz#Op@yCBFPhj077EUm2F@m)M5SQws?xN(WS_^K&}|C3N)CL)-ET?DlUIS?oD? z$uc5Chh(sP@5<)W5?P|`x#2FvzbUc0?o_+%2k##iQdA6rV?)Z{#+Y@ee^NAk$36D; zZK$Jb=3O0X#@$3<%YLq7jDN~^ND9SX`H2EJmNTJIhb6wtza?);v;@nlf{Fz=)nE5< zWg{XOC{@F-**%+aE66S|hDr7@OGe1Rg8{0~)^@{O7Q5F(j3wfq(9QNHSgfzjW*rNa zLJsuqMDE*K=lRke<=N&X+%xK^3uT;z@4>RNttp(y_aTDg5<)^m6NqdZ?3<%)nv~-7 zkS!j#ib^8T`@CkPUfp6NYWncL?~u&nWjQ1JK%5GwKyc~ob6|jYZvryGO>wXf3kF^)NFAPz8#k#w%^B-6OA}Ms!S+%ack_eIdgpzsA=mBTCN2O7eP`982l1Du-bX2wQuuC5v7K``-GOf!=+j}jjp+SNKOX0^8rJ92#a}(~1+9YQ=F5hmDS!F3q7| zAJXMyM0E%kITI}XQ+d|Tv--}0`7%HK_y+)07t|OJv+=~ShU|}@MRKK=e8Rk|k%yj? z3ac%b20-OmNp*7t>k0?htU$7s6F|Qmc%0xSuIp~t^}7TEg>Kl6IYXQjkn){1!&^yd zp-6Y(+PH|Xwv|lXy}3THn5o&bVQ!Kbo^cI}A*#}fN2M_plxzON2?Mrdbv?ek2XX5r zTEqO`d? zTL~hRgtX7asOVGOWg0Eb?nk`1S-Uc2?WSYsS^<$jCLoh)Gzo{%7RGRInoN6ODhS*&mAZtBa>o{^~Az)AR6+#=u|x z*PDNk#Ll(uo!VxZ)`^6nL)ipN#q_c%X`t1ik_Is0x}~FSNK(kew~fiuVMllqoCnII zVt*_-G*VrU40RLf*t5xs3^vUd-Hw5NH?D~zTjGQ#K?y7eV4%8?@(H48JXbN;T)GKs z*l};YP{sFj3)63=KLFvSlCn?QZExuemggvxu0a~f^WUq7hAmwiTI#A+9!azQGT61> znozv_+s7eoz3e6A9T@tS)-c|*?x9@I!)fPAL9u3idh6Gdg6o13Sf=K<@vb2=jl)eD z!w_SC7#+x8Zz{@Mw>$l?Eqp8reC}gnaVC5YyAF~ z!2zxIkN?U7(YW&F%Ky#7tI_?>{@Z_W;)1W7xMF`*C$84tiJ&~^&8+CmxUjjk1_mTT zTX%wyW(*5XYWJ`t%;hOhRV^7MbHzpL<^>`(2%MIg@~B_>rh0*795`KZopw%R8^taV zcKahhcqR68#?AVt@E3P_uYdnC!?@zi_uUtN5VQT7*PE)Dexz2`n|~!+n_>@z4Z5cSJYURIu0+mv@$hB{)&1vF@H|r74>prHZzDK$ySbEY`tj7 zr}Q?L1M0)v171(0W!iHYMh}4AJ(zAkT2Sbx=46Xk%<-Bu^)bPv?9{xn)Qj$~H7K@1b7{AhQ$=U}g#NspUjNfh_arU1Wh4yuE^}*A zN=JMWYIE76(!LD=T^j7lYj@wQJsF{e`S=~Y`vG7RX8Uuy`2(PVPk8kJ!P=5aV07uS zI_*iXC?`ao@#+Noz0z!9I?k8)K6-{mkv?EtU=aU5ex7=r*E!7Ks!)Kfn|%VuzPff@ z$ctwGhgGBsqcH>i(SQ{ayR%`Z`)74uDsu<0V-h`|Y)@)xZgovd1lE!2WgjkX(X|Nu zFZsVimRr%?4p^^r6k9mAngc#)07kC(PATkh8WKLIf;*(i-NI|2A`T;2k_fbVdF!73wj=2tN$H^!0+R{u->pH5B=Ci7jzJ2(0H6<}HW3lj=e;&1$X(+F&TVKQF| zAOV!O=^)g5M_P#af8gT(-zDdW->EciS#YGRJhzgQfl;9e1&ufnq+UP9{tZw|0|XQR z000O8vSLPEZG;8sEBF8a)-(YC6#xJLcW-iJFKuOHX<;vEZDD6+GA?RxXY9KNR8-Hh zH#$gE5J4mlL4pWKlrTsV$vMX%=V8bhh9oLE2uP5ebA}l*isYQr3^`}X2#7rY>N)S8 z8@_w)TkrecU2omZT3xlPtA5qJr+0T%@8)*qb_qZrCnYNdKtlrn(0={_ZczYn02T%& z7A6K37A6)pHWto3f_wMw-o5t-{{bEW=_4{S(nlmD6jY2f6qNKp5)#^HwDeDym|2*~ zY1lZ~o^moiWq$e>2pTpv_C1_?MEC9yJ*6O_c=}(yZa)JEaqf&@0?^Uu0Cxz{&CTNG^=flg#MM;>+EV5*Ecmd47_}jnjhLpzl^Uiic178 zAMw{7K4AjI=lnz`NBe#K3*Tseq5rI6Bm7H#=gv>>7%RWMU-vH5Ad#+SkZ>e!<0+~RCp&(oi5xdLrn z^i--J+?@!AZS|~xrp(~&7hKO9NcXO`31{GfsGid{%ia?LaCe?|v|KUmPm_|kF;#6G za$!d8pO|#_)=oe4ZnK00HV89vd&_0hmMhCDq{kM9u*Qw4|94e*MEvtEIa*e$p{_)S#IrWuDeXpnd2}1W5z|^isXwkX3 zqWuxC$Utb&e=Oytj)g}h@oyru@Dmg3Ry3EFA|iEujLt)X5CXq!rgu(T>fDNhy$w-~ zBU66A+Fi-}*WI{w-hNZreXHM%LH~8f``<)uQoLt_gW4+YsE=Z(cbhqGOpBGt@p8WM zDwyUL!1}lx-&@hZJ(-FOkc`7#uFuZV#7$5KDn$Fzuat#*xh8`e%EZEy;$j{=mE}$5l zh1IKv6M{uMe!?mJ27VL5xBdNmUi;0hu&5htKK<0j4^Q4NAfpzsrv$G0$ zde18UP|&v3kUNE}(+)2DC)#`!5~gep&M-@>DRuLy9rXLk6H5;4=0wjGI&uMy$E4F! ztzNNev#>L`j&Vlf!yedQhW7N`l{TM5-m1(mq~O*@?T;ShDa*eFgK5TQa|)?n&K{ z)u5pKNcpDobIl7Sm$=0xuP~$2bX(u3#TJ!ByHx)|sH-VbwIPoM!o&XmjC$nZevlz9jJd zq8PkhVfwtFV(t1!%ytTSiusqkv%)`cH4SE6pvF0k6Ie5lG`swQj}vF7E@Hg0@k2Bv zCW#;b`r?w<*D|-Fip&@6{xHDV5DHlR<0jfp!+xO;a=0NR@}W`|R4II)Ox8l7Tcv#YiyY4MAvf5H?re zM`_dW?&ZCY@Wej3-Jx#Vw;uP?@?!SPt0%V7OF7TG_|P&q+s+QbWjTA{+Ok+fs#3}nWr8O<5O+wLFZy@_~fmhx))d#R*=*ss%zA!KrROymo@}5 z193zw>U32J2?z<%{G6hEc*(G5wAG0+9BnYvboJl z5}%r9j^{xz*L>r73pjo?&#DH)Mr$LE8w3)*&|NcksylkoQ*JXgW0Es<(OoplS;&9n2-b7eXKiK9xD(aqKZYBIg z5-%Bf7x;bd`EWs$K(*I2`7B4Z;JM$mvN>Esuc!odx3n-}pMxGZhlcNoAU%iIa?JaY zyTW%fKA)}`Dmv_yU$>6y7BN5VByP+)df~-#Op|pw-scI#+IFQ!^kM*`$XGv??yVZI zIVShZ%Ny8TzC1762O>E)zH|#8fS|b_J0ha)I}lXpC10F$IO$zA5{y{nQRst`x}P`C zV;bAqofqE%#CatR8edR7bhaa$>eQh5{LoEG2Kc=@Y_aIjr#8Y9CZ5tk?3^bqz%rX8 z0XSZb5f;l#mmlQ?WieEKLcLiFiNK#Z4^I2+!WyzQ z>g=iw&1>D4c4!zBcP=O@bYo>%au3y|jU0m{aN@cIodgPWV@?d60J(+C*dX*G=55{_ zK!m$u^Tc?ljalaXPQhq;jO3t($M^u!G=tJ+&gbu&Smp~FrK=Kg+t~&JE7;xcGt9ci zKBwhr2?zvADZTf^W1VU@2;*Qw?9cB&I~&ub#`+a`#m&+d87Ib%o!&d|J9t@lVT;P0 z(TWGK(Z1;*$VVb2X5^UREd#IjxwvXi^Cy97viokTU~u7=xKJbgE20$3Ce@*>(s|ZSnSoqmjq~e2t0eZ(Lh6h<#wU|vOObse2S{1 zj=j^kq`H#X^wqdzk{ZnZzo=0DcLvMwcD!$MQ ztc^N{gG!w;Vnw$`a;QD8Yeho#U2}8W&@rs@(ifqR1NHw+6;ni(uew6wx99d?KX&CwOxi5r!@{u~Uz<}#pCI8s;d7nX<& zBTF*8XkOyYG>`QLs10a@F`Gc6^3P*E#XoIsYbk=|@i_b06rP1yRmBK3n@WS0vkF?3 zJWb4>a^*O=iw9AU2NDlGE@L=E57kJ8r1L*OViv5365D<^LvP;XE%^4H_@TOVd%WlV z{P&zJrSLE}#q%S?v^NEAv-=LNPX2&tOm(9Rz5IM4=x{lJGlOMcGfs-p@&WqL10Uj| za^wq&`#D)PTE~^j2IOu$!}gEkmySXNMMZ(G>5iUOVRMCCW=?F6=YZqEUXy)M%bK*? zP=h0yz+&2vpK)D4NQj8eEkMpBz5g2H0UzDZ_wJpQ`Cwqh9%Pn%9u5NR zP?ch712zbk1O=!tJSrzoEw0VZ{cZtHxfLyX5GX4%SC1mA^VXpoou1z$|Cc=zfh6J|=NoJ=6GovI%Ns8+>kOkT3N0&*%=fbb6s*(8RqMsw?bUj>wm)*$5WV z0=+(SGE&oW7ntcoCH4`6Ijj;&)1;);o+E_W$=XD9b@^ICW>XZW%Gd3xN7be^tB!_w zRJS>xA?(;Y449phON(2QKYEeF``fpGe93n;Mz?@uZBe1cTL2#EXcI@ZJ5_vCR*E1r zzm7W-J{Ce5X>LV+VqQW!bCdA~l2OZvgy_Qj+_bQMRIWEF)9_=^@VbLh@^zMqWtN}! z*hHH2pIc^U?SGCL0C9t2kW!1fB90`*NWSnJO1`ao-#Uja?Y+SaN7A_pl#BL$wvoO2 zvTfMkqDv4S7Per%tAd#_jSn2f?hW&}oaRDa!~UsPQ;I*jZIP7F{fj;d?;WQ1t9X0( z_R?He(Nk{*ui4$r5qs_(sPcrE)@eiIb-PFx854-LP|g)#VqrQpE($1fIo}d=zOz|f zvwuD0z^(iV5ggZX%#$XiBJifB<2g|J5PSFP=Oat*($m#8&q_;32vR}FoZWMeFy^7Y zuo0He7F(MSfU$PZk_@vkei0G3wkG3GfY+Os4PiuXtquux?-*9sBGTfkbPvwzs_o+&@{-{p8vREcY;wSA2spLc z)U4;4!OrbG@KP6@d8hE)kW_6{W4fA@PwR!%!^>qyY&t%GK*)qP$4u7+Sl%~_gyk*= ze$4l@AB}vnj}!HyY`H@%+mE|yAGRedcYhi@rDJXl9u}|4pV}|IHu9*~?+jlr8W4P^ zh;9knUTq8JVDA?Q9{gIz%HD2{gu$n)-q!63n{(8*gQbn=kC1h-qm-e;`*=>LQ0r$&&Z?9LN+B?TGqS{hQ$V7AZPnNVZiaB#M zUX4iR&Aj?izRVZe+|ojU({aHh!ACSIUDAYKWzr(N7KRkzO~xD<9AlHVgUQBSD%|Ag ztVv>+!yM%Iv4I^{(UWnV`wz@!3I*wH4O;K#BGvl7elT|}FR@~#d~4?tj$;gHPDjzM z!@ig(a&4f*jr}^^IguXVulzRMov$`OLpN-j8qAc^6|e#pE($pWqi*b?+WNcenjDey zs1IwXSIaca1)$-_kpf>gQ(9XiX$b?liGW-STIxU#Q=A;CsArmNVSLJ9g}%nbs@M6t z>1eR|C=a4VgD?Q#GZ{{ehJ*x$#LNGzc%(YSD^4#h0HJY?QOTSh5#n1W6dE?MzK&k1 zlNVE`%!#`Xa#2DMBeF^?G<-N2XoS;_ZUM`BF@5Knvj{tp;c>MTLHjXjUA)N9Nz0U2 zipp*DU;(InJ@7J`YqhA1loBznc`n+Zq19w%SL$YX*4s5b@#?(0r$e9obudMM4B&m& z(WYTfD9fs5^|h$oER0b&zaK3y2ye?IW>|oUVZ9^WSv&1qA3j&immZrP8@tH}JP#}J zi9>CZYkV7sm2lKq0g=Glg;!cE9vZD1-mke9bSg#(e=IJpn%iD=FsHA=KmAvfgE9z?s`LF+Igyi7Y8x%_~ff z)@D`swy;^PG>sTXrN*Q}$jMl1G_~}l@0#W1l-JK@&t7?fE#SS33h~ZWg9}ew?TyC_ zIydWFQV(ncxMA}xF9(Hk@C6`b4g$*yYIJ%c{=ug9Tqtmh?Tv-XB*uFwS5jwFEgpne zOxE`lY`mD@)R=d3w&fk;^3`tV@-4CHv06RnohlpB%#Zi?&9S5HN0!FC!Hb6P!?n}$ zg?yVHA*r$v;G(VjZh}vYixRR2=7#^YMX@JxH>yfGKzm0Bzyk znr@u}A)zFx;4J>fGZ>8#F0GrC7ypYVHM%Zfdi{gxPoJrAvn5T1Mh9nZ9L%3wDm%m= z*XqQ@wEDE0ax0}jyS@&9EtLmX%?qih7|_T{?Z`17JnUB_4`{n;VFLsa;7W;o#hj!= zM1iX@iN_GJqsLT2>Y8m%QU23{3byy5*H#`!u^@bwD?PoSbLsLDAMSfr$fXGR+%1lW zJ@R7PfG8Th?HEOBe*f9V#{IJ9e(T!#l$L%u`-@X_d|?!EqyBjNN`zD^y;-Us)R7GGDa zdnVAve*GnHzi6?2LXQ>NRgApYp*zaXFn^M*%oLo>Cv}#)rn7wSoC=R4c5OxMh4PD|tUW*xx z-|Z>eRHtUOot1}EStO%VU0HEoU3Gu7Fv&M(`?v{ix|-wkYmT4Z>*`gRqw;LDV+#t? z>)U->-G%J4lxJ{^;EL?UCdZq6z0AJs~cK7`R{?LEC2t(bcxfLHQQf?Ta!~ z@y>rR1#IPwgYeiuFlnzD;Ig;SL+6;aL(iq<5sk3#to;YRAOKuDUNdGLnZ6u&lIn_o z+#>N`7>fT?p{i06mW{&{A~Q$r=P2z3&3|{)EQ){z^F)A6iQlram>Kq6bwyxz(r&wW zSC(JO)wR8u6^1g8bgd>zeetU#PH7fl5jAJ6Jb$y!vUul#`B_1qTPp^2@2>j6;kUw@ z_rL3za*z)`l=$EX$4zB0YklK{F_kGdwXfuyzq0?Ol^$*Dp{>=!RSx=r;E!I6$E9x% zUs$6BYQ-#{2&#~gp?*SJOPY)By8)9n93y8Ty?lMEaK zqS5Hp-X%X_1Z_D^-U8MQL)a!ogGnpB$2EQc4cm6L>2TeYmpk{UYk!L;djjXxzd6CM z%Xoi@;m)*mzcm$qi}n94fQ!Ip%$tGXTL4QSSBZKktkGcMgmv`ih|$}4zweaBaUGpz z$ij6R(^8O^qjDWjh^Z*=ZxRc-V(@Xyac_{}UgB}WqluPl`8~``R*as;O)TVgw5l={ zwaA_7Sy(b2hYBn1D9Eor^iG+mkRUPrM-8$6QTYF%g2o?#gc#w&ONsRSGZsRQ53)NB zYVqngbmPC-{Et4_%Ie-9W;DLwxc2`7Ot$!Ct!}~@NX7lzZacA$;f%jX{_Pi>)89(P z7{9RwgsfN8!JlLO@a8a7?L5n}>fU zYy9c_#G=?DL7=KM0nn}fG%@B-bN=y`KjHxX;@Pgw8`t2hAE?Ih-(+Gd+4TMxb?~+Q zuHtW^o(&1%m+_|AZz}skltS}qe*@J14d+SH|G@kgV9cl{oMMoqwWm8wE0t}IF3De0 z#{&`J+WhXyn>2t@dAyQrv;4%DPS)t`!uJM>_CG0#e*6@ctHezAbyxIe^Y6~WU)2Af z@2R@WFP*7ZPm;RlR{kZ<`_O!@i+}KCP6vtb{RbdjoMbZ^m+)WC{%@fF=D*i}PZ)7o zQkc#y;H$8Wt0Grve0h)o#tw!>o;nLSdR%P7V=1$5oMpXp5bEa=b!Wg1XzadzAp9ca z+cO!#>IVYfh-=kK#Tvy&ZUJ`lkU!MMRb89F{{5*a%0urDNh4DDw_1u^SlbW8Z|dCg zf0Lq7o({@f;RomQQz^emfyDU#0R8hoSvlcA-Z$f=8DTvV;}rAk=24NGj4eOj7v~lo z)Op|k7H>Ls@5+A1A@ggvX4r2gM3tVG@R995wd41%iaT)i3-bl1LtGoJ{G2AMljr~~ zMpbjLNP_=!f8wxeJAe7VrW-g@zi~)7+pn)D|4b3qo4dBk-lfb*#fZ68IUx4k^2V&S z)nw!D?=0*|4WY@uOza+)cId!nPQ66)V+*>3}i0mqQuS_%M%pkox@| zvP_Y~y?s;k4x&#hGXxIS_RXD*OszL8X9%--s!)!e*4;dM78f8=osB4L-YBWwk4^UW zmSszk*iBu<%Zi$%&vR*a6NtP?BoH`_1zCZ>^I0gE<*=>QHt}}ch}0ImIyNsW9^VT{ zHy(%D48HSna|l%OVOlMGu*^5<+_@So$*U-g3~Sub>7h*zR84FGqSr2eeh7-fg~4GS zklB<;1j=ybvV@!`DYR|aI5Ih4^d!{d`Ac%90EPU<4nt+x*)M~t2J%YJ>JF`n3JdzJ z&7FYnnI30abgYI;lUy7&u?*JKsn}6{nRXN`b>;hZK&08XL=UCD;6z`9MJ$*S8qf6Ksv$4m981!*9(X_!<=JI`cH>W7+_Q|)u@Y8UL4j9 zTq~)w7E&<$EXMNmH=~GrKtx(eAQ#5=lOa3d!IU`xHpej3Mk)@2wrM=YxanxW{OuiS zEoe;J;$P7WtCIBPcjF)N=wK!O6a2ij%%+QM-mPJuo!;|h3_ahmN&M>Z)HFc`MGmpd zDrTRH5ZIp#6sYukw^nE0kFvx3vKhAP!>K+c(T#=Nba@QLe_~(86hIqn9ygr%ZqYyY z$spg^6_+Yl`7kp4ykuc|qA?8Ap_y6vqnKS| z2Ln`j)D0qEeK)Ar^i1Eu)~w`wp|j@r_`s|vvu04J?9QvHV1XgF{QzwGJkxWjT6L}7 z%ITZTRDHWx^^lM9(tTKbeCqP_^VBcB*y*_M0?xCX6NZ2TZmEjDNy=eZx)U~)LG zAiKCYIaaK9$Y%aoHSfFE9m`jG(uA)^-^PtrysCE>Lo)4)pul>Pu@p~f-G~)?D?^ww zP&89iFJt&p`9r%!1iOu99ID+GZTK1~1Y6EuPXt8>k0>fqJ*(CL9YztBbx8%>o#0wn zg1e&lk2jF+VuhJ@{ScPzd3i;=V-3W|QBjU{ig9{8^X|Mda>(b6&Az@pHVE=DJl@TN z(rqX^Id)rJ>C&cLMW)Zg_>QZy*pTB8FDJY}=#F{YDGMFD-9I~rKGn)E_%$DcP2s%4 zDA81(J5?-`anLK-?}Oj9So+{M&wg0`V428Z3#5BidxSqs6r`8`P`^cx#sK>6QzP%Bw|wYUKmA|7F{eoNlfg>T+Cwz z!jYU?fUF$FRlC-CYb&d!aIEaYmK2@O7teN`3*+eIO`th7Zb&O?#}38oS>CES_m~*3 z9=y*pEn~>CW9FDY8bBGqJ?*k8u+%8am6*4`Xz|(tN$J}fg?MQFl*Y)_GNEBys4APn z{ZwEWCfiMbBg{%uHEr%&U7j7a=u$PJr4ND9h-(X7ctY~Hv5z|FL=GL%f!{X!W~EIK zQGI-4w0m;m2-ym$~O(LwrF6N3z0&D=e7u3XsLwSIIjN z8ofbocz3KPhztl$H!Ua?ZltQ)OY{hQ16`V(Pb-I&?j?}UQ}PIik1f!bXIE4zlV z%vhDVVS>yZn+R6LkAVhhLNaX2yI{7kJ(ybWIluKf5}M~(H%3k_sY7;-uazN{0K(cr z7rxQ`If9gRT2aDq)Qiw!8pw=y;f{OY2U)ExaY_btKJ1`=g-xqxUK3oeGfFMo5cjik zniJco3)xk~@Fq35BjgqP>eTg)#)o$dnN0)jyJ6ZjiNY0u`2sA3&_ysW&x1m!jb)*2 zvcDG9HRz1Jz*yHCN!2K5-D6e&A7a@bvaM<*XUsE?bmK|JS=rmgNOdpPflkE`T1fma zf(8}M?>#r11wYBm4d**aRVI4nXZ1rtiDm_8UU?M|ME0gbL1~BrrI1~mf|k8%Sr0Z^ zSLQ>|$&!V)rWxLcxT+j>7a(A}$I!qm*s91jVP=lQJv^M5E~r*TWumjMnFkwtJ0cjk zi2!;YvUERqvUk3XV83y$Xx6uz){4FIH2WCk#(r=xJB&ec9F5_g6D92*IJ0j#+HU+v zF=pVQMt=ZR9Fjl$5L+-Bs}|ow;FI2jtp!^{ld@A`<%q1j-5g|jVn@5JT;)=}6(;61 zrkm*W)d?(I1)nnD#~O9cD0<)Lr1sd@5na~9dQ*^`0WC_%86U@=p{^hwvjm!7)}pQ^ z{K3wAQuEPzB&7RZfWq_GcXd%q#V$3`CPB=~f>A!d2u2UfeH0U~k1J};GGJqnEJs*F+%vg(P0Hx$;rFgA4ei>`%jKZ*1x0nkyw=Iq7(9_a5d#jR zg`bpd=2kPJsR4xuf2fhJ7BiH2o*7n)D2_^3$8mQ}5LM}yahLL{cN!mf>=sp(U6Gk8rFmEn`aUXP;)(5t&_5%W;;=zkkUEgYQx8eA}L0I3qNqsUz1}Ctzwi@3l1&r*w~|-s2WdHtz!eF z_1}(k%HzDhzg}%shYdt`+&eX~M7bjp*5POFEILov^Iwm(W_^a|4Zi0Z{Mm`Sn;Si> z$w=z1pnZhue5b8KftSk$B#`@Xk6(t|1RsbmA0_SOI;oY6u=`LqV{rE!qCk!Bd0~BT z9~2wlGv^Atk=;s6zy6+yoG**B%8Th5)K!|R(@5PR3gqp%J0P3YQ5 zX~dE_o_E-;HYQe&z5#p!eo{S($;hZbsgNE^PbJZ|6wn=E_NilS-J@7riK^us@>N?d ziIsVOs@QY0erQ_uYBQl5&yJR~IY3zefHveZfW|7TS<8>I+X$T1whyY7D>9?(1gdR? zaqodX(Y_A2yR5+C8E_86TTErUWF^|8!Ez zXm=~8AiF%PZhU}+DLJn>JdbTC3Ay0RYaIKMjEsC3oeyQeU3()${qaX^xmHI0n{m-G z4L6I&5>LksT&{G4hQ5<<_cq+{P+R%olG{A@(;mC96>&LawTC}y`IRo9inK$Tb8hJE zxTkG>sjSNrD7^2@F!-{*99P*Kq@*l7x_ox~j%oX3+DeiP#br0({^z@MiNqKnKO!1!2I-mt|dX|>=CHNL4 z_gg1yT*<#Ku-z!Pk=GRLP!z4buaIQ?48#=8=gE#(pNTUo*Jg(9vQ4UK_OfnpTuSBD zyY#ZN-BI8d5W>1M)Zi{Si%MfGk7`ZMhxs<-RgTGOvu1k`h{fd1H;^qEr2Abp5z+AO zMKW3hjw{2brQsf~jpRt-L6^HOm9EB4%k2WYP24JmxqG2C)f4LA zvoY14!7Cdo(?+Sza&2p4m&%cs*5qvNGTVmZo->q;3!Bo~ddO}``QD_$j~eG{Z^-)} z(BY>81?Sh(YMa;`kQB);!Y(wqZKM=|-0DMHsiUksLhH>gQ5Gt?56i{#FT-~rR&-2~5 z#Pv5+L9eM{+QvLF?W|LldsfxawW_FPc$k)IpJhRMvUazSGtkEK1C@CyUaXSii#tf8 zbE$qmM6Z}*4kS0heL|rp)oguXJY$MvshRqlK%b#X_poqC77}*>g@Q8jfn7(nlzjuq zi`L9`nRnpQ^x6BZ(3da7R=Dr>7^$%_u3Fe$c}RGkh^(j?t!Z|1)Biu*9wT?N3)>@mRucZj2bO~bC}RhWXSGr z^=eCND$~C07E&U*uS(KPWk%lb?H{<8 zJ#H|@X8_1L^^GCVSu!lISy8*>?okxpZJKOU$+2%c@jR^`_<6lTYfrul)dM=U>4%)T z5jB;IiY<~9X(%1k-(dUbW#>sqkZB4}d=>ljuvB~ELcIm+yIhsl(~A6q{44x#?@U`$ z8dJ6eSBSN2=>9rXj1BvzcOd?QIC}PX9NifYz0&GI;UB`9{IMvi{C0p26a?4d^nCq~u!H(x~UDk4P}{-z>1&h)d+e$=)1E7epGo22_b zslrbf$e)T|M!x{_e^*$WPH6wpPWcy}{!ayxc&3@FQJ$k}$^;?l1 z`pf$Ow1GS9Ebj=i;nSk|Zw9`$nLSI%__gy`m5{@~?#toc_SXivFmzL%^g zriRo>*0-^IJu2boxF_)0g}`NlHKq}@RJ|Yltbfp;Q8f0mo5WiMy{TSGbg4>DqK=DW zxzDrAtA(?yZ$)$0AYr+!={hU6PQh|}!b8uP@OzjtHV=V)o4Jej`6<=Z!^3fXlUzYA z%D|umX>M(gaQzXnVOY|Qe7PausYSN!MT=uQU&Wcgye5OoBnSXBg?|7(Qb7!JEs$?cS@J{lQ?ir13DD4v!^$ z$0KtwREu>7R`;Iq$C=6snb_eTA-_;srMv z)7R_x;#IyHKh^y0#JNvJB7dj}UA>*<_Z-D>js|}yYea4{h@A)=? zr~K90*7Y0NKUDrM(f!iJ50FNS3yvL)OSz2SkSeLay`TQ&wdij)#AGgLF&#t;RO^1L zG;ePKIy>rP*Sdd4jQ>UDZn{M8{-~NriSQ%3F)I?Lp7P22)7?MxlT-8;|5CRne=wA# z;Tg>8zx(-zR?L|lX6#bQ)^{(9PQ8d5-M8w~_|w1Nl=Xt_JJVISnmyMy<+G^VQ<&}_ z@Bf=y@sCgW-?W0RydY*d(hFaxZJ%wp^jT?{fgNXr$$YK-a;G^e*Y$&~%aHzEh%ku3 z>OlUkuC79AmUnb%{{}7=|}do-0IaL(UyL` z_OQ{n;aWp!$c38!4%3h4`=l{Q--(Q?(6NlNBawG~7CvYH($0TXTzA%C(2h zYNSR2pG!jMubD+(oR)VBzh_1?RIB&n78zchKXrxui8~1A$f32z(<(sFe~DN)q$b zX_emB>2m76_cK)lmuO*?nt@i|si9#I;0P^c(`H%!^*;nD^dB|Iy%&Io$oZ;|V15{mDt2L_hKjuhLyuoiM9n=vf_A-2!li^%_C#Xe;`w9rY*i z-ai+re`l5GE8g+@{i&?@>Nlf79ukrxlQQq@eg9j7T(*N-?-u{cI?KOZ^P;k?i;C9M zv!%N66ggmXjua!@vchC?UfD$jVcuSp4BWNC(U2Y&nI76x6Q`EgTYzksnC2v2@b8XX|ddj&ihLi_ueHoc93(}65fS>mBC68QNV79>n zMyHjKdR_wj=f?t_W%gV#u{gb-!E6U9p7R$WUjC$|HXFnIqTH8L_XIUB%-p$?8}>^| z`5|rbXV0PYOAlNt;?(DJ)9^Mx`=|mynYLM-3gyC(@P2NFwW1qkyZ(j)_eQhmv)tvzl}43=AxG5OrDgx2HEwfN=o;kLY6)t70F4paLZaI&|64IQ1KO4T5~ z@#D5g^E3?JO#y@Wg+)!HnOi{B>Sh!nCL6dTk>$%pWu5vw(D)&6>lB}Txh(+S!n-Gf7o)V$IqwS8au68>*2M|Snlb@``iR} z$;FzpG;a(M`i9<&uNkMh-BW*)>^{+CQ@+S*@BhS7M4`)^e#8Ixq&;KPsuj`Xpey{z z>?`jFXR>1B+*p|f0Au-m25RQ?L;F#m6E76yel>!m@xqIzD@mx;I{R%uI~rR!SK3Q+ zr?20AiHxBR*fuPM_I3A)3kMPRs;FK@YbbjO*z1hobG<9+7EV58FqCue+S&D+1+Qj( z($?l{tWFQhkNVK^9>CeP>%awB9q(XAnN&QVXHyl|wr^6?RBI!$@bwi4kM~P`IOgX; z;Ic`@VhDofN=U{NWM{q95<1V**NpWUd*dAv&KB}B*DH%b(z^r7T_a;bajdyR5mg;sJa|MMM|}gc^La>^zeQWkG;ZgYZTrPV2_scm zbb5N1^)Biz_?MRl=UfH5dOOMIrz%rlDO0cChfF%#uSs+SLA#+PK&MnI+>LESfdj;< zS$BtnCmHOM|N4Rww#avI6&wIb+LprA8ByYNlp$ABl1})H~Zz)JvwCohMR>&1ypm_^*DB&*~^<=AztDVqj{iGdHKOK1v8wGL?MQMml^Ggh+&xAodgX^BdECOxqK!Xzx|+L-Tl-cx+PgvsmJnl+L~?Z zuw9+&g!r&j}ME> z?b&B(752j@_dCTDxCR(*!$lU%$wGZPN2q2#X(#uXyu5aF_9YMpa}fU^D_v-mPqZUc zZ!~trD?rxu*z-z%UMCz?3S+81Z4$3Rgk74r9pg~%^gTzE`3n8ZurlwIl zVar79-B1xR)EKSRPmrS<5EZ83Q@%;GVJbkU(Noe}6n(%>WEbT{S|VPhMX9M-Y;$3_ z`M{R=!LytP1^bn*4RbSJX^IqQ*{5qX&ifM8P&<(Pym~Uc!07nhU?Hu+sH4J#I{;H`OrX}m4Xs8GMkT-zysao)J+gY_4CmItqOZS z_xY=5-6MKiMbJgCGA_+s7qN%ZCD^K`4GLAEP<^=LbVizG<@c-(|6R)AMkYHoy`y5i?7|ohb9jx5IDUT7gRlS+yL{4mE~0;nb{v|kAt6Pm&a)p2fZ47 zJh8IrJ~K=TiW`$v6|}Uq&zw_CUuOGDc`stvzclE5Sk#<_lw6={>7qdEy zk1xj?3PyiPFcv=`tR&V()}&s3?eFrFwpP>jCebx!@2Jf7Zo1NeqUW8nfY7p zTq*~*`1?VuvW&kS#1bYX(X(MZKvpRDi)#{F{9#CvenrvNh+}4^nUqtNs^OT4=UDI@ zhBWK|Lnkm?P}sAgAS=Iq1Z---<1{@F(^6)2jh>L$vpH!>a>3jSYky=OYi7c<_pZo^ z+N$bMCuNqr+BQ-p8Oc_CTqVxz!`WjVfrmbzk4>E>VBlcxaDi(rTHk-e=*kAw;hYMJ zE;P{y5W~3hz%&1P^yJ+Jl%G*n-KwBqg4XKUl)45V#88hn7#eyc+yF!)qgtP}#q8=; zhVvKiDn2jVAJL;r&;b**MYavObm3sE3N4vsd2f-C0sE4rvK_fSt?n)8B^}>{&GeSL zTN&(@*IipEj%Dj@j;l^3=`5&r)F!+h0>8=Nf3*c8($JXL(-hogDQ3wh8XD5_!i#=f zU5{6PBy?wwm}08Zr0hNwz(l@ZoA_rKK}@Vkpi;PYnP;fs>@!xlm`&GiN=M831aqVZ z(91@D?^Ntq*;EGcgk>iQu>v(<&8btXif}Wps+XgB`d;WE7wx|D=x4|77pOfRK3Uj{ zajJM8BGgKQ%(q31V_Dj8N7|++aPKZ?Ldgy2!cl;y8Y^oiD|}3>*Y*4b#nfg7I<9XV z*@ca?HgfmrtST?-&SRffo=P-?E;1A23-kii7RN13R(l9azY$4{>79~(zNqY|afkf( z%^LkmTl17_6!Okv2eWg6YL2bdT0vX|Y*4XY0rWge{bxRdGYRE_#CDq5m6PiG7F5J; zS!12J8OqWa3AatN}gV(ut@u~$9cT#g<8>_!DIi1XAC+kD6a|uB; ztvI*-hB>IV37y^gE6_LS?H$gSU#87ygxu*f>s8%l;Jvkvh_(8VNWGnJs|nm-u5_*D zTEY`~3d;9;)TqIXtZ{UK?nkv-VQ&itL+zG4lDTF>q1YxTk}YjC6kz5$ zVNl1H@UAZp9X9T`?;YUP>R^c>#?b{`230xiZvk3*i%SjOmOVQmDR;-29r0*av4ubv z@ixUzN{V8$i?s)ZqS$?+-St;sYlZQ_>;~m6CniPb`C%85$E$2up~(Z2FIHUF5}GhR zy$EHeXN^YTicD&w$dA+5VxQ8-zkTuHOSg^F$n)Gya*vhfK@#ulX?sI2&$Iqp!0;_V z*}o!|HD2?o)4nxvqFb7nEH6%-?oAxq`jZKzbf6e|H0JABJ~{cpSiwogzMyQB15DpE zvSFb(yj>r-5J^kmc{mJOX%=T9>VyfjQ{OqwS!x%he?<@7L9yK%~8Nt zbNyK-so6~UEnrSi`P-+p7N`EIJ;__Z0ad|wqvLeAAJFGdbkbp=v|tfUC%P%o!Ip$jUu)P1s>+=@@h=j^&qS531k3Z$j4I z=<+#!k%J{YXjD}U?&g7P40~GmHBLBgyqWK%fie*;<$ISxP=uL~R(+mBIjL_&ot_PQ z-00rksq4s#yp?+m;Te?R!tEzQ=C9k_d0Y_1vG;=RP_k0eVyE8WZf-o0tgV>AO*40? zo^}XZWKhw~ix5MQ>MIVthEDXwAI8=ap)vm;>JP}pT}QBmHnBCDWUa~P;vuSQCRUlLz{82=2f zT0IY4jcM~d1^RQlB8yWuSi-PcZU#Qs2_%2-}1&()d zrRmvwQD$Uhik0j^#84j^29sn`H=QR!6*!Ei)zoQe!7CgOSBfdpSWe(0ZwIUhPF_w* zV>-ybQU%vNe<1yVe zrG_9--f97LwA9uibx(9q(7K(Oxw|tJAC`|L6_#+8cal_z+2lc_IrgFvkG7D8uTlHy zs8PVD`UBQ_W5*mf0NKhjj{&q^St%oER>naoj_b1uMla1M}iR@UQhYq8fU z&i$2ZHvS(6zpGqB{O99w1Pd#KvZ;s$wQf{EI zR8u6DAPu&MYpUMfDmt$|k(Q!eqdr3_h1a$AWr+JUkc*(KDNRR5h4{l)Yk4D01X@Gw zG&z7S*z%Z659)7K>Omx{XI?WTDlVp{qJgzvn$#aR${{S*B)9W)-&;5xheHd?(c|e1 zBlOTYWXOJ|Fo0qtqa=?x9=#PqUoWF`9;zVb=1X^Ouk!Bny3XH6!ZMswbAU_zJd!qg`G1zdskhno6kn)@} zDA^w%SdwBy&4=JvH?QYa)leN*8Qt6GgmrAsE)dZ@mhZ064de-StO4+QQwxr*5zO(p zSATjDUN*eIg7YD6T&H1#Ys@mXid&+62;mRf)LnBt4fVSI%0ulAhFJ2=pqlU&f?(80 zVNqSY3q3V#_u8fais+oEX2i*t$?bMT9)xvk)N27IoKEDBVr{NU0g|t)Oni3rB$fB# zvA{E%BMR@--h*@CPr|W=yY7whAqL6aYCdcnL~wMPix19K`85@gQE$xb2D~i6j;esY zo*zNmM3bYMZRz4y@9MP6t5qIgQLD@Ra;k9t5fqibZ_(n4aQz;@X8kr2iDn7=l753U z6(8qi8shw(4+;{4%VTlsAVs7@h7v_wy5dHwr;oaXYX#pxs!pJPE=3>3h%eU;@!aPo zlmA>`xR^$}F&)yow%WB3ID;JbH&F}%IQ;BCW!P=fR9=)RF8Q6vD69ny+qSCR84IF} z&z_a-2>f!ivZ@yr+z|!cCAq)ja&Yax1ls#&^rK*NkgP5edI}-s!Qf$}TejU#RVTvn zn3>eJVj~>Z0*i{>=nk2 z-tR9!2%1h7Eb1%T628om45Uv=`-2#VC?T3oO@9}GQw=YCLmH%9T|lW*56`Awp$ z!Yip6p=Zvn%0H%@pnrtmrau&K+duD%gk39t#(Z}-BF`V8LY^HTlAk#$-noZqy()6j z|H{of`_1LqvAzA&V}Jgy(`FHlZ{7fse(`@vnKe`Oo-}{Fd!R8Fvw#xTg9E2&EB`1vyxq9W5%^7q5syl{z&{^mzA%C zqVun_#Qkp&aUBw_#tstd@LHD%1_0R5?mc_*uRc)YJ0GZ8#hnlI`M>!GgHLThhwthJ&MW!{>2;pt!v|Xx})I6k)J*J zarYR`ZUtW43fSE7#u)#r98~pw?q9k_aUItq>mo)j4_EOoZI{;j>`e0e^Q5=W(*DxR zBC+BJ5gYOx>EgnF={6tw&;_dgWRq8UFrK@4Gt&Qd)?C*-jC|e8`Dbzyi~nF~*{Qdk zVmWX{d<`OJ;3@E-BC2`}pS*|=JiMJeE^v+~;@7CT(8j9zh1;3-KYrP6$fUAnQS7O3 zJ-=OZZyKHa>dNg;Ql9}i%JHeni>8G$U z2@|W^w`TkKve)a=JpIlR!Sc=TULsU4>W?loj!my_05r8XfKlo3v@DIq3znhlXoZ{; z>MV8Q$@+#HK*s8YXX7Q8*9{U+LdRzeEz1&~&<@YA z)_}-Y3cB;(SY0Hsi7$Ikp0g`-<-5&puUsk!@;NU^6RUtt$nM3W4(x}K{mCvYpA<)I zr+*jtrn#%ccxm(3CHVP2T!Nx6oW!>TRwnrWYTkrE4Tpg(D!(=@xLzMmx;MrH&Db~M zZ*}7~4Vb5_VhVG-Jn`$4ltL_XyGG~%4!+n((*R@prMhu-T}f)zwzorMnFV$GsBdsc zjRSSE2aUr8_w9xrX=ss=5mMb-Ix6j`UoIB{2QOyIr0WERzr>Sn-GO$?`MDhNI)r&i!-UEs zMm>eC)e!VY*g?|N$r#^6N9UuWQcN8C2CO~HXLL>i!HjO);N&JZQ)vF!I}%`&NkqAxkqMeF>9?Pa!!hEMN(iV0k_#`Gi9A_|^Xj6T7!UCyHHoNPOU?EZtJzuE*dEk=uz~S#cP7-NIKKGWY*LyeFFBE$c=n8_ z^Ldax_9$O_pcHKhI=Nkqe85cKSp5?qmJpD(J!*`A(BzEKg?Nqz+a?Q&TjcA&x!r~4 zP*cCrD|zGu0S}1MK(!0|3dHExcT9v-v=IUyY%Ou{!C=9AQ<}+_p{8FQJ;coeH-Q{= z(eL-MqdD5_qy%v$9}eVQd~^4?(5+EuN%DE$_h#_Li=?r}&QZRLjv@0WF#~~M8;a}8 zgB@W{%Cu_@=Eb;cB1UBw8exC$hXt{zJvix$etxQN#0|$?eqj@Ji#1g52(>6Z#Rd6e zibG5IU*eZf6dF>A>=PT+Svj)0)3-Ks9HCs#IJU5MZq64o=)H66hvN}369S(cgd9y5tR&w2s4 z>L~FWmrf6k85KUN{eiH%0fZ7=gzLZ)p8u3NaTT!|Si5~yZ9^W`Fx{&mTp;?W z`Y?|%_`i#~zb#gi{GDiCm19{T0Q(EnnfVLUvAzT9kZc9RhC_I|HhH5s!zlnfRIaLP zY3q2GpU3@Fl^hh0K6%OSC`ex`y~uBrq7^5ixdG58jDN}gUoZ1I^NyDi^E30EihHC~ z-s`ZoKizWvO1*gcHo*4T-$wCk;a`G!0dh=kL>F(GpeJ;9ylf&v&cgrFW+Bh`Mf~?b z(%sFyv?o0IsIw|E)lojNvOBiQ4ljN$NYpuYw0P~^pQVKUS&ClH|H){EZ2uHfycK&F z@RsndOH7nc#4jm4!~5!Y1K%w-iU6bre&76upCg9+(-Q(cdG?IG(2a}X!?p0QN)LSK z=NG?=qv$3(Sn4hOZj5p9iTG7Pg`MbmN^-*8&BEg9+U-+diudF`&$+wdarxa@4A;S; zC*S4Ijr^Z6B0D^j^TOYCiy(S#pV#K=;gS32@j!awY%4VsoZmO4U^=drB>m-KG5a$V zqDrQ?SK@@Fe}hEE^G&~fF=24LZ0JF^;O3J0gk^sH@4R!kauEUEnX0~j6N^e7?Ll56 zx~F!A`h*Mfmk;O6w4c@HE8NkS%Hlq~d80 z^n!baA)k@D_`~su?b=clczlM!&+h(Z@>eB&qbkB`qQz7#>!u`&V!WMXBY7fPxeH@! z-9%@B_me_vo4hSUcv-WvHM?|W4f=Wx)?A=YWdmy7C7 zJC4<%PI_|RRMf}%I8h!DPx*4hQDuR=`LKR-}G<(ie* z7_#u#G0!akxg^_nKjsSSsAHHl>=s%DqdzGz#Za?W8^Fnlsyg3(FIc}LWe_aX3d8T- z!KBSLE_2*OXFLvU`Yet`KG#WuZ~C&Ay|iC(a*$f6u*TSt@-hiz{$F=Bnv{F)j~P~A z!QD^aNBR5J9yuR2IILE?yaa(YOR8KM7VWW2nBf!+?C?^Hby-nT-BqJl)CYB1Y|@jj(Wr}r-K5)&H7Vs`EX8eD2= znj~JHDnazuf!nYtfldlSmeEzYGZj?_zXE=T8Qm5nTg+{28vEri5bFBw(A@6TVs3Rr z{_d^D@pAFnvsN!^4&w?q3Fe~#ON`egr@#t05H*jbHv3!VF)6S~HuhhijI`Q03XnMD z)@mQ1Elc!%cC^k71p0X9J#2ZhL>8g~?yNBa7fK)=A>RvPR zv&rNJfT{CkTsI#zBmT1D6T`G#9!FNJ4{LX~XBcYM2WP3}D6m77y6pPSD%_FTF@EZ; ztTZPWC>V`9+dUZ*#71H8t@SG&H0FIy@d9nl{2Pb1`|Kla)WKj~naR~w(pTHdDaGMc z?LyoWLm<1Xki<@AYcN_3Uza4j^Xm}iY2&&xT^07iV#(=)CwbYx2brKGV(ZqeXea-L+4Y?IE@ zcU+NHRkwmGK@6G{RTgbed@);wMB~4S>K@pyn_H`-N?O(RJU1^obujoeV$>D4<184( zC7214J6)H|a+Ex!Bq=Vb_H^Qje{5>Gd3YU?3pOp7Cek(1ZA#0$T16W;tfa&SyB~;%61M7Y^rAk5?BJf2Sy?g9eBOyNJX-iOLk6#U}0o`KJ^^I)Iqf zB}x^O%Hu0+r=;$D%fy4&dUVKxd`)oHG3$jK2H@Lh=_j)E@>-qrZb$?R!?g zpe)PER#YgFcIlKTkB+G#AmT;XkNTzh!{`zz`E0orR3=|EI?C_~$K%M|YR_>aoUrFy zgD>m=M3fHhY8Cf5g|cYD6CW0r{SUR&UymD)!XEZ8G;yX>n_D;iWXG zG@7G!K-?3~abUumu+FGd;s8%bDvHYtvIIidy8IV;DNf>p{XT?Sr7TSb32Z*%P2*1w zVH3qPrxrSZI5|AwMDryDAp0VTDScl$z5yK7%9VdvX6_$$n8cGNpXp*hi<7wz6k3utLdc;USnQz zKf(m%K4A@PC-?GZUZyD=uG8(+b6k$RnmV>pq4sO$cN<(b#pqYBU#uQ7NxK~&Ulsjo zVYzFWTDmIbi8;FgKnHSk3FH}H)n~pcAk5Hxq^72%`rm-u9}*Vi9rXN)zmES^iHc<4 z#&dt-uVFCYUHp~$SNIiIQi;hRH{Q%ohfKDc{2ZByvd=E$t66%j3VhEGc7KQ3+7}(I zF{6bX@1_5!KReOWN}(ubG7;LD1d?p4{eINebnm*?1D>&Ng8E3NqAgcOu7|wS?eJ5Q zeIkq$B6^d|>JHO_Xu;-a1JsU4BsyQgnGFrJ3nEtMLG%xGTHN3qL{jDyvxsMg|5qKW z#)FU{a~`s+1$k_;SzgoEXCR5mYJP|!U~-c#Nsf$0TkrEMzwEA=v68B?h6*otW?*qf zOq=2(-C?O#ar z1y_~gMpC{iki zJC^3S+FLkh&WPz{1q}kizHO_ZONGkY&FYw-PEOfEpu+kqx=%a85oj?nF)8Ga*sv8* z37ah$3Jc%ofEV3A9pNEwRw)t~1-jM_0DK5qo5Y9Y;jvLoRZqp7qM=}WlrnLt&4zmq ztbMUv=Sl6BH+cCTRtjiH>WDh#heWSU>3BmRG8!DViIkjWhkWRPd=st1&&H>#`~oky zbby17QDeaoEFUsOX@F5V4WMvV@+B6SZ)jrC+(2?x9)!dOXrF6uJQPAg3ns$0yC5B% zj9Tm={#sO6HU3s-wOS}VuapQg*-(s%r5CUu-i}U;ATRWHPt>J-VM0cz#(juFL^p;> zBs1$JZ_bL<)4Ig*s(078P6gqa3m4Eo5#o%KTb|ttAA!#Z@kKSe8w`m1zpra|tA04E zF4Y|d>-+>jXYbw`Vi)8Xi^$irt{c{)(wy^BReKHw$%{O9ppNC_ErUdozueh;Yx=C9 zy1+jP65WpfXwU{r#DUUM<+j= zHhJ_F>&w&OsS5R!$~Aw4UnEc*xj5Eo1m+^DrdRV43-F0gLp&yCAV2rqCAPJ(&Ct@> z-+Z4;cp7V^ird&8kR%oowJ>Q(l(Z@Fh0`4boThp#k(Xnn%L$AoINsurrAf zZj1>GOUrg-hExH*w`WF}Pw?lASCIwPTE{cjSScd+IG?XjF|BcOMU4o)*`ToX1V%nS zUF5-Tr6U)`5HNFYTC5~UAPu>{BbCl?V(NQ_pY;|ClXcwAEy%~uV5=-N;fgco1`xAP zbpzNj`&nq>+N`2&oCQ=RG=aN+CR_bjo3Uh4UQfj}xIzX&2{WTXW&@Vx2lTxJS_G)k zaB+WLc#@wKyBD7sR-Qa>H>}`lud-M*+iHSEsKL)8+bAw|uBAj-Gk-xwsf!VaEDJmE zeOSZK{QNO(-L`FQl^C!jy9jqlaIAlZbMrGV9flHUPC&loN(fpr0n21`Es#x;yU^U| z-X;YwqxfN(@gb)e3EJb17_wEKVdaT9>1uzVx=t zcs0$WLKjxyU+CXy2{#g$LSKqlrJR1~_|BQeLuluCF2^dfKSN~#jCG3XbAiT+g*&Ps3|SliuMbx2W3;XLP4DK_=f z7W;j2USpHokck_>3gIJoC&(-Fyw5SrI6TjZ9&>ol!eww{g|KzTP~(0GeZZsisXNOi z;)@p1i$7U!0eJ)O}}e#~|%~ZwxeV7b68wntZOU?&>*ndcLtpMz=7YY@|m)$n5UMZ%&ev<1c4m zKxx0h`%qs-Shc68B9>)X??d#Luw#3sm;W*kXBRyH0BE6DSBv?#(QYjboQZCa&YwcB zyzkS`K{%u&C0?DQMotD+a-{?Ke3d7n)U2i{HZ`7wvOZl?lyRWTW{8ptcgb_ZAI&yG z_S{*MlkFYBB^3Rq2SW4wy<6X^QG~QP)a=I>7am7HobK7IA6@f1*)J>e&C8 z2Oy8?^TXZeVE6{0nwNm{Tfxb^&R5GW(QVR*Xv;2i_*g&>Rl`;407&y9r=)*xY~K6G zoIo_2$1un8${b(j>=E@ipD+0)3gM>P5c#Ii$)_2@{RALu^h?@^$j6YVY1ZU&zo4ghQz`oF4Zm{Wc>lrlhdOtRY`dpoYxgP@Id+!X5YAI@Q;HbMW z>va9;)1Ub)b8V}&k?I8bD%)p+3;0)4QgOcln5FGg-vHPPEzCuBaDAvg={M*8QkH(C zZNm&zxL&nEE%!d%t6{p=@T69i5%ukVn^ariz4tqqBQv465OaZOVZzIUu{8hIkq}ys z7jx437dy41Ai<$5TxWF!uD}WFWY;XW4{Kas0T5LC#?XE4I=$qXy6%#=uLVv`IOBaz z$x8af+o{*XXI0% zd0=-dR4B=cod*pV%w2nHSNoxfQZPnP)a*@Xm+2+`C^ig9F#lAT46Vw1uE0mX#v0i+ zN-FmuSIZo01I12V^r653_Ou5K)x^aF)vRi{k4v$*{QUqUm*nk0&{v2Uh8BY7#H)olWc| z9$w@pUkVHWd8;K+QN?vx0yBT;K6mw#tO&+4VjW3aso)-5K;a&M)Q!$1si`PoJ{sv{ z*(o4djk+p-R9j08r)gYo*|w!ba(`1#T@gdFz!fq@z3H(QHPFOPYLm(GoHkC2F}W-SI%0!FQ`=;)6L0? zmaU{67f1C_)Wwr(u0{5qzHS-TeTA~*a*m^n zsMQ4Wi1F3TneT)h!WiU6xMruPh`4g8gHfWJ?D;Lc!J6OeuzJzciM0lW{ct%_aP013RWXzX;Q< zoaQ;3iKBTk8n$^>{CN|jEGr~t(_FwXdyg6MSJo!jgl#bt0;%$g&U_ezK0sau-;Zi1 zW<@c8Ag84>^Lr(fsVLVaC-+zdrjBxJh*Qu2tsrCZHNI?8f`|ra1WndV2yyY5z}{!B zH`WPHRaEdHUlg>7lkPui@bfn6Fq!U3-$rvA6!=^@5#Q8S8vTGa1P1ACF|i#A3-$#e zCP!j^5~;buw7<#+RC{=_fDD~$I^Vp0HRb55?ipqs2BNXjMcgBw!t~>RXc3WW%Y)$s z3n@sd?hAmzF#5SKWi0vg-v>r7^s;Aau;)r!t+M*iJIJO01Rw8DUY&-Fp-|gr6qnS> zN~84KvA3M=U^3$v+GOMfCSaobN^lTmR2W(?WUaBdc&t~2o?0+ivE!qQaiKrP${^e3w~q9q`Q$vX8&bleXS5_3AbbJ8=|$&kS0z>2j#s{t{~-1z6^W8H0o z>|r|{*t|lkkbo%xBW}YMpDO`#lt-dKa^MsHNKxdc!0l~@?Tx&6$o_p*iqPc#w>~ zonEXuKIR;Nre`-$JZdF*T1*hTww!JZ@wSfkhR>^vs*K62a6W?ZSsLT@Z-kLhl1|=p zSBS54^Hs^uBAwHd1*Q8{EebjjR8$J{8Sz>9eaG%sb7EUqViy{zi~n+&tPyCn2H9Q? zu?(z6e-T1d+n%MwG;Y4NotNc7zZ8NdO`QWWx?T9Z!zQ^)4^4Dgm0!E4x8Gw8m?#a- z`V$BV1wokz@i?N=4_oBJ2Hyi#HCMNyYK?uhwkgAUJyxZzU610=ovLswuo8pkguF*j zJF+%f(NY3m)~2C6d{V_OuR)z#D|EXQ-yFzk%h4s_w?d9_jE+6U5`g%C5^2|{^ci20 zsl_ z>YCOkj%|DgONv@5ROezhN$NM~#9>~Qg=anwQQ3Yn>xWDz%SxM#6deE%-Mos{aw?o< zNlJf_0d7}Oe-oad5;g{Vun{JOhE6l}8iAWq&$|p}w+8AD_f(OIQvkmVa0xm^R!PlZ z`lgJ%v43pxG%I)r89~=nUzh`3bOzHO#HyY|bsU{?xVF!dYj5EDw{O(8_sdL;?K$_4 zsfr7656)yj=+F@~j_h3hc6=z0=KXNI^dv*x8F+DB{-EfxBFvf4*m`C~og1}6_mKAs z&AJv1E7nSjtC7kzym>l^Kc>8M_RRCkl3yJJQufeLh;y`8a{&_!T#>A&6GKCO384m~ z=a249fMa_t_6cy4Y8BpArDnZj$ki_)cQQ8x4P`qrYFE8)HIJ8OQI|Erj9%5r&o>II zN2lh0HHbsS-x%grImy3O68DV*dc~zD6rEge547`SFLGoeAB>gVI0~vw1=*6ltol5RqF-zbfLgDg3%4rZhx)L{#YZfk)Zdgl4 z+@lNhqN1}c0Vgl25S|=Yj3rkAxjfd^8K$N8#XR1(KTjXL&hm9Fbt%lwEea1S^kbOr zA!E{^7W3C1#n64Zh;r{C0+{(_HbZ%q9`#kq_$N-R*UE!(%|f)PCGPlg4m|D`1yGnbi|=<+7yCY8<2 z!-w3kuM`>th?kZmTyb079qUC*lS3Zz72m2rucSjr7^XKQ6on%t&{Q2gUcS#L4k-y7 zvVj(a^3(byMb*|43%;UQ=X8aCDN>z3VC(bd7;P$8vMk7KP#bTVwV+Nd3jY?E_#X2` z#3yRf$6s1O-XnV`UrUOMfnAN`C&0`csFz`GAYB!Amk~Ky?(3t&sPDmoebY>N3`|Sb zT;s#zucxYB^=Oh0Z=_T%owWi2C@2aR#k90EB*o+v)ijrOlHLb%jp6p|OAb=grRC_c ze?8$C%v4mNeP=RL(xJD>9)-@8K1 zh-@~ui47-k94X^OZ!q~@n+1>PSnkDL;Mk==A4Qc0cq15?=Cl2AjlHXGY%B=Z*DGHC_&2HkVYY z%IzH`k;LPz{xH0RpnH`rf0sGb`K~AC#!_{JHv!wRB%Nk;nCL@6slyx9+=%BJRU?X| zApw1pK&Q$p*k&jsA+y|GPA%`A(WEu7vzm37!u(34+sY*YtBXU?!r)Kq$9aiwu(&ZJ6v17Zb4Wud7E{G^8|8n9eDip|eO zrKL1q^f)xtNywyYMp8{p(I2zo^;B&lA2E$x>xyvYo)PN;%J{gFn2H9i@c^;o5mzzj z{Cngu;2O#J8FSumpTZq-9mXmme^+UE;ts<;Tda16VJ}eg1Dp4?%PLTgMJl#Rg)mX+ z`a{rTPIc$K*139CXiln&jh{VdKlwxcM+-4xiY_>2@=N8P3p_H|h)NgoOi{;u?9XNL z_0upf2iH$Rz+L%27p?n&|DPR(yh>Ukx}8jskH+lW&=>#!*dgKm%3}eY>HNZgM3ldajQ%LPh?99GxilA20fD%;6k!sNqJJ%X23UqqpXsWtih+^M*HQ>#yv&!K$1% zPYALf2B%TFg$5ySFk)E(b;0$0&Eemm4IZuSC?_vTHnyMMmkOQ>%b za6M|E^qA@?j|}M&5yatdbXe~?tX0=LH_*QU%p6>gitJj>%nAhla!6?18kc7EKcsE| z#f2v32gJ=09iN% zp80QZX#sPn?dZ^k?MiuXchy~yudw4cS{7@m@n7Nb3(!CaS)q9bch7SxDu?;@Y@8PA z6WdAqAA*9rlp_xHs=5qJruFk2bE#F~<3FL#Ks1?wlIt~_tR7%*_!Q8z|I5LgD6M$G zs%6Zb252e5n_qP#2kX95DGKJFIsrd7cwdRym+v6G+a)w*Z&9xU{V56aECOWiz*&at)Y{Ct{mw8 z{{X3g`e`~cnS!h?=;vb?Frj9APiP~gZpN~(W}b0}F-e}YbGXIWestfILpB-Pft2^V zBeb;@tESjb#=^=u;z}8|sIUZ#8`p+&c27lGu3K2}lGqvcphuuitLr+ap7x=t5^@AH zGuu@j-ZLGpiZGsK<&1UM+b_AFKTT|E4A)JgV~Dil=e#$${p57*tjsneeEQN0 zTI|<%s|IaPsvGGhIFH0|J}n`qAX|9q?Re|w zo*rr!DK`wfDtCW!18~~gorwIvtq0^|uvCNw%xN3Y?Q@dfNt{o!&Iy#>F?AenWy(%T zdS&oTV|%R&jf?!A9ku{g^o&PmW~;N;EE#ZiRZrPcoZv%LTYDif$NfQtNSyu_YUDH~ zMcL`2^GUJS+xxM{w$-he6SxU=nr2|PT2GUU>uj~IIyT%CnF!4Umf&vn@YSw&-S}NIfZDqy7KKPphx`>w{&wExi_4*w0%F~^P+NKQeRR7uqX$ynMUb6Oau-@!PZB&I#e3$L)^ zwoS*PioLErnck5576!TbAIe}1+83eg`|q8xsi@d`M*Jl1CI2X|-suCzFN$l4QwSA& zne|K%ipY-|AvPv$>3{Vy*bbY|g$J9(KY7mu&a+co9v|-!ASC;a9$dw@k-G00Q0!f2 zdc=au$#p)w>Ywe>}OWv4t*l@KO>{lYzLZ_L0s2;?|!R?$K zRvXSotS2$lT3No2HF1`lXbi6%T+kf-GH%7s>D#g#Xn{SxX);5N>=z4;!+rcec7*KT zkJrI(tq$&V7A+#GKk<-a3Cq8DVD*AKJh0mT{SpB-ze@zb8~4R%@@+h!R@A>U^-=!h z^uH%fs{5734?W{KxQdy~b-U1qC;c-GzO1^Z*<}v`w1 zO#RQ|1beq)0ZUP?X)2zZ}E=ODJlv-I&7yoB$^?@S<7 zwY1+SFszGf5#EJf2o3KNg0!E}k3njEs-f5WL?<#?wC_MS09*O1*%v!e5;B|K3L;31 zN#a;)as*K%me3Glgg~~P`AHlh;|BM|G`#hy>^izmT?ocrYUH1|94X0;5w{n-r)_Zq zsHPfK7i@;rx%zn83uZR)2X#q@9~e@jRId89O_msfzD%+a@gV?6(J~k3mvRu5UDb60 zQd0vZUQFePLC6(7M_yc?Hzb5wYw1=}l{X(1^IE@tK^cuQD7L|y*}bs^B%-$Wbn>febrZyENR{|RLIpK|)= zqf7$QAODsK@RmhF<5m;<9sh)@Uj4CO^3@+c@F;lks|4)$9qjXM;a$cp5|eOYt?4mN ztCh6w&$M=3HCj!X48~CnL95>sQ-{DaJzFjvc@^?ULrS(EKLEfS+5$>>YoNm+{*+n; z_9pTd0uex3r3RUcYS)GvK;KT|+!WlIzh-i3Z;!REwhNv!;9a%t%;C7^7B9SMVdUAM zC$w9jN~=O&OJ5Za-t>WbBU#2z4ua&41Ydr`X!bwTc=4j0L!*j5je33(o?cUX`@!9gWtjHi09ca_G*NS~C7EHnHvdC%_w)_0KEBprwZ1srS2U73Kz z4`W9Jd3k=Qa#E4obp_8U+5{`}LrHmyO;&I@=5K-o|-hc2;ir=mRa0r^%s-Hd4{t zg<_B4Dm@2cLpyr|zz0LK^Y zvxuwEv)a$@&;@)~l~sJZsq)4SV;%HrEGnVWaGv~SKuI~*as1T&aaCx?q=)d({8u7g zEzHqi(h>Y;9>G2K&Q69UEeJgHM-|pOZopdD@lKug58jIMXtkf&U6L84Rw+1^n|AGr z^9@-raTG$YI99aGXhtaajC97tW0Dfr)fes@oRrp^Y3I*dhsVUt_fpC7&6lA-7S4=l zt#^vpI^^IUXk@gjuiH6<(YVvB^*T}&nw&l{E6zN?UiXw{Er|VlAmArwJg;Q_xzKWZ z3hVXa%)JMvR;FLMxG#e(4o;p$OR@!3#lPNUBcep9Y^)P)*(5=595Lw+=!kPwjo4+> z%G*TCNKA}2%VM55aSk~;2#fZ2pG!<~0>=D1fiKuzT6j=R1CPcQN<2(-kkhl1rPhN- z%4D=R2R9t9v(hc7DZKSDZSpX7K#{J;u zBmI2o`N&JGbH;){QTzM93eJ#U{VD)W#K;8weRfZ+lDfF2$8Qv(s#?&W(yr>aJ4T7a z_Vt&~KPul%Jo}{Q9u=j(;aF-#RxjR(K;G=GWhtMv}XwFybU~Al5H$xTGt#L9Id$ zYiH)?ANE(Qdioj^Gknt(Dn71Mqw9icuts63MRGKFl6i4R2prB)K1$r`2&AMGP*(In zkNBnyR@v36oVvdZwN`+JNIt;m>n1JJ3A3j-@ZtZ47%BPqC66wd0c!F_(Ykz`ugJg- zG|MI-8~D-}g!m*#Slp~EH%2J;!r1mxRFhO9W)L>&z>2p8rBREQ)hiojW)FEzVh{!z zSva3PAC=~kU^~SLO|{fo(x{E&9`=xBmoL)tK>N;*LAH{LupjGRn6lo-M6s)~4_W}$ zb3U$NUcIS5H_EVtXP=bI-Zy}PdC%#CCa7b#YQLgD%rK=Cu z&{9!-+v%B$hVdJKi^%xIR;~Wm+^Y!maqp8ERn=aoh6@_YSj`QfBjR$lIv%|ID`jOw z59c!XJn9CZqkcLv&+bF@NeXcd?Fn&qiN#c@XaIkDUBmRc=1Bu%z^j7)W(z`nI5F@W zgus%aU0Z*b#6ocT2ZZn{_s;mw`nBOnoWpq`%AzO8ttydMdrhNpkHovZPv2Sa;e6@a zXHY`X4f<+w8uS0N{wK3!f_?wt+kBY3`n$#`z1pXrg^K@ymb%jxV*mT{9Qm}sf>d_b+V;282Z^4URXOSt+2J~hbBNyJ{fsn=YtcnRZlA0%fE_9l)M2X zfxaEy0HXOXzW#LD!ioj)X~f!oe9XYurU5(WoeFegR%HIkwy3?JDe&>q?3?Z~Q`XEi zC;FI(-!9_gst~)IzQ&w!a8~@=LF7-WQlVrCKI8d)%{wR5LRk!tU$EW)3dd9GuS=CF zZf^z5`1XCNcT_5aFu}%JPO5LjZ~rZHq>pWcj?T=^@kCG^s$#Yxpf`XW`ezLq+%p!% zr5>2!IUl~qBl|5)CKw&a3W02#lNnFhx@Pl8cn$eju+5!?Pulm5HH0e576SX#dPME3 zRaNKu@kQ9wv7VM%AtrGw51iBTVrO^{J`)*MV&xS@*Dc%UL92tG**#JUM=iEO_W?K$ zZrWe^YM^^)90P^EovxloiV#|-$)ZDja(Z`~GbuldC%vEm_+nZ#5HT0ujIy}xqi09NvM@Z>yEN5im>7AOij*-cZBGL5 zLFq8j6kymZKHZlFR?olp(v!-23f26fAU!KZBLFU8wMkh|hZvNVG$vMQ&sZ*Qco|0} zf6Dha3@^3!R5o{cv`?MFYwV}JWRJl3IIWk`C;&qn9-AE1<)dI1Re$G@Yab4KwXwr* zNZO4~t&n11#uVCQo$W)XwY4{nCu363P?yaCqJ*kUa20`S9-pQk@@}oRusD4x&8xCG zldMz^ws9U~%74x}yiLtahvMIIWl%I5k%pdo1BmPUxc4C8l(|xF<>(?+U|x?pEk*9s z?}6a7`Ns0%*OG&*&DQN3z`Dc0#k*yPI|H!bZhxo$wXf4G{MpwT2mYY(GV>VQ|GLSA ze!IytIYw|LAQm(4zg$kqGuyQ04bOl(nx$BW_8wIyFL-9% zHxqseX5Dh#qsCTNZh5Mtp1R)qjnbz>wbzt-y^Kep6PjedIa=%-FNX+(_ZwxdvJP$l zLDbWo7mcd7uZ!)W6E1gsb*$%!sRhp^+9Wt80affW-v_`zH#^<0KL-8x9jyTQ(U-w_YI)n2JngMB%ry{<(C1eA!IMI)Bel7Uc?&sXK&R8 zrPadTr>3qW6YPDZ-->1Ot7P)SXv*cmay=1-RAEDLf_`!S&_a) zp|)d+8@4NPBJmElM!lrRY#(j(ro3(K{FB^*JfmzQ^1~GDs3Al!1c8xtKqouD$%+tU$8NHk7dh2N#Rorzl=9YBet!MEs>Fugi1!P5^ z?6eE$8?`L0MzFsV;P87rtLIogWE0(FzKs-hLSC~j>N(PJByAdYI$(>3tzcK5xCgrq z(6Wgmj8BVRf+q$DsToJXhsMuRh#^R{HN-UE32h(XIh1PJjLngINYjG66^Yn3I#v^L z*a4U^Cq_&u(7ke41-yii%i1VqGDtXD!aq_01h&5C*{5Se08e;muP56xG62IpsyyTx z8g4saHeXr&&;p8Exff_Q|IWq<71Wo7XYPfc#tgJUL*uNur~BXu*g# zcJs}wc3~9=9d&7v zvBhhw9ok_9WbKZld+AIctg9K%CWOcg?9AACYWL4)4VpkqCB7$NM=y0@y}{Eq>fU71 zdroJ0^2;yIC-#C)MSG*!&5Pk4k3h9K4Fvgf5P#m>ej2x>Kzd%D6NOHPQf+K>w^Jl` zH0hXshue?7&H9|GRnfQSa}Nl?rFl01l`7Hu&%|<7UiE+yTd)OQqbcI%1xzbdO{h$t znG8&vsEEqy2>6q6vP7$=)L`Rt6=Sg)P;X-Kwu`RX-cK!@+~S_?)Hg?^)s1knN}ML$ zqA_$Xe`-~>bl(D31byeSZEI?%5xfX2XtZun4fA5%JB7LQG26V9#V|9H_0g6U3oGHp z60}1?5FXHlEwt)t?8vVGAexCesMID`ZZ?ht~fgL`91aF@ni z5}d|@yF0;MgEa1L!QC}LfEW9nnYs7eduC>>yWU&pzW$@Sy1skYcUN`Er*`dKb?cH@ zK3Y?_dQJQ!+k$z0)x8w5U^C@kg)4K$?7Qm5ynX#>fwsVq26HT)B%l%W{@~u0j|e_3 z+2u=xM_qj?s4W^lOI*?VYvc_FUfe^(CWsG1=80a|TU^qR+!=o&3=*Wb-Nqt34u$ zTIBuxb4eXAR4Nk_Hp4R2`Hq;8sM*Er*U2qKtxh8884h>3q4TnpIC{Huk+HMygN<6F zAt|}CR4GNGd~|~=7bOC2H2W(t`}WoQY&|{MthFkfl3V)HwoDz6e8~C7t_kIr_nlff zm_U{4IMPq{Y~wIx#w`2D$!)k&TNaaX96>&BI=fnPRaHdGyBN1@CH4&o3i{KoH{p;# z@0C#J&IJ_O))2P^fJ`@C^`WYkreSu}8kwrS4M_BSbnvFu)+!@gfW!x|9J+;QH2WEk zu#k7xvRYw6a+7PFZ8_GA7_JRMk^h-$KR^$juC*Ox6HG*=NycIY7u~rVM8YRZ>_wDB zDwp?Iy1xu?bU_wi_MAfAAuF>^SxriU*8aerv%I6kr@1)6dKha*uqy`yn<~A9WoA-$ z{KHi(RN~LLt|;<;YT94r*4+t`8+)SR=lAV;?g#wTxD%A7{nofk{BKU+7!g+E*%Hbc zQoH}Hesg)XwZ0L*v$i%n%U=jLEGYH>XkvL~ZYea^0IE_)8l5=(S^%-J>%Od~5wsH( zevcpg!PJW61@a5@ILD)4b*&cVpU1bfxTfY^jM?60o#@6fMLkj{w42p5EOh?_DKBq| zGjSIBoPRYGSsG0CyELoRX~+=mYdzkhcxsGjSRx3bnkdTouW z!#(r>sC)q24lmci>Acut7Pe_jiHhhqHed7xEeDfYMbDEV&Tni}ISF36qy{Gm4l2C7lTvhd|c;-C9tENC& z7^=7+g{QF<+w z*Vq*q+0#L0F+HWh_XVE@SoE_=5~tZSwkV(YWS_m$shT%;gjlOgIB;@SC=SzTEWNT) z90)p?SpKmd864s#_`Yu`LADGs@<0@N(#5FLCt7IINe}fKjKe~R2~jM=hjg~xcKB^_ zJ^Fkh%RDYnEv-+qyvkY2LJK#*o|>>X%+@kPQaIO-8nvQDW@~W@BNHRiDk*WXK3PRU zZUN}%u&ru+SLY~?1vg@rOsK|`6zKy=kpj~raFm<+jqq(6!R018cTtiI<(W`(80WofKQmn=p_vv>DyjWF_7gas56^BpoV zFFi2;C!(<=G{3lL)?7!TceEiF?7XD?MJ^qTLQm<~3Aw7MirCl6XF45M9LBcDnYValu`erKBay1i@3 zM$QZ0wfdy`+XM$x|0_B(-)(C9{@~Dxkb_|%kE)ylh=$hPb%-sBzO6qo2+WZ@lmD9kau~ZZ0T1+$R387lcYmi0qAnO2&z?v|9iU^cZ~KLvb+k0BGd6NloHEx+n6gaXPQI zZE7v-{$`uv&~Yg>Pr8_8vQu0mrJP_kPmp#Yr=)Q$Mu}J-ld;8?O5%(~n_nYhU8yFQmSR3^zJG%2@XIrh3!Wj*2=r!G!!fdgdMCVlqwfRy9 zX)X&{S$7<&6m~_`M040iR>tR?+|SvMOidQ?qLj^he4Pe#7)9X@`TK29h)h-+`e9F4 z(r241>L!;C9;;2m=!BGkMz{)A?a(oMf5DyuO=srK9~0(?UMt#BlY=YHY(x^rszJp%pbU z4Cc>4^aiB`@h{gna-xi-b%*9b&IGlAGyq>LWoOenjnvdzr-E6KjwT0pO?uB(ue@1Q zNupRXfZ4n|I+PqTprV$NSrj{~uEP|q+BT=GidS0QD?t#!k*av)%m-Xp=rYoB*uQK`v&Lp-baVPJ}_ovZccWlucj8q`&yW&LI;JZau#AZ zjUZ==Ht)Is*+$4@{p{x8eu!%?O2eF<9*sXZ(aFhDI4$8`zFTFJn4hL_-0NzhuP~dvjeHW~s_7_~OgV%)LxkC|uXI zW9dB6f&E%qkXDF)w+!>bw1TRVa@0)nWj}h(hM_U@yZ}Az6Gk}>m>faL$*$bD*?osE zpcs7dXqA3NTF9vtYt~}bWtbzpLn93qGT%{YEZxw)<1krbO~Y3*ql?$mdqKk?;(j6m zipW@NgCj2l`m;k>1S>uG<-;xN-1@nx%Q7`>WAX=$$_h~Lw12d0M18itN}0?=C#YlR z+4meXH72v7@SD1ywo~ZYf7W)myH|3=r17H(#GS69j#Iytsb9&JJLM4HM|T`!wW!6nSvOEyl0${7-L5I zp!>JJEAl8&d%{_%2NsKUlJt$N@L0Who2+~c!GaNYi6Ku`ZI#s*SqQ! zPgM{p_A5gFi^KmntMG_=7mWcjF#@FO>;qx3sAUG0+eiEtkOkefULF?PE&2dlS2b|Z z_+?jlSrZfi3h=_i^NmVPiL6LXeU?N-gV`moXQO*1uF)_Lj@#lKuG6${zmo48#XRXrj&9oOLTb)mth{hw%(gh ze^+F*K#H&eCA2$qR81mrpdoAx9>j`lzR7{DEI$VWqB-{CsFiB=YGjl z1rw^ABdU_bstC$2czL-ckpWU{?MDTo2#>Htj|znb^+Cxt$R0>E2Wr2FNAlHG){Y$dGx$uGOJyxCpl02j~djZ>LF&fN6;`46e^nFZOZBSoJOO%wW8djnQw z=*eiKAQzuJm<6LyDG=l$OQ(Pus94<`sh>6sPDBQt{BAZc9q2fqI`XLe)$3*MhZfiO z)o$;CD*4sA+Zo%;Q%SfUb9l>7M(?TpU2RkTV_RtW*PF)QRneOy7ECt~(4}&~D>w!Y zjY{pD!2>0Q?=V%*)|N@)mj9&6RD@^Up5}J!a0-#dyrq#Rg%NX9bzz z7$hAIPUmN=;&+5K&bV%df8|*%-$?EW0QNM)pX<&p%N%_A^IUjR@5h5?Yy*9JN9pQN z!>*2j*AkU#GfO~fNcj>Z2>r+6lanhQ2?{_Q4?u@4Lbir$^9w7a=k7g`b96(pk|>;n zAImO$6E&cw*MKb!e|YlawX;%n|{m-A|hZM#tT1@V2f*U90uleKvey6 zuq{Gbh!NL)x!zgph`WpF5C$AcyFuz+lFqTPm+w{rmmlJ=aQO`3C^H z$h^P}xO6|@elh&EQlwy)IgPhE?I7ijS)0#ucdz4;x%B`MG3seUgA(}Vn-H{>)xmXp010092QCjFQ#*1tG&7;)qmz;%r`V7g0pkDA7mkN zN7pf9yrn2mfmrnbIIq6%5aB1FzRlo$Iii^wWq}QZ4*O)E)r(j<03& zpammS+{iC4xdz$dY#eQzof?%AL@;b`T16NmTO60P!hgU*o&CzQXV8WDA8}c&A8}@j zc}zu2aSVrUsPyJ^5S2yvXy8003yCCY&OUAEno`S7nX2P0YoB%gw7mDSI5sgtH*x66 zS|7QM@Vl)(hcy2Ofbs>#c+KSl;AzRF=5>T+bz^UlN35qICXfDXp(#TibVoMug8zlS z^VEo@ud`vR;4uv!*|A;u{yeI(U2b}u8K?1Ve6Fz;3scyvvd3f=!BuI}uO0VL7k0maxFTYfX6CZdh-q{T z=-S34&vU(e0Bm;b34xqRi07)_l`JDq5TuzN9nTa{Qxi@uFzECuj*3e?SANRjllqo# zVXZwY2%N0j*q4!?o|=%jn6nSu$m7*;VEIuah4uvA;!PWr1^4h zG`y;;FA%pcJ%3I8&Micz_di<2Ou5|9sZX#YOW;4H+%;JIbtUp_OmWgLqaigqMR}_m z)9-`dRnXj=e(84o_;B#l1bBzp1ebsOuNd&(VyK}aIceh*W0TaBAzk~oPVR{_yM6OT zB;(mT&>1?WPMm%!nom|F2ql0MdW4eZakC?PEjH7F)CM?ZW!J*=SdI6=RK1-HFWVAd zw#oS9(RC#Iz=)?+rt>pT$zhEUrzX9Fs>y0!lR}RQ+0vS7QEt2@)xPbMQ4 zLb??VN{a*@nwnth*RA`OIle!s%3ZO_n*%5IJ>SsZa92`zMdPN~HHdBT0g7Pz&sU?vz#SkW4v66{&F(3YedACq=GR@Ba%1Q&kd5- zc-fjZc{abSY(R2jy&YB6WiD-BNjoe~NM@%Y)9+Br9c$KWmb-ALXpM#QFhXw`Q3VS;V+q6k<{^ zt9BbBNU#}oz@aqE62Iw0?!lA*0}80xxSFxNbQCK`DKt!;R_?&0*_)?5x09Sre+M@l zPE!M~>UNq*@m7VZ4f>YtyUKq z&$mz~adYE|m1m^%Rl43;eFql>y5)5~!oZ0fhT$COPA`~55DY@AjbUnu2_u|FTMBENYep|V2` zD%%c)GMiY#MU1(8gU&86OBpnNSH*jC{VGX(gk2_iJL_%O5ro&69z;SBb@9=9 z>`?I8O=2Uiq_$z+k!(^y9;B*!vl}d3M23D%-Tiu#tG&E>)`i5rHa_`m4QbG4|D!|W z*X?a9drJc@`}P5osU3Yc8S`Xa8gp_~1OaIhZQ(M6Jz3WZR@}M6-swHH37D7+8Ltb} ziQV7KsCp~JMObm6)x1Nf){O5PIlwixTicAKQ2?Z_0a5tAXJZZ?vx8)F4UtH_SW5*u z=fv}vd|1YX6Hx$jRC5nUdMa(uj`!J-w)pj*Uc+d5&rTDLyvVH>7#(EVp(dN=J!mmN z!;g7Mv^Tybtb@_x&qc;NzI&pjeOZ_I;wUqxm6I@{IB$@fyX0+BV8L2k5E|{fsZ@pe zt_hVtTx5_}NtSGmRj}4lbuO=ba_Wpuwf-XVG^r>(oJe2V#6EO`9KIUa0Qs#A@EScl zZ$H32^-fjnw3$iez&^}BQzH|uy?mFroq1x*1}DHAhCAA&Tkshov94u3OK@P4S(f;W znq5|w%up`Nz{fekOGlnn66QGk3r}87RlD33nT`YlDa-KbXS6~?z zR}DiZH;hp8swTkZx-l}4V-v)tlu7*uUX)oAzIGELztSqHDzUMMs;|{eCnBDW2a(hz0oz;+PjGLXOA*IP`ulh>Gf zgjsz6Jops-{Uxle6xizEuyRYTT$^ymQWwQH;I&cy7QDBbZ4o)CD5eSD;~21!%?o+F z0wY@$SW90Hmzu|nvD`G8RDL~UHn&KxaG)zNyDb7&oA&SAcMa9sbGWm2G{^>;2fHvHK~5aIs%LFb~r#iH4~4u2LN^6w#0Pzs2l8FRr}kwrY0B1=y`}<)s$vll`xH7?;J6$P4{=t z#wrq2O5dd!q)1pboV?3Cqk~7(iWGT%P85SlW=y0bOf|LaAv z=J#HAC61Ge`b|qY#r}jHq~0d_$MUmISA1q+5b@C3(5g$X(pR}w(8{Siy{GMtvcOBXV{Ifk5_b6n z7xDoyr@0+j$V%P(Zc)|)K(}t9ZJRZTwg1swn@N4hSXC_oMmK z-)A5W{Dlk48G`?yz;xyLmP9WOFFfL&z|8Ws8_hemJ7%S4^K%og$A?yd!sXr~h}1Mg z%w%DvZ)Y#j%M#b@Eg7lTuVCZi==$Tm0pcVeZ1+0ew9f#hAV;H{gVe07a0iRqK~xH;nmbvi>vk_rt1Vi3z3~AEWxNITs9UnB9_(;@<%x zi@p%kF!G!`nQqj5HO^1%UV#jdEcK>t?|4&10)PwdTfECBkf3dtdr+27gGJZnTE(r1 zn4L$TqBAy}%#KRAxi_a4j z<+RCiI(<<#DMKH-!{Q^qYT|SOv2ue6*m<)|&57FmtKhr=!1gy;*OPDHFX8BShuKkc zZwPPbqzFejM$y#6-auR>@$e2O(cL;Ra7GkLBm+xBW6^QNV7o_cC`h=Rb_P?Po0 zJicMzX$m~i(S~Itb2Sjct+d5_=wG_xZm7ytc9P@xvejW0R!iuKt9-pkk5(c8{MzgQ zWJ*>w3CCQ)!_WGR440CbiJAU0dmVf9u{`WANipn(biuP^PoOAmG@{5vlpo{DZ{ZLN zzT_T$D=PHIu=V#W#AOS>)Yd*G86j)q1Q1PO_$_3b)qy_i?^%j4Dp$tNyeo`ggMO?I z&kC%rUj-4}^U*iMXrmfZ5;Ia~E2nlDdXt1y@b(SHs@}>_!Yc{TH_pRoli z-+RvOdHL+>x%D)OEqbn{fayCEWU4TIxRHSq5x&l|XrEC2l;}Bq$HF@0iXlvKR)1*< z1(1D&y|*~rVnI7eNO>rRp{p5VK{(GG*@uGC+L_h#y!7B26pg-y%;PUxY@z1zqxHiy zGVT2+M|?R}#RABtwR2x(ZGF*`D|y5#WFL=bF$*SvWyS`oa8c=CAt6C@4n0XyDLMk= z!NyVq1Co6jhRK7BU%{6s4l)IER5-DXe2#FCmn%!U!AMBR?9^I?)PDe8{$>DYbsIsX zFSdv3V>8PskY(_!vb*S-*7&06=~L_|fgOa>7)*317Hxg;9DK8e||m z`-tyjd*duP^c|1E{12{Eqb~b>+@DFc&7a68U+QO>|A~jre;NE!SmdhWiG07UK$B@A za@BqHppt68#B+BI%22-2O&i^yYHrg~y9#NoA`s^>B~Iu0^)&lkcs;Jo)Q@?;_KZcl zPRo%C*2_Ck{@LR?eob=!PU!(~pum4i5!v|F>p+X9JdWcQe(LK$u>d~g7`dc1K`t5k z-3#+w3vAu$>g%nluy%OQ;!*2mNy1E0TFCAEbxdo9x;*~(!SB7}kzd1CO0KO$Xq;Le z0CQ=~zgg7!&lz@BTNBa}L|&DqGF~TKN9WPBQgmpYE_g~l06ZQ5)hfDcr#!bucSZU) z`1U7y1H%JpzcL;8lc_grWcYp9{f}wQtVu8H2kFYSn)SBoc$XK42)pOUML~tjq(8Z0 zZ+!b6^ougT6_&c{)j|WCUlYP!kHheEvw3yqtTU2yL8$f3112*nN?bdzT@?UBwlD6f%Doi1Mx zOSHp25hXtqG-w&KTI&WKJdZ>Ws5^zTd@r24x;u~P>8O6B=U@TupYU|UQ$=wIRo9+Ky1sgAw_?`tIRjQEX#UVU`HE3ugvS5t{#6<^3~t zZu_NMK%v(O1brQe^K<9n|Mk%-@IM8d|NG#dhog0%1$92RXG$Rws?40eBWpB;lsec!J3#^HqaTz!GKSC~`|;u~x}pAcykYRf?4h-4IPs8$drT$MLE;qDqgY ze1XMgkZB+w0@G4#=F1?s3_J$6Hhy9MjCmg0xOS3wnJW)OXQ0@tas>lKZ=G7uWA-f# z7*mMM(=Fv3ZP;XcWf|c&W)Xa1$)muk{2j1sv3#x|vz29E;dMU6>t253Qf=`UlaP&m8jm!I^9#^9lBE ze@xGvC6&NLlx5CDp1blduaFf#1AcfBwKN|Ns=ok9K(@c_EU~SNH6H-Z$6&wRbyV!! z`zW~HVrph4hAB*MVy-bVG=q!HN7O6m;(un4*VtRD4rfdyd?_D!XyPYzP+|>@K+Nj~KTLcAd`p)y2K zLVY({e76hE9}v1T>ekQPfTNZ25m1H_3hyt_yF_MQDGq$ZBKtq~K}9r-e@ZEZgCp_p zI0hpzHBUSML|X}|L5uP~?f)5kB^KZO+|Z=enHc_gNKW6cYoY&zBL@Bic#N7nzb`E^ z{4+w}2dVrS5AYwQE}oBHCw)sF5|_Z2;wv_V1e%bYs<;gZQ!J>)Z!nPSbV`bW`LW=J zm$Jo`T|zo;gRR+|y=+y*@s{2n->)VO=>8y7MC6HY5~<5QBMi90R}q!nWW_#w-qf{n z*QNUSpJ$@LaQzf!0}(YvAb*b^%#9_Nj&y9^-g5) zfY|{bPFQEyh41+@gWnk!2L680F98_xeSf{^w*ZBdxqnahTe@EY6lS9R7fkqS!%vb) z$k|lfkBY50_Az4wM{Ic+IXi(Rj$W=VQ;Vh6ifl| z<3qOme@3vsm{_2aGAUSCFkykdjW7kyvOZoRKQ+(NZ<^0C@m~2oT01}f=|842{m1yV zSmN#Pn}tTrmj6VaBZw=C|I1AaL0mM1)j?#$x~nJZO8E}yyLNDTq?57`vO744(1Byb zsVkp7^55$Zh<};ZFeiX}|K_E5l>6ID@i(4(#_=O}eb{;Bjs6YzGsF+9y$b)bm%gbu ze8>14c3!PVBen(s!Y3|^BFBG_;(0d@(%Cg)Czw>OFd(`~Jf7V&Jg@`D0N`-kp0ym!%<#lre@mQ!BNQPgA$D z6}eFYmJT|cCxf3~K7J+1K^}`!XhF`5?9JHF1TJLYjx*ddH3iQ+r%Sk?B?yBX;R`!D zS$(;ZrZgq4XEC?u(YOE1G^3QsZ6lbZ_NDj}VVZ#I&o_aB(tzdVm{Hc}GhvYpn$|VB zXlR9&-DV}1tGi|2ik2N)WWtOp_I)=6u*}8mAEORas44ve96={#vWhw3+Gl_9XcN9G zeG4J{GxCJ0uf}?jIngEGXwCvTjI@q2@U{e{1}cG(jEi3HsDer&~(g%XT+F4eFspWQ#N z!fE}qt{ET=CNXeX-HPBf9HN8m(P;(!yb$hhe-9kxBN+geor+{89H=QFYq82Mxilk7 zj-yC$1_mrpXTBkoZ?SWmXr(+&ZtW$JqUqZb{Qf=F%}RcAcWtm8Ssv6?fiqZ~{Q!{1 zKKVxXH;skLJt2#pDfdv4@opzqO=DB2efgK(s2RFn5q)ow2zZ#TcXLVZzAY3W)m zw^_pKVD7v;=e}b`fT{q7l~(d)dBO`@=ptneW=(a!y&)B}g4ZBFHi}`EYFwUnG=Q-D z^DytoJuSdK8Ta$-T}6!^JUXm;uo1U#zypZr2kd6dh z-?g@-2=%C%Fb*Od+eS|4*fmOMy?0|Z5Oulj^*({w-{y0)UOFgyJ8kGYx2h`MHN~yA z9YM6_cZ(%ewPvW#_OdppJh2~vH|u}_Tpc0WCxs_XML#nbAAUNQ192rxW zvV#~TCJc0zm{_GBXfNBWWZz8E)V&H+QA7M=;Z#s6BLDM5ppP2C?Y|v;GbjIwD53m& z>jFOl-CeKruOX3ihj}-c-|F#2sSk61T1?@x>>8&Zg(&K5q}ro|S2&^@JjijscO?5W5dEi_vINcEQz!?Q zCfvNgojj39kK>z5bs1iMtn=(CkI#^(;w#aQA0Vb^4saj$=_7401?}r>$PF0If5>*F z=lUx^AJxqDTJ+fY8Emsk7$rOa9IkSIh3U=siN<%+OTPl&e~~FUd1!g7I;%C?Rurt4 zc(%mK5Ph8ZWT}_JE+GuV#9R`v{3tsVmjl#v4O~vI#!sXN!e=>6i6Z_k^X@EBFOen< z_%hXIC8FT}h=9KWKcD@t_uJzS05|JvJ7%x9t>3{^KTD!A=0^F6NrFyGS<_;rn86}awCIG(pLmr?E`Cp^Yb=s?cK=iLv?4T7jE!o>~8OT#wrMDDo-cI7R)U! zqJ^`Z3?S{C0j&1&6P$Hd{UGUK_jeAFcckv^8ao}aT|G_VrZv;1C5m@5MA$iB3@X2mt9W>m*8cImQKGchWrTXOP6Ez^237--N#Wc32F z$*2+C%klsSPzxF4R(b$bQ`f}K>h_t{iamq2h@uZf8nI}F_?1WIzpx>u@wbiXX|*^S z%&qUXx*|~PQrKQKIEE30g+bMc$=?tQ>eIXgT;>Hk7+q&4UVYNlH=P5eS8HLaT+vT9 ztnWJY&8#Hyp*s_Wqx4{{f?xIsu9w7wo3Y>v7(3*|4m;!BJQt&O4#AtN-gRsA)NecP zJ&;G}&Wloa4uO51S9Pxu!@!+ZVR!X;8ox)1$e4+dD7Yyl$OV&evs=PK0Ak>lv>cR7 zSd6+le48IqI2Roxw43fGs|B;~4#d!1693SHAu+BIpj zkc}x*=IR=-MSw-qoWAUizKE!2V6L4r^VcTX3rS$ICh7K<)OQQi=L{(CaM_#%u#$8RJ?WN5*!QXuP_%Cu zQ#@ioQ_J83;P8XUQo!}!5~*Q@8RE~z|C_II-%0(|Kcy(_Cm#SNA{m9^5EI9! z1*_PbU?Z7c*@6m*ryQA*b$oeKk5;Vhxd>l>%WhKq`XSVOmX3>2ixwNpD!RATKQ{Hg zRM4$|k~ZiwpCDSL6FH71jKz~>$l5sHEJ0b_uC9Bgu+Wdj0Mju8r zL}~-tjX+RTi*Yo>ec-?xj<3f=s3=j66#A}h!@P)_pm595f!RX>XkG9*wxUo&i=9RD(tuyE_ManWEy$;fy zegs0{2UsN=$76jYZ6pT?56?1Rs1u`R6ncn<1xr6w1)qB7potT(D`P26%SWym5jTjt=Exn*Ny z-*Ej#3f2AQU9|1OZAK9_Di;rdOncd3G7@dEpw0dYXUJzM@wrxW=yqT*|GzLz4L9=q zz|fB$0In1pJ>>$34}k6mK-&YLuHyE8@gRh}@Z;mGH~-x=r62#J7fJv<#?|lA@BIsK z2G^XddUzJ&_Gdwr^DlReEjETplfN*t7`0&bSHiG=Oq`;M77qY}r0#J?aN~&9)9e8K z;sLkaT|IJ;9}+6|FhBQ~n3@{Z;Zclto*3tCBjX54x&*p%5fN^%e@w^9K&&`BFLmQTJO#f*P0Axk-{tg2<{ zRU_qwHSlO|l=vs+W@^+8mr7P`4-UEELTbPs$Us zNwV9FIP>tD($jmxuo#CMS!YXXu=?&o^O+_T6cu5rs1^#f(nF^M(PN&KU2dgg+WCdV z%9Rt-yC9GInp8<;o*2_q9s&VeZovTH+qC7JVX@&xyi3W}h0Cd}@FY#8B%%BlOd8FAZmX(48WQ8nP?^XGsV6h z!Y%ylX{|9UYw(GlePHZjN>MEFySP9W5dk@Dz8+*=t?=`9{h^+jRE}P>Eo6IxZrkJM z(PglTOO<&yq|yCzp@@=m#X0NtQeO=)$+ll0;MjI^VhrrO`~W~Kn;YuYGIZYefy_d? z&+#Cn%0M%tB5Ad(TnWdkkLeY*PdErwG*F0%5ax z6->%D`5Sq>f?N1ly|-WLIixZ#arXW1dr0{dxf}%Tr@_SHTx_t29|LL=e5WzO+f>Jx z?V>H~bESc}#im3S&cjqPS_t{vd$#YwjN37(%Fn2&`~G#D`Fk40zRI}Q4*3h+hOqw6 zX@TXt`HEz#4mqsYjtV67#l{AAV8 zpqM6dVv(+cg>DFjv2L^SQOo#U9kPBuv|sOY43Exck(+;6r^bzwe{~k1es)vno~qMk zOSdd&E*y83r9EoIlB{&2YF=L1&3`=4F4x`4Tr+#aug0xx#Ks;9M0WEXm~ZJ|*X1tF zGjY^6DJ;gn2xTh5;p&u$fDdGbNDm=NJ(ed&pHbAEu)PbZ!SXA=97?jp7%oWE`wx?j_21zT#HF2=2fR|Lj5LAk=63XzngZt z{;z1luiy|KqX;e+TlP_%k%6N(`mA<`swi={a$%acks(E>5bo|@mJ*0|row@_Sv zlP=7!8C{P5B9&d$!}-2~E%}@Dmt4O{QGdxrwf&p)w_LwSf6Mj%7vcX)MR;@6%SJ}h z^X=(hQc>Q%!>#H?J_!8+Sj5Rwl(m( z6aqFfVoF#>wgB*no7J7T>?kl`mQV_qL8z-3;s**O9$SK3Ahx$!?yWZ`@@rYrBm-w^ zpPL01POQE-%P0+f@dz?cF36FJP}6&Qq-aNKSdH(Vx0r@4}eb^sK|j3H~miXQ+m_7{ZW^=dwOXGvqZ~* zPP-Ru{+U#B=zk1 zI1GE{1g$2dDZkZwIx;29Gsd0zxJ{FC1Nf8|nVBx^M`hV=2`=>KWfoW(@+NY>>5k)T zFbwTJ#G;8mfnkx+AQEVLKFQp=jJi-YEAWX7#*#CN8Uo9REl3S@Xp+`p)P_%GmMt9; zGJd9FBDfnFlhB~g%Xhn|cy&DRsC}72L(FI`N215Q)x&WJ1Zgh3y=9Gu^)^I z8|Zd^ZtbQ@S8**PQzs)NuoHUPz>eO&3MN@tzbyWAW;@=|5;Vu3tsUEUpej4p)UNsJ zJ@l=fJgp@yC&orNy^l>Bf70CgT6&`~{(7a^R>dTd-&eW0!uJE~mHgV%@Lzjq^^=VQ z%oGh{8YI%^LJnl}+0j6TIpM9npsys_j6gjgmf0jF;u=W$3|@Pb?3XQd=r zR(lKvdBMZhxv`qMn`90aHWURh2lNPUji~M12Aw?64V<>CCV5N~D)0#%Uv?Ne?lz!pWQH4}T$4V!nrgna)}z}W9h)}=E^l_#gH$Bc@^AuD zFzw%YKS`ZASxG*osdCECC@z3T#e##XPi;Ay=ZJLovHU}$Jk#svJW7^|C-Cj3b_R7E zw5uYNq>o`{VPnXIX|o;gZ3Vw=u7+4ZGYDd1zx6ez6xJiv#GJ1h4fH{&2|KmPfm%aw zrmK8k#uY6MO&xd(YkO&Of-?q!QE0Ja2BNq*q&?BWV!d>2aBb@da-*}EtCv}3hulWX zipmLD*-#g1#8ccW!i^G2EO=2m7(6_KPVAiPe6t~CBHBBUQtyDBq?}C90D@m9U!LYF zwhPv{?R4ha1K^E+Y^_s#Uw`OCW#G=!$daI_p22s6R;V3XUj=0}c@}e0p{2eIXsEly zst8flo7BAihFJ){!ex>+t_lZa{4B~wHHDxqOF>+*H$!T;r!$7^LQtZi@@yn5UU=FK z6I1TZ3w0C!8gzSX_p%_Z$51)iQ2*T_;o^)rAvyxQS|VZT*foUmUbz_^4g=GEX+ZLI z9TSnY-#LrGewabpE_HDQ`%Bx=BIzx`?*iKmiA&-dOzrPop#{Ajy#@1zhyuY<&sbG{i-`#0#zN+|Ne zbw67;#`c0|{7`FI{iS}DTTF}?r^UEuvp<`w#Cw@XE)&AdSKdxAOYR#IS~@q^r(uzC z{%N476q+zLUVpejX&-K`4P0<6SzQLM3K*>+Dz(?x=`gY!`)dK8bMaGQ+C4?>5I+Z?FwyFrt=CrO~X$cUDmfVZUPDz(MYW(@1FbJ&Y~GXNIl>+m@vp zwT_j{bV zn+&Z$@?%Lm6b7NhvMDLsJWGd+3CqP@n$$vKFbq@-%Z`G@A-@%X$}ICnHN%x+nLwnO zX(*xJRK<#~T|8L2)hDzWG-hfU-IgxnK-tm6w!9bj7@wAYfR~0V_PVO~2+2In;qmM@I;V zomglj@q|QoOK=T<5f#J>V=i}e4RPpekTLlxFW+0i`)2UtXWRaematCKHX{xg-*Q9n zvmD=K_RNe)c4XdDs5w}gg%$&V40w5uHvH+?w+BGU_`0N#NHLIzEzZSX3jgyR)9mo| zUDkbt$Uq1?Ym??iowiBga=nT|Lqb&L3w9p9_8UR&I=DG|<2|xF-5~{ei{c`Cd;GBM z>{?}o@t`!EsPr#}tDKEMv82wORTtldVb99(8hUw$+RoW{+R&Dqu&IuLmFP|nvm3_A z!WK_S|1B|PZjRm#0rGwOWjuECxbXK``DJhDb25B)I6_O_2J%0vu%iCT z`?GO38Z#a}0O+RCNTiJ|3}jG!!V}r4;xO6c-qvb)1F#Twho!9cVxCyZ);1L4Xm8qu zc{iCe@4!A!xZ*jHPL|Hn(9~<^=dU|YOijqm^an^Ie2^>uVi7yMSUfGN#f(u=|Ebb@ z(84Ou?n8M!JMTu@R!|#oOAuM~MnIDp7*nYtzL;TuP-u|#ls9<YR^huCby!JJ&hr_XtY*1z2TE3>9*e@zR2M1hF;F+ z?9R+PR|UHmhm}TUn$BsyIX*;8#L5%OM#fI$tAkQ9;Sn-gu+J6I*cZq5QZm$)q) z(v5K~fbYZjliJ)zy=$x0(fHK}Ra82NaD+W)*94Pn3ucadBBL)penO$d8Bm1G2S*$2 znsNU>?R|Gt)8Dpd=qN?$Eg%?>-U%cW1?jzaP?Q!3AR)Afg`yxB0z^Q%bO=r99cd=i z0HH~h9;$#M{=hc=-o1CtyqUY^y?1BLdh^!Yf4=Li?>T#|^DXD>&))lU_O8p*pSh*t z>*S;DTbvF$C$y>41`e!T!D?Wk3fThPBX;S zGN9sVN|U}JTLw2dosN~hCy-9y0Werrxpn{P@d3-T1~r zi99T2eve{A6Cpa)G(HSGRyOePNNMq`xifJ6E~}4wwCJ$n9MFV@7(t}cBn#(xxS$Tq zh)YFtdoEKJYMb<8JjNg%M=1qGI^kyHJ^_7!sq~Gg1xe*^o-!(s?d*G{{+1=pre-_4 zUO)V5LK6j(wS-}!qOmUR<|Ikc?`sRc05-(N)NfDuq{m)^<+85H4S2(2GK-NpPrR#Y z`0nm=F_``=ZK|00V`qtBfx%JnmeYRpO3*${jCQ)fTLLd<}U9|aNLX; zb?PUN(_;cv16vFR0s?FtGmvI#{0r(e2X0%26g;h0OifD5t(sc)L+5#@;yt_4QkCSa z@Mj(#QjC|o>`+|+I;+de z>|8I?J=p2_^Wh`j&&8~2L5t|LWz&WkZs_$}U;Lh@x~1flSo7h^GW$d`PO4ME7Uo9t z8P_mQVJgm^i9Msp`&vMHoes~F6`4?pisbjd0Qy260RFN`U#BWMa(aNcMTgaUp0;W)jr|qi?Id{6GQ_a2z>~~Z@S{YYi0B8z-H6@;@s3mg}S^fZ@RWS15Gzc+`OZ=Z$MNVP7u!L zdz+;nfR|cawsAaaAv(UIeh>0j`+Y&`>oe&K2ZcLo1x>Cn$!qYC*3>VIDLt)J!b*8O zpqW_nIJP=xwXotgQdP?*C5xMe!BgE4B{XB3%l6z^ZP+!I6VDN{r)3_Wn0MUIA&io)=+<$uJydvwO-}e`` zH3nXH?uqMs^+?|d6dD!AF4Ix3pxt?{lw?DH0d6!rp3y%`AGe)s>E=_{A%b<|sD>E5 zrFT{d(K7mZ)_$G6FGH{}I2@FKDow#;KJC9Ja==I(8*}X{vNemB08m(K%NABqb1fY- z+J$Yv(E4^WZ=2%#y)D#~&rRzpJ^@9epD@^)fP= znHeGk89eIkQb0+)q_xr?nrh3_>mP~2y(^;|k4E#qSo7J^eE4fKElO9r}LwF$QkEh8CxeP0Q6VsDjTn6v8 z=L7>~5dalXmm%q)iNdTF&L0@EZa9OMj}{yAciiw% z(T2eAr}LyKZF_UzNxi-jE0YOUg$~?T%+mezs;t9G(+zKlgV}*nTv6~`kT+fe#x0?fRzWsMkR=wJvzG}J0e^TS5 zuKz1a!oM$t$$#M(=riIr?&tVpZQEUZn6CMsftA;KIyzb&Yx>%PQTrb6%Cz%HTQSSR zlnU3Yl2p&uN@HR98PJB+M32O!(K>%K(#m9<+wmY1vC6X#V?RE9nP6=$%+_#SoY&zr z?+asF`SGwDt1F^^=XYufwRLa+o1{P{ck#K{@S|8%}+BzHOs6Pvnrr^=N6&vS{C9V_kh{08Y20-1V%1OMKZO7)wq?FF15|ngf0-!bgi-I zi`(belS>MNdatf`k+y7Xdq8zx2euvAuEshn2_jVWKz(`UOr{4tg6Rz^qV)@vu3L5Q z3@M6mS#~!CAJlPI@b<20h4L{JBf6=Rd6o}fYZlfoZ0{CVl$E$uyihF*y)DGgi!r-i zwd!5O7FU+yw^Tdx&5I=0<*=nZJ8VIaBMh+;z-7j`b)nA6H&oB41%QV3?~H@u{Czw_ zdPX1AB#y>9egFpTFiR!b@ukG6P$WLStaStO%CM}?*=Ma1BcTUw^q;uFYLeK)Eea+0 zg@@JI$;}zl!zd^9qrT!B$AT)DwgGEC>$B`oQA>0$$K}{ej)q@7MB-7j10uo#UpuR`V6AJ5VoQ zzZ7su8I`qxY|mlL$R(PoiFxT0WS#GQhXuu}8_q&JNJngNbojb(B~CguI4y+3=7@I6 z1~@1r{1PDwM8z6HfRMs3Utcr&Gu~_DD_!N1Zs(B`%O3RRA?A)ZcaBwNpSJHc%oB~$ z3rEC0v<1xU$PI;YM=A_5)A9*FxODAvqU%TZr!zm}_P+|=IlKDeh4f@15J4t8hx>@H zWKQa`IZGCKm<0ljopV7WV6~Zei26%!Nw4bKrM-$JhuyhqHhSQ?S{8BAl2Ha32f26P z9X)HMGc(-YIjQS=rgZ>HMPA*cF`;^1k8V;_jJq-?Os2X2<*oNY=y{5zzTQ9yOxlM! z7w|bYI`BqxN|Q6v%cDKV46EE(CBxeghrJz%sxusWMIT&cn)>R+n>ifZgJtoy9-)ng z-tS3lqQ3bJO1*GoS{qV3%V~wdobr;qgVN0Xi;g&tvNAZ6)V&12g?@hoO*ivbxz7|) zk@XWTpQ87k+Ksx1RQe-V9%5Go+IIzI3V7Ib}GUL;FM^C|F{#dodiZo0CpdX;*ey~-jmy#Dc!xgiI;Yk@_u4*l z&1HHOqJSq1?F_tl;@}oYXF1@=eqsyeY!5D7vUk>7aD;7Cpg3#Km-8Ov95kYHP4V|Hq1fIRB`E=^@Y!h55Ak=eOe_qVyH@UzNK)DbfQxv9udK8W zIb1C%jm^uAO7899+mH(~f*f^Vy{$+BH_$qNmljEoP_85_#Ht$<_4g} zM9pKaSZKfQ40Lu>4_R;$4**}bwjw~Huv6e952njOC9AJ#vX;$~$yAX9cZ?l&&_Y5v z^jHKqKFHW~{&G4YydMGnUL&Z=*Yi5~&Su}MEpkVv>S6uKtVH_s1@DqdCPqa~=a)*X znn)MmtQ%HO3na=tXhHI;rna1Fs{K6MR;Z#2s$kG_ILsNJp>1qEOs3HI+{1d@wlZfN zRJNe{(lii}ZW_dkDtq9U8q1k{foV4On4&iQh|KNmn?7x0weP{XYO$NK&G?c1Q=Lj< zPL4nE7CkxeF!)3Uw;+BeP;ef0^f;Ka7rSJrcXSTp;p>-*gdjip5!1=}9_JI@Tq=T2H z-edX~n6%8>x-`A7k}KR_2_PfCDv^owVrE<#tv}Lg%9{4mfM33(j!(EL)3w$-XW9-e zgS_a@d*nGqNl$%QYmMINJX^Y}bb*PwVU#@?a5eEsy(W`%x3nOJI;o0PZBHW+&db}) zJ1z&K6dPsbPCjNZ0LeFgWY4o@d)L1M3Q1CZDbN%0Nag|ZwUr})R-#pK>L0849^!^5d?f&L^M$QWml(1B> z3e1;|K$$$YTDJD)hJ*JM>aN?aLHd%oT0R5RHc{z=zu~S%XJzb8Sevm=zIqYxJZ`6a zY=jPTiTQDrdsoSRrna@^{b+sYKDwcab&~H@ByF`cqb!wZJa7GIY)q>6t(QzXiv1q3 zunjaTL&l1x;0pSO4hLqhn#yE#I`v?K7H3=xkaLHMj7i*ug~=EoZ=xg&DNx?{#W_s-D`D#c1Q_BYvc{cUxIdKVyp+#h-|Y{sogVZ_zcv8(eE8Y~Nw8TXdj-fw#I*Pz zpl}yGUQLY+@V4Hb=B(zdo#w1LmozuBdy2^aW-Q{_m#XPC)&<{eZD75{^@3F8KYT^Q zU#9zw=d@Obi5TjQ&h(1XEi&Q+j!6vvTP2 z2Xkq@CyHK{gKzcnfu{|$8xREW5_1TCf?)3$_#iNAV9zVds}E>CGCB;9L7F-s<@0lL zV)}$PsKEzVJ8Qzt-C0wC?e`;ix1c3%Vio2TQZZ?(Wi#8B1>0mqCC>Bb$^chRILMvJ zN?A_5SF!gqtFfv^mKLXjCfb+w1bEj*Ap?S+ljU5oO$&5JL%s`NgW{ECy1jZi*LtmaE8Yf(Gd0v)XO7m7KigOQfI^T+diRSJ575bSx%v zo#SgQ+cKeaL3dp|6mQ96Ij_H8uJjAWS8!S;IIJU=&*PFk9`E;eLw41}k3S2(w|(z# zn|2RZSrF~B3_va~V(ApxFa*CstfSa=!BbNG3zQqa^n`9-$gmei+D=k+EEk?WKwquNz@4>t?VN|W5i@D=AKJCP*yCM zD+~EUWCIKmTPgCt*1j02e@DYz0ah!y{t1zZlCN5E3tik330kmi2vLsTT`x9&Ncm)SIA~pl{&L&(lO7hq;P*J|(nBO*n84G@_xUeXioU!Ot}qoaGY2HprxN zvP&MD&8a~xxN9&r)=p`N(Ot35qq250i(@%t~L*H&Zlj#qp9%i$l7U2!`yuS5ps zvO+HUFxW#sLRA!UoRldveG(jH5>E@a6XP^&gG)hZw|_; zy!F+X4OYP?mRBmurJyi}x;AiuoJash%*Wk)ujV7^o!g*fbF$UtJD(6f^5oeZ&|&JU zd%U`4H-T+g+x4!rMs!zQg;9&-D0@<5v&j_J6HApBigh8;AN~SR5u51?WiB@R`})+R zjbHFLTiT;h6nnlX;YDZ8c?>#DiU4x zY2`*C!QC9CV7>u9K z_#rDj)%U>%ub<20pW^Pak;fNe)8OZqCKXSN#}I)l7Xa&fE>nEBhnM{W>%@MVRg_{3 zMTLLX7;=BD?HUOf%Msj5K^-j^&5jxjR`@l|Oj#;4mbMZD^3Q~ssG6?S&Aj-M23~;g z!r;zSmHU=&EcER}GKow%EpMNMtG|cskhNXsWh5TrY94y3Bf6#o;0NO~EiM9D%&2fF zYL?NmqORs9zK&UA*NS>XgswZohIHU07c(8^0$pd+2YPs5g2Z5=hVUe9BVL(nl}KWy z4bS_Ui!u(K|7NdmD#AYTQuTT2qXaL*xR-9MCW-6whTSSupqM&(&h?oI)W?Yf>9wq^ zXlGP#PGjeE5>h;aFRF}=IXV6NRL4{UU;q^%WQt|+3ho#CRjyn(^bw@H1m(%S|53kW3^m{bF)B zlBeDWL`odqE1bWdWmr_1m1Ef>$zyJ^6WltM3c-#W48T$6kg)ODo6qCs7k&(34hI&< z9#ZVJBRo=q8|hOTbE3~6PXMasQ#J3a3#-~)m&`S6Y*_+2aN~DXZ{v!1+%eEG%Gh=f zm!+S_$R-jqUm^IgReeSXmlgvGc&zsHxlZ=gYA)91HV6{l}tbp%(HBvT&nKoD9P92bd+F`nn{08kKu0EF@xrh_6jVt z*sYnQ^(mtmbH8wfXwbjI2Wr7QU__1278FkGCvF)pF`1A84mW)Hsk}-N@+JT}Ya{`P z_^@_~qeD}d>}=XFyXU{`6kvzt)E_eE_Onz=bpsi@+_sqP7l6Rc^x@^6{#QGeiGyPy zX(yHgvt0c&D&j+g;y}{iGv?{aOmZZUVuiMy{T8Zz!7!qxUEdJwdMz`D41d^qz$gGv zFaONAaW-T6h~!FDGhsbx&Jx{;W*g()D2S@Xf8CX420_&gAgol&5Z;d|L5Cg75@PUd zeJ%FJlS%wcQ@YnM-@L=@Mw^*=6dex_NHEeySp%2n1Szg*nuTRG9w`^u&{SQ@Xi`p| z0|)xJiPDuNL3#K7MY;b|U;lgb^(}O(d~HhIhlnyv<34uvhBSNO^{u`$J%A#?csO^N z+}qo+&o#upmZiGwY$Uc`?Cw>nkP%D?)?bJu1t}(*GgHgtEj(;;*>$C1azPr+yj-CK zD*?HbQsNko1_ty$_@hg4Kg z0Q$4$ajW^GCi~ge-h{OwSjp3IQ}#DORf0b!^$OycK^Xn1CL4~_FDF&FqO^L=?>iBX zilWt5qUCBO57Xx_zTc6QSWhU_r1u#Em{Evk=I2pCh8TGhU!~3L`WoGz;De!=3z4f+ z?!oT-Z~ee=%={liH0lO?%1be&HTqLiw)c?6w0EYy$3#*Ht1!U>4F||%N6N4MD%t@Y zh{Mdu!Q->{(`D-OwFDj_d+>s;4{jO7`-ef<9qdgrfEz@H`be4@iGIRo&)9%Y$@|0Q zLAKCuOjG2-AR9G&iNf53E`BN+UVFkFmi9{l?9&RCEo~~=Izm|O;%0>#mSc1RR8$aWs)o?9l)|>A zuR`ykwDp$5K(M~f9us58IfPQQWqKurKR4T$~_$lk@%QBa(=}G_DW~>E|D3YGdY$QyUu-B4Q9q) z|DbI$q*ff=hAnkmslW>Uoc_)ruz1=B@Yn!GhD(p|8NzZ?KVsUhioOa(1EW3h!I$;4 z2;u7;brmvG?7eTMZ1ve-eXdYcHyYyM@dI|>SK3+4TJu|?Gu&qZQJIKlj!xEPzi<5P zK*4YjF(@h=Ed4_~V^YUAn@@s4U+n#&%WnwNBj_O|Y5Qp@B;BCg7d(WIQ&p**=urBs zW*iAQKTGdAYvQbwws~Wxfj7tk9`*J*r{uWXA<+T>=Zq3Ru$7gbGcPv{cmi6@ywWws zY!U}xLa$}J&x$a47teDOF@;rTyM#+$$hI1VH(v2DjtG-8GBS`~+!^lp&EIFp0pBa$ z6b?~@>f@JWBjN}wbKox?1%z5D4g}?acq}j_X z8n<>rZ&hTqW24$WD2nH7cjFDGAc6L}4-U1PjnXJ{3h3mAWQua+xf7?RCI@>hv0Vif$-k&0v1f4TvQJpx^eC zR~wb*FJ`Xfj8)LKjv?4Im_Lv~F~c??4}QAmd195bQmQHxt?jyZL-j$K z!Vu&WjC4Rs9#rt@v(WkX!sY09jziYFn~sCO6(Lv+1YLm??1*H0;G`QbcM?5q5SF@n z_|eP4Fyx}^tJk-cA$RPu8qQfgZVkNva#^Q_DES#Kp^$?L}4^||<{t-6sdut)B z{ORZVI3_76y6eYp?>oZ_TP$?#>5+GnS*ecbdk9yoE=Yfk9=%a&OnjLZ;Y8=39?eIT$C_!aqGb)?G4ntYkfcBlrIv!H1>5bK zt_6NoOvR|nd2AjsUWth2gho8Y9D*6yPe#g;*gKxYJ)lzm@fw-a5Z2nU^d*$|UM4kY zV3*u~Ej>p|08v1$zr-bkDcvO!012j2|Ipz2-QHQLDw;ODiAnq(g@1-{%lHYS;`rD7dN)fLq5)I-AFN35(whI<2{cx^{V zx0bPnw-R+^BPV>U7UN04i)8MDh7>{G+z+9O7~oKYGgw;Vq5MPmZU16idQD!2cAT;y z_yKu$jZW-4BQpXUSYPu^7v5lJJ?SE`8g1Be`bi1K4MElg@dl^l`5jqK9B9|zl(Z2XH+Knj8LQ+J0uRun&ZXN#6+TM~MiSth91|{ebUN96!ER`eHlRwGN z)Naku5!5`J>~&4HcMHp()>(f_bo0C+$gLTH?8Aghr?%UAMt7BBD^|_Tr6``_9i7Gx zOsABN*SnLPN(jEvQ&xtT{rzo5NJ>^DV;SS@a=^+Gl!Qco7TQTP_WHeVROF>sh=1g0 zL>Q~}Q$k{B(_3hLAqQIPSi^5^wxwnB#{Q-nF5{~C2{4to#uJi`G2}R)3H^O?bi6U; zV7l|;6JE6#KFRmpWcdu5eu|tM#ZOq4q*U(DpH~bB7nh(?u=3G2f7;Xw6%eI(d9|S2 zVL*hvZvB@@XYuVyP>~0VUC?M^9Zz7dfSIAYmg=i+H#drR-mc1ZAN;D*vr5u*C)Bia z2I`iasE%LB3%scbn09XV9o*!&+?1^6;g_;Xa1?6cS;x|APioWlo9bE{Yzvp>C_CH+ zEeep9&Gb52=%8l^CQxk3yMVX)6^@_KRqZpM8nK^VdpyYT7gkaN1hX#2Hn8;{t)kN& z%FN9B!d$J{$An6?^54X{Qg7ZCWP#UckIZT~MSH8o> z@P?cNZrzeugCNo9&-wFLH;D_*)M+dkl~ALHE|pLrT$Wy$hqpQ%$0Yt(*gxVCJW`16 z)#=~E4xD&Uvc}5RC~?x5pK7la)h=Rr3t*29s^H4V8kA2*bVGIbY?}TXq8J z_}ldm%aWtYHBWBBarqI)9Hv^qNrqK$!qkqCaa;T;iC`<~z8M1G zue4-FsME{v*7tPCJw#bn!<~4?0sJd0^3~0^cHkdFQspi{eXZkOQpEJfpn(`r7cB~} z&rvhqraIJKIu@W{$WT;~Ld;DGiWV9$P|#Y9$wBP6a>KQAR>pxJgXmN%Bx5@Ko_p6c z>)VT%A}b{}(`(8!1ER(A@DLwvFZzH>W}L05Duco;rig;{!ut}t&|BP#7YEj;x$4y~ z^e__)dQYabfoY|6b*qhu zoA$|gkaCBwI7SQ!$vIwSS?}xUgjyRA0~IHq$ZuuyNWb0qhMs*^ZpwyRN!ypdK=q_J zy|EADnylvHEi7eRl7LB{uouy-88erjhc^5A2qrdOHVAzGACf?{q@A~L+Sq~8sBOkhC=6Dhjm09s@k=-D{o`J#l_;#uWJ3pmZK zHnF%m>$;sGU?eO4hllB~6R#mnnXtQ%UsDY>Y{sRuG`7jfhxu9ACRM?U)Izy8=$zJf zhp+*Sk5Dv0|MMy58B%nm}=k;rc*AQ-G7LnOI}&F z#i%dp!(XJ$6fz4O^JAJlUZ*y-%?{B>Zv95Z5rZU>rbvIXB07rL@OA!zm@F;KRq)|G z5Ib#{4Sk(H%TSXWFPJqrWt{io7s`J*OHD7P38H2c!f<{Tk+Pp19}UM9HfMzrY{)~O zxx*Osgb|Z`Ig6}F?1jUeD*oKq@lfZK=P+^cyCF)SLg7i{7 zUB)+D9V(}}LodphsHlJt8KXL0p#U^PE{$244!##uF|*j3&k3DuQEG|{94{?8Hu+tm$*CCl}vGMX#+saL~fJxiTcS3n*UStAF;6l)=fD;BqJ0x16cr_LwX1Z*4SxMr4i#WTK6fcF!e68({UY^!C0 zXsmIgeC`^(sKlP9T470-&df_wp{G-u6K!0^+!@=c%JMt_y2!vFgF{B|scrxkFi1Y1 zU<{uIT9FoZnQV0;s>O3MOR#n-&U1F7Oq;?;m;G&x*8&R|)GW@avQRc**%{<}wt$#?q*M|k zT=jyeAmTjX)1Ij`s-w#p*jreeBvMb0o+6~49V)y8&_f5@oeT+7L=B(IwOeZU%!Yj1 zC;a_^X<(b6VVP(8vSu^A_}E<;i2DFgDP{o(JhqQ_Hg|9Bk?t)xQig5CxT;&=|1j0Q z;iQBo89?dOFVVR(GmwrTM?lngq#ix>Lzw%!TmQyhU?j61^G*3Xdp{*TNbqaQ1$pw) z-@z}O-hYoJ(C_>I7aag381upIe*iQ0RmR5}E|2pFsh9Xo#pb>gAJyi?4`>gg%-r+C z-om8Hd7RX)%#T8{j2w5IH6HX9DW-4J^pt!Acw@}M8CN`x_IJg;SanH==iVfDbPQ7Q z8J%K9;hF#g1Qy~E6&djz0)mj{KXM=s*cGhC z#|&vaCB3pF%Icrq|aLjiecKXKP1`Kl)9Bdm{C^4g0itCx|GbIiL}{A0m7VP2-q8RM53#$6SI# zwGYAUX)MZT#D)idJ*Olqa~hXzZ@x~8Mw2eu z?MP+fwdaopq^S;_>8ohPg7rgN74!{uJkx5>s`hF?*Ln9y03#s1`V}YMTGu?dRW%R5 zJ8CwM`FtPLcvCt_0fSN)oa4#`v3YAvfwR<@ot=e?0M~Hl1F!R>8eZQ?W;xESLVY zk<(dn-Bi4veP$gJmO8q7Z&Ul9L;jx~V*C4!&YySWyHDZn#d8qear5(q3xsf3_}H=r z{L&kbdn~s+q*Z};U}51YuR(_bjXT*n%!&Ky%0sh>vaC!_aav;$yY^O-T88woSo-{D zNQG;(4UYlOS^x76VMs!?I84kCeFoBFdWfkQ@IRPw$fDY#^S9~z*uYukGOb~^Q|C>? zl9ab#LfjFzortaJUki^L?TS9zy)_GjQ_<~R`B|7Bn8H6^pwVafmLe#4QIk1e%V+RUdV zm+|b`S421N!|^}`j)7?9{u#8=0G(z;+*)PP!SEsf%xfJ^*tei>gpkstX4#G~r_Rfc zf9c4&zSwoV@6aWAK2mrETMqO!=R>=2Y005wD000#L004Jya%3-UWn^h#FKKOIXJs=kYH(-l zyLD7tP1oSt1ShyVgvQ;SV8LA)Yaj%d;0_@Kcc&qEaCd7gKyU~S4Kx-!cpzBNn`fT9 z?|imq-TA(mx%ZDbz0X>^Ygheh*FJU5u2XBBr^Tml09<8xC3ye>0sw&U`v-Vh2FLOQBYA)&@gZ@FwoI42(fW6aY+bCNl6HaiOH!LXvisml*Gie?6g2eCKgr} zG8ztU4rXo!W)|kZAPA_as2FG%1Q-|u%;d!6%>UEJQx5tI15D=dsJwrvrKte`(h6q6TeInr@hyl40?co6BNwcZds!2y_m8SxPD0Fr>)lGHL|HKI;@4OcojOnZ~n z2_jw0WQ{TeX;D4iy+{wRKB#^E;)W_!w5pZ4sQdsM{pj7n?w(ddbE<-;uQO&CwMl~_ z;gRNZq1T$jBbSys$n$I@BzWIb6xar;>}rxYe~~#Qh8hPYyH8mL-5+Q*A{?2j#0MQt6?Sy`=1(fRn5$y znE^Xpb2bM0Oek3+`g0v8%Duk87FLZpdhRx1u20n!hmf z-QSO6;fDZ)iN9h;db&f!q6Sky{R)u!<_IT)us69_ySXj+WKAqasW2BEMO*PBZ{1HM z4*|U(W$k}0dM|GBq~%#}*V3x6(S%%saXyD|DK|#w&h9n}xvU#0*^<7z&DksU$yts^;+8BXI{A(X;j!PJ8t-b?qwrO$iBN&n1ZZUKZpjFG)mgJ zDm?+VQQMl;Wc;IigO_m!wQ|gYq7qoury>|4UMu7unnXJxY>aF|80&0!Nk}^J1c`Qd2C+VN5^ES*T=u6PD#F-n35QbO%lI0ho{{nu zyW4Y@ZFe>PA1HG8EMqq<`tL@)!kLRM_h*}}8AHJ?PXN+BSBLWD17HvTqo^(YXomWD zXCk4O$mE8JhSEkgP_d0~--`#XXa=?zWss%IQveFnTiz~=Iz$1Q3@BsOrc`2=uukt=nbTbN#1Rb+@Kb23+448=g}ap^+^Pc>5>>AxL6kKD4F_qfT)2@y|< zH%0ip8 zq<#L*yaxq+jAk<1K$}v!S~PLaJV+5R$_*H~h9QPmIlq~&^-$wG?+Ut);0g^eW%IDL z#H=qYl;Qh;;|^#QOg~ZYu-?8&^kGO71*BDf zwh;6|ri{)yfer7g{j%c9r*Fq1RH%s+t?#&sR%MaY-cBn#SN={5*@Rn7at9YtcO-nS z^~o`&IP&frAE?Erc;(rUyJRGcM`gL3IJ)%CgV)c1`W1C>*}km&tfAZx?(>+m#^CqH zPQgOCVugJD2A_Hkpdu&WIRMoOC+^g@WTvKi;y6mIw^&sP*cP;L)pc>JBS_o9ZfFwr zBcCUszNJcVj#po!L6)M`Ydff9fSI)kVlCUM#EdL3vbbA<4y>Kg$#7Qs@-DTeQ{TA(rUMJhl0Thf2R zZ_-Ix1sjH3lIo;zSlp*ZcG+BKZxrO}hzr){BU{@1hua#(v#dN>!81%us3qSZ z7Dsal)%>$4L@?Wl@J=HeUi|8uXYsbh-d&}Cd9#Dvr&d@l*-iLmzP}F#8O==IeZymt zQ^bo0>fb{EQ^z4Z0nqmcj+hlZE0x?rr@ZDlNnKtZkMOx0r9~Mkrs2w zeixO#eU%Uwf$F(;V5~bsJ1yC=*ZhLVTQynU5fqlTBPO-kJSN*Vc0_v-`=M4%c%>rMt=ef zpq6Zkea} z4Oj2-NqOs;hZSdGNSpk_1TF|>6@1Foy&3Y9=H1BcNA7T00)hbawy%+Ck zLsX)BIms1gWPvM@^&Oc3_VUkqj+B4^y=CLQm>ahzfXPsc_m)@#u`64tk&5ExwV4IH{F#pK@-$6nM3ND@CqUBnhnJD`?^noYp&c5{ z^ZYf`Oc>3d-)Gp-KXYI! zX$TgS;cn?yBo)>5!GUjpP)UC@qXbg4NY%Rrgu!oe!-Cid zTRu0VYbr4kygt=>O2D&cyKA=$ri#P>&*a<-G)&96p zxGU#HoROG{CuYSr0_trDV&Ev0smoJ&977vI_&Z%xkff)LVauo_&=9 zja(*6A;Q%3D@b5ow_&MQ=~D`>4x*$x(Q=qIMP|V`uF@3CWBy*@WP9-q*pxTkiy@~FcDL~$Xf~!J z?h_z6ubnkXDR7hV@%2S{{g;$r7cm?Y=|BJH$Wti;id0uPE2$R6Wy#Xkc@n;UASvn! zAZUY#+RO;w+n+DQdWf{%#N7Dj2*+fJLnY}Gm%jyz2yFpo;82}3*uBwTT4zb<*A&_-_rDJf`bZkUfe4|j3V*5#ne zDtB!wm1Bl*?CVS-5Tp}dRCgNdcc#6u>V)M6^L-J#33srI>l$bt4Wj1-V8h^wcU48W ziZ3FJ<}a~?UZ;e4I4B)sos<{(Ja1z#v;cLc3ErPGD)yP-KS$O!^oxgnbpgd~bJf_3 z##I`QSFC3hw|MLMB+3#hla{kVBU>p6uIqDCdm9vc@v_5TNYgXZKLKdPU?JXDv1TyX zfCt4ABCkxOb(mAGd@pG$JB{^>l0~f9wiyAqIH&qEq!i5&_8JGx8qhfUFd}jO)h{>a zU6`xYhDywX-S(8nxR%hPAKShexv|$z6k*;M((FCY&``ZW50u-6A)n5=sT95}5GXKI zX;@Mam0#c?3Ol`&8sf*o7p)KL?ku7M-K*l27IR?6rJ5Uv& zyW9EIFTJ*bcJZipFnzm&RqsRf1ON z_xu=KF~kq<*>A3r3V&Qdu(mmfenDIO%kagKx6q`U8qpM;~arA}( z7YFWfn{9hb5XeADY1x;tz;BM9qM4}!sVJ?Y9EX!uIxv}aFH$XLdL$0>VYZ*r(MUUm{7+YOfBlRwdOnw%1L?U9TvL%TT$udez z*~*fv3th`zha7wGKABkx(7x4N8nu#{729uXrZSi3PItz~L6?{VV^uMQU5EEIT%i%j zH0>MmOmbIKk{l+?7JMnTe@wk87WZ;=~7lO^cGxNVaA0(#u9>~UNG73R;rV%Bz}(jo+9R!d8Hw58G*AnES2%cxR9 zJdeKQk7dD!eoRgTdzAh0Ugr<)|7eLPB5apdLMlbwcnu~Q{@zo#0B?J{vDJ$oKaqd} zVI`O~6^T?c;UcUGM}}{qq-a^Xz8g@2(V?hln%_e z_6trg8A$W(SDijz7f+NI`Gn4mOYE%2E$L`aW4i(>Uv>>IcDlY6ebX$M1TI+lXr4*e zAl|?O*kX`D43<~e(sP|VI%%o_UFlRG_|+1amK3|Y9a055h8qgGO$rQ|ejpx_SsWSg zG)lAjV#1=VtNkDBnvQ**5vVpFit`v#<2^YiHQ`X&LE>TY&nM$W43^f3MO+{25_Sf| zxNcgW56*`@M9x^{9DS>|HOXLrTP#|cF<|nf>?D{vn7o@?&?H@PuQ{u{WoPkOh7XwghKs`Jn&pzRw0{ zt(~%-?!Vl+_#z*`gCr1iCBNYh=U$Q0N2{d~RyCZK0? ztyGVYo*HPYY3qg>%FThkR+JMbW=i=A27O&VFWW|NY&(R?ePLlH;@MeRWyKjvd~2@g zEej_G>rJ^MzL4*p%hxt17mQG3CPZ6P=tvjW+|eyQ&A^p4JiC*|!nNAOC#xgWFeXC?f~-&wK-7y$TWd^XSnjhu zpAJ@IQ65b#W+wdCLKL}qOa={!;PPl{7YyG4`F`QPbLqJno_rf9IyMvXs_R>hsY7~u zO!S_RyU~c9cq_41_wHgy=<_;8Zr7aE1ET~$%;8dKdkB{3CYvzli=Ca_XzVwO#<@W; zoGyG}zy$@qW#@F#r&6oHKDKhIyRzC3`#p8%ST&CoV6vuL|{ zYMt#*+4T>pa+47ui$f1|xzsooG#Am?@k#PCildRA8u=&zsBUToYloR?ageT^lTr(3 zJJ%*z@ddOf&J75>|J%0Lkl*ue9Mt-RTRCxY>OskUB9NjLW)ZHuGJ<@ew739Y^+e>|6A9y4265rul1B$xncOwfpXUolnIZ->!I`0E(r5 zkGiVr@`3zXEA7jq-s}n2COdsg^bYkaxXY5J8@C?~YpH9$ALw&arfRyvc?ipU?ZM+_ zDWpbRG|+))GOE^|{&dp6c2MtDuhObgmOeA!i)#HCJy(2~2~|=MYVDdl+2t0n*mUmy z%@F@{ak~3U)vvb}dF9JMYURFwi z_+KoRnRUhgH4#f6G~49w37xM!W;e6Jt4il%S2hTCd5+8XL0uA2FK;sdv4`V&XPm27 zJi8cr=6e2n5*7)%<`x!fCI6dW&=bsO#de4bPE>j`iHQZ979-g|fg92-^3vBnLphy1m+t7!h`4jBf- zwY!B-5MI){!RfJ1R%sjj6}%=tXoqI!_1yHMH^UDdAgTrVQR;x9E4kxIda1oJN425p zs#3YQtdPry81E2oPlPqXcPM;WU791$#C_HHBki}bm{lhZ0*xmCCh1m38rqIt)?504 zUp@Nl(EYftgh7Wj`!Wb8d`eo8-+o!=g*F*FRlx?m8^Vg3br)ZlhcJ`Op}zI2H}umk z_?J0?$fA0GPj}X;8Qf9HLV?W5VaY=O7F(LSfLF8}32!PGoAox8JT0a4jA;JW)Ky}< z)6T3a?T3LF+KF+wj(ElaFM7X;OtKQY7i4+k3BVxf0TKxu4O|t_ra4c!meXe8x_`Ak z_6QLT{>S}OCPK0_-tT3sQMwP8Z{w^coLW^XgHJjVx)~^a#eD8)GHjR;zF^If9Uoi` z-IDH{f1JyxDFSm)HT?qSl(u`~OVv70cwSrq^rWe0c)r(5xHvSL`5z2v&+xBmmd{mj za0$j$PKH_btW?JrJ}8!6m7P~Rm&cJDwak~!T}r60>YUpqZ?ZW+qn6*(x2FZ%04oOR z(W=B!IC;4piu9xNby+_UVgkf4u8RN4R{t^ygcxs%QQ1?>&HFfcW^OaFI*OinfqfSw zNGYkodc>>l|YEOoBGf~A{vU-~esyZHoQk@V1ILmp}mn(>j+x@`Jtx)2Ye2GO`c?3y?-rk_1PSY@k zI=XA*Kx5N>w`}?0_dOPPr&p=3hc*E57-eaAqE@iD-6k3e=p9HmLW5|8~w;JN&;0O4Vxl zN&j&*7MVI9R4$9rf=>T3x|UaRx)%_%1FNx<`*&e@^}jQE{{xWnDlxInZokDt)bFPK zbm~SHBJ|sNd^*L<#Xd)6u_sa>GWy#vf4$a+S1bp<0LfwEC%^#yib59us_wbPrNthOE|FSeY&G*;eUJ0~{5*NOa`WfAtL_2GD*+Qw_4Ru5 zBg+$@zRd0Bs`_M7j>uK-IxzqKK#yxMti~Z_G+jr*S0F71sn(e$JW@$wE)qSU4U(8@WHXY0pZMMHWPm!P%r-SHl|;GnK(B0Ylxqea~y zoOE;x(OGBqrPfAm)APFr>F|P%xLcUqb29voz}N%6K)PV8FT1PJ8%FU}xYf8%r>3W7F11t?Iinrr?yKX%Tgf{k6%K zg%i>(*r=<%KKYa+N$q(~tTY?sqQflq881ayC71)zI3m=;f#Ulo|Cj)ywXJl7Nmind zJS#(|c>4qii(;TtI5DKkfyWfQSa|blwgjz`mYUA{LIy8)6hXqzDgq+z;JaJhxms zzHo=odJP_>EW?mtkY1A8K->cv_}YARmP*<@Q|6jLxDsVPpdi@*lkx&S;X6VGx@ziG=?C+*1QI3>p7n>c<44hrqWJNuSKu1d7wf4 zkjJMuDT@_|_hFFNphn1dYfdpYWQe@@s!^hAPB6wPX>?edmuwVec#`|LmumQcFIJBr z>PFIVjzlqSRxKAL`fDM$dPb4fm68G?fJ|RLOl+_Z+yz$i$s?ooLgV*D4guH4fzg3S_U)D6({6`*ohN{W=FZu%%qwiDv^;;H44N!yUM5x$f+e=W!t~C9-&WE_U1+M zl3i|N@I%;Tlbe;iBCTqwL6h;(L_+| ziH3Y)o&cJZLPZYgUbu_)-anQ`MxpJkayylXA+bqGxf$PaD*2PwL+WRmCV+QJ8>`QQ z9eoNMBJ$Kbo^R+8eof&)ItFYZne7P=V!io1@wnLZk{>n^pO)V4RHQjVsBaH|NR7ay zPg`rSMZLy(<1>{1^}El1Ld5Iuu3rz(TygwP8wu;}kIcW*hW$aD>&<`9A{7VK&YvG@ z&omz5WYdS5CqAzhcQ_&EsW)zn<-D_}U+(lel9irn7@G!*8L-gAc^J*VpSmGY+FIp> z4}txQ!q=SqD14t$Eh`=-`k7@m9^%9c+uTe0*4l}B!Xg4|r2E`NM75t4O9~r8x(H%F zBkUgxcyl$!KWkZl+URW^d#uTowWJW%?Z@{sq-K$@YIxD69BAc!gQ13YU)9f?Soj?t5BbG( zwEJaOxVq+O%aC3qmiYVY()}%38>CzLc1iRfl6ZYr=%|=Cs7T+aS9y%@KpU@{PdKMM9&r}lI=-28w9*SuHk{9t`V_|5JMzwEu1$hZ=~`i` zab0SKis3Qwe$2wmrrCpO#?(|ZVJG_6@{#r+Jn-S=LxBpv?To1Li8*he&|4~ruSzs= zo?r>FSdaIdQ%zW+Fcv5ZyqCj?$sIQl5|!R^{Gh1bw_sfL0~P)n-O!Z=!(||>Ccp1? z43`tGiy0}8vu4GryaA?-&y7jcu}!3)Ep0j6o*JiK4h&q)CSZe zSUdsB5*qI+b(h5l*H{ESMl+WDo&dM?G>exyDUlb3)LUX#RpT!( zHjq@Muh_PeR< z^A&Y}ZPob&v%$}*1?vURNzdJMV{1F+?<*(dCR-ymXewfNlp)lA^z4{CXPhsRAk1>@ z!r`{7ANRmZoh0|;jT?o7dGf)xI+})xKx? zr86+F!}TQ);;T$ydh<7<^dHRgRKc!45RE@Q?=U<1|AFNG&8!^NgkS%Gi2u#hPtE_o zj{UE648(k5?u9`bE)l|_9dLfeo?Nfkg8F*G`ljPorX->|;h09=IP{=(A{cZjgeu^Z~b;O{I1RG(l!7 z!&v~upvqIlz;Ub1Jv82SY2r%&I5dOoL^pwzM>k7*6N?l5w6uM;xr4&msv~}8H9wQ8 z+ux?7_v#w%qEXRuXt>$l61}+!Q?!z%ck0Se90vZ#o33)W>y_~y1IJ;4Zv)t zzK{<~&j2x(GL{t&pGMqvgFfsT1oK1LtM1+TJl_-jDWW`Gs2TjkD!W&k}Q>s&0v-9 zxdtHP#X=?eD);F$A}i!NC5i@Yo)BI0mO1`M%ytu*%~vz|$xDuMU)d-tf-TukQ01un zSf~I8sAlR5hFe3TF8--MuEob3?-%=IjNh7!fB(trBDN)w0I?K^XPj-ysHW?%Lp1&t zOfW4cA;d==QmbmiG>7FjqOUZ&Zm|8DRMt>6NsXdk@3jyKuj+Q%8$wtE3aVRUWrsI&Tu$N~9V(-lj?fD_ldpcaVOj=j67qOd zInWjZjHsZ#{LzhPTPH~=>vN)@mvpUZrxBN84xa1$u!g~yMBV{3M5Z%-M+?vXAMjTU z(Aj3iEzYFv<;N6m5Y@w9pDyj58b`0~bA%Ni%{I}wCCNbxlBFh1BWPi9FViv^HzaCe zipK*4GYAE}c(G=h^!;UMblu%&a{Ys^@;<2FZDQcy~YU!qJ$hV0o0x0#_!?H9a}lr@ZT%y+Es$i8c0B!*H2( zEQ(^Em)GI7dr(rgCBZDc@tTRW)!S85YP_S4l95hGBt~vw4p9^H&=@go&DAIg1gbtuzd^Nw>TYsd zJ~dt{8MJva8O3wXkq~CueAL=1-)*m6q%p0{@t5N#bkS7uS3ZK_Dq`p*WLA2Jel;t{ zX8yN_2D47&lUmIIG8AP#MiYkgvnTYSWqLrwk1x;V^Rr)=p`cB0Ki9ug{Lm6nW{-n| zt%S;u33DhzN>1mAeaiu1_louX=Bt&vK;e{Lvv}am3tsjq&gIAFH8xU1fUEP0M7JGC zfKsY;WM(JPzRzY7x80>p&0gmFJdOG>-h0XNWS2H}yxI zLga=%Y8fZ*)^!4e^w^tXC+FT<-y3#T8PS+z?zY&=Ky(|(NMu)Wh8&;nJ>0=(W#$k? zEj$)Eg^O}z8GAXTG40GcSM3DV`x)8XF|O=DMpZ+{JqGmF!n7#efYR(~ZmOXy=*$a$ z=&9vfT{K#8!mwtVg#-|-bqQjc;jQFem@eEnwmah)+LMFV2Gg~wT%Jb(Gg0KVT7?g| zHI5kT>s<#zvfeGN)2Y$BR@Nl|I*^SwMottenkD$1Hq_ZVTZqp{&HVkXn_H6CwlYb? zOnFbn(iWd(4Dl?{$MLFXsvE|><3WajKavUPx zUX*TsJaIb37F;%xu}ZvsFhP~l&=v#1;ws>Wf^qKVGyE#RS1N`pN*V zNd9rX0~LqoHE+v`e`uwOh6E2QA}mPowh_g5&T8DiVgCM3#%}uy4($8X2uZnE9UpPJ z!h|P{xi$>qaf3HiYRJNlYO0szXX%^Tee-P>GG8eZp_97!zFjhowWu|s@T@zyS8*&> zbElebUf4BD{>B?hCnty58^FF-TZK{S+AqkX;CI%P{%m|k#Fq`~Yz@by9tZ*gC3yLa zxM-I99NqiHv+gVej#Fn>=mxXzJQcNcoeyMqw5H-a;#sW?j+;!>$vi1WXqECaS4-s- z;fOAI*;@5}l~x*g@<(5y;D;9C?xm=08aVD>Th_;8`56WWR@M^um=HhnE&kH;QqzWu z-Ki*;HyHQQpQU{0(EKFwGBEq~b&VwJzNr5pWy}_u14}YXp-=SKcZ9kyF)6dcCR=~3 zq51ZMcK0(>yrltzMwXIANb2g+P2}}g%?}7~_K{;GZc(T`m{=EQBiXTo;ho7m+pKjXU zNLKOXO#UiMQHDsS*;iX6b2rt<%tE3XxO)8Q-*lMe1>3A-k8 zRm`1*7^Qc;sZ6+w01>N$|u5TGR*W=9~GgO-iI?)!00;#XiAh*HG>@&w!m}SiK}3| z89Kn-06^@+Y1i-spo)taJPhAX*E=j7u;55tFyG=}gRVMZ_E;2_Vd!G+*&b(-Kn8ym z9k!d+Otf2FcFod-zaa?kk%+Ub%=;m&;;_7L5!#u!6p;zXr`oWf4>J=MUMnjrvVq>q zISZ1wyj~jcw4+T%*LQ2-IYlj#3_6zE^5VXoBr@11;T!NI8Zpr9Os0EQ`19?}Y4)-F zCCJt%n8|;5yP-SUL9sAbF;;q|Fbz;9<9kGm6gs>$8BK?5`h{jUTHa+TLbFBEk}?R~>PE z_l_mzUn4zubuv;Q+Bm-yK8+kE15ioQSCky>$`q_&3$;Lb>lHe9fdGbK zL%-Kb8zNJ!{dQWpJ4d!(s9K4JRcEMNi(49U&cr^(cqo#1Xd>7NaO7aMnS*|MQ}KLP zO$?}!tGEKL3f|C^&LF+U+E46KUyXK?ri&6WcB(s*h)r8aaXTp_Zu!iUrl?FD8%|r} zzh_tc1i*(ItQtvkbZvD_YvHhR-2GhmgeoCnLrUE~TVojkniUYvQtQm~ib6uiY*ANH z$qt&3bGD1^zS!v>c%70DT6kPu5wbUXo(&HszpykYZ ztXrWMISrRd#y8QD#dlL002SsdYX{j}p9DrdRO%Bs|3f1*0CnxHw>&akH5>m^!vKk8 z`8a*@;Vg)^wIub~)*S5{4w;%))*{Ve3U5-Q^U711d0Wl+CWKzIqD8zhHt0srD7CS(N8HveoA?-^4`+5n|XGdz-gX z4BC2HcY&4^g^PQNyuW{ZxD;(LFHS}0mtYD+iJ%Jdx4|Z&Fu69Bx-+)tp@U0qs3knJ zsNEW(yOMVL>6?pC;iI#go*MUfzWhqt0)m2DJW@ip$kPrde69F zaJpc=8NB>}BUoSDnTu{|!O(>Db<7bdB8Bxiz~6%mSiMJT(wPbA>Kb3*Q+Gq|O5e`P z*vMmnI$7=mF?p625t7lVP@So05JfKMyl6?`&Na6dAq=K6LP zi~{b)A@5&wTvfEaeO$RbjH!_Xr*C>jPaN#7*&e5DFvxrHG!n}Yy^8+y=3Tt|tJAHb zF-mv&5mxr3R+%bZob&Pp_L;V*UdlJ*on!QxYLvc7Ka3QwPx{0*VnhzG%sIE@VGJ|y z#pNODnd@hZ;c$Z*-53{y3ytCq>Q|S&VjWtCQ&VP_q>^!NPCT$?EXnBR=gTTXC@_{} zLSdFB@BkxE{O6=ezlnz&CN`aUIzv-~!D~JDxjZ75SQk;V^FB=Mj3FcTomPq+ZoX{H zt8uo>hy2yvH|6V+lFF@VVmQQ6J`H@UO8Xz8T6Bk2v=*-mmg7?aWId;Aoe19efXSLB z0k9e!H3!tdIm4_iUU;j?o7b!t5m_hi6|uR}5wH79-R*19!GkYk7Mtk1b9Bik2L=ql z3`XGKq^cE2(Kr_hy0^{A(J!^v=h(c?xCzm1ZgtcK{SchWneGSb@%gc32&Rt!%Q)r| z-&NEikJ0TLOS>Tno_$QM&lOH%o)?N(sedUwc&d54GIe|+>d5x-Rf??F*D2dG1#z>vG}rG@)D>`tB|*0rSmOFm&oFS>(o4ztbqf#hM~P-4w`6O9P0f1 zW!e^JB@0Dw$h7fRdC%!Wsq`u=5(!sc`cl)PZos{ULoQ3F+yBN01`|jiu`3b(DnF%y zF8yUo_;?nj)(0|bckeYi0RF-`!u6Yk0dVt4}Z`{AfHhy@n?ehsIRSCdqYl;#Omi3&CTmLF?Rl(UF9>(&3( zro?r<8Q%@&@j)8t8IG!cbVUV`6owc;Odm+%_c`-yt-8MqtnR1_G#wYA8K1AwqO)HS520u6xy}8P#1bRowJCSbV#pxayY+>vN2^tb8P$s zkV93Ug+^*%rVUaFG9_|Lw*{-TOA$;{)aU6}eySj+8aQfC3!Ob6koMewPcY=Y%H($( zZQwn%LG*g@JrHpw!bTB*{UrxgJ-9ihFn|P(l35!FG&D9^No@wfV;WQDyXTgy5B#w| zcry`PWhQ0i2r48imLzZxG=7TpM6Sb}#vcL@%sHBiTF3YbHB>AO>l_@LUQnBYhTl(~ zA{iBb8Kbw+793|wJeVGOv9>Zuw{eaA?b!Gm*ISH*bv+1eWB8SSRK6ne=wKARJ^IJv z#Q1k2UT-?HTgW0wm*oTZx4J(7dX81Gb5NCc{K8fyd*G_GRq1+XYdpRu#jm@^lO^J- zW>Dl-*Zn;--3_r35~CS`0>O=iSwM|0Aq2`XAcwG?*%rTKayD{IToH6?_RQM@d_K_YgMqkIPL{&SW&>5Q0eVvuJUi#tH|r2d{2~0k9|>KsnyUNK05In ztc%x+fwm=m%ZdW1GVSPt-OkTfE$}Jl(ulp1Mzq{2b1P17^<)hsAJ+j+gmYZnu{nxP zb5!LUn5k~)f4!vtmF$=7m!e0W8-kMW?o6LDPRKo+{E^P!i{fx^YCSU;N`;8Ibpx~SZYv%WI`h3FA+c&)Kn4j&}4&}lM^ACMAix2P>{75 z3ZdT$%qf*Oz)1QHrD)FTc_SI8MZBQSBGPJXpkbwih79;Y`}q@q#^0HphhMR-0U06Q z;8I&!7?JjhrlsK*s<1@4Ecxw^<|aSK%UFHyO01OvFGi^WdQ8%WZI2N^o}S-Uc_rBm zjs}F&)zh1@7459EEHUCmFV;TV&p86HCv%R4>70+O+MLnxiCQnTO^Ymt9=`uOpEUz7 z#F9&ClQq)Va_~2f_ksibK@bMb?tA88UUc{fd7|Qe_8w{pHkNg{+;HD(m&@jfJiF2X z_LlZ{fETSF7?*G@rp!kTus@0^GBGih9U5~vRN4pM`tB-;u%XN=el+8wytQ2o0KywD z@{?+oTp*C@;`zEvU%EDE^rn;yr>d2rF>6rM5!wC%W3}_ma|LLpL)NSN9N^GsAeJ-2 z3a@&A@M8FZUo7>SOv|X2=pf2nSkqkxq^&o8|BY>$S>!}VaJh@2Msf4Az2VG~P8J8` zxSe9i_#C(KvX7T6i%SCy-K?bvPDfHLPRb7@N356OfGX(CKlnNh(n9ln-T ziqXn4Yjq&fWBz)kG_(a`ku&#rz;opAB;Dz3YfpO^8|TkQ#J4aQd{zcP);g%f`;ukd z0`aUiG=&RBQb_SYLxW|Z$J`)hvq%&xDQPE^&i#P}6#N(}f_gil

U#_FZN0;f{2&~#YKUjp;D){FhECKl6JgL7Pt%&zY~e3{ z9ik;o7{fV*&(nd{p=*YH95drGX=+F6o&MbWzA}~ja+ERXk;8dUZxgf z#;QZ|!TarD1M?kqhPba1S?LroP^`a%X|2@LXJ>W<_r93tJcWE5ai?@`$n9Y~vbY^L znF;4pI+yaoL-mSFxf8af~+X zcyX)t{0(5mkdgR{h|4UauLKI6GIrVkQ_n|XS zTzjhMKzu}rT;YEG61bz&cH%A@pybWz4?xwE2-BIpsC^#j>Mw9SzSCa@L^1my{~?)3 zhV^#jz|G&Y3c_qb(s#=)N>4C=G^^Y&@|985k`mznk*P#ULWw@bP+2?TOKS07Uzs=F zT}$>q&i{Vw{!?RTUHf^u97u3yRP#?Qj4dai?2HTV$Ny8xSH;8ua9vJ|YjKAb7~G0e zC~a{q?l2S>Y>lO!W_}ga0V(ozb zF`2s=J>6depPua1feGX(M{~k4k{AqgyJc(L2$raJ@V1&>mpJ4QzAOwL(j1-|TZ-pDJ~6Hjh%8rXQhynBfzh z=a$o=$KOm2m;(L%CCP_LI_4^(5W&R|S8^i}suLmi=v^qYq4Ar-jRuK?^}sLRj1!x% zI3BGvE8?!|@XqUU`VRy$XUW9++eq`MOl+^&CIX#P~e{mZq)GszIhh}%O>aFEC z=_HG2gmd$~&P`=CB7StI?JKvmgsZLM36KNI!^U{%@fQ82hf4dsmz?_ZSa@rvawU(f?`v!RS9y`7g>{_utrUR8>m1WM(E^Wy!-*u5Ykg+^Igp%;D2He%a;B zuqEpBYW=8dnfAZHS*U;xqw;|FKpo2$5B~b=vj7hE()+Rr+ZWpb(gt-Nr%c}PYTxmc ziYnonY2Poo5rTNNW#VwJP9B%p6AYYf;i?(zp2f)gbEUVM1xmk=FI}nR%v6RVFV0{> zS-VX_auO|0(L_O5f%%`Q^&@a=0vvlh{pE^m>nzs0uHh17xj8o1`{_uM;{cxCN zzA$n9@@VQ)acMAkUx?K=Y`D^q`O4^CqL!u%T1aMLZei9E=g39WN}$t!mP9ItS5O5H zg_Iq=W@PT5nfa^}q&60e#(9%P*2;`)Om|snNmJi3d)D;o+w6XGLq|(gVUzDnu81;6 zYTWiqKc=VJTI(<++m9QZjosaGtK85;E)gRCC^GyrLMDkm(oa)5B2U=G(~xc9XPimv zw=dv`Z1N)>UX>364D(_n?7HCxipbW+murWouP!(h`QH2($$H1pbxh&?Bt+H=Wm-Kt z(08%zD_M`r!7FhlqoU`xL;vWg#O$CKp*m;Z)oRMXUEiYo1X_isnRsC0ocj`mx@b@< z!B`TG+K2czsg64u1Zhd0^^E*sh@h9N#E@&0n3+^9dTWr;K2@^RAP{-zeZ}sG?TURM z?pE>>VN7dQwA!~WqEV*y8vd8(POufnWT+Z>!&3j?==Xj70tmAJsX$7dXpbD>XbqQ0 zBZ(pPdrcxT{1F}hyX&e2VM1}Gfh!7EJhS{_0Q=<{5G#!(Tb@O$Q>@F>h zWDFEDHD8$26GZBV*aerWPaaWxfGoBtg%>lSD8<``1y+RfKK&15g`lbQ@5tsBK9 zInb)9HVRe)el+}TQ5mf(vP2Bmsr zXJbpFV`17p-;KE`yE0>3kGHTDey=X#_M59)Q}p6Z(QHXWMDIFi3VxEP0;L32q`g9q z%3vK=W@&uq>}YGwTr@GGAZ*1X6-?5bPZi+!$1lrCkxI=L&qI+ATCF^tW>lJTCbzvw z914KdO56TOLQ1%#BD`pH|^1?WnqAwn77D# z2ZtTIJ>Eo=JE#!oXPF>%8oJSB@Z;eji(7zUrs|}_a6VD-sw&6VC6cZx4@)hIWW&lcfW>vT=}MqnWh~9BHBBs*KbU}CzZY}% zD3796B?&?FmuyY%blN+UlseL6T3lJ0#bjmeM-Bno+mejdHXZG`9D$^L4GgX;oego` zsLb_Ag+bn}#Nb{Qm9jHwmhI>vCngOCYnF;RC69?xF=sZmr?d2cl{$wS4RDQgsDaS$ zwxI=9+Yrn_jvMtTKDCySDK(j&rgYL~BjBboz(JwCbw^hEj0#W7D%QvQ$&o_mwps#s`~v=SO+J~oai#yIT|e}R7X7^~ONzF+-7tlCbxOLVpI|w_ zls$_4j-%MYDqj%D-pV|3Zm=2Sx{YdwApgkoWkFbDPw6Q$G^?9MNdFX3=FQ$P^lUoD zOGJ1&+x2J0c0I&EY~!4FJ$Z}r>+~mOw9xm1=5e&0NzBSJ0ul#W4XwEocNCzAj0R2O zqzF>@mT++Un|O5=6cOo*ko|4U#{S}2-}WlG`-Mft?vRHh38Dv4&U|I+$f33sXA*a~ zt1}Awk0|-bA>Von%{Qk?qV~Ge-d;iNeAh=qkrWfzwz)xZH_3CWdsPCNce;Y(>h>mo z4?mIge5RkEuD-ydD@pbZbY(^?QLOeeg|^{32tGZtj-Rn0)6yWr`{tBl;Z$4fv@~nt zVbouV+)9H)`_j_v8IvET1!+c@xX(vI-gLG%reh0NQ&TthhQZ_bV8?+1ryy(INCRg-qCdYpu=8gaztD}%HS<0_#psvVcW^_Oc)5I=XGNaj1xL;iN9;k`Hj+-F_{X*90?Lxc3BaiyB`V900F-5-{J^IX6PgNG6 z)732dcG)m2{n;3}cvG;3g*(@$#)t-APK#o&A4%o%^P#5SAG5yKbQmt?Ra$(& zcP(w{@37G!Z;jO2WBe)iBv2LLPEgP^E580-EQY!*MMx-*SQGRs>=|2uO(4n2UqiPt z=f&xxSntyBZUIr>g76PO1w~$RY4pPzxb+sgpOcsS9Y}M^C&t>E5`!8OQ@*Lkt;3dP z@cyPUJ2^IyF!h!~j0yYBX2$i+UUUD@X7Nz})q`<&m!2_#U0ii&^URupwM@Yi;F$#z zGDV-0o*TC2KgK#B>2;tZSBo!`3X=}EJ^W2g(UavHAmQGu`(okq=%^~FeS32noBcaW z&Y*WOO_J36(tqO>l5+gF+n!OPo%)rufBr!xgEU8r|KK?4#ML&9hV;)rtGYQ=%>3rl zFjElIzp`lol2NaQP&wHl2HqvZO@!p%9cp<9XSU4$P8#YD`v(w86#Iq4p6JUPrY*q6mTG8Gfu0ql1w(2qJxg_gvIKN7Q{`ADUNI6D) z{tazLK@gs8*;EK@8nA&8swzGpUp8Am{I&a?9aHq%lMWjUIFt1wEu88!gD{!9l}qIP z16_tk%Ir@rR z_56@D71D>1n>=IAg zxcKoHS|$}7jTYIub8xg0X~n*w$Gju~w`f{I?sxgTA>|wc(LXI%{iAk(DYnTOcbdH6 z7U7ehu1qw}=;mt!Z>Ox5o&i4%`zDAso>|F_N53Par8D{m7^HOe%Zfg&-kD{&pqX|O zIhA`of*+qY4m?zSkx1o5IW7DXCeUVe|0OKxh!pm76pY+O#o&8vkJ zY2baTr*2SAk}?@(-&dJZ^W~sT*gPV58eHPUX9v$#bE$?Vd=;YDRuvG~dpT6e7<9_> zgy^}V^}8GIAxEdbERu6;hBThrFFp@7#3saD=YFr2z~IbcRbuyM6uQ7&AT zwVebhZP^=nISNcgKb2J>mevIetLsJUrR1CbdC1!ibXpiRU-{pRhT6^d_Ov_dPqp!X zG5M5Y$ZJn$NZ_aDm&22bXD`->+7r@*clQJD%(+UW>j7|F1j@-+B3-{V?-Wnfe=Iu7%FJ zJ--qyHqKFqWan`rBDVZD#VVem%V(DbHO12$y|N^3k_68W0ZAdwD|cUB{U5 z3+tl7$Sf@99$MdyYO(CJNq7s6H{LNbUQI=&KTlrtt+z4SdZi9eW<@2Fnk3$S>hu+_ z49HOv`rRj`5ou36_98x$Y>1VW{d$+{9BPFKx(6OGb7vh_ca@hG#V~G~RmJ91*jZ$I z-z>~~0Lxe;jTKf>b{V$Js#~G#9S99CR+P}F9cjnVpBDh;ixmU#L_}rHAuSEuk2=VC z&#~wct^J10-bTA1bjclqf1cne53(=UY550;NWazo!e`yZ5GCUJ3Zye?=3z5C zApeF{_0Lx#nX#~j`E3pV97x)uf>UzvVJNn1x()6EHcC%)iTPgFtD&a0q#Xw&Kar6Q z;M7yQo!_5#u|j+o-$TM8gwuQt0R3&dxjUoC&rA&+bEWfKX{$@Rd}S%^QIPYRtCJzaPp-CxYI`CQUxTha7Z<;SxU_WIcorGWTb?g%pvrv^s12 z(k)T{0NkpA)?r^r{oY)(;@kBA$<&x(M$%F_*JZY`URciCVomn(iCdTKNIdxYH6d|SCk=l>r_*zKDJIIqDDvoq) zu?Hl1$lOoWc9OVlJ0c!~**u%iSMoHVuxwxZ3Zs}(xsTauwr*J;np<*+9j_*w4l%i3 z<;f`H{(fj~u7sSfnRNvVayh5OaVF7D4(PW-ED&D3lLRN+Rble<-*QX~5`l*H@&*UQ zr1*dGLwLQ)e>UYDtNBVhc@&q;*F-gw73kj`jG&dzx|>7oaxYg&y`{J5#)Yqn&_7(X zx)Lv0qK>{(3NHq`7T}l97$>RzUymwu0TttqbtsKFZKq3p|3M}lA-YV z@MaH5dx;6S2`u%E?~jaSCg$(9hF6+VYq&K~jcl(GTenravk6;opMw%z@3{9t#w9CAzWz-uNvqJ5{PR}`#wg#Ge zSH&|a0%T`x%iiSab&j|^2kFkF>*N`=CW@KPa*Io*8N{g?bEO3F$UG3A^-OBLE^9l~ zvrwR_R|3`-HBzuETM;FQxXb!5J3&Vy$4{sYY?IspHG#gQRgcCM+SZ)Kom<{k%~^ZsSTy14A~|;AJsFl>VhFZzrwa@DJ2G(4c5vZ z`MMD*eX1a`=*gF-@?)n+QdT?6NBn(NJse$qD#*6Tg*1|bu)D^7J{^1*q7f;S8a)U6 z@B%NL&4_omR}i=J#*4rVSi6up*$SS-VT@oLclQmI3k+Yb6MQkIH|ax#g@v5>DEd-Q z5Nz%m4`wA*)x&p5Vl0=^gCQ(v+}ALf1|E=xw-Sm5!bcv%bp@NquTRepi_VFk7mQdR z2G4PrdjbuqWf%5Ep}g-(i2UqA9Cz($d; z^~;cT7Mc?uF5j1--?^&gIN_s%hP8jc_R4N<60?`G|zK%>hGJ zw(DExja1o;5*jjACCI4`^H0$p0jdE$MZfyiVpq3iyd9MWqU{}Rz@0T<(279IRyOf1 zR^1>89DhGr4XC=S;xj^8(UUqdGL^2?q=)QoEH&W=9=wddqTxHr_L7(hlD@y1MXB@a zwzZ>>}LM6n6@JJUgCSx>gQvY|U3N#8Y;# zI2B1tnLWl2<3&dNwZVPwY{pU>AUlTE@D^W)oU`sWFK`vMPAq*{2m1j=>Ar=iUz+Vt7R*Quio#Zsg&Z zX^_Ta$C+ij2y5OA>M5qW3mXzOE2V=;6xvZE7lZkCGW+&*()lTLdBb{^4MJ4P9Pqg2 zaXnwlRDSq?Sw)JjSSYy>W5`Q{<8)pQpgVYg*^NxUFw(g_&H|prkXvo&t%O9QZ1f*h|7dXS>91nr^%A;S+%0tJ6Hw>d8=|=R}SdBQ^Y~K}LFUgA2DG`F|vLMjo{`zzjLI zP9@CEoxQ`g-nY}l`c6$#Cbdo({sW|=A(dV=JzZ5c|5$>pF4a#XOMXmYU96GN4E z0A@f%%D3v+u&?2(ln|&*vz;Sln#6#CwK~EN=vTj5HudeubCYQ0dW}cu3AWZx9(NUR zJALK7j!p+M{8B7#OM_Q6DTq`SXf+z}!$`_~Bcnn7m?)G0QAR0+mo|QsnA_q2URsK0 zHI3G#k+?U^Y1_bObKJQ2TAB#@5~p4J*_+s*RNWp+nK88o(BIKo(z;5)mvVD>x6d0|7_E3LL8Ht|&c8Nb$Rdc^ga_>rI*P5apK3FeGRGP1-8uthw>+yT6fOm)&uc?eh zuOmKPx2|5c#~v0K+;B+&tl)>QD}~kR3dD;?f}<5B^Ej5dx18ojQ?3*B!M8;e?b30- zu_-(XWvQ;|SmYa!`F*9tkopl8iFvXh06`g=8vv(!hWN}};px7Z41)o0(_(yqU-JH} zA-6oyysfM%KLAyo+%{wCv!@?ha`{+!2Zm)>9K1gCDo`RnV?C`jGyTsjNS>xjQhY7K zXqg0wp6MDMDcK16cxtwGwzOx`6JI6FicGPE$cHgwJy|AfpGB^Lc<0wv*nvu`^7LcO z;~suV+I}6yu0ayuuko!iiYQh{{g-=To)h|+!qthJx*=HH6r%aSnY+{;V0pf#$|XV!qMe|p(Psr z)bnXDcI27#=`nQ1w0Wh;ytiQFhz!a+WzM1(7cs?>00 z6KFQFKbL-H93|3}^i>dFaBw*>wq3<9vL#ojJ&H>yc8xK-vy9T-Sc8G9bDJPgN*9ymQI^AR>qDVv!Y1GaNvxa ziA>h`yzcoW-cPl+%w@U3#u{2|@10x~l8cfBI^10@C_b)Eu1rqd{R6Dl3L?j<<$sMj zFQ5#~H6pnTWR^teE`r9w>GZSXcb#9U)6M&Q2>YP2aPGztqa{M8C~;-}t`5*S;y4cm z25HzH)Df9>vBVoh_tc>H_14`EXA%OKNOyVT9_r_sMU#_FrFH(7$^ZX@{}T{sz;FiY ze@}c2dj7jInxAh-XVfr=R~cWdnA+NQAc`tU{*`VXZ%Z-v0FU~A_eAmk4X92VY$t*z zXrAFz9>vNVo&Oo+!v#>E@+fcqTlpVQO9KQH000080J366UC&aCf%{tk0APy%02KfL z0C#V4WG`)HWNBe9X>DO=Wi&2oaA)kgcU03`*Dx3xdI7zHf=IE@2~9vix=Qa-LLi|@ zC!t&e0cm2nB1OP}0qII7Awf!rp;~AOO&|$fETK2)Mal%d_nmpx%)0BHZ+-L5^T%_t zR`x#qoPBmZzq3EE{~2)FNY79YaOe;KaESQ>><!*lK|H#e_<$VFa0A%1S|OH!AFM8zb466Y^UUy&BSA|fs!elW

a3mR5-4a#t--Nw0Ft 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 %a4Blu$6u8+F zh@@ECC<~fqeeNs2EudEM;jl11`OE``@1iS#oOT{+}OlPrL!(EGV z3c7r3MsUUo&g*i^b=%<|dWeRcY3$jH)-~gjMrxI)1g*cvr zpUCG&4+L$lnO(Pyeg2w;y2!Ao6x^~W>19IUK!8GEQSn$$#yfU6I#!y{J7Mu*%{o@~ zRJg3Xqy2!npq7Y47Zisht0Ea!^_1j6#}@og`0)@Y1boJ#f<<(n%}pA+$p{zJYzmxt zy3egeK#uSHTsZ=ZFz6%nI+Dw8W@k;Ya-EZ=`9Qu8D>RTHBO9hAmO^pzK# zhh}EvDI;zH2#3##HgV~}$0cMiG~1bMM|6L$N+B9t2|SHw@T2!8zEW*<-}_+mn81^0 zxE8fV1l-sLs+4odq|AQ&x}&G(&=&6-a(-~qHao)>0bBG2mCrMUsT5|>hry$6*GIpG zplYe-T<6a*somXZaPumHE+01#j9;@GD9IMKCOOwh&AEM|J-j<4OujsCFil_VauC{E zmD_SCplHV7L>;zx+qM$x05o;hjfU$^mcbZ|H%@-A5iv5GjdvdOv4490hiGWcfr3{7 z154lSiA+VEYt&gWzi4JV3*>;2h#Tg+9si~0^?<}oEg|wy>p~GN0NpoOhPxAKp{v); zXxGnE&8^b|gNq1*o58Zqc51R6;e}kLw!=n5Pa>=jYA(DD#?Q#QF)Tg0g0AsAsYj;W z-}l@3&o7>*R!hx`8@xx(YMSef@K?9pl2EgKNeff#b0^La!yrVFLZ8%#C*HFP>CT(S zS(0s_MNWWc2v>iUOjn@@#Om7CDvsNb404#o4SrH#EUv~X`(@mrZ-}a1 zjYnas6iPqV71Q+w(;;NHhNl)8s%DW#p|%tUh?8+)L#b7DGpeNP0Sh`sH@qz^lS9ZZ zG>Ua;Q5JZj4-QgOy4vE|XWzRr7!))b*7M;`Vo%p%C}A39Uj&CC!Ie0u!h-Rjgtma1 zJ)tB^z3Eh8?KCME-PIz_(>SSD2S!5dQx@Svr43wPYBIjpJm`mod^3T%xrt@uTIq;E zF=ta+2U6V6SoBiUz38SI$M@;|89Y z2(?KE!ieN`1Zdo_nvhY@C-;svhJAhZImgNWj4}Fm>dr6EDBwSMMos0I{<1(dS9DJ0 zn4b8HEy_*O^?~ygA+{u7fkyDL7PDHKx(q znakqi9q;SDgTcC{S#uqRw$b`xLbEdtj9vK^Ou__!WRStAP^Ivcw|WJNf?QY`>brDPmKot3@`OfP zxs!GPWw)GXEpDtKSt&@w~KJtD`6)arjjFQI3PKfA+Zl z)xUs^S10AJPJ$KR>HU(dVz1u6X}Z02I~h}TB85IAeKQCg`D2c5_xi+1Pnb=^Gi!}& zJ>7+m1bX$@j6C~A$-LNpjK3IJ;a;dOGDFanlgGS9Ta$C;m_;rv3y<2Xn@?_z7;sZ; zo$AsX^=#V+G!djXgKPZGBaFzFm!Gy|VvBM%z!h`;cfa13V<-t{#yXP<6a6gaf5VxC z=~f|m?0YfvoRQ2vc#z>|;U?p-9x(@VXg)TltIsflXs8mrQ>A>VzVE)=da0hwaYY+0 zUB&h$RdM3*z^wgfWXRZ88PN21owMl0g1V7oL^y;Z?TBSY#Fe;#!4(zEa!VvfWtAtd z%?2P`wKE=!ewabGmdJhk*4Q}ohpvAw6uhT=Zz8ZWlL69sozH7!g+z~ z>wF(lr&LF~DJS(wk_k;VfMCfXKhXCL^SmOgznbq6ffYgEoKtQY?%lj&YAVB+Q<&JKlAu)e+h<~=k`7@wZFTA2THCiN0nnF zx&l4k`JChGIrijgA!d6!u{GDN7iKh@NS;R5=l!!8^q`4P8 zqc-F>w!@xDQ!nITC=V&xHMc{0Z$-ylHF8@^B|U<6u=`Y1fIzDXO!j&_+`0@7KodRA zUuH(@tuqMpe%G-L_%OZVYvmUXIYv`F$VdYd5J3kgh$y{>MI(bGJR6IAEcLHH63KS< ztYpA1H+E+$*&M@Xd#-iccc!*t@AC~ZUcNppb4AvSkRdH{-YB9JD?ou5OLPHM70Tz| z2f1sM2Wha5w(6@ePgb68QYQw0awF{sk!$Hs_ISovcK^`QR(d?3EvQ0zsMKsNPEu8OPYDawzNOb|$+DK?_0hIc$;ZY5;L5gr_Vv2DI@dTV-A&uObwaBX zDTmWzZ`v>urKVWp-K=$uR(z>*%&<uM3!kt9IIIXXfG`?J^A&#Z79+xpK)&Oa}1Tm5Bm8`n8BeP!l9$IPc!zNZAjT{VYX%2d4eyGmNIOIzmbzY94 zQO^}U=9=Cnr@3@m@K9Ntq;phEyuv&5_iTR2sh^A&GVF6tZORjTL}PAmnC)-3xGpp? zuhFx6>PFrRhR!_biaCIU14_Y)KeSq%K^fUyp5Yw~&m5ISV)Ye|wLM?D1vY-gjg0y| zZsgp)sX52r<3?)z9ygMDBJOvLVEo4KaU-8=+y9QiIQ}W@=1Q{?AOh23V^ zJVWD?XsxA$nNJe&;}843!x;J45Kd^#dH#$&Fz`wG9`1CWhB&@vpUVHhR4=m8v2V3R!>FYOXmVS}R>mXgp(>8}@TZED{vL~oFYxAJLz|qI z**W@JRDgOLcP6~RN(H@Ldb*$ z-e4{y@mH1gPLR^{i67w1^OhE9m=8=}COya`fxgbJIYN(Pzune2%Qd5Uq7GAPJpbVl z7c7eNp{rA_DVp7_4fA<73$TyQc{IGpZ{ta2hx;=U2ryeQT}o{|z?I02cCJB#0kV^!D~bfSR$?X!T|ya@{64i)_B1PUG!jL*=OhpuuSoP@U4OYXVfS)d&-S zU?)}>Dl38&&?@H;rVAQ^B_Yz+r z@izlmwr09Mx0o|kswn=78|%e^A4Ej8Gm^NC+(eYp4#7i-6o2`~#_2*zpTqIVD`gdW zVHroJQ>C1-lMkAQ1S6RQ8V<4@d!)<^dUe4lO%c}PDDY@@#)X>e;cOBTN%5;~cxxq5 zCOEZh{-L}r#k)Q}LlcsrZ0Ifv`O|6t?@#L0|6el_I73<41Bnt)&V0lx+n=)vqQQO7 zN&4ROtJM2c-eShJ1G2KPJ;t0s4vX4`%l|zE;Gb3>uaup|D~qPirq5KxcJ7*^`8GnP z$bGYu)_s8H0Z_&eoZoYN-^{apxxNOB>M>Ef6^hekF=Wa`HhHvP@g5saY2)SR!`{lI_{d~W6RI|3` zbeBclxPDIY$@ycp4_1B6Vt*rBnu-N5?IJ1=^jz_IcX>XSseu-A%OQYswIobe~d(^v7Y!YIlsI&CujTrs=uT2SU z5v+{DfH+1M(4gb9xCnOt~>0$ zga$dF{Xl2dJ`x#?{d&Dv!H9mQDhTAyZEgMV_iG0K-If0vH{}0Y#lT;q@t4q&x&BXA znE$Qxr%ej)-T1Xhp}DVm;J1w<-zI~acbcX;moBO;Elz6v6|zsRIXionmCWARdA##Q z+i}#){>P8nkS)>km%LB;e2e1xR(1EpU!mhsE!&1mxqogue#0`ZrlvTpTE9K&U6|dE ziMo)bF`d6bnO{Pp18HsJzcxD*+c*<<=|%B)RmIc4K{MaevQp=~ zH#XLJHk!Ahe)am>pL*Tw+_@zCd$0crX1}(&E3YFfVrfPXN4+>mO)M*{m+RPGfva0&wEwH|A}bt9~J(n z@V{IEf0T^*`#kLm-#^s92KoCj{puOuA8JeNx6RpXX=&XYOkI9Z~yta^U4`hD8(z#+sVAO5|2_8_A* zC=#1oeMOO~C+Qk$Glop7_m!Hv921O1gUty#t3sRH zyBVIs+3eyYi>vdT)&zc{+FMl&S%-rSpoc%#?mt)i7^8+c+z%EB^++*x6 z#|Puu{m&yEb~%pP1B!MzLKO~kKa{)oUHXpR|1;q{mwDI#bK#VHsqAza~31 zI#_q|&q3?~aP%j@<_ z%%XcMBTf@3C#$&Y1N2{0o%0*S0v(i@#rlzNW~D6-1sxfj>?%zq8lyZT-vyt3>U#Sn zx%(hCyA4*7w{nao?)gw%REd(2LCc2^(`hqwxpIkW?{+`r!u5n6p{C;2qwU7o$)yjm zAKgnV>Wq1^NwdL++^W#I=rm-u_ERsyv9>FGsCM4f7Z+a`%TO}Fs&Mf_->bTW5xP4{ zbz}Vu{>fyr=)n&5$s0;H1hA=$ULDjfhYLE}c*vwJKS}G7(R}$g*j8GZ{K@T$o#8AB zUb>ied)Qs|P-DH5Y+PZ9E>Vu5br3xA`j92aPAOX!9abvQ?~;5&=k2<)pY2f6 zJ`d3heBi7fvVK-wNdwJH&_C62H|eRGV1B->BT5U5(@N5Ds%DabY6YN>4EqfuixUr|NPhTP7*d)0zAwZa%QIC_36 zs8T4Oi-`0{(N8z|kff9?VlNh7OcxYZKtntBiKBbv`j>PAW8oAgrDb#EVgGw(^i6lQ z1Jo9k&76yqHuIqRm6>_TL{5}#5k~CBO1FbC23g^`)fL8rH0=(u=6v72<^1ef8k_&P zpT=;jo0y?sy-NT|K(@c64Fd=dw99k(<|zq^2$20}At3*|(;hAj2kW&>Gwoxy>|O_iY&ECf$L7Xdg_evU)X*I`w+M@^lu#Lwyt?to-avo|7qAcA9Pf zG@H_rXDR`4aC`n?70YGG?Mh26qPu&mOL{AO({*Xwa9Nu)fhWa@ZoqYhr?IUxhy;Nmpb7l=zNcJ8nzTqr z@X%>|<~_*hPU{ubkk+@^+7*IX==R0^*tCr4!tt=a;m(J&S&)sNa9d_`cHF7Do4KTt z?5FDaX~Y-j<>y=?$_Sh`HrdYT#^J(Ye6{9(Q`+elj4HkL=Lby^nAlL>5b zMlznwE$wm`W9W-|{dY_9{P7HoK(URNXK~YqmD;(`#7m}mf)af#o}>78&P_7nx(Ic? z8B#@XT=B=dEmAAT4#>D=<++F&hnjSb0b^tk%z0jN1CQU(T%JET!=p6Fv?sG&!w!gb zm2snsTC>g5G=-R0I|(MkJbXXXUm$j}8-mYMFNqi{Kb;g?&oEiED$nDYi=J~JN|naMNn;+w7_JzEJi52n;;(Yo zLGAqY-mORb>9zAtR8nd-pvd=P9?t>^GB`OL$Bb)`4_B%W*xOoKdcs+FkO;Og%q`FU zGAmII5~FmKEV9me4Lm@*9QBdim%bpguhI4AwCgBrf>uWuwdTUXg})Ih5UnYMkzD@) z-(d&n+kQJ*G>eXTV)}w@ik*)E5^}BJoGCkDT0D+WRS;OZ`+lX7cMD6@CO6DYX$%)s zj6##w7JV{VHaJu|j&(;Asv%cP_mTw_3D+x{c%5tY*WtYotH)Afw@%sE6H;UH=kM6i zO3^}_{1WP>=2sFhImbYhfOb@`0G7@N_GG%`xp;$1)>$e5IhP^CH`q6`nKrH*mrLKm z0S)JD6hrad+Jtl@-AB`|e#y#%RWLBE_DbH!b@PPY9ZA${#iJLG8x0$6Ps_M8Fj;UC za@^R|vdM!C&ff5{ZDUtq-?=@;9HunZUB69OmgZ}Tw%Va_PU__dtg?s`3=X(Uw@5cw=3Kt@hd8JWMf8NUhixM&K4p;4L&<@NXfRq%AhU%}HWk3OXQ z8=BFfrjBKV^BmJDy6Jp*mxeT-n%jm4#Jqmm#s#`i*I@dP<6iPTi_y2bv@ZYEUh7qODt(5NUX@q=e z>a@q!NJaBB&KqWk<9&+Gi3c2dV%G3oJ+u^=TeXnVjTKPpL4bi|U_+!|EP&o|e|olCt4}&vgLx<^qlV96ZHN$wB z#?P3STmCYLfM*-dY;%1-VnChyjgZ4%2j%syT`f%zgLZfaLd|0yPdyRijP35Z)-&G^ ziIu>abYq5ix?tuI*%bWZisgdV0#QLMv3H@0(vaf9wQA=I#aljt!nC=ZFyyO?=*xXw z#7=hC8;rYm#%9covU4ALNA2TG&*+1hByYMR|2OIP_;)Gw?B7W>+J$Cbyaio@^j{x` zG(O6IT^&h0OuNEw^C*~K@ObILZF%Lr|A6Fp2Jnqn>+*U&f9_Vs$IBA?QGeIYkv|Ck zApC>y|E+{fMeO?^+ZM5IV>i7;{t5LlDS{9>)izUOYDYHJ3KQ$l?qgMZ{m=XpY z!)KL8F=h%mJ8<#pZa=C1oxjNMJ=4@cqVx~=%FNOea`!D}bx7!XgT~rCdsoaFOe2eH z!}n#7)R>FWR@&)ITW>9Rix`yJ2Qjv7?lnH^+ru{b@pnxfYEF{5(E~G9PI2>PbvSC& ztqMo^*iFxjH4_SqGi-M@w6nQ{Vb}6u+lGA6m4bzEy>XA2*IFqJJHM0LHLio;FCBliA~-la&|+#X-hr(G+V;U9Uo_l4 zu+U;t$vJ7pcE6&O9MRkfi{jHHX&YqNe5nJAcaVrgXD7X2vvyk6Cw|@l};YDo6fYD^&R#sOBfNnrB^uu z-1%gPLO!n1qtN;E7zOXcj03<0zA0kSvm=h5CUyi}h6l3=iFSPZqX6`RoY=22vA!|Y zdU?aeni#RgnM%G^S};BMg}3VUf>(@WHGV%Jr{WWPLBgB-4Rto0tV_ZIY*S+>GB!{E zpcR|7xOOgih}3@*;$C@6fkS zBmCz8TZz{wqUBo)Rz`ZUv6$_o6Scqx2#pGf7F&1Cuy33)@A@J1_-676{3&V7~2`d zLX@;Gs^$Dt{>AzLfo;5g3$fOrA`+%@T5#C8PS}(afITx{G-*s%;b%g*za012r+qOxl;^lRVInJ2dOB$@;jc=?>gE>&!9%Me;bs z_Tk{ys?)`@Gbt#T35vhk`0R5cGGpAM%fQQwaz5u2Qbo%YZkr_-ns|pg6)lyd1X!u; z#KHl>BxC>aX-n&dZD4Q+Ane0p(}ahX3U6$xPS8wg4ucuT5(Gt(S>oSF_3NX2RW#`Q= zs+`j}1tJ6Z-Z+whs$l6%oO3tI#iu=%x5)1Z7dJMA_gJ)j`Sf`R7IjnY3e>~5%X@gn z^R9#JkBJ5);7#PfkBx%)L_s!})${(DvH9%Jw}MmHVWs+AOG>BZ+s!IeTda^ercm?H z4vBq$-ud&3LFK;Lu)zol#$Du?drLPwgg;q^CjEKN=G;a35>gn;zjZRnEL)yL1jxCJ zRzQZ?OS%RGVB0eR$6{A2V6cvZWu(!}he$-dH>v{_$I9(=JOP}kwlh9ob23T9 z8w&5xhvO|I!1sn-ay$~JtBl`b^W!|?O3MaIT}*S@D`Vs);GLnXn>usC+lI7m1Ptr= z)_BxC5gfse92y%wm)mO7S)o?ftXG$3cuYRtKiI@@q`{*GWXikLaV@JTyXXIBA zLn{BLy)zAJD%P1HnWRBs3xdGO0}ehSr)~kB&^_O1Xf2Yoeb@pC+ z{nz<#X{9w33Lz3!Ef${=F#4L^9;7pZ;rW6Hg&u0S!&mdC*`FPO!6fJL8w4`0X(g|+jGow^9W|;u(7~aFETM0-m_*tf$qsIfs9~jFJQWd6 zCZ2lX-%h4P95JJEnIzJX<8+gMu4voF`qNkXlZg-S6m8ms$S}AK$l42BEcMx8zJeK! z(=rtR{N?dD@c3|cEBSnMjD5&SJr6x5g>(K$0sVBP*;6qh`7eQWNVqeT-#(8(?>1gG zMi;&QrRi!b;D*M!9gzqvG}~n{Bmq~q-@!Oa)SDQ9t1SZ5M{dvO=Cxiw{5{vOZFYvq zXLrPHXC;&xyzNz|;+2{trWG$Sic~j`pNGR3)x1aV8J52Htyr`>SWU=IBXEyoSIunB zL_DI3DtQ%?SJr7r>y7YyTdB7;V$^(n*S6vUzRm4adlWQqDrmpLw@i3y%cX+K0&A`~ z)#A17wvs=fUz9$N)_-uJ#BaZ8t`ya^+)uz8N8?|7Oqy6Dpo4*-4;dme2(?w%$8bLe;Loz?8&2WTJz*x3Mg&_z5&%7TA;6~ z>`zG@jUh3z<6h=9Aib7Gh}Y@)<(UTt*FjQFZ@;y%rfZwP4Y%~(3i{~8GC_}R#4!>D zB?W0c{rK$%cl1{~dkw*}tieq0sVG+*|r;{5nXYHT7k4=9{O{ zXi?DqCks`Z0DBug~XuM%^j7bm_fEABvI*Hw8O$9o? zfU~QrB9lldPBX@d`FMz?pKcY0FT6$c9A5_&DlX^6eltmC*M3%>?g{ip6sxv@YiRDI z1~{*%|DjT(OiFQSR@D_QcpMZ@mH}0_0 zy(O6I1V360C4T`|BUp(CJZx>k;++L>g@w8%qBMhfHaFuwp>d$rvFx&zZ?`FnL%t&j ztWC@zkp{u&D~>NO)>=1P}m-PNy=1%%_9~efY{Wn1;FBDPI4OdIuD@Br!cl(VE3ikTmBs0=wjM z3bC;6v2d0>Y_zp_WQ)y}qoK=rDED?!6-y|8vpmmnG^d8?Za@XzvL_yJsv;uGBGU9aImOiax;JG+RVC#RugoU*stx z)B~b77w$jz@VBB~@257QxiSLSMOXTScuGn`V55C%2S3I>%RbcPKj{WxXqeZ(8R&-F zDRqZs^}JAMV{b~sfTRi0oJUwC3j->?c4j|%U$6Dk-Iy$c6(UI(rlY*{ECUYd3J$m~zDz@Se=@j=R(9CjLb8L-m!&za& zg9!JY>rXjT@S2q(fsH=VAV@tRBy`5IZHr!~)la>!g4%!;ehmRuk=5rI$tp^AALP`1 zeC%PVWP+iVVwU8rP1V=ASj;38UaCr~GPb#zhWeEd$W;qr5tzxfwanZ*!pTd-$LQx; zb4$asfig~XRCkietD1&o`Q9;xQlv(_QJTDy)o?!@x}Aqeh{!Mu|GCx-S4rFYTZ{~m zrc8mZa;8_4jo+A|vo!?33f%T#1B1oov9)(`#Yc(Xx7bOr1~Hj{wg39D~%a1+xr9q! z#rqA3+i<-avD`L|$bu^O99H_#B${CVkSLis4Tfis7&S&F4TJye60(&SZh2B>d9s4V z31o3LBmaKbXa9YfR?%0}h$W6>GIC<3_3dJWz7Kp&PJaJJS!8oI^d&m9FJ1#nE>m^xr zUXhAzYww5-;tg8dEE+^<>8DAy?y1n^R+o*KrDMY5*U9({*VCYf^vjfs#@TrH?+-E* z@d7DR>=LbbxfqlyO5Y>8OH>IBCo-#CNA}(yyoD4xizn=Q?@`2=v z_h%(Swp_oWlRb^QIIS33Es+ZTI^aJjAUhHKWkRrV{J{$ww)eOav~}@1d}jv(;tlqB z8eBr+YQ*K((oXv&a-9Fq{|a_gB@8(ecdp|9|-afz~wc?sN!> z^-q`Yq=u6ho#LT3ka!!Of>aw*7#pdWQ^qTJO$d7x6`!b3e@Z=>+#Q}#q}f$dlhXiT zJXe54$1aO&?~lj$RJOgWrkQdWux+}!kf)=(utXFoCx=8^6fKSqXV~7brEoagNu*>q z*mkaNk)0(iq&)Op$ypkDd)?0Ln{w}}Ye`23Rw7FH7)&gSKpd{&0}`SYxc6c@Fc$xr^jk(N2j?-g)tmgmVaQGyoa3-1Jcred^tyw(KA# zTI7Itz~IGBF1D+Pfa=(sn=3yq-JX9=i?i*TIXvI-7eL;d7=9RwfQ*MrMr!8x?ZAip zYHW@-N+unUJ?Wa{QA2;EEKs}T@yyH~c}UHUiuCzdy$82-E>1ms4YhaNreDzwt%@cl z)TV(O(L}22bi)3ffkTpf^~#c~zSQ6mRKWKrO&DT6$c$C1yx>^#N9@V}90&a+;o)`u zIVh^-RSK4M{hrD*)*Q?Y0`b!-aM17_HE5#R0cyXfw1&S$d<~nTQiZGiY1F;zAV0VB zBz1hRnHD8TbH--x+_N8CRSf7RV-MXRT5Fn*2sd*0A?I@w^P{5^UMBcIWXYcdfWOh$ z=vnh){fBo*ofCvPjqb|W^4mom3f>IR*oTLv{O~{C?Fw5?!Z8c;hXcikgyQpfPDxVc z{J<3a(bPI9;q~~Zjq9L^yXBVtg+cfD;%|S8EguXVg52BA{L~X)J@5>c)Hfh|eo^N; zS-$T(UN5|;h9h>BYb5g@TQsR68^Guj&UZgM=;8G3td2pn#@dmmJ-)DR;5zj^=rM_P zKogeOwC$0<*J|EdZKo^M2X;f3+xEKn1sG`-3}TP%;Z-G@^dLysZvmCk&DXq~sQweu zrqa*XJS=FxzuZ9&i(}4kbQ{`1BPr6p=lBX{fp+=?AP})DQB`FmZV_O&7runPd&eYV z727{}Y-{BltggT{STOGMt~q#$Y1tm%2*fJu?-fFy!SWf)cM>tja! zR>+ZK0FU6g7uCp73mZq!r_lWUSu1PV7*?c%<(@*9Y?Pp;*2xDV2lpdGM~e|2(CXZ~ zi7YR)Uw(L$iP`uSS&Mq{$*SWckjizC@DVq%S%aG>A$q=ze(+{&XV!Dvl{3%lrG0Zr zABrOB=5*JWsWZW^B;axJblH}N<(2kDDEmS$+TrS6NYP?i1p*7Lm1BxE(atmUe6`=7 z5JYd#tZ6@h%x#RQOOJaXsC-^v{rgD>Y*a`+v|#hf>5A&j$M1Emwl0kZGj^al0a#Ag zgg?gjrH@gkV^=MKHcd&r$SljQ=qd@=?dqNPRonCEqe8rXWl3>2i7z@e-Cz6Bn=Lep z8Q@!qOQJjt^4Sdl%182Jk}V9Fn%`OC5N^~xAFDRfn z>~+wv&{yYW{xq}dN&CDitOVzYj@g#qEP@>`a<*LueIa`Nc<$GVM1FnFiWF_SZ<|<;7t~=`np}kN6C)`jd&xUNb za|Ff#Dd15pGkS1gro?CD_6HYnEefyNCrTO|rl&cWr6G7xkDNNzF3cK9yHQvA0G>w? z`skq0x_P`W${3Y8+Eg}Ot*tn8vds#uJZYNmIcJM zPwMwO4?{^GZk#(SckbbAeU^*8<3D0}N#?oe)|9~syR*5j-RjC9_I^)PWLn_+Qm6w8 zlKYq_x0CmqwY>Dw)v2+|@Hg+xmLI{v`Pn8f=5)G;1)|r%iie!l2IYd6`cacOclW1; z*ROf|lOOrP#^~1g;Ms=xdB^<$4+u9o%w)rjR>I3an)oq4!%7nAoR0yana)b^g5sWT zJo^HUQE2qQI3bLV|NbTxJgQsGidYA!!jcMU; zZcQ2+JfbA`S?)7TtLnRK-5i{cuT<0q*l@;_%=w1gTHx$mR>Eiq%5@mejDVqBcDh5P zVOZ`hLM>q(tH_cM@Z>sc2K_z`5z%CF5P@S!!a<`Y$;p}( zjTz;M^|svES;@mDlsw6dKOh|t=V#}$F7+Pp&gSdP9>=posy9A%5e$l?8H|VAk98WS z!`>}o@_FX#AhjXGmDF05nN=LlaN+rQ!s0}a_Ti^{X|$V<{jSUXV2;~ufWVrvc0gd1 zlkv@0|JtPf|2n>UE3gkO+(o6j3*GDr-40%c7a-La;zdn~=+0TB_@wRAw(S1C6TY)Q z(Y8G$=bl4QgE``nurrUZdt<_m7}}d|??r7O*fN7%%&+!4CGnS?M*-~l6tcjIw-GT-28oK*X)6UTe8I=IrwOHDjlWq+Tkt5kFw2>qF&(up=%OPr)t5-s zl%m=&>vT^N13HMmJ|b7;m%0%vDD%MDM@kCKWa85AY3t@b`~v&kLfF{^|4#F*qrtM~ z0q3E4rGg}Ogg6lB)GBE34=t38a4}Z6SD$lxG=GX=eJ8S5Q=F zCASh7q(|K={Oet>DZxG8eG1tfY4FrxCJwrR?rcFgWHh^iho(N_w6mA0MP@k7{O* zm=fQ;=seu$&GrlOWV@4QioL>AHBi_|2{dFl{LE1Q&;Vh2DqH~O0*`|`JY^x9)}Ca3 ztlV3^qpc!F9~OTOgUk+3qC)jXDpEyxnQj^frgAvZt(6|=EsH75w;@WV zK*8V*TpD+Ng;&m6oQM@^ew&4KgJXat+pR#&yUHfmz1`(0`EjK#z$W5RsHtIi-?z`2 z^Adx^A+Lv{>MHqc-mUi1Y*~kfnkgj1j-IooK}l^w91`hPk;?3%qt|@OqM|tAHMxBj z$Uynd+;z}4a)R7@<|$Vhi~Fk*@jq_D{-NprFXCSe#m6Bwq#8EEaAPuQ2=|=T2rMN4rlsCzn8fc!l&|N4AKF1gA8@&~w8f2GWORrBVmR7iY-W zOc^EKkNn;uq~qk)z^pxN1cq5;vWb&L2@6`HQ`Y)u9p)Q#{$Vj^bo=(6|Ku=7e{lcQ zKMdwh5>&q0^$&l!Z9Mahwtu33qJN@)qW=orL=FpB@+YtT+`OljG`vCMWY%}DO=Wi~EqaA)kh z2UwF)lPDYoMUf(4=!jA!^lqpsgkFRsgpNW$I!XYMs-pCu0qIQ$1QMD70s;aey-V*3 zNH0nkkn$sb-`%@=pKbr$z2Dxw-{j$(lQ}bU=9G8J$;SrJmzl0GGc#RbWMt*wJz``jkCVWGT_lCfY-$Kq%P*6}_pk$z=WVpe~$a>@74aXk=bQj3$&H>2I zZ~@NJogt$;bKC%6KT-1RS+WyN{|B6WJJFZo!bz{$WxyG-vuDqpr@TN;e)b&YxpROs zXUWLv&e5M|xNeBKB5nYU&Y+OE4YRgE#nklxxwxh7KXNBZKFjRAz<8%v`Z*J`k;fYz zUKtg5Y-!)r8lUV@7HI_Wt}M@9!w2J8nf_u@pVK}h4=rZ2JL<=Hw_igBoUP}LqQ$F_Mrd0X`0`(CVct>>bF=OR=^ zc4@V0PBNfytmfX};ZQbYC|j56YhKxpgwFjc*S#RKpO&#qma$T&6gH>C)NT_#Fbf~p zXT)!u-CuZ*Y)|FA>i*3Zo4?Xg0P#&pSr}4;-@H+8o;{S+WV;BB>iUk$DY@2l^t-G# zk2>K=^nraVsm0@0S|m?Pu_0d1#gh?lj(=Zr^p#*Xf!9c($~QGH-!Igc*utl@_vSFS znr>CG7wUgf_iLRyv?%v$Vx18=o#vyxT7=72N$~Gd%qif{>IAzDj6LqK`%PF^@auHt zl30FIh$nA*O>CYo|FcB)rxZ=6#H?TcENI3l1CbsyW>l#TxV0&p#5RD^54Y zkgjEfesu$txtYNwD0{jGVt~%m{m}tP{@FVK)t`;{NcMk@0P@3$VHwP@dG_(?cfrAO zFUSG*af=hw%gXD=YetJx@*>mZ;$P){!6aGRpRRjnY)^%1ZR4v%tN!Cj3pTKQn>I0% znuSiit1#H&E#7~ud(f9i(%z6Y7YhFd*)?WIR20q|CoeqRB#3n)IF;=fa7i%0j`bK& z5ZjU;cxNy08vj3;{i&Iujje4ukNIY76u;2HtjBAj(Xu$0jn0Yf_+??8DgQujgpOfv z3%{&H{^3TS_pKg^cKKvRu*y}_VQ^6i61|0}a80EwIuI>#yGs!n7^a}7sc>=H^Gb{o zn9V?Me7(XHzk}Y$=yy2ag)MOI+Vq5vI!F)CT`$PNd9V$MOm9B8 z!oIb+Cv$2A%{WWeF})P#tF!4Pqza``*?IBmN=uOp%XA3wstCT8p^V%(-T3mD&w=&v zFILPnxSOON>qyqJ)Fl*|jEBC$pv?=N`koL{j?7l)DjR)2D#?Gs_NA|rWhFGiMHE)J z$ufL+?qa_TO8jgIZ7Ldc&$KYl+k0~PyCq<&SxZd$B6CQPg)AYi(%bY%SANFCyjePT zOJ|v6yl_-(<>;)Y4&SnG|d%Zy9B6UNLhuPeO9B4Q99*syFexxNU$Guy`}l98`w%CvGM zv1QiwCA~gDDU%{NFu3zdZ}?+tQ!AY3fLlQmb5fY763)2eai88{n&Xsi9X6LU>fbpy zyz}wqBMfeYT5iXFcjR$F8F&c>4!C`qtLz`D4C++i@`mKqCxKW-aoFdfatGFC9B{x2||MvQ8@yJ2jlvnxsc0p-Xq7h? zK>}Aze$_v7)GgBC?6>#2Mz30*E{br{cr_Z%=H~cRC=swD&aJ){3@ueaud&?wNxnHZ zv-Kj2pXWh1Y2-$8)VUXySn#GE5FbV9D#l;Ruj?%*X_Y>&f>B$PIa*R>Rn+0nid!)H zx>T=8D~_|nLlteaD2$7%2W$lOtp0-tv@X-Q@U`{(V9Nb4;Dh=#jb$5K?Q7a5#ll0Y zK&3J>=ehaeNL;layDRz|%oOsh$9fo6IV$(QS7TyU?~Ub4NF~T4GX--6@Xx`S5HRZi zDy}8WQz~WFH@0iuivNxW8_>xfBbySozRQ}e1$elRK=(}=^V-5n)J8@aNOT~a1G0F= z37QH=*oLi7kgzJBD+Fothor%2COqyA`PTej~~S? zEt!7NU^X^7^LbGTE>vy_`LlVL61`1Q_5gj|+514s9RtPa%&vKHpaJq#YJq<|XivC2 z^3$*9a4KBSGAjyvx85cQo@?>gA(}~qU)75q2+~e5>iUASdo|jfWJ(CFK%^?4<4usb4-z1`M9|qrSTo1adc|KSSRKt;*8pA-5W@w#+cs03|q(U7)jU9%)Q-|wPb(+Se7L_E$RJ-%o=jO)Q4gkMM zjJ6M#igM&P;n!~vwQf3yv&#_e32fx;Li#@H?1{s(P6$v|7}0Q%B(oWbxKE+6R)B-c zvAp~Y>xK5}EG31g&Jr*yNEc^AjlzAjdtu8eQeR+TE&bBXmvAkE+HUw z7O!^AEguc*!2Jjk7Afj2%I>?Ig$pY+Y-+*bG^4?ojt)Z7p!gWm16et$Lkq9bN>ASWkLI>?Iu@cKIoFHu$e{4Th8bM* z8sU7?kh*be%Dkw&J2zaoQKOvW+52iw>N_%5ay;nDAfDT=;`Yp(oJZr1Y#ZDsuRg|A z`a`k1P1iN4yp2q?>|k8*0XZ-~!fu~PVy%c@+RBl;D7)ZuP3~%#L;Je3rH|I481gwt z$!IAYM8f3nw~QAdq=l+nJvBZEPwVBVw`yv#m%)v<=?mgBe-cj)Q5TJ@8d0iAj7q86 zQMb?%XbH? zx>`)6uV&F;GFer^2NrqNfDsesqn3sfwoH7!0hKa?gNi`LV?c=bNNEV2j_8G4f@bb? zY(c5EiG&J6`V7Q<)BN7d?cPViN^i5wsf+UKucZ}wNt9g#4gWMG+Mr_LrpqX-;lWrS z!>hHhDW-!8YPPjk*t}#oWjou1+=u}?dcVR8EVH%8^tRfeNR1-VTX`)8nw50xy^F09 z$0hUPr3q^Ic!hIr=)mZ5_Tb{@s>@rwCh69??!=b4&77EQIqJa*_I{Mn0^UQ4ngIEr zm0SqhJ<#Yk2XH<8XD!HYxVG(H!NM8!L-dYEJmiwiXtLF;`zD?eR@t&Wk1$c@8TmEd z*K2N(aP^Xb6^~wGM_bF3^`Qe2g~_)LaE0m5QSi|UH;N1C#nX9sm%X;RJgA=Msq(H( z!zeh&xXcFGHQ;*;P^=b=rTLb*OR|ON1~5dH@if{?2+o8_G#fDVxNG&p;o7tAAeUm2 zUmR1o)4QP1-V}@XBJ}$&(rLmy-6eP$K+$RZmA{~JnXB!IPvR4nuK4)hU3$-kKxAP0 z1V^K56rQlp75{=Wa9Ozc$KU3~RWo08!&%bd>cqoa#P%IoE48lRq6nG^DKh9@$zY?i63wOA%z&Fyc)%gW`vu67_Ueq3u< zn=l@>c{%J#L(2DAW*=8ynQ<~p96<;t6%G#`K5(h-ZFzjIZ`{ya^h`l!-P%&{^uQ&Z z@r3Nr=8?9rMD8(SRPCLWQPE4(uT&_|_l}tIme=!@(7P^|YzVo}fkrjXotnJH2l?$D zq`j5$VM4j;O45DYaNMOV_xoG@uw}hr7A}1$xTtzX+cHVopk}ZbHJ0L0tJeHBsAxe( z7M{gS=9GswjI)i?*pR*&nmYvI##{}Zfv7@8L#y;$37M=~CIrVUJ9K!4HxKBCPoa#N}+$Wcl|ornQxR8r@~`qLL|tMVqiY5dzqe0w4d!PnZq` zK3mcRFLea6^{rUZ)IUmC>rg&FlgFc}I${AWaI9`AMAZ;XgyK}^Eg$U^?%uKQH8SxM zl>?zNw^DSyFrV)_aL`bj6+HJ@80ha)EDJ_tu7+{ex}10ca3P9^l~@5ML=Dds#BcK4 z9|L9S#gV>N`ccLHKG~lE)SN=cfN*liTF=`HRnV2d-RRnjl@~+3CD&p@7A-@-pYJ7P z-+{ta8}{D`6}HWRT;+c1z0|Lx#fneR_8bHhE#@Ff*jMvsPNyG(GTCJGM4F!rBI{L-k42$7 z2qfyxHY~z$`}zHc_uuOZd6bHAWj$<)b25O#T@D8HYG?dnX7`?;zHOTy(J+16oxilZ zx2Yc3a70EEQoq&35h{Q6`4#l%PfbfXKD;H|McW2&nF*2j;qWKNfL*snyQTw?MHzv+ zgT;>HN`)D#Zj$hB#}Q@0bi=`2@aMJ_gGa2LOm%blsFF(cULvY0yVVIC2!zOp6;Sk~ z@H65Y);buY;%YLYkR_@egq^BXW!_?T4ol$CMdis#_%Xmc=&(pSSNYI&FyQ4eV3O7U zQszGY(}gTJ-NJV!-H_spmPNBmE~$n)@M#=NCNr5-_Nc}Cxm74{H zRm#9c8IPc|pSB{X1307Z)>){{stZA7B`m=4Yj+jqKg|a#$f}frf*3x<#0`DByeu{- z2xl#TK?arAbXrSN;V!-S%@PF~hr#Qao4dEXI&8NEEk}V-eJum#%OHLU5trO{7ww}9 zwN^&zFB3@`~hN``GI7i0t zhFDNy>n5S`1ziPHh}cVe_wc=5_@uF#q*?fsH(Z#H+bqC9L8xufwcPB)*48F=o|z1s zcA|*_RbOr7%TF~C>dN+%`VrROp=&l^85v9H_nBaj*y7Ev(ig2Win-j|3B(f8(yv6B zF8K(s8Sb0L=QEX=ce?tgw3Lr@e)fMQtstqy-$~`J#M{Z1)(^KH9nyRGE-C5apmfrO ztbuACJ1?$TcNAETXxQ-!?9EH!xg~JmQN9Vwi z*1WxAa08JL_!=S#Iynka?ck<%6^5Ix8p)e!%n*!GEpvU|J-`P2r?M$oEy(_ULP^O_z^I#T<2I_vSx+QD^^+O5{O zMhB$xA~|Rv%)}R2Ny;OE#{#=w_vCtnu=fU@BYAgGM?kf2Yg?#W3H29?bHiR5p9JyA zk~lbIgFv|cW711}(_g_9l3982NF%py>yz9PB_5g4Q2MAm9ADT~pviL#(02VrFg*sq z8a3B2s}^6U4QQ(_#j=Z4t95uR~i^cMCed(3BzA&yVuVo7HU1 zQdnIJbmr7RrD)Ksjo3aRfsRz@-(#M~_I=D5Hn)Kr7;{BO*>iZYOkGlWI4qS`IM5!Z zU7!W>S{f&kkmk7^h26d)NK2QHn%J5PSxMmZE3R>ZGd?6>N3CLf>!ac3B!}~_VD{Ls>PUN@@<*X!p4PB&djgKLw; z+PFv>Zx1+Y3#K9+36;OROj~Vgo(lI&GrLfIwiau6?`gvya2tgt(LG4IUfM8 zkhH!eVhsE;%=cY%U)Z9H8+K>3i3K%q;{5PBY?8V{0WK#$H7+jkDmuwC?HtU<-`1MM z99cacTBhp$b?K=|JJl1JbZ?=0aYDGCPuNO*D!GI%{7R_=yb`zSQrLhg?C5tKpT6uvZPO=N@&Xv~_~nOUtthn~rs*OQ@}EEDnHAY+ME zZguou83LYQpYui|xJ}cb&pnFpiG9_Cu@xt`j^{vYhC3HDsU?JHCmRq-M=!^ksW+t$|PhV;UrJhJqKR)B zamp-li+BCnvHz4cWnFye11C)QkxoR5HsEyo{WOLyH&vWd(bjO&R+(5;-(Q3V9sC<_8f@{JMKl=F~e1 z)8?RzU9X@+-WMv=Hi8MG!Qyy6BOVE^2k!inV|yY7Q}Wcoekih;{@twTUeX57mCG%2 zU%Cbe{_wE8^i-p^u!C26=T>Z5wrI~M)Aad(A35silA^G&NPn2g^sJsyUOK~Yct6BZ zQDhb}<|eTGlzxKDE=;L&x%bC&{*QxZD{8CmE2^@Y*6M7gX{x-&uK`J)0jz*CZ~wL8 zO2qcnuY#7<%Yk7H4rOf6ut^cSt7y}Ghm8Cjr@>A?jK&BZp+Vf~XJG!>yBaA>r1s#@QB(bSlC;p{+N>*{w~r!qJ8kl`X7|P6Hf% z<+ZPW_|PxqJJIL&hPQ$3x$|+)lj4$GqIsMm|`V9 zIknwFqfA18ma$n&vw2^VW7~>MQUnc7lQ$P{!+Cd3d{LX##V^kDdxe2%GI%@$lKE)~ zw73<-TqpKe+AIQMpsx*8dtG2o9WK+#D!mF(waU+}QYz-3_E}(vV_rLy?jhhyn^|JW zvKp=zrfD(t7RVdC%lhs-k{#O?9_Qrd>&Eru?o6qfDp$SK5%!V?{lFBuekL5Dsk74< z+tW*AE`qhq!ou3h;2T>4%O9(M^t_5+dZ**^y`i{gdNj@8E?Q%e*D5dHv$$GdVrCBJ z)%|fR#R@Xlw5CX#7NowmJEk*e4ZH}Otpau+G#OQ0AAl-GJ|vs^yk|=C^!xU7O4?)p zfwlo3h2eMB1DMSUfHdoO1rXNDH$i&Caf@>65sfGaYp zHIs`Ii`8Bw<_@678y#)o`USojtM?v@_b4zz8`UaR$Zy)JF}4a;s0i@ljHCJFWTfdB zM>t4P>p*C7)(<^LFky&G5H6Jap$*AW4j+7&N>%@`!yxvN63+NuN2y12t(273@|~&8~y-X%At?afdf$;LfyYja1!tdn`FTMx{Qjh}iWRl=6%;E!iYyLa* zn2O=KqFABxt+R0WO*PIbTJ2m9JWqH$n-+OCBnslZW0Q>ZWw6FZkHK$V#p?4F%NI7| zn)&a zTIfE);7Ew@aH{>Ge@LyjEpbP_!h$=xZM(XXp+)D~$=N^qFWw3K3vfnf%}J>QPInBb zoihh~oA46Of;b*2jH`oNM83F_p7YL!MH~Y_OiMY*wd~Ol-igO?9P$uxGy}| z+`N|+HnHsebL!bEZUs_G8rYSLb2+DSpsdFLjlu7ABUXv8vhp6^TPf-oHnsmfq)m*< ziL6@$rRai*oD;M^uUVD;30dGD1!8`WbnC{xR=F2V+rg)yA^8Wx zbE+2gIj314rA&2=nYmht01eaNY3OgUcg)kSocICtk=uB*Do=1PwEhqBx84joj@M+t zr*r!=5$gYS@dhx$vD>y-! z?MO!#HU5T#-)fT?_U<*Lux&8LckxVq#fUk)5f)9+tgF55;5V&Dy~hB!^N;(<|K9!I zvpde}W=v3k>PMjMX~%1$_Idh;ZY{-4Lg${?Zid~Iow;v#N&+bpzbDWxYQ=y4AlSrb z@1(=RhVg8E@u^gnKcr^&?}7f1L}G21XHLd(dHJ+}{*+(M;18+LyR(0xwq-k2fy+zc zzrsTNz5Bmu_kRpne`>nLOpKrhsM7ywzazf>4-)-PfWl}E8*X$jjg~mBO_gk5rmIs7 z;e&Z0EM!Iu3<8rle$P&17oSro+|1n^xrgkI# z7!aa@oh13(R+)n8fjrb?G{YO)$NP;QxXYR+#-cZ>863H`P@>`weIJByUdnsB?cr^C zzRf4a#C(Kc1`En7VWfxaD!8*J`Zt zF(9nT)nBkHaG50|z%B9^Fg0>GAF+FP?M*^iO7FKM{;+T2ea(bK2gkI6D6nzuqO~Fv zl*vVK9t((h7Z`lV*kf_Mp4hyo%gd|!x}D*^$*d8G3tQv_^0>Z|zU44^lIq&tx7y7K zeB!SabyjqpEu)={QOo>(5e$MdJTDyI7T@LNa(1l(Tj>@hPgytJzyce#P+Yq1WEKmg z^TNiv_TM-LVD--{{}QA;1~kh5>OP6qXx8fWr<$3c#}>FKJRB&Na-5*U3mOR3VkC@} z(t5ROZe!nP+iq<5nAp{-8G#OH;}y>C>SKEY{?a|;n5zOlfp zecE~;f_u#(o1QQxO^)&EJK4GwzvW3ubw5t);q%uGay-2~;4b)qk8LUHG4fpEj0^p~ zuJQ1(T^ePTkz>H(k6X1nXv7h{{_A5vPW9Piz^JsvU2=6cTu3rnp%d%OSS zJZMmDm3f4nPP{xAW>M%I(KRCDZ24j&upsd6C$Ux5wa0IF<9M+iL!Znp5&3x}^G9bi zdR&LV?L^c5vazf1sK8K;E6rkr6j@+T{vBL+Mj{XTdsJJB7YLP!>o?%9)!K^WtUn)u zxOe4ds-++!XB$fTUMiFP)iFEA5t%UwmyOJf8Rcnyop&pC=~VeW)S|KbBxA=L4mlXK zyLV^w7#*B(p~eFL*(XYTGDdZ)itHmR(P(N5=23Lza80UFg==O zt7FKGL6uuqS(|p1xy?ORpw-*5Vt0YAeQ=EOG9+=zZz7%T^N?@^7nh5|=24*>+r0PJ zBQE75lcvR?AR*dY3Rf0i>3l?pGg@C#syRMk2Lv`z56`iMny+K_y8jfWQepSEh% zOM|sm=t{V)k&@U+Tq?dyRyxmCU1qu5O-}Un_ezr~LH44x$IljNgT@uNV}U3kxR^}r zHqA4GyhH+eG|rvxD+uI~`uL*|v-y{^;y=G_=@!;IEb|kRQVsWdZ(;+wTxt25(x`qkm+25UK(bJCjrq=TZu_NxNvBShFV^D>i}g{k5Bl&Xx!Sr&QoTc;GKM=h2zKy%3Kz-APM}v%T>) zw9PE$5qi7Qnp(u&wt?!+!XLL+?sYq)7o;7^8C-Uq)7 zoZvbJSab64BHkwJ);4e$QHSUZYVr^bCDbhp61gBg1(iUKk3X(bA4v6gUR6e*q4_r% znSvYM5Q*iwPD%uEE0?0^gYg#h0T2;<44~Row2bz?)wtD8Z-;!@3+5?nhIJ4M%V!22 zJ6z&(Q8!(CH5tVG*@ZPg5)pM9&R~l)eUDjKu4*sekUtc$JqA$pf|m&MYTIyl<>9to z_Yr7TyIq^;==XgLEO&G~vdE(u5o&p#kQ@V(hg8*0Dc`L-21G6l9e#29DTSq66Q4S>Z}nn&chy$fu@A1o z6WwXLh-_)b=7-PJO7Ae8(EcNfI=Qd^$9|swZ9ftJ(8m7FZK(u+@^`iLh2h<}6XWMd zy?8Z2TWq7nRr^#{tOajb9^Kc)j(F|N?6@%(RM&@#-fYJJp=F}KAQEUy($PbgwmYzp zT@8QL@uAB-bHs&6zvx-9`q3?4J=i|**|<97Ktw-c3b?F}MO)X%kXjab)W58OME6ar zP{KR5Wn%;nR;#tWY~!+ML@i@sPIjhgB2%2kDw0Hv5FO=ao3-=>LsRw}m`LK^OwA_M zY4B?f=gFRT3KH2Bf8=K6;@v^j-`9r;p`mEcnB+tQCfBhoi)(9~*#kFSL+^Jr_Ev_| z7U!bPdnEWXNEr4u3|qUYn1+Up2M?3q z1psh`z})O4#+KbUHE|IOSSX9w9h$;gE6j!5cr~=ukrRhJM*h#Q$clC1w-#H>@Z~r<%FEY1r%xt&a`sJ zwcq_I@;k13%pd*J>~ZTBUx~Wkm3HhXHG)?}@DjZS!4>V%JEyK_o=224fv#!uOI&?% zskFImI44N-lIa5jUF~eo{F#TflE_?wO+xz$g4<>^&-KmGgW}!WJ#sJCgyEU{%2cta zdd+iERB$H?KJ^ku!icCH0l)CnMSS+_)Q}p{pYgL+IC}uP-_xxq+OBDy)Ru3g7Fr93 zgGY06pK7moT3swnx^0p{iu}A3QimoP?*a>*P$R90iMWJqsZm=A zbv9u(f+NTVV-xigW@7^%>+bQKhb{w5oW(ELIEzc%?Cr2IDA2FF_!ROtepmni@{>O* zzSq-?QbGfRr!hfvh&iAF+->>dpQ~T4nRCP*4 z{*3KUL*#qm@Av)b$zA_6{&3yWp!+-f-`W4p{{Jew*qwjOUU#VoAzEeix^mn7SGnKQ z1gPNR835jf#m2Zq005u0~v30dr*>wwe|$ z6$RtzlFqUB{R`fRD81~3(JnvM$75k5QH za{YnwO@ro@!mykG`qESn)VUzqv=W+(w|QDR>g;}K6A&L79`#EG1UB(N2$vP~C@alQ z=4ovW>5HZEM6+96LcgniJvESmVUWZO`3~~J%?T4>zAjdE`XUW$EH@_O>4PZLr=`8i zuG6<~K~HjpVpWuRzi%{Oc3Q1Ps|TsaXbj9r;XYNo;F_*CPQ&~NWKKh1vM%lVU>}8c zx%4GG(vOfEk%(5c`kEa>H!c;SyH$02ecXzs_k&M(rOd(sY3s-H*z2Xsd<4F&-LJKi zW^a|~qy}S0IkCevksG6tMpu#)?&uiF*4QgN(8&!gE3xo^m=zRsJq)1TLe((}-+tO_ zG?U+ZacyDA2?)ZWt{V|~Fi0=w$kFidG;M+jWo>;YTsrVY*dpOkFkI!?-S*qh=OB&) zw@RvwV6}2s1NsTdWP-ji_>ix+S}dz~C6KbPH%WmGQ_=hR(|ccj6M^vq45($uUme_z zR5$UU8fHSbSKm1 z$7MolZ-8+jbdC>J>^wheB4la-$8DL4bH4CtY~TzQxz4k-t1I^@UlSO=UIr?NZi$=r zq@_&aRta9Dd9KXdI8)fOU7wv5mJrcHXhiD!fV&~8m3dgz!yCz7>{lZpG1PTLRxSOD zVndQt;TXqElXt6(`;l1>H%VuDzcf+|S7yMxPg(2hSCVNe ze3@vP%o;bEJA3pXD~_<5unYoOGZ$*UKB}+WKMAEJ8GKvaQ_a4Z}lrW}tuz zzR#kpoB(J3`Tu?TPX|!mudJ^bUx^Oz2NV26Zva1}+N@aEgMp(aW$x(a%+dxp!g zxr8!(&tjD|vuf9$e(ZFXv=!_6ql9*6;Xc z$7`PmIn6T}g^jLDrdmE~y85hwDCt)LaQ79`gvZ9{_`FL`Bz(B*;yEOyOklw3N)KsB zO`}=xYG^e}QrUr!=ZXkclc)nq-Bna#d2v7bQ1Epspi^m^jzmSD+_)K)e;RtXb5DvF$gxCasKLRr=?R@?GV*)poL-A#7pW|2QICt&k zzJ_B!2vg~IZx{llf^nwWKobWjmRj(N|=mA98GVEKtBsesWoD zJ@lQOrb;Wv3&p6+X!K}&!yrLK)#$|LyO5NDFqlP-8<|7YtL&?nN*`zvN5uUMDM>}q zGEIxu^P&YwA6o4Q905fi8DDgVv}#@w*D_K*ygQ`mQud2($n6Sr5HOmsEC+eJdp=r{ z(oSAAmN=C=^DMe*sn8CKkU)tv=(l>kE&QA>;eRrEMJKVe<>G~%1+D_UU_9! z6zk@@nVLY2F#YU8`N=~hia>Q8WW{S`}i4;EZvD|!Ar@v92y4dg- zLz=S(e?5n3EC*o!oI2_{Bf!}kf6KM|U*WG0*7#p1#s#P5d10zc&CRF7at#1z0i2;% z1BAaebiA!4`qxOoVJiJJuo{;%qOjt?$;I0PG>YH^0VjHWEkE0LEaI5qy7uY7mmV_~|9{sRP^kVdn9hB16el+?)|3baE zk5;8z*d!jIX{JhC#yRFCgyNBEq?Db}ypjjt{)fka3#R%J1A~3CO!W)ftJaO&_9J}Q zRcvslldXGZUY6rwrfA%tyjRqM%=HilFJM?r@}-=dY|UsreT0GFL}DTo8Lt-*!EQu5 z+01}V5Db*ZEN_+V5^AJzyTE8}7IulVT(NK8iy>(t2Gc%{Xm4&eV&qg6@@hYupGO zydpV~LDG0N3|T8zdC5G14^8SH7PjOLu6dx>R*JZ@qn!#5tpIunCY2X^*M`}>u#b~| z2Jg9Tp#Q8sxD4D|^qOQaAmVIZi|SEJq|V;KCHXH*&k^-5UuSGYbk>{qE;Z4 ztFraVCbPBZ{Zz4rdp-7fi_7br_|VF@Oy@hnd`c}tc4}BSYv_RWgn9We-qVa-EqHN9 zHq_c13HQ!pj3VR-+9oB26$f#3j-hToYj*EdSiPe?wgxyY;51FfJ3nb)f*W4(5#GoXQ>@5_Bm) z0if5~_|fT|kW%fU3Aew6E#iiGbbf^?hKPpvkSgLjDhpy#Qc4tsh8zLR z_WwpBai;f!paW1XYVr+zkCCu2T-O8EY1EgsG*^L;PV6evF6=B<)fbrCx(XCe*vh=H zGG#t4^qF29a)Jg+!q60Fne@aXuq??Hh zw1s=1D~h2jd@P5@W{;9ZASU1AfG<05t;qQ_4?jXTS`h!<2|KKqQ;ebeH^^-n7a0i2iO5H%*OgB9lUChU=VF6Fh-5mL2! z#Bq7eoO*$EimZYL#+&zoqoqx_Rjp^M27l43t(q5@zbc6yd-8#yuF>xD&eD(gYmkfV!=zCA&`c@1oc}8<===iw#1kSOUonzISaY_nbmR9g6dm!C8zmM-CJXci0 z3}!o@*p><^iH0-y1@f`cOLXzV}Tbqiu5Wc?b8>$OyMyL@< zR@72DC^&0F3BsB?dQ3*RFoZ=pDBnm({zCoYBNo2kn{T5E`UVJU4R+?O?3!1{utr1f zCeHfXiq$Xx%K6`RI{z1!Oa}`76C_5f{ZB6WA7#DH{q=#TzO2kH9{`H}f#HI{TuQ)D zY|AqfzjblvJ>!7|1Q+wHm}igIXJVuio1HXk>V@E2d2i~5AY-@N?k#7oX4s$olebd{ z1QkYgdiOq8xeut?pLP2HPMdGSLnsmGvk$D$K(fzv@|HuWO z4k-+PpUQpvXUNhsh*On2nMX4@lN4;!CRBSt(>bdKoh&BCHFIRm;i@QtFmw<`Y? zj?(|7tW?F`X=TWK_bqOWHkBgU*LepUlW~{odG7aCMqaqlm?YdsA=ebp|JQ`K%+cEF zG%i>DYr^{{y+8s0VcaJP@6Dvw51FR^a=j@n_Vx67(SBGK<6*Ur~eM2XP`AdITs#(@9oX;|E~P`$3*s9 zY8~y}N51;clkIT42REy8>QuEdvOWiCW*D6Kfm7LH$d7b}G(v{uX9C#%WMm~!>UG|o zbaI(iqjS2y#?v!ut0J_r)g@G8a|=geTT*rwDNBK6_9^k2Yz=W`iaYCPZ$u&{RHNXra||+;x@bb%lp|i_1_iR*>`oC{29mZO8UPCdDtobtlMPm7Cs^HMR)H@ zLq&c_6mO+SGZ>6fsPfV7y9d<%85%fu7@;+1UBNo%y<(R0ZTEaPTbUrHaDy}k1ibsN zF_pg!ImV+$TBKMul=<UUGGDG~Pxe24_`rvGV@@o<^IQk1 zYrPGELWyE029xUP*%zA3XF<0c`h%WU{pES@)RApCHJ-f2fZLlA(j^nN2Tx-XhJ?ol z2}d_<;8(wSU!E0r`+4KEU>Hz;|Ap-D$p7n*jM4>e;r;rpRI%;}<-gvX7MJd<&V&A| zDEN2efAEImy6(Z-tiOIY_+8u;7Mmk|ku(UD68x{C;NOw|d&u*qO(fSr64Tn98Yts2 zz&+};d}e>0Js;!TZ1H3-?5VW4D7~n|8q~SJ;e*CW9C#a6nsnJg3M8RXcX}Ogo+{zQ z8#IO+O^Vd}Y5oZVY5p1p{ySpO{|xvDprNVK5+i_98Rikyc@KD85GH|2Hf9I&FMf1> zZ;y@Gc$8k)MngJ6eR@3i)8-Gl3EJAczw&n3YF>dqz|Bj!%Ukc@%ZjZ+O5lGWsb;0^ z3qcH{rh%N1G>bkz=Q1&|0>TRezLs%xVB^u7L&4soB^<3Sd6Z5)ap>;rU;58q5=?b3 zND(O`|Kf=ObUgPi;3*gkY0i$zHzfbbUVhNK{l1ckz4y0V__GOs9NKJ82}AosS1_|T~xK%w4!ru}ZczJ3U=3rslIuXrf~-DN}+ zwne4n=GMSe^*hR0GM))!<>nwCX_DiqI>I4-j)d^sIl}4&2*hBzylj3=Br7Mb5C`&R zEsRs=HVyIJrwKBHYIP{dC53BbxQ-YJ+oXEBPcUVE8u<2UWB8e*s6wXcW z2<(ai9K7dXLVm02f;gv5$wQ6Mf$9|$@t%~hC(QZNefLaT+a>dIGt2gpCE-}6_UQYf_l4qkKz68S06MyX3uHKjYFjUsVJJu;^~n zkWM~?Np2ppc4J;7O>n#LDNWrg2xLo!1+J+&Y63EXz|^7_p?O%(xGm)`z1`(Xft!}*uJ>VKX2!#5+erH%jh|c=1_cm! z@e{;-oQb|dX`hVg6V59IbH0pi!Cx-^TpiBqO)Pz=ZNZK)#I>2;NbC24&-)I!4je=Y zUM>oE^j@^b?@0@Cq?#6W&DSPN#&2vq5y54{bp}vEB#9ampm5@{rvUT7Y^}D#d|Z;3 zF4-X1xZEiwl~y008x;fWHf&R0#)aQti)Dnn&sN3yg@%?N16FATh5c2#Q~CUQ<&ZEK z#+)!yF4JRIMB{HUrYShx77P1)x1w~wv31&)jt4<%x2=r@(jNm9%gTW>@Prj1LVZpi z-p`;~TCc=(U{Nmu|Jib0@w@MMAu4W(P!6|@?$5((M#FLwc~#q9sTcIfiGJ2`YOi%2 z${t3OJ+d(E)8*MJvgRMnGl>-RuM4aaGqj{qd;t>q=kWutLAw0s>rX87N!rY|EJ>Fy`Xg&*b*<1a58xD6R z5URN^Zp>B9CA9MIxm5n_*!EO0s9YFh!$=hDaG^LZl=+1Hf9$;nT$9a~FdlnH0RtF{ zN|n$A0S$-^LT`Z-AQYtuNk9ojsdlOX0|cZhfj|lgQUU^kiqz0c=va_ml&&Dkhwtm| z-tYVWzumj{-MjbO-S_+;&y+J~CYdwOoO5Q*3>_#yc9(*Wp-SyMrJ!*_kd} z04U|hr_Wzhm;A)M-p>n8(s~*idcHSn9SQXhu5j43o~w=Koj?Bl)(&;^?&=`@&B@BR z9Q;$eaf3-n|D{z!I!k27^IzZRh*YKJcr5Alq*-K4J-g4%RYl_tWm`yL!5f zVAu^`Ws51E7h*J+ZT-DtH>6@Aj+IS~B-nX=^mgha6XEp$`!+}JAR;qAG+kF_*EEya?Jt_DcAHt_g{U!>Y}sm#`zo{~6$ zbv!3|KJR^Y2k3cBgkaIv69^OO`yi9OlFolAaQsw1OL*p`e^Wm}M^x0|^i3Lt}Q?S8T$T z+s^;rzs+?3N#i0y^*0shUwI=L|B}b0tN{M+!bDFdLW{KHK6n?L4FnQT zQ28~~Y{nJRq~AJYln70cO!;K3Lq|0~hVUyxvfJg4>Z#H}wjBs_$1~l>O~lCV8P1qI zY@#ayr9e{nc)WLA$UOvNne(;#VDzM}VDyKso8FiXR`i)ZeuQmec}iPiWydlt&t+H3 z(m4S+@uwZR_#9qpC75KC885q6pIB!mT-n!vWwYR>!HL+O6nEc{(;qIyypHo}?l-!x zLF)4A#ydYXUI{@<&0@2!bSJOv7K46>Gw_N$xI;+PmDf`KOsxz|Z{N{vv8S~@V@hqJ zni4rw+y)@^h0LvW`_}KPTTb@Sw`F};L&S7WcxnM#~@mJit+5_uCMW`%c^Fvd&f}u7OF^vES<*S)D1wri`wkd)xy`T$6xgr zx$T1n&yiA*@8de~0r!*1Qn(f@S8c{F8bf9cyj>}QmM4YSLk5>)|=DkpxIkt)^G*vC$)y@Lu2)&g%HRa?qNofzYRI_5O zHKtwjcyedz+|i=A!>^yE9_4xM1;UBrEEvdjQ~v>wrE&tEnTUCJRYkG+$<)QJ&96Ix ziP>Lv1#wSm`{R{;2Rv{L{e~-rqQ->4YnoYQWHp#b3JmB;kH}Yg8w7G^CAka8Sl)kW zSY&Ta8&EyGf-#V?DVA|gQpr=tvCw2YrDyg6pf$izwI27n`_$`pr|Bu6s>jI?6^r@_ zS$@qClmx7)DKcTbZE`t8uqa(tS)lW)zR%2EQk;#%(M!fo?6UlEp%nGIg3p(9+y7ZPPp*AB#BNH|}l>nK#O7 zp%qL;Jcp06XTue^1U18H# z@}~$0U9!}yQxUQ9bWz){v29XlxhW#9JlV1D-!sU?PXCa)o}B8SH#cP~2X(1awoa2Y z@5+xH$-rbHTHq#$zC>P>qs{ut%K}kLGapcxNs=~?oL$6g1LHhYXM2~tF}2wv7S|u) zkvceKji&^ShSzC=gG8_3-3U8yKKwnMr*=eEg2S51sJ64-9kT|CqXCq-hI}6G`-SLq zhdnk|jqEZS?{qX|uDZO=2(&LyMktZc&gF3n>n%g*_eXabTO{WJYQ2K?YM{%~L9%{2 z%Z_TF^)x;;jbQAq71!H^-2?@TojxaD=8?6~V`jW&E$w?rVz5rx=83iXcLW^o13q5a zt~^qC(8q?&)i7Lc>$|>J#5I8&4QjgNOL!ctQ9a9aeqxVOh*KdiiVrx_f^~Xl&F;*o zXfTy?Vszvj#Q6DM?nW{|JuZ4$J-uBG?4AXm87-N^b6alrTq#uZO2r%7O_G$sWt3!H zwjZR_Pn=y(k6NAo+{=1!MXi6EVtAIUfItz=gb%G!=e(A;ZX2!RyH3Bm5PEi?>Vf_4 z_49k%O^&sHSE){UP_QQnb+<#jdXn!fmAd{`2eE+DcuRPnEEnTQ$Z$RS;XDsYcNL<0 zT!Q?7+RdmeEL12h#*J%j0HD_s-`kuH{a}GKv7I_2yz2ysS5z8a03O%?ysYtWc|u9v zLYO=djK7thkC7K=IJQ|*^?rIUrK1U1`Q*@>tBHr-ID})5WwBN0dJJeG3}~C+yTaBu z=v;Rebmei(y_xgcv?;p#$z+4$-b8w|&y3R|B+o8gWymw3Ft^f3F+2II^y{UF*^r~+ z?=6g%J%Wl37!vE^Y@^`u^pDCh0-j; z$cQIb9g;bb<^Gin(+vQ{O7tA*<}F55zRkMs6P|l|1J(%%%r>%?wC<2cK{r0N^7wlR zU8$O9Wx2}BXFQ}-YB+8gzQeit-LtK?6jpmYHUK;N9kT5AdD%(U$xSH-tFb%mwOg)etZk0)a}})GTu@he7A}oE7PD>sE+9e<+upnNIN9)yYmU z0FANnYPUKf)6vY*nvv(LyY}UU;xy6?>3z$e9OX6ui!+C2zwa|0y*5J6$-B9|eNg!D z&*S4!f_lR@eMr1nkGho`cF4C&!0eYWQl0YjsDf@pe*g8Dt;>)7j+p2+Lu!+Itsd&W zIgE2eX8?h)^U0}S?tR{A-0r@V;U$7J_T29);mo8x0L?J5{nSxtAuFat#am$EaqPLE zDmPWV_?wsBT+lriSGa67LkxE^~-l(4g<8 zxzLRF2pD|yMC(ovdmN?WrtPPlrUua$CsBF>49>XrOU7>u<9Dgw{s+x2qB15!OX|e; z{RZ-K(xUtE?Wj^-J9?xsy-z+}$J_76Ud)yD3EePtTTE<$U>S{Cub^JB3h6ijN`#xx z@--~J$p>spj>fR-Be_OkrT7mMOAcGf)$hVPt{gV+uJ9~WIShp^(0#zG2uLIA#)Bck z`CV2nrbozg*~j^6>=5#7?^;GsG;wO?WwJO~X*kl)eD}K}-Ip<&8t(sY*Zs}*2INz@ zT>rD#+jbgn0UjI1TzrKNyBQZ~c30Rn`vOH7eln4laagJ0J{_-{beTKB3&7wKT42pW-C60q6*j;E@Y= zgfDhoj%S>O`z~IHk|)W>Sk2J6sL_ytobx00p_PfdI5&CH90}TMi#%^o{^Js zsCr(2ePWO%-k^|L5|mKf639UKiMCdKBDF#9OmKJdQap0g6Raq7q~l<;VZ9nADFKOF zYjo+u`>K6DwyM3qQ|MOH(tmuQ!e{{}wsz?8b z&DrIAT_q{e8tBXw2P+VHVSeNvdTq-2`T4m7rV}UuYm=a3dS7ynClzq)AIl)W1L$!~ z#KGV9?)~<%eERQtN6OOZITVaW_RS2;qI`_*yKup6F_hXldf8h&qlmUv6v>Vnoe>=z zmxd?5tpzI&N+(6GrCNjvNJc+E8uWLyygO2kN;^wEi9gnrTRm}t+J~}68<`n?b4j+g zsnwYDDJ0=aF6C+pSLH+O1cW2ny7jxqyk)13h?9Nj;;h&A{<`xO=`4DBblNg7uEuQJ zS$C-bW#)hfy`0}o;9eA^Lqvd;@yKHMtIuKuuJ-f`0Pa-DE?0K)nS9GE9AdtpA!GgUK6vplZcBY8zRE=wk1VvFbs{*)0=s zw0!@z1FyW|+;<+>-&v!saG~L{V}qQid9{xRR0n~#p9rT%_)bDj{#|<)u=Cg8_elP| zpHG0Zf0~IN=sbL^@*Bc$o`^p;W(s`xHTY@2`q`PWE$gPyT}=H1?ZcaV!+1SN<&26xh{7h&LZNX%6EoMx*Bx$6i(@lA`X7$#vZomN zhA%`;12+H~V@b1y>4s(9-4=*T%l9;|#aV?XHhV61&4~yee06e(T;;y1r2=tC)J&%{ zTIehUV%YM*#HXX7jtHvo$#^dKSHAhq$Fo;ZZRMrVQUkTUr0K|6#!+3*q5L!sMtaVA4pCiL`3tLdd5 z2UQ)Dx~|>ZuWMi+iLY8BebG~f*}VAXN9Mzap2ahr6OC1gBsgN>L+^tinBLy96BbYd zk!enN6XzXGqGJFdeANzdc#V{>@>Sia@5Nr><0T z}xD~tQ;o^C$PogriD15u3#eRGhbkRgy@okeY}KG;0i@~hPc@8I=GWCtb8td&M?1D z1g|C3O-b$c@F)}q4|xPSq+M$b4!Al{#_cgsj4nTv9q9gq*28wz3B*MtH~zc=*JrX! z*b0GF7CE<<+HMnj8Y`F9K0TZ1d4ZLWWf*0M8$iI`9y@EI%{ z(n4GPq)48LXo#P;j7f7UT8R2)$;Pn$iGne;6nUfS(I^5f&JcAe9>775M_gtoN?hE( zCsIS*IJQA^S}YffFIBhuqGxBBboRw)?~kp0&-^oUeBlelp9!%olZw;m?}jhx=?(_7 z@S8P0&+nUIGh8I5KIU{Wcv}iH3{G9u11p_>uYY&663lRD@h+)qfTMOiOqOSv099`2OFQ6$noR9+ny}@G}yNAjhs-P&K((C zK(!~ljAfF7T<7um*UuFKXMHO_|KyX@x9anYAysjoW`5jy{>vu>D3EqTs8*W7q(#TN zrRG;fTRChS94ni2F|rnkjPmp;7?{`27eyPLY`RqJ|4yfVh@U#Nk2qjEin8OStrI=T zz?{48iV`w%e#dGh#GMP+qNWpz5}wqgLWS6OcNe{BW~(Xuv7xad&!8}H-|`*_U=I|I zEI!RpoTemjsNpZBeUx7N_|e0J7*J$zZO5B6Zr=~HI~3P%hBEfH`DVQh(KNhBsFp1subz`smM3i*G(Ra2>IY_T$@&r z?r&-7XSmbOy5ziWywb>%q48|k2y zculvNj&XX-XY}x*rkixN1X6!olH`d|UQK4g%Vr8(3y!Cr-$Nrk&*FcrCaT&XV70t9 zIFZ;iK%as3My)1x1j4jq9P!YwCMND7DZD_wy=*7s^Slt3Gm3Wc>*_5r$#H)JcCZfX zgg5Sewd$moizz`4DPj9~(o8ZfYQ#Ww7Nry4b@NLra}}`H#1(qdTJSTb_ewq-UbMIp z-^JxqH#qL7n|E!Es4o7)@7Z$`kK6nIRYxcKlMMiRt*hvto`3s0_m3F^XzGZv4ZxHm zdKLWc%cTw#Ww8i0tbq-LwC&l-Xh~72{#>V0QpP!D#;y4*`0YXw(Dex;>aEhs!_H-| zz?vUz3OlTGriQ;nea}?=Zfie(t7zXvr2E?Qis21_Tl0C8;0uS@t!;?p5SG%-m;L{v zsa&FqgXw*T7{B6GwX3%tGIc#m8ds@DC{RN`2bYdvkGM;tV`Vvq6;7^5^fK{whxgx& zH|Wb((N9yfWqgxO{V(xF|BFz$Vl5xx4$Q?YW&#nY)jP=^%)q#$R)nck1}`W)JVB>7 z{BIwVf6(-zk)Gx*gNvL(7u9j-2HBDrgUmYdw-L@pRTHZYn{Tyf9VTJI7k<-@CI>|Ert}-OhW+ zcvZqfiyclSGDx=hW$Hh2?7NKwnWpX27Z!1rRcDFsZ=RDiFxhcd&4X$fikJp2eU3O+ zh-aSyOQVK7My?q!GtM3I3i3Xbk;%BXpWx~oxe9XtL9BXQxkCss0$vRWLjZvYAg7ZuvO+;?kH5;Z-r!%vJ}4+eV~u7x%=6`HAD^Q5abr??jMz;z1! zSJJ$9w-JuLdH+Us`eZa3nwx&Z@^ys9uIlJ$f!YSKgr;2m1u~`GV`SmmZKZ%TdxLY~ z!@vLq^1S0sHB<4TSh#xL!Qc>w!ho0HF%%h6U#d>0_m30_LctSqC)aHCph;$?&zkz_ zNmFRcrpR72h%uN?R{Ly{FmBm>VHU-xK5=$WX10rD2i)wuj3-*Br+yTR<05mo#nosT<^J0*n3AsmE*Ji> zo%;*^SRcb#_zDTfK7=Bp?E&SNQga*cc8e=)TcK#&_!gonYHW93;Y^>`jPwzQ!_P?) zl1?NRmVyC;y~+1I7u+-+m+$@^37k>wHodq2qGD9g>dc9mlCg@HQu2n6kr{205lpPj z^0oJ)a8n5CHq!q$e34|HY{e=8B4LIYJ~7zC4q~F89vW%$RrWiC|BdVwu6c1zTy8`j zH@B1*hyp9*Rg=!PcXigB<ilSj(HK42iM-J)GLH!~+REwThzU5x=R%?MAldZt8JDs`M` z`Wjhh(VLweKrV4Qj)DMbt7?c_nyD>>c8k~H!?Cc7BIbJHmUTo8P~_(+^eu^i!tEKk z>DCy>z#&E3ZelZ(6B*G&>&SXG0}4Ap>VQ>Eyd8m~IbXzwJj;OyrCYK-b;kfIPyf}9 z-b*|8sdfBY!hap^k|p_CWHE-pE;l~3y)3;Bh>Q%U{`4l=VPwX~To4aI?~;!4uGo~q z@NOlVUB7+oyNLRkruW|~gJrEEjhrP0A(u7)OUe!8!Os?6we_Eg)Pco5$Sa*@TN9Vh z&g?aV|CBBT{GXfbcECH_E@rh+iE%qG{LB|p`Bxm;6b~xSy$MHjd`y-*py2E!K|d<4 z8{e9)OP6BTcat+oR5}3)U2B0BH&Ws}rJgSziVAUh6(k0yyCV-jcD7KVbnOX&0w(M317Px`eGd~25 zJ1J`U+DX#$p1J(PSoH?Uh1x!`7bofxaSH6O_9m5JREoRp({%dvtk_Yt{f|Bh4a7!S zQ=P^g*~yLL8vwn8v2MYqz4oGnPDk1~2?WASxVHrbUnK$ufD_SUe&`aHSWY=lbJ}z> zXkZ?$4au6?08q;ekW0I??!Y2|pah!BK>`zr*)d*C_+; z1^@;;sjZsku>4!f_SgTCVa~t(_h+*V>iY%bLq8wCVQ%@ez<-Sb-PR%Hh?g-MTmHy0 z^dA$1ZN9tDyl6Jc87o;8ICSmp(KYlpDnH<3{?uFT3wbWu?xTUkT;ft|8ui6Ds~V_X zcqRPnmil{H9quC277>aNsH#^5pWDaR7@KJv!ecp#gaAU?{o8Sr0Bs5)f0%22x$pur zD>gk@_gqpZV}#U#a>3ei5l+G>j?5Lx3)=ObfL*#(OO=>NcI;Jk%n9l^6?Ji2a-oZh zT>pq8y;R+Jq|tW)6kp~LjyQF|$rZOx)t4vXR^|vzPb)fVN;wzqhs=$3EVaZG&I@7N zx3pjFJaXmrQiwYVVuHa^^oJc--81#Id8givI>CTJ^h#~lCr4`EnHf1q_6As(gyW$( zBY6g(p@5oTSGL89(br-j&2Yf&KmKC+2|&dJ`^#AMN>Z1sRa{*IqLdw3Y!vjlU`P{C zc9a+9H;TCAe0&4oFlBN1Z?EJJt>IX&Av#AJF+(jyg6F(=p1_nYy8xHy?X1oEC2^ysDExNRpY zH=&X2ah&P9L(53E^ze)`lSur2qd1L;!}`JtE|eq61+zXLYhOnnWW8yR2eNWikP5;!rV5;v)c=D23-_xUNe%)`FTmYr8yDHZe}@yzYK{U5~yUK;@I zj^N{*nQvp=n8M)n!raD+Yf6jb{dmA`?H@0@vN#|5xi^R{h)b{j_DcTHK9j9V7%lmd zJ~r@d=!HW?w8B$@i$+4<9JF8Dqfhpa>Y4Fvs=O8Z@%`7%gcaXWm;ad)oR{$y)#(0W zSgfB1Z8Cmnr43X#8_YAmQW@s&ppd;79_R+~IGw6JZ~@cGUec`VUlSb-Do$xRKKpdE z=&jd5k1dRIJ#C+lVkd5p7JegqFQL=FTB~Sh?w{oUB>yM*znOfU_MthD zUxlm>&l}Q-hIMrBQTz$DYbQ@S|A7<5|NROpXjAn5d2VWv;a;C7yRC}aLR{xs~vfgf%e)Gcv`lQ$h z)+QZcF1JeoaZdx}pB2hV&gj|z)JChJ3qA7K>Xdb=m!y2*3}A%*%w`Iw0q)Bv;zKvG zsV_LRk>`@^+Iu9wE#Yd%^e#n6w)%JwT6D`M5(k1Ko>d+I)=<*s@qYPD^P~>-hJuw| zx*99>W%Pa##`XOM+?FhxAod=TN`MS#+<% zbaT+_UKifE^4rXqJP*lHK*vthLHNHzN;d!!UaC%faNFEF-B5&XQw`b+WO_F5<9z_| z-}?4j>!oAUk&WAiLi#M-I&tGv6q0a#kJEHI() z5Eoh=2g_llVvv&^U&cyKj~EGl9F;66*F7(SAGX3uJBe{~9q3KV<&~v6!>bO+r%k>SvU-R#5<8gFZc7#z-iba`_$qr zI*h=S1mnmar8o>ZPBf>n*3Pd!E5SrwSARhH1VY%4Zs%RRK9RQPt8nbOG&bU(HLqCi zotM^0$y{r(hYqbOd85u6yH+1qTlG`jWHXb9r4Q{GB-D2_DouS}-ZQ={Q`+9du#i*V zziQjaASD)(AbIRF`wbT6@m7xQ7qfY~&CqI|`8F}$pok<`{mg)WT!T}AoYRAjsgtFk zVsGC^1=|s(@oQhs_5iCTtEXbge!6{lH5O8;kS_D^Wdu9SY5$u^k=_#-qnJ8nFrqPu z_ZAN}@yN#ogUPyXe2B#lDAVTF64oOnrO_jG6ac#ZZ?kZK{heE{j?9Yqxh{%2UDyD; zmtTq2JY{-g_Vd>bz?ihl{^RiyPychq$J&qGI2tqTX6(;<9}ErU{M*)#w;L9|w&_Ad zNz*t_Ced`t20-(R=yJWK9B74M-{p;vr_y{Z8XtOp?02fUIF=m;Mzi4Kunv^)gBoAOYa;i zaa&i&?__?bsVTO1;r(W%Xa1s6r`Ptj2VuXHIruxxnVWKrcc#w&PUd%-qA@%EY}%hq z`2PcrLx! zd)u6;9A9BxYkq>GlIU{eVkG_{rBByf_P5xDoD&?oc$clInX-Pc_`UxVvMxpvvxt-= zWAc{J3`qeMK>dZk*_r>Z-=UqhjklTP4LSFc=rN*w)gooVFFx~^?c@~${xgb+3;s?~ z*p9G?e;ZenX_3-8E9-F^h_UqlP65Tgz2$D?N67f!qfZeulkt`K-_jKN)$brFr=Rr0 zeoHHH>)&DX6HWJLn#EA2+n+`MhZfD6J<*lDo<>m+*t^MSpJ!#$46ilxTfEv4ko9hp z(SGB-XIt!Pr$=T_aHTg9wlRR=_)572d7>P>}%`czFI9a+av4np^8qv3r@X6Ptbk;-2QOSxx>MOWor?F zV6p^mHp-Vxf~gEnusVYJMI(`2lP#%rS;R&aZ8Mic9@HtuQ_6Hx6Z zL}Uo@$V8Z#m~w7MrUb zM0e~6AnWD2tPB}AEN_sgo@sN9I2fX zYrSeQL60nlJ~kY^uoM1wAGTXYDuq8rO`3=%T-7D!cVN+q$EnW5nHT=Nz)wxZWo*VW z%#xEZ9k6@JQ}cFi3^h`)@Q|*-5?Oz!^kon>Z*O>5tBbAo|nx;3uGRj=}DMH7-vC$nvt@UlhG$o(3T z>26~=nK_YGAFUp*=n|0m2%t@5M80Bp@%lbl+GPrkkR5u)Laz*!2_iIoQ5YO8(V#C< zM;i^4uLIs(_{-m6hZ&Kx>};Y3fpC%aw{7-TzT@7ADOt9A|4+e*h+D}|1@7`1q)#xB z6)$EjF8`tBv0dpmu^sdm+w^4TX109V0Gx6bV5L($UGvBo^m$Q>TGoW<);^7Y@Z`6lm->1nQG99GnP7Y`j1w*MR_rzK8fPplt8ET~oHC?;?q}HzX+u@%o@UVu?@=M%Fj+h}Sv>yoy@p`s^Bqt%UH%6bHyL_)@+z2+KM@7kK$g2^Oqp_}!8+;f)F9=5{N~5h|i; zM3)HcJO|V(*&Ze|e*acu~+n3)L z>3JH|ndhs1FDD+KJ@m1tprA4icu)Vbr}7RH!&V8A7`PsL1qw%!XBX%SFT$MWuH2b; zo8W%*K2BykjTN^&mz))?5iulP8qJw5`&?M8@lDV%yTwI|!_fBeV^tOx=j_T#rsvNa zz$E&7iS0REh;`-&B%Dff%uQ#3-HsqM)TEN~$>(%DtMxR~JVu_+I8{wvuAW?%{3=^D zKWG}mSK}s|FPR>2gTbnKfCl~a4G)iGv`}+M6WM#r6g4kqs(lR=8@C)j9Pe)4Q{hfe zfVd{R^?^^<>X4W^XgieSqU^Hifu}Y~cZYp%MjyG`aS@G-!FBZ6vhst4u;a(8g3_O$0=D6 zk2GF_lL@L9Mg+bXe_&iLxRdO+mr>+~=ut8eqUs4dy_ z>h!VFh5GTnsV*Jkrb^OR<%7UrOrz3(peGRon>>O9_tt?s z=jJ}YrhTJbKEw^UHmqi!@-_KPg691X-s&Po{25uK=9X?VO(%TuN(ITkSZV7`SEbP5 zverzwNjWvY)`l@$(zQVQ#)1`lfX7tD>3L9|$-1ecsPwC`v|}-XPkZQeNh3|zH!UFg z$N7X#4`oBCJ8@FlYS+@-lgmSj!j~P{=SAvi>t%qxf2ut-DB$9~Mu&Q*>WLxiG^Z}f zX4II`P;tel1iL49JWQ3sI+$i)X3ibi0&JRGJ0a$Dl&@V%h~2S&uHMAr+`UlJ5FDESB=@klLmw`I&bm*j6UA_vykp)l<)HHpLyb?WOQ6%70*%f^XQ|ZaGObp zu7U{^wqFjUEs@MM;Fmj^B+=hfL635V+lA#MGyyeT(B}m-HUJHlV>a;56?H!^!Y;b~ zha_tW$%hf8lt8Pu*izj6XvzoBlLYe*ZS1)$0^OPzOBdHV!v85EDaK=_q=4-o|BTfx zYRm@_7HNkxj$qs2`L+=)RDV}Or-W+a9y8~ zvdra4%bhQI+BprG)Vq5`wYFAFG6Suuy}5pLwPu8Alut%LcEt{$V3H?Pis0g-zmm(u zK$@Wa;UxuhABDubY1;d(WUm_|3cJj&sKzhKN%{%zlJUW-S$u((flF0v8hoLq@fsvm zu9p)DxNOyZjDxzkjpF3&*eaqJRL^x_u+h%m$q_y+pYE5_@@#`1I`#HcFul8*p=h~; zo&uj4sCl1LKwk_tF+*VdiIWbtfEx9{!NvqBP!do;%Y z1?8ypR0fD(Kp;*s=k%4XWnQM;rTn%rpFR>$h#nbU`yK6F{DwYVA%)N=IGr`W$&0!W zv4p_l8B_4eDpIve*@N9 zU*7zju~thcfwOKwLA1VdO|yOCNlVs28>hZQlv_G(04REvg?*XC*wd=lumc_3GNDMT zQB;HF32ughP#-%02uCs3=Y?}|{MG}jHo;P`^oRJ6?aJF_Vhm|ygz;+tu{c(EO z*y)S+o1x~b))F~up6(D*2?E1RTecX`RV<%s<}+YeTg7^g8O=!@&Trr7`{gcF9Ht5ZhS=s|(Kiw6|0^mM1pPVBQb-i75myf6HTZ$A0|^` z4rL~toC+#5IUHd=73>Hu^#((%LwwOn?*n&kUv+q3Dc@Esr7Nx`4AzhAGKos!g|sDH zQ7pN=-Tdz~|Niriyt~04HoM?uS=_dqNjuNuhL5`*hsdaUlAi{<=D~zB9WzmKK!lPn zXLS9gs^s{v=bHTk<%m*eAL`dMd0w(h0FG1&10sMT2@YVX)wZ#D`MvjebEtQ-WwLyg zS~Z|@!##?&2?1=FZ4!*HvG7W%g6P>o$-IatuX7=T!zB7V)G3xTr-oW1a z@$6_@Af1?RHD+Wc!h>-&VPO-jPsylt{6G(osxQ+LdEPuRof;uLjutPF-|uPF%T~!u zOXGz1j3TheNgStAyN!As0|xnDp%CV?@{47(B>jSzj>^>NijMjeg{Ge;`dA7OKFH@} zKUjjbaC`$Ztv`b^(?`A2ZrFK)>CDxYL`zZOJwemfVW-jI3(j@mg4(Z{T{8WxP2XG* zKd{B4YKOWnIz+--rYOU37Tps7AcBw(ClJXWkEMNm`QB z4dSCb5+ffm-ISsbI68A|x8?V@N*zz~K@K0vmtTJ87(V&R`y>8)c*h3dz&qv!;FEcj znZTU(2cBpV@$@jUd%N4u%EmW`2=73^nLhanB#}NT9jAe-w5{=KykbEBvKAI=Q-x*pK1_SSta=s z@vEjkbWim0^AeSF9lh0P&X+DlrhR$70nmQwmq60|?DZooWLDwWAM�kvaMr{jlK7 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 literal 0 HcmV?d00001 diff --git a/lib/billing.ts b/lib/billing.ts index 65cc19a..995d2f4 100644 --- a/lib/billing.ts +++ b/lib/billing.ts @@ -128,13 +128,14 @@ function billingScalarEquals(left: string | number | boolean, right: string | nu } export function formatBillingAmount(fen: number, currency = BILLING_CURRENCY): string { - const amount = Math.max(0, Number(fen || 0)) / 100; - return new Intl.NumberFormat("zh-CN", { + const amount = Number(fen || 0) / 100; + const formatted = new Intl.NumberFormat("zh-CN", { style: "currency", currency, minimumFractionDigits: 2, maximumFractionDigits: 2 - }).format(amount); + }).format(Math.abs(amount)); + return amount < 0 ? `−${formatted}` : formatted; } export function billingUnitLabel(unit: BillingUnit): string { diff --git a/lib/client/payment-api.ts b/lib/client/payment-api.ts new file mode 100644 index 0000000..451b2ca --- /dev/null +++ b/lib/client/payment-api.ts @@ -0,0 +1,124 @@ +export type PaymentOrder = { + id: string; + organizationId: string; + accountId: string; + amountFen: number; + currency: string; + status: "pending" | "paid" | "closed"; + codeUrl?: string; + transactionId?: string; + createdAt: string; + updatedAt: string; + expiresAt: string; + paidAt?: string; +}; + +export type AdminPaymentOrder = PaymentOrder & { + organizationName: string; + accountName: string; + refundedFen: number; + refundingFen: number; + refundableFen: number; +}; + +export type PaymentRefund = { + id: string; + orderId: string; + organizationId: string; + operatorId: string; + operatorName?: string; + transactionId: string; + providerId?: string; + amountFen: number; + totalFen: number; + currency: string; + reason: string; + status: "pending" | "processing" | "success" | "closed" | "abnormal" | "rejected"; + failureReason?: string; + createdAt: string; + updatedAt: string; + succeededAt?: string; +}; + +export type AdminPaymentOrdersPage = { orders: AdminPaymentOrder[]; hasMore: boolean; enabled: boolean }; + +export type PaymentOptions = { + enabled: boolean; + canRecharge: boolean; + presetAmountsFen: number[]; + minAmountFen: number; + maxAmountFen: number; +}; + +// Work with decimal text so every accepted value maps to exactly one amount in fen. +export function parseYuanToFen(value: string, minimum: number, maximum: number): number | null { + const trimmed = value.trim(); + if (!/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/.test(trimmed)) return null; + const [yuan, fraction = ""] = trimmed.split("."); + const amount = Number(yuan) * 100 + Number(fraction.padEnd(2, "0")); + return Number.isSafeInteger(amount) && amount >= minimum && amount <= maximum ? amount : null; +} + +export function formatYuan(fen: number): string { + return (fen / 100).toFixed(2); +} + +async function paymentRequest(url: string, init?: RequestInit): Promise { + const response = await fetch(url, { cache: "no-store", ...init }); + let payload: { error?: string } & Partial; + try { + payload = await response.json(); + } catch { + throw new Error(`支付服务返回了无效响应(HTTP ${response.status})`); + } + if (!response.ok) throw new Error(payload.error || `支付请求失败(HTTP ${response.status})`); + return payload as T; +} + +export async function getPaymentOptions(signal?: AbortSignal): Promise { + return paymentRequest("/api/payments/options", { signal }); +} + +export async function listPaymentOrders(signal?: AbortSignal): Promise { + const result = await paymentRequest<{ orders: PaymentOrder[] }>("/api/payments/orders", { signal }); + return result.orders || []; +} + +export async function createPaymentOrder(amountFen: number, requestKey: string): Promise { + const result = await paymentRequest<{ order: PaymentOrder }>("/api/payments/orders", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ amountFen, requestKey }) + }); + return result.order; +} + +export async function getPaymentOrder(id: string, signal?: AbortSignal): Promise { + const result = await paymentRequest<{ order: PaymentOrder }>(`/api/payments/orders/${encodeURIComponent(id)}`, { signal }); + return result.order; +} + +export async function listAdminPaymentOrders(organizationId: string, offset: number, signal?: AbortSignal): Promise { + const query = new URLSearchParams({ limit: "50", offset: String(offset) }); + if (organizationId) query.set("organizationId", organizationId); + return paymentRequest(`/api/payments/admin/orders?${query}`, { signal }); +} + +export async function listPaymentRefunds(orderId: string, signal?: AbortSignal): Promise { + const result = await paymentRequest<{ refunds: PaymentRefund[] }>(`/api/payments/admin/orders/${encodeURIComponent(orderId)}/refunds`, { signal }); + return result.refunds || []; +} + +export async function createPaymentRefund(orderId: string, amountFen: number, reason: string, requestKey: string): Promise { + const result = await paymentRequest<{ refund: PaymentRefund }>(`/api/payments/admin/orders/${encodeURIComponent(orderId)}/refunds`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ amountFen, reason, requestKey }) + }); + return result.refund; +} + +export async function getPaymentRefund(id: string, signal?: AbortSignal): Promise { + const result = await paymentRequest<{ refund: PaymentRefund }>(`/api/payments/admin/refunds/${encodeURIComponent(id)}`, { signal }); + return result.refund; +} diff --git a/package-lock.json b/package-lock.json index fcdf574..8197165 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "lucide-react": "^0.468.0", "next": "15.5.18", "pg": "^8.16.3", + "qrcode.react": "^4.2.0", "react": "19.2.6", "react-dom": "19.2.6", "server-only": "0.0.1", @@ -2734,6 +2735,15 @@ "once": "^1.3.1" } }, + "node_modules/qrcode.react": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", + "integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/qs": { "version": "6.15.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", diff --git a/package.json b/package.json index b1ee684..4cce350 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "info": "node scripts/print-app-info.mjs", "bootstrap:admin": "node scripts/bootstrap-admin.mjs", "db:migrate": "node scripts/migrate-postgres.mjs", + "db:bundle": "node scripts/sync-go-migrations.mjs", + "db:bundle:check": "node scripts/sync-go-migrations.mjs --check", "deploy:check": "node scripts/check-ack-manifests.mjs", "migrate:accounts": "node scripts/import-legacy-accounts.mjs", "go:fmt": "node scripts/run-go-command.mjs fmt ./...", @@ -28,6 +30,7 @@ "lucide-react": "^0.468.0", "next": "15.5.18", "pg": "^8.16.3", + "qrcode.react": "^4.2.0", "react": "19.2.6", "react-dom": "19.2.6", "server-only": "0.0.1", diff --git a/scripts/check-ack-manifests.mjs b/scripts/check-ack-manifests.mjs index b0fd068..7714605 100644 --- a/scripts/check-ack-manifests.mjs +++ b/scripts/check-ack-manifests.mjs @@ -1,4 +1,9 @@ import { readFileSync, readdirSync } from "node:fs"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +// Reject a deploy with migrations missing from the self-contained Go image. +execFileSync(process.execPath, [fileURLToPath(new URL("./sync-go-migrations.mjs", import.meta.url)), "--check"], { stdio: "inherit" }); const directory = new URL("../deploy/ack/", import.meta.url); const repository = new URL("../", import.meta.url); @@ -41,6 +46,15 @@ assert(!goApi.includes("name: zhinian-web-auth"), "Go API must not reference the assert(goApi.includes("name: zhinian-go-bootstrap"), "Go API must receive bootstrap administrator credentials"); assert(goApi.includes("name: zhinian-go-providers"), "Go API must accept provider environment fallbacks"); assert(goApi.includes("optional: true"), "Provider fallback Secret must be optional when settings are stored in PostgreSQL"); +assert( + /- name: DATABASE_URL\s+valueFrom:\s+secretKeyRef:\s+name: zhinian-go-db\s+key: DATABASE_URL/.test(goApi), + "Go API must retain its least-privilege application DATABASE_URL", +); +assert( + /- name: DATABASE_MIGRATION_URL\s+valueFrom:\s+secretKeyRef:\s+name: zhinian-migration-db\s+key: DATABASE_URL/.test(goApi), + "Go API must inject the separate migration credential without replacing DATABASE_URL", +); +assert(/startupProbe:[\s\S]*?failureThreshold: 60/.test(goApi), "Go startup probe must allow migration timeout plus startup headroom"); assert(!goApi.includes("rds-ca"), "Go API must not mount an RDS CA when PostgreSQL TLS is disabled"); assert(!goApi.includes("/etc/zhinian/rds"), "Go API must not retain the removed RDS CA path"); assert(!/\bTLS\b/i.test(goApi), "Go API manifest must not retain PostgreSQL TLS configuration"); @@ -50,6 +64,7 @@ assert(!goApi.includes("DATABASE_CA_CERT_PATH"), "Go API must not receive a data const secrets = read("secrets.example.yaml"); assert(secrets.includes("name: zhinian-go-auth"), "Example secrets must name Go as the session Secret owner"); assert(secrets.includes("name: zhinian-go-providers"), "Example secrets must define optional provider environment fallbacks"); +assert(secrets.includes("name: zhinian-migration-db"), "Example secrets must define the startup migration credential"); assert(!secrets.includes("name: zhinian-web-auth"), "Example secrets must not retain the removed Web auth Secret"); assert(!secrets.includes("zhinian-rds-ca"), "Example secrets must not define the removed RDS CA Secret"); assert(!secrets.includes("sslrootcert"), "Example DATABASE_URL values must not reference an RDS CA"); @@ -66,6 +81,9 @@ assert(!configMap.includes("name: zhinian-runtime"), "Static Web must not have a assert((configMap.match(/^kind: ConfigMap$/gm) ?? []).length === 1, "Only the Go runtime ConfigMap should remain"); assert(configMap.includes("ZHINIAN_GO_EMBEDDED_WORKER: \"true\""), "Go runtime ConfigMap must embed the WorkerLoop"); assert(configMap.includes("GO_BACKEND_HOST: 0.0.0.0"), "Go runtime ConfigMap must listen on the Pod interface"); +assert(configMap.includes('DATABASE_AUTO_MIGRATE: "true"'), "ACK Go runtime must enable startup migrations"); +assert(configMap.includes('DATABASE_MIGRATION_TIMEOUT_SECONDS: "180"'), "ACK startup migrations must have a bounded deadline"); +assert(configMap.includes("DATABASE_APP_ROLE: REPLACE_WITH_APP_DB_ROLE"), "ACK must require the application database role to be supplied"); assert(!configMap.includes("DATABASE_SSL_MODE"), "ConfigMaps must not carry database TLS settings"); assert(!configMap.includes("DATABASE_CA_CERT_PATH"), "ConfigMaps must not carry database CA paths"); diff --git a/scripts/migrate-postgres.mjs b/scripts/migrate-postgres.mjs index b5e2aa4..af0a2c5 100644 --- a/scripts/migrate-postgres.mjs +++ b/scripts/migrate-postgres.mjs @@ -167,7 +167,9 @@ function applicationRoleTablePrivileges() { ["platform_runtime_settings", "SELECT, INSERT, UPDATE"], ["billing_price_rules", "SELECT, INSERT, UPDATE"], ["billing_wallets", "SELECT, INSERT, UPDATE"], - ["billing_ledger", "SELECT, INSERT"] + ["billing_ledger", "SELECT, INSERT"], + ["payment_orders", "SELECT, INSERT, UPDATE"], + ["payment_refunds", "SELECT, INSERT, UPDATE"] ]; } diff --git a/scripts/run-go-command.mjs b/scripts/run-go-command.mjs index 591e7d2..0f28816 100644 --- a/scripts/run-go-command.mjs +++ b/scripts/run-go-command.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node -import { spawn } from "node:child_process"; +import { spawn, spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; const [, , command, ...args] = process.argv; @@ -10,6 +10,10 @@ if (!command) { } const backendDirectory = fileURLToPath(new URL("../backend/", import.meta.url)); +if (command === "build") { + const check = spawnSync(process.execPath, [fileURLToPath(new URL("./sync-go-migrations.mjs", import.meta.url)), "--check"], { stdio: "inherit" }); + if (check.error || check.status !== 0) process.exit(check.status ?? 1); +} const child = spawn("go", [command, ...args], { cwd: backendDirectory, env: { diff --git a/scripts/sync-go-migrations.mjs b/scripts/sync-go-migrations.mjs new file mode 100644 index 0000000..c01c009 --- /dev/null +++ b/scripts/sync-go-migrations.mjs @@ -0,0 +1,32 @@ +import { readdir, readFile, mkdir, writeFile, unlink } from "node:fs/promises"; +import { fileURLToPath } from "node:url"; +import { join } from "node:path"; + +const source = fileURLToPath(new URL("../database/migrations/", import.meta.url)); +const target = fileURLToPath(new URL("../backend/internal/migrations/sql/", import.meta.url)); +const check = process.argv.includes("--check"); +if (process.argv.length > 3 || (process.argv.length === 3 && !check)) { + throw new Error("Usage: node scripts/sync-go-migrations.mjs [--check]"); +} +if (!check) await mkdir(target, { recursive: true }); +const sourceFiles = (await readdir(source)).filter((name) => name.endsWith(".sql")).sort(); +const targetFiles = (await readdir(target)).filter((name) => name.endsWith(".sql")).sort(); +const sourceSet = new Set(sourceFiles); +const stale = targetFiles.filter((name) => !sourceSet.has(name)); +if (check && stale.length) { + throw new Error(`Go migration bundle has stale files: ${stale.join(", ")}; run npm run db:bundle`); +} +for (const name of stale) await unlink(join(target, name)); +for (const name of sourceFiles) { + const canonical = await readFile(join(source, name)); + let bundled; + try { + bundled = await readFile(join(target, name)); + } catch (error) { + if (error.code !== "ENOENT") throw error; + } + if (bundled?.equals(canonical)) continue; + if (check) throw new Error(`Go migration bundle differs at ${name}; run npm run db:bundle`); + await writeFile(join(target, name), canonical); +} +console.log(check ? `Go migration bundle current (${sourceFiles.length} files)` : `Go migration bundle synchronized (${sourceFiles.length} files)`); diff --git a/tests/billing.test.ts b/tests/billing.test.ts index 369da1a..84f313d 100644 --- a/tests/billing.test.ts +++ b/tests/billing.test.ts @@ -2,7 +2,7 @@ import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { calculateBillingAmountFen } from "@/lib/billing"; +import { calculateBillingAmountFen, formatBillingAmount } from "@/lib/billing"; import { BillingConfigurationError, chargeGenerationJob, @@ -42,6 +42,12 @@ describe("organization billing", () => { expect(calculateBillingAmountFen(1, 1, 1.01)).toBe(2); }); + it("shows a negative wallet balance after a refund exceeds available funds", () => { + expect(formatBillingAmount(-60)).toBe("−¥0.60"); + expect(formatBillingAmount(0)).toBe("¥0.00"); + expect(formatBillingAmount(60)).toBe("¥0.60"); + }); + it("matches the most specific parameter rule and snapshots normalized parameters", async () => { await createBillingPriceRule({ id: "rule-parameter-generic", diff --git a/tests/payment-api.test.ts b/tests/payment-api.test.ts new file mode 100644 index 0000000..d25ded1 --- /dev/null +++ b/tests/payment-api.test.ts @@ -0,0 +1,57 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { createPaymentOrder, createPaymentRefund, formatYuan, getPaymentOrder, getPaymentRefund, listAdminPaymentOrders, listPaymentRefunds, parseYuanToFen } from "@/lib/client/payment-api"; + +afterEach(() => vi.unstubAllGlobals()); + +describe("recharge amounts", () => { + it("converts decimal yuan to exact integer fen within the server range", () => { + expect(parseYuanToFen("1", 100, 1_000_000)).toBe(100); + expect(parseYuanToFen("1.01", 100, 1_000_000)).toBe(101); + expect(parseYuanToFen(" 10000.00 ", 100, 1_000_000)).toBe(1_000_000); + expect(formatYuan(101)).toBe("1.01"); + }); + + it.each(["0.99", "1.001", "1e2", "-1", "+1", "1,000", "01", "10000.01", "0", "1."])("rejects %s", (value) => { + expect(parseYuanToFen(value, 100, 1_000_000)).toBeNull(); + }); +}); + +describe("admin payment requests", () => { + it("lists across organizations or filters by organization and page", async () => { + const fetchMock = vi.fn().mockResolvedValue({ ok: true, json: async () => ({ orders: [], hasMore: false, enabled: true }) }); + vi.stubGlobal("fetch", fetchMock); + await listAdminPaymentOrders("org/a", 50); + expect(fetchMock.mock.calls[0][0]).toBe("/api/payments/admin/orders?limit=50&offset=50&organizationId=org%2Fa"); + await listAdminPaymentOrders("", 0); + expect(fetchMock.mock.calls[1][0]).toBe("/api/payments/admin/orders?limit=50&offset=0"); + }); + + it("uses admin endpoints and preserves the refund attempt key", async () => { + const fetchMock = vi.fn().mockResolvedValue({ ok: true, json: async () => ({ refund: { id: "r1", status: "pending" }, refunds: [] }) }); + vi.stubGlobal("fetch", fetchMock); + await createPaymentRefund("a/b", 250, "客户申请", "same-attempt"); + expect(fetchMock.mock.calls[0][0]).toBe("/api/payments/admin/orders/a%2Fb/refunds"); + expect(JSON.parse(fetchMock.mock.calls[0][1].body)).toEqual({ amountFen: 250, reason: "客户申请", requestKey: "same-attempt" }); + await listPaymentRefunds("a/b"); + expect(fetchMock.mock.calls[1][0]).toBe("/api/payments/admin/orders/a%2Fb/refunds"); + await getPaymentRefund("r/1"); + expect(fetchMock.mock.calls[2][0]).toBe("/api/payments/admin/refunds/r%2F1"); + }); +}); + +describe("payment requests", () => { + it("sends integer fen and a stable idempotency key", async () => { + const fetchMock = vi.fn().mockResolvedValue({ ok: true, json: async () => ({ order: { id: "pay_1", status: "pending" } }) }); + vi.stubGlobal("fetch", fetchMock); + await createPaymentOrder(10000, "same-attempt"); + const [, init] = fetchMock.mock.calls[0]; + expect(JSON.parse(init.body)).toEqual({ amountFen: 10000, requestKey: "same-attempt" }); + }); + + it("escapes order IDs and reports server errors", async () => { + const fetchMock = vi.fn().mockResolvedValue({ ok: false, status: 404, json: async () => ({ error: "订单不存在" }) }); + vi.stubGlobal("fetch", fetchMock); + await expect(getPaymentOrder("a/b")).rejects.toThrow("订单不存在"); + expect(fetchMock.mock.calls[0][0]).toBe("/api/payments/orders/a%2Fb"); + }); +});