From ada300835b233e7559c7349c95cf05ac7051ee15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Tue, 3 Nov 2026 00:31:52 +0800
Subject: [PATCH] =?UTF-8?q?docs:=20=E5=85=88=E7=A5=A8=E5=90=8E=E6=AC=BE?=
=?UTF-8?q?=E6=89=8B=E5=86=8C=E4=B8=8E=E4=B8=9A=E5=8A=A1=E8=AF=B4=E6=98=8E?=
=?UTF-8?q?=E6=8C=8911-02=E6=94=B9=E9=80=A0=E4=BF=AE=E8=AE=A2=E5=B9=B6?=
=?UTF-8?q?=E9=87=8D=E6=88=AA=E9=85=8D=E5=9B=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...»辑状态说明(收票登记A303-2+付款结算单A102-2+A302-6).md | 55 +++++++++------
.../05-付款结算单列表-发票登记入口.png | Bin 305468 -> 295002 bytes
.../06-发票登记弹窗-结算信息与选票.png | Bin 196629 -> 205821 bytes
.../07-选择收票单候选弹窗.png | Bin 162412 -> 147471 bytes
.../08-结算单编辑-选择收票单按钮与发票信息.png | Bin 184580 -> 185629 bytes
.../09-结算单查看页-发票信息重推.png | Bin 0 -> 228550 bytes
...�Ž款纯操作手册(收票登记-结算单认领-发票登记).md | 65 +++++++++++++-----
7 files changed, 81 insertions(+), 39 deletions(-)
create mode 100644 doc/docs/业务流程/2026-11-01-先票后款操作手册.assets/09-结算单查看页-发票信息重推.png
diff --git a/doc/docs/业务流程/2026-11-01-先票后款业务流程与逻辑状态说明(收票登记A303-2+付款结算单A102-2+A302-6).md b/doc/docs/业务流程/2026-11-01-先票后款业务流程与逻辑状态说明(收票登记A303-2+付款结算单A102-2+A302-6).md
index 480169ce..d51d0bc1 100644
--- a/doc/docs/业务流程/2026-11-01-先票后款业务流程与逻辑状态说明(收票登记A303-2+付款结算单A102-2+A302-6).md
+++ b/doc/docs/业务流程/2026-11-01-先票后款业务流程与逻辑状态说明(收票登记A303-2+付款结算单A102-2+A302-6).md
@@ -1,6 +1,6 @@
# 先票后款业务流程与逻辑状态说明(收票登记 A303-2 + 付款结算单 A102-2 + A302-6)
-> 更新日期:2026-11-01 | 适用系统:运输 TMS(业财融合·金蝶星瀚) | 读者:业务/产品/开发
+> 更新日期:2026-11-03 | 适用系统:运输 TMS(业财融合·金蝶星瀚) | 读者:业务/产品/开发
>
> 关联文档:《先票后款纯操作手册》(同目录,纯操作步骤+截图)、《先票后款改造方案V2》(方案与改造清单)
>
@@ -8,6 +8,15 @@
---
+## 修改记录
+
+| 日期 | 版本 | 修订内容 | 依据 |
+| --- | --- | --- | --- |
+| 2026-11-01 | V1.0 | 初版:先票后款全链路(A303-2/A102-2/A302-6)流程、状态机与遗留项 | 代码至 933fb37d(10-31) |
+| 2026-11-03 | V1.1 | ① A303-2 分录定稿:送税收分类编码(行商品编码),不送物料编码/税率表编码/税额,§6 移除物料编码与免税零税率遗留项;② 匹配结算单金额支持手动修改(默认发票全额,0≤金额≤发票金额,未匹配回退全额),§2/§3.2 同步;③ 新增查看页重推(/repush-claimed-invoice,A303-2+A302-6 一步式,failed/pushed 通吃);④ A801-3 指定补偿增加开关 assignCompensationEnabled 默认关闭,改人工入口兜底;⑤ 接口表补充 claimed-list 回显、候选分页、列表指定失败悬浮(kingdeeAssignFailReason)等 | 代码 c82ce7ec、6c5169ea、49ccb435、34e90301/746fd3e9、b7d417f3、fe0ba8e8、da1ddf7b/2943a7c3(11-02) |
+
+---
+
## 1. 一页总览
收票登记不再强制关联结算单,拆成两段:**先票**(收票登记只负责把发票推进金蝶收票单),**后款**(付款结算单认领收票单,推财务应付单后完成"发票指定应付"勾稽)。
@@ -29,7 +38,7 @@ flowchart TD
B5 --> B6[assigned 已指定应付]
end
A6 -.收票单已推.pushed.-> B1
- B4 -.推送失败/漏指定.-> C[A801-3 定时回写
指定补偿自动重试] --> B5
+ B4 -.推送失败/漏指定.-> C[A801-3 定时回写
指定补偿(开关默认关闭
默认人工重推兜底)] --> B5
```
## 2. 名词与状态字典
@@ -40,10 +49,11 @@ flowchart TD
| assigned(已指定应付) | 金蝶侧已与财务应付单完成勾稽(A302-6 成功)。历史数据终态,新链路由结算单侧驱动 |
| failed(推送失败) | A303-2 保存失败 / 金蝶侧发票异常回收。列表"推送"按钮或定时任务自动重推 |
| unsynced(未推送) | 审批通过但尚未推送(存量历史单不自动补推,走手动按钮) |
-| unreceived / partial / completed | 结算单收票状态:未收票 / 认领金额未覆盖结算金额 / **认领金额 ≥ 结算金额即完成**(全额认领,允许超过) |
+| unreceived / partial / completed | 结算单收票状态:未收票 / 匹配合计未覆盖结算金额 / **匹配合计(各票匹配金额之和)≥ 结算金额即完成**(允许超过) |
+| 匹配结算单金额 | 认领时每张发票的认领金额,**默认=发票金额全额,支持手动修改**(0 ≤ 匹配金额 ≤ 发票金额);未传时分摊金额回退发票全额 |
| 往来户 | A303-2 主表 receivablessupp_number = **发票销售方**在金蝶的供应商代码(客商档案 supplier_code) |
| 结算组织 | 收票登记页面**手选部门**(合同承办部门口径),沿部门树上溯平台公司取金蝶组织编码 |
-| 一票一结算单 | 一张收票单只能被一张付款结算单认领;认领即**全额**(认领金额=发票金额,可超过结算金额) |
+| 一票一结算单 | 一张收票单只能被一张付款结算单认领;认领金额=匹配结算单金额(默认发票全额,可改) |
## 3. 各环节业务规则
@@ -51,6 +61,7 @@ flowchart TD
- **不挂结算单、不挂合同**:表单无"关联结算单";结算组织=页面必选手选部门。
- **选票即带明细**:从金蝶票池(A801-1 镜像)选发票后,明细区块按票号带出发票明细行(goodsCode/数量/单价/金额/税额/税率),与推送分录同源。
+- **分录口径(联调已定)**:分录送税收分类编码(取行商品编码去尾部 0,填 `eTaxclassNumber`),**不送物料编码、税率表编码、税额**;税额仅参与价税合计;单价按 4 位小数舍入。
- **往来户回填**:保存时按销方名称查客商档案回填 `supplier_code`(尽力回填,不阻断保存)。
- **推送前置**:审批通过 + 已绑定镜像 + 查验通过 + 已选结算组织;往来户供应商代码缺失时**推送时实时重查档案**,仍缺失报错阻断。
- **推送成功即终态 pushed**:删除了旧链路的"应付单已生成预检(A102-4)"和"立即指定应付"。
@@ -60,26 +71,28 @@ flowchart TD
- **两条路径,同一套关系同步**:
- 路径 A:新增/编辑结算单时"选择收票单"(编辑器);
- - 路径 B:审批通过后列表"发票登记"→选票→保存认领→确认推送。
-- **候选范围**:审批通过 + 未被有效应付结算单认领(关联仍指向作废结算单的票可重新选)。
+ - 路径 B:审批通过后列表**工具栏**【发票登记】(选中一条审批通过的付款结算单)→弹窗选票→【保存认领】。
+- **候选范围**:审批通过 + 未被有效应付结算单认领(关联仍指向作废结算单的票可重新选);候选弹窗为**分页查询**,行上悬浮展示该票推送失败原因。
- **一票一结算单**:认领时校验,已挂其他有效应付结算单的票拦截(行锁防并发认领)。
-- **全额认领**:匹配金额固定=发票金额,**允许合计超过结算金额**;收票状态"≥ 结算金额即 completed"。
+- **匹配结算单金额可手动修改**:默认=发票金额全额;手动修改范围 0 ≤ 匹配金额 ≤ 发票金额(后端兜底校验);结算单侧分摊金额取发票行匹配结算单金额,未匹配到的行回退发票全额;**匹配合计允许超过结算金额**,收票状态"匹配合计 ≥ 结算金额即 completed"。
- **双边落关系**:结算单侧 FormalSettlementInvoice(发票信息区)+ 收票登记侧 InvoiceReceiptSettlement("结算信息"区展示)。
+- **路径 B 先确认后保存**:发票登记弹窗打开即回显本单已认领票("已认领"标记,不可移除);【保存认领】后弹出确认"确认认领并推送金蝶指定应付?"——**确定=认领保存与推送指定应付一步完成;取消=不保存任何数据**(不存在只认领不推送的中间态)。
- 历史兼容:编辑历史结算单仍走原增量认领;收票登记传 settlements 的老入参仍走原分摊校验。
### 3.3 财务应付单与指定应付
- 结算单审核通过 →"同步金蝶"推 A102-2 → **成功后自动对本单认领且收票单为 pushed 的逐单调 A302-6** → assigned。
-- 收票单尚未推送(unsynced/failed):跳过不报错;等收票侧推成 pushed 后由 A801-3"指定补偿"自动补指定。
+- 收票单尚未推送(unsynced/failed):跳过不报错;收票侧推成 pushed 后由**人工入口**(发票登记推送/查看页重推)指定,或开启 A801-3 补偿开关后自动补指定。
- **单笔指定失败不阻断结算同步**,失败明细进日志;已指定的幂等跳过。
- 路径 B 的"发票登记"确认推送(`/invoice-assign-kingdee`)前置:付款结算单 + 审批通过 + 应付单已同步(synced)。
+- **查看页重推认领收票单**(`/formal-settlement/repush-claimed-invoice`,A303-2+A302-6 一步式):前置=付款结算单 + 审批通过 + 应付单已同步 + 该票认领在本单名下;**failed/pushed 通吃**(已 assigned 拦截),failed 行可同步修改匹配结算单金额随重推生效;收票单重推复用 A303-2 状态机(A801-3 幂等预检防重复保存),成功后按应付单防重键指定应付。
### 3.4 定时回写与补偿(A801-3)
| 场景 | 处理 |
| --- | --- |
| 金蝶侧发票状态异常(作废/红冲) | 回收本地状态为 failed,提示人工删除/解除指定后重推 |
-| pushed + 已认领 | **指定补偿(重试引擎)**:按认领关系自动补发 A302-6 |
+| pushed + 已认领 | **指定补偿(重试引擎)**:按认领关系自动补发 A302-6——受开关 `thirdParty.bfi.receivedInvoiceResult.assignCompensationEnabled` 控制,**默认关闭**;关闭时 pushed 单据由人工入口(发票登记推送/查看页重推按钮)指定 |
| pushed + 未认领 | 跳过,**不再置 failed**(未指定不属异常) |
| assigned 缺收票单号 | 仅补登单号 |
@@ -93,15 +106,15 @@ flowchart TD
### 4.1 收票登记 kingdeePushStatus
```
-unsynced ──推送成功(A303-2)──▶ pushed ──结算单A102-2成功/A801-3补偿/发票登记确认──▶ assigned
+unsynced ──推送成功(A303-2)──▶ pushed ──结算单A102-2成功自动指定/发票登记确认/查看页重推/A801-3补偿(开关默认关)──▶ assigned
│ │
├──手动/自动推送失败──▶ failed ◀──金蝶侧异常回收(作废/红冲)
│ │
- └────────────重推(列表按钮/定时)◀──┘
+ └────────────重推(列表按钮/定时/查看页重推)◀──┘
```
-- pushed 是新链路推送终点;assigned 只能由结算单侧指定动作或 A801-3 补偿到达。
-- failed 重推不再依赖结算单/A102-4,仅需镜像明细 + 往来户编码 + 结算组织齐备。
+- pushed 是新链路推送终点;assigned 只能由结算单侧指定动作(A102-2 成功自动指定、发票登记确认、查看页重推)或 A801-3 补偿(开关默认关闭)到达。
+- failed 重推不再依赖结算单/A102-4,仅需镜像明细 + 往来户编码 + 结算组织齐备;查看页重推对 failed/pushed 均可一步完成收票单重推+指定应付。
### 4.2 结算单收票状态(invoice_status)
@@ -116,19 +129,21 @@ unreceived ──首次认领──▶ partial ──Σ认领金额 ≥ 结算
| 端点/任务 | 说明 |
| --- | --- |
| GET `/invoice-receipt/invoice-detail-query?invoiceNo=` | 发票明细区块取数(镜像 items_json,缺则回源 A801-1) |
-| GET `/invoice-receipt/claim-candidates?keyword=` | 认领候选(approved+未认领,limit 200) |
+| GET `/invoice-receipt/claim-candidates?keyword=&page=` | 认领候选**分页**(approved+未认领) |
+| GET `/invoice-receipt/claimed-list?formalSettlementId=` | 结算单已认领收票登记列表(发票登记弹窗回显) |
| POST `/formal-settlement/invoice-assign-kingdee?id=` | 发票登记确认推送(A302-6) |
+| POST `/formal-settlement/repush-claimed-invoice?id=&invoiceNo=` | 查看页重推认领收票单(A303-2+A302-6 一步式,failed/pushed 通吃,携带匹配金额校验) |
| POST `/invoice-receipt/push-kingdee` | 收票登记推送(A303-2,终态 pushed) |
| 定时 A801-1 票池同步 | 镜像含明细 items_json;明细变化即刷新(含金额未变场景) |
-| 定时 A801-3 收票结果回写 | 异常回收 / 指定补偿 / 单号补登 |
-| 表 | `blade_invoice_receipt.supplier_code`(新列)、`blade_invoice_receipt_settlement`(认领关系)、`blade_formal_settlement_invoice`(结算单发票区) |
+| 定时 A801-3 收票结果回写 | 异常回收 / 指定补偿(开关默认关)/ 单号补登 |
+| 列表展示 | 结算单/付款申请单列表"金蝶指定状态"标签(未指定/已指定应付/指定失败,failed 悬浮展示失败原因 `kingdeeAssignFailReason`);付款申请单列表增加"已指定应付"聚合列;结算单发票明细回显收票单推送状态(`kingdeePushStatus`/`kingdeePushMsg`) |
+| 表 | `blade_invoice_receipt.supplier_code`(新列)、`blade_invoice_receipt_settlement`(认领关系)、`blade_formal_settlement_invoice`(结算单发票区,含匹配金额/推送状态回显) |
## 6. 已知边界与联调遗留
| 项 | 说明 |
| --- | --- |
-| 物料编码口径 | A303-2 分录物料编码暂送税收分类码,金蝶基础资料不认——**待金蝶确认**(默认物料 or 金蝶建档) |
-| 税收分类基础资料 | 金蝶环境不认国标码——待金蝶初始化/分配 |
-| 免税/零税率行 | 税率表无法映射(V+整数),推送报错人工核实 |
+| ~~物料编码口径~~ | **已解决(2026-11-02)**:分录不送物料编码,改送税收分类编码(行商品编码) |
+| ~~免税/零税率行~~ | **已解决(2026-11-02)**:税率表编码不再上送,无税率表映射报错 |
| 币别 | 固定 CNY(不挂合同,数电票人民币) |
-| 付款申请单 A103-1 | 本期不动 |
+| 付款申请单 A103-1 | 本期不动(仅列表新增"已指定应付"聚合列与指定失败悬浮展示) |
diff --git a/doc/docs/业务流程/2026-11-01-先票后款操作手册.assets/05-付款结算单列表-发票登记入口.png b/doc/docs/业务流程/2026-11-01-先票后款操作手册.assets/05-付款结算单列表-发票登记入口.png
index 715a41baaf92c69ebfaba3873f935b4e446c3094..595dc5f01140bde71a94c0eaf202dd64b1561f86 100644
GIT binary patch
literal 295002
zcmdSBWmsFy*Dg+7DA1M%C|-)SXmN)YcM22?%Bbw)D?*CQr#sWARtmwl+_|2
zxciEL;D+VxtN0Qw5M0UOTAEqxKzFaH$
zQa!*nUR$D5ZtqyJ4_t3VZC3f6RRj=E6lLjtyJn~f)0LwU)_n1^SWn+9AhsUl1id(!
z)NpZe)pI(SIkKhdm%xQ4Q}5I)rJ#@Mq<#&h7m^aR*IgK`dw9D3`0CE^Z&Utrxp|}2
z;YcqB_iBQ7ipI3KhTjheGFX3pVt;*kOF*#v{&w9J{)}j$%QCOKdX;iYt_0-DN!NZC
zX4qtAi~PPJAjrsjvUT&%?VjTGsXuq`=z@9buIN8%p}s7WAhhtfltn<`#pdQxNssle&E9GX0F5e?)2-{%K(!#oKTx*5K0&~V&b+mr{lLwQ6cqIJzq+%XZ
zp?V=KlG(VQ)9uh5U8rz_HmvDSg9*fmG~!5aDVmqlJd5VWb!r&8
z^nj%W%EYLXOC05VX1V@y4Dfha_-_>qJQb8yr{!2t(jBgMQ1FG)G7&YF?ZS(`2lG0=
zOA%2GWa-p9$*waPcz{>_Ws@_enyx3taq&FZ*_Rx1%kI?nW$aS;L4NNGnA`;cnU
zRS5%kI&HoOQ~-fuckEvxAOB^oZ&k(Ii+{-K&w-Pb7q@?f2ld^Nko5F$G)`^Qk(OqX
z&4$A{_;F32=CjV2>k5Q<8@Xz}a!q-)>FI$mhZNrPvp+{RB*&O-DgM?-xN%D~vxHK^
zlnqg(qtO%y>-;lIg-tr8!tdJV!2LUfWI<(IqN4Vvhuao1Sy^buPBz-&?;-}xPo$-N
zaJwVM%i-#j4(l=B>n3iz|1%TcS)hZj%_}B4h-zJIl@G*TV@%Nz_-Y5K7`j`R^+fui
zg|xub$gS3e3Nm6~u4L%#LfE%LLL#EDkPsDhbz&Io%eXdWC1?n*<{JXf7|b3>Lh{6@
z;_&q}A&o!%>&pJ?qKTHr#s07bK#HCFo{kw9=Gj&0ysxWmyFLY_p@$~jPkKmCMQVp)
zgN*0{swE8#4fV9OwY9Wn-9%4to9R*W!VGRLkH;qR1i72k-66Hw7=iI{y1zU^xMr4C
z;Rfd93-yw1U?F^J(%s!GbFfjv*4)9?BR|#^Th$Pp`7?^)7GX;6ZWWi2fx+=U+EhVS
z|Eva9P(Tx_!^l`kM_;+*SkpZHp9=OzvL0sNK!1Tpc?$`qikY0d7W|;-thqQS8|OcI
zDpT69WAHP1EJj^;zEiGL-|OC0(C@wy5VU`tn`L6wZJ5-)c>BU~<)uQM5>lX7{qvo$
z@ZtuAz@Sl>?56#%Y(}%|P2bPrdhEm2*)`+7h)0=tyN7MCowgH%(KIOwBsKl2@
zM;+A20H&g%qHnx*cG+{1b*47!C8`Um
zcBPWjCOpy&EvuY1-6Y1T*0#bete(rFWC_0)7WYXwm?XZ#r3ObAF?Db&!(j1?_{4__s}YYx34QB`*g-8og%X`JM(ep%wfo0lO)}XTi3N^CRFR*T
zc6hp#dK@2h+w+cteZs*}N#>q*ABCE1BH+E5WKB*L-Dx?u}TJmIhcBEvL7P$v?k`>fHhV^OwZ`7+Sc)8XhbJ|I%&N1ETn=q&Kr#
z1#S`A*P#dVV5ta2ai;821N&8bfki=yI>r{67HN3ebnSyXgylfYw+#c+CZXOsdBF2d
zo$^V>{xoYV6qR*j^=oouK@|6+%`7KRgHT1e=;L|UyG*Py=X^t7`YE_$2|-S`yVc+u
zTN8k~iPccNu8pm02AyKl7zn?>@1vm{OJTMh*~xQssn%^Mjd`*YfT-q1@^aqk`
zgEqeXgQcGhEpJPA>!-7eYInh0-MlSg2Ng%=-hlP5no2#O=iVl^3n;&{GxNDEXpW^*
zAv%fU4F`u)S=`vB*SYHy_(6T)X~T;TaNgp8)$kWiD9y@XwsjN!^KP`fBeggf*fB
z<`9HG1Aqdx#CA_T>1fT!#EW>c-U%(eO0>)caA%Egs?RsDGilE&Mexogy+yJ`+Y~wn
zj8QMNGVp?+J!7K@j@;Fi42&T$5l)D7JNLyAE9gR&TO#8~Gj)iiZh?TW*-S|jvZU{J
zoh!OK?H^W3##rO4g|kIT$qm?vX*yB>t;Z3GG!mNRJv%+Zj3*r*
z<2xBaHeN*^K>k
z2=Li}scbhVe^jGyx9U|N$GjFUEx`gtv&s9f$ohkU=hQiP$68vRHRyYi+HoW>uWSKN;OFEV5?6Y
z5GSY>?+Wg4WH-`o<@Nu_PVTNa!Vq;H);+(Z?cH98q32^t{Ht(g-!r
z+!gXYG!w(NJLzQ%8fWMwp_P;+Pvf+jn17(h3=VUrPaV|{5^q#ge!?u#Rv?vb$OMKs
zE0p(?7+wpSAFhu3*?G6K5T2gM`m$4MmI^4Y+(%<{Vc0RoIss#9C{kS+a{EbzjmIW?
zM_d?e`)fo9+xzyU@B-*k1`@zaOI_Dga<+Bf%fc2fXwXGsa>&6*x`2-ay<0<001s@6
zZ(XcSV@)e)v9RAnP+na%dMUa8!9;fSRnUHu(9UZ4@h{kJPuN51g~71FaNf2qnLI@U
z8M+NL`(i4y5}XY@`W3anR)nbX1ouJcU!kO8u@_o8Fgdi5z(9px8eM8#Dv7N
zeg9L03z581rg-V(K6>K5#}a*U8*Mt@5c`%11D~FL(b3N`rcG>Hy}ptE>AsX#aL-=;
z>hm8|v}T?0r9Ehg`+R-S^f24g_(-JT#)-ZQhWwF`iM7z=WMtwqLNABKdi$Wu+3DuW
zgD`I+>pKqeZN_GSwEHJf{u52TPLQIazM`e9ZH&(NWN-L~$kZIO31#yT
z>DeUTE7oY9^Dgy?U*(i-6AUU{h2>%ju3c`PXub9AWD0|yqY7vP#;b;@%@Jj@%{t)6
zSlcx-VH-sY@~OK(V&(K+moa_dxXq$t9tPyJF}i^nOnhG@|05)*yRM;h&Ct`bti12L
zbmyITx843MEf+SbwA-=6bMxQ$tK?wJ+y>{6O5iv{c*1c853l-S3cEJA^TN-Xj1$+B
zNiDtHcBJmPTgY;)=7fLlUJW8$AZmOoyp6S68a*XcSvP+4j!8+Veo(^1RCaE3@c6Z#
zn=feQ4Ovz7tAhn?tCXTE#hY}PLvqLQDWg13HDu#l!N3M|&~zhBprnB7Hx|H!_Tz}y
ziwfdn(i__7hfm@%;eiIzKcQo$i%AoVG&}QRP!VITgW3;E^}NG6wVCCkwS<{+duR!Z
zPdYcJ$;m8wmA3a4p3l9m@rAS7rn7iYMYVo^J)==B?R&<<#~t;}*WFLGuB?p
zFL+i6=llkL1|HD~RJ46<>!Yf#^;+LY*482alc;@*a)H%))Bv}O%m*L*kSU`7e+p&B-(bg
zYk>1sz4_6Rc+D7@AEzT$n6^wY-i_`oB?s513ZUA1dhCc$E3L<6M;vd-KIGa}Rmew)
zACw62KoVp}l*eBIJd9ghD-cP)wq0;BfiEPq7W>@PLSu4rw?1M)Ch>`oZ`l575kRH;-@tDq`8L(nkvY-VK+l}u*PR0OK@VKnzaIuFkB3_V
zR_`kB5_eT>Dz!n3t(t&LjcvyPM=^#RcEJdD!ub+1qJ^v$CW#U=idN`SZS<3A6V}20
zvj0d;AZ26X$NUxJD*{@xDP-qJ8WVx*+0OEQ54M%y(Oq}dVc(6Y?q7F
z`~KEi>dxn2xx7vVYuzxo!7qXG115m5>WA_kn^1U>ef4$VXL0v9%jz>x{`GTr84sG3
zFGq~^=c|m2S0(mR0IYs~6OKFc?NDb;-*>cQ?ZiUjLoNy$1
z*Zn}Ag&yVbx_sqG8Ql`r8Wi_?mm9Fb$G4yvb*tkK0y7?4HgZfy$AUum6qi;?X4`#6
z7GCI}MU)FjXx-O@UzHrZZ5_F~lolCz%(iI7pvlY-l=V`E@$m=PTB#}K
z4->!LP=`y@GVcsGaX%J^Z(AMaj+qCR5Aw5r=ovR`OnptHqe7kL61JXNp*P;gxLcVk
zCbS-hPv9`^;(}i$<&{A-{6kgM2E?MwEwNrK)qbB98lahZiX-U#IoA_DtJ29-hID^R
z=I;Q+3!z;Hz`%VE8&H(Dv5-Pf;xoSN8#L<9)wQ8QH%lsJ-<~-NPhNzz2{e!~Ur|Zz
z7uHz}x1))uGYJ(J)|mxbjtF|XG^QjD9`?KoJYV2jYZ%5umua}sR-6D!1a5j8(@hXH
z`5_Q_i|TlxA4MR>G0K@DRNpDQ5PtP&pSqz|S*T8r^Zp{^GZK!A&z58-%a-)hXy83i
ziQkmBo=~`G`oCHK=|TBO`N^+)RaBc;>iEzI5EKlHk%T_se88g3yU@^_D-#R>Y0LAU
zMT1DZ!TeKPmssHdm<-{@%~B`1#pNQOcmyT^**Ln_ls&Ic#IdhLM0+LUrDw4XcJ)$*y-3|NnP6|>0qQT1e<;7H@`NvbMk#>x%gNik;VPMfX(rP_;MT=NID}a
zj0?doG~>lPlCqTLhWI?)HI$_DiBEvU+5G%aX;|9Qo_v|957_4rW4+B|{y_#ZNUnV*
za^A-{El(Tkt%~~;n-3udxry~03lW7|HBm0@p0TKS^zaBoBy~WekJcy|S%WC9LyS>G
zK0+Px*7Z_qnYtUf@=VO;>|3~?cL9TS-+KuQ*IcH05yqo(Kih?3Yz|g)96t1gaVjCh
zSkCJHogrNJ>ZVT(N~xrqch%#b5%CmSM`}0}rS}P&Jb?rohfis8C0eX{hcA)?jNOxO
z?`ofjs?w!#${3H?C_%H4UweI!)NX;6EP`Aqo=}c8R_@vxamPs0y1`WgQ9n47LtHFT
znN8~W^Ea*)hG)A6#Vf_Kg0I;iF@TmhF_!LscB}Q{P#yPnafAHH5gNr^$u_~+LX*>)
zS{p!Y4pjSbgPdZmchw}-vwi(HpC={0#_qT5;<}9KSJN#?t=+Cf>u{%Va%!`yNJbwK
z$v~&kTgeqUOh{2JddJiCWvK{CM!3mNW&R_e`j-o-4?6VSyxMH0aQ`<;sZVzy0>)n(
z#of#;K-OpI6T%3VH$^^vvev8sfhX{`E`|x}sgaa3C(vh^I8Vq7-4nt*m0E1>`_rr)
zPZA~MCBW?U=_)#5=vhf=KS~qquamy~3RYEdbE?n4Mn~-^vx^hi)zDEiWvpX3Tkqwr
z7TDtH6}!8)n)LGcIosM>pW*Q<&UR;W^5mbAxn_G6gB^V+r^L$~g$O}$VT2MVckQ{-
zDk~b2D%Pju_Rkbm@Sq-e+BO*Cex-5C8X#QA^9-M!DkEJ>4aaW$B(4z?`JWDtaK42W
z`k2=xKO1>taLgM^_)nfyS3lLD)3=z`%}(C1%=RvB^-?d9_`q&<6>8V-BCLX{a>~{+
z>5Couo?HAS$R|L>6l`S2BPF0>MGy<}IGHXs%%sR^V>x#}M}}F#n2v@+#42oe2cp>4
z%8N|5q_4c2XLz$~GB8Z+?gC&N*05C4OFRx_9zxv!rPXt)=avl6)<^44@q+HM{V0wEbymZ#eRwl!H>vIuBxxACfoJFO;
z@E#sx$Wd76Pd8}%%reVdQDeS%96~*_4`TBU5if7%TdySA>MHm+?17ekI~dscu_dX8
zQs`xyKvmp%TYDhYt1?wM*VD+<>$!jB^W}7oF4H?V8{;L=Us442up3i!OJ1)w4{k3a*PiR{`
zXqx-Vp_;1Q%A}PJ;Hp>V^6(8u6Jr;PI)Cyw&^)yQVg(ypWTqJU%Zd8-7y$n{GN^LvH&tW
zrq?+SZ(fCPMR}4kVF?=(_d@yRYvW=*K&tFx#UJibkE-#1`})Vj8q+?FB0W}-O^6kx
zFAV1d8_;rLSM7J%a5R#&5>@6QWrzZG@hogo(n~6Lu@u&kU^1fs#g{(Agql(8%D^uN
zaU+2NpF|7T>3_i)FuUrh=t@k=ky1JOC#4MH3eXsw8yS4
zmd?(_6RNmJv6x0rR!?GtkpaUt546!#P+mm_;M~a-Lup;}Pomf>I+4e&Yp4P%tGIGx
zP@BQUPF$Kp?9a-u{+OIZCqlB$o~rpSjznh@nHh|!^+aR;Lr?VnbU8mI1@&8-kJLj>
z3h(Qxm0W;EIgR!6^ih*{*|+)z={?P()3*84V{0s!dSMs1Qs$k{jVYtaGHJ&1RlFY^
zfAvakqL1BKIuqQcoAXP?u>)hWi0I;61LGsk5()Zc!KT&CuQ5T`e=KAooev
zSYA
zy`|5DTjdF}Sy1SOdW*RLv`VW~K_w8F$j7R*_%?Cym7w@VB)iRiza}OdU23yw8PSA-
zYXLbIC0=Wn%2ZvFWG{ZPaL6&4B?6+*c!F{wL~YLsB=mx9tHF{c@I>p257rd
z^@NIk1QHG>xAFM&DL`Q8nm*&uFvLW)#dWujjLXD`E
zmnsf2rp+Z1gdO5RhO9h9>(A)MAViF#QYNm6c|rg)g?6|WN~aR1&`C(yxRS4%7b4E7zU!qS>8KF8H+rC!HGf|nw7|+5Bx~R$Xu++f#8ZU=*
zN=$Xa2G4$^PQMYSMF#zEEI{rcUg1PgT!%fq@NRX8?3mvRauC!8q8~As+x4|XEv;Yb
zv7XhAOA`e?8Y&8}okWO~HgVs?;*Tjb9sBPw7-Kc9{eWI9D!o4m0oy
zYaR$>zoEZ(STv(IJ+)+X1|=WF?1x0hdK;EQ$*j@rk)hg!_VeUHbrWtg>v*(gn!*T3
zgz{M#Y&!~xH}I`i8!mi#SYx6AK*gx(Ph~+jxd`iM%_K#6Zaug9s@h4Oe&k{a7x##>
z6u91m&qzN5?`>LN-K2Hd;#Ufe)WKTWUgT4V-*U>(seaVEtapYDu$mK|x_X@GM>I~wY79jST
zQ;kv+3G3$Wi+$EYO>h6{LVtj4#xQrZ{WZbnpCe51f^Bv3MrH?7OxmB7sTwlg
z(pPDd>=zSmev310R|;HrjW0wVgBAq~iAC?6-Dv%H;*=%2&nX
z$vug-QW%QVqhqK#r#N@@x~=pS#m4m?>lpgD0n!%YzHN@_Nkz?W>x#5S+3tG?(xoxl
z9DjRBOUZ)nb>KBPN@iykQYKH39Q(-&ij(zw%3XUgBg52+(5GXe{8(7zd7wWRyR)Vc
zmI-gD+GQ2Y#n^X!b1_Zqfw5NbHwCc
zdO)|&sW*7}mDDLYg1VTBj6`4C!z;2
z>EK$|*p7K!%vz+?75m%6%6@Vdbc+&!xFtjfA1*SR25ng{B)L;jq2yw1-cp{sb4&KP
zD{HCip9pa=lZ`Y^8>grvQ$X-e!PTNBq?RBplz9y5S=yuKl#*KUb6?w^4K_%1b1FQl
zri^J0c(lJ57$DfyOU>;1!6=>~5o~r4DD-M*_V9cka1yG$a8Tm3S@;0Id{kK#^?Vb?
z&(0?;+E=Vv5`E<91db+h9_2t{J+K&UrA{9Vk6IVmamXZl9#5`xJbz3zmlHJKl`~S@?rPla74gea
zA&taFuo0%v&fhRTnFaNW6Zfh65p-<8ugcrr{Z$j{`-*%s&PV$;W_~i+N(m7w-=E55
z=d|LWUO99bZTZVhi3B!1oT$AZm9-ESw&PGqR?@%Bnt09fMN9;yEw96U$nwAz
zK*q&4sb%@inVM2UHP^BWcD4|O6DM@j=!`rJ+?czgH>pj19=4*P`D`MhtINSTw8SYm;b;41
z+~BQ~L%r9i?|+eKYBR4fk5rG_5J&IIcd#NSYSJP2>>5m>S`N+>lNMV&Y(nY_k}J!9
zLHXmt`sYiY)SNgZVyeifp=;JbS%UV=D97sM(z`;EDA
zft^{T%sFNhc+99%04mzd$u}Yq(-lN*d2S6`!eOGVbd%=SXbsBmK*}chXlp-V()#y^eM^1wC$>gRj?(pw(Hvo$v~=*eUDmBN{kXQ
z3URjM>t7P-y;V$mD45xjl%`8E)!;+%lw_6W7Zr1Yd|2C
zwbYpD2KDT!_qxCE`kH{tf~4o$B%PE=&BqbGX1zY(MlugE8fY@>Cc<$|fJ4BxCDx}OORsTvxr9wr=-l=_`g&u-D)7V-dBJtCd%?zpK6+e}E8TmaG~GKc
zp>J?(!fN|U6a%l}d{`ibIHbU*VeoE3eXk_Ir7=op7L8fzN^=jhb0e^8u~K$#Q77Hc
zi(0duTY9f+x~|u-gW8tR9Q<+y{@hP9GMYDO-l+K!I4RwY-hYm@?Bu@!uHXRt%DRcn
z3p6cvJN1~5Wa>&hqdIOEvjn`oC|LK0J)8%EPbje$YT!C_5!}NHIIMz|x!l{G86~G?
z$Rm#1V-nF~!4h{h=7#!{qhcwPuJilJT_7->Q2n
zBo0ugc^v#xcMZ>(LK1$Y8Wnq@8py09UqI$gq1QG3F@|UJDa+PID0K1nHv|L&Wwx&h
zO|wqA@?VSi=I^^_=o7~(`PKZRrxc)_f;bfuS2b^D=26x%&+$*Wr&?~k%FB-H8hO0>
zA}j1~PGyr2QQyFN1
zmeewT!Za!H8eXQ$R**Bya3l65N?hUOZ(icN4BKqSW{?|c<{#cI!3z@Ezd5MOQGd6E
zK;q$Feu*GM;csyS{~L++Z#wD#1xLOb@{Y#yp82=N>L>i3%3>~`EnD+<
z;z#;be_vgWosE+>%jJ^+wFKdiCh8ZA5gV8T)h~&EI!TTHV5T#?YGvY5t?xEM@f|e<
z@2FikT}p71!CRl&t@Q(W1<;>Dp`^DzTc}@1u>B=*skoFAZ!~G*Uf$9Ee=7QyYC8}b
z*|gC2ySD`IxSAjRMc%~Ix&I$p;$dZxKG#LwshwPOVyg}>jtHy5dR4zd!@A)y$Z2~!
zW~{khCD|0S#9Q0DLMUNM_Pdk9g7^vXqKNFVyP&EE&6_JADm{wV9Y4;YkH~CGTB+fi
zR>XEUFs<6K!e9~BLl0$BN3C)rk%q)DTZ4;wJvgL^6{A>|DDhj|@_F+Of&rDnQFa~m
zF`a=AIvd7p(~E+MS!2bipMiru+PSZV7Y^rNQ2#9Uw0VC|H8Mm&g!8xUFxsso*T(PAzK
z#VjvNre{>f~#ciKanL_Ur
zU?_HP*I>fdSv8E=aCL?kqU&$GQIejsK#^yKof?;vV6UfmQ^ADiVv>a%4fdLM=@N0U
zA`Z!7&@_dq507=vX#TRTcf-y3qPo-4@-7`cQ;gx=M5BE~8KE<xp(`)Iuf!@1@`f^
zKR)+X5x60RO>ymOY~o`<{TMg3b*yx4Q4^Y&5CQv)@VgU3m9j9fj0xu6tmcI-XP1oZ
zhN|+#fg78e7A1~--(aDWw3j3Xk~$O>dh9gJ3qU@E6kH$58Q&A9#btg{5+(Z
zY_Z#3r9fP%*=W5!Uzu%t)Gen5w)YD1ju8?v9yPR4LsaydYT(Y+TIdbMl433=e1^=w
zt@b*vwY@k4X?XS=twn3>b^C_*-=2KR!8Tb1n*JQc81cQ_knfG!hg&R%w~On?XfxF4
zPS@66s3g5H6oT1RnaQuwr8(T_v2FwpAYOXpXjjq^32uS&sCn$XX7n1|kZyN~$^^DX
z-b{$?jwD)N&gy}m{~DTvzj1kQ21eAmn^Wp-kr`cf^XXMg^Bq!_juM6FMYcSF%=gak
z2qtVAmzq?I3*T2c`j_AhA8t0%lc#Iw>Xd9WU2pht>q2y>?8Ke*DLe*iy2~@YG%#0~
zt660|L6=yiggo0ny$t>9|9UrEY;v;q-qx>fu14{Ma%6G-*0*+g?q^&F2^U@6+};rS
zh|tirR`)(NA*}8$-L;7=^n$_eS`Hem!Kz?b-+6)kcpOBPgDuN-@i4QBt^f;gs&CXg
zWBRPPmCC;Q_=dYnE4j8X?y{`^t~Mk3fd}Mf-Vo*L6M|D<{130SYG<^G|Htclc=OQn
zJIdKJv6fwbe<#fK3k-h$xJ~J$d!^ttyIWZq&Euus%Jpxo&o(wZ(RUlwYT@5^vD49U
ztBcINj^IT{sY|+NYHrK5&GGT^uw=m^!>We-eBlnAKw?^GqUUVJ`)fHv>zJy|0E!FG
zwiWHXRA(=J{e-?wgR+C8C5lv+u6ZD$q0~Lt9RL`kKi`Wl=qi|SLRxjqsB^Co?(tt~
zo3AW1j^1Cy7OC6^Z;tPuN|Bp@j}|0Va&gKarzntX;g91oOjwHpNYY$~0{ytIz97WV
z!b49#wg*RX@+ci?EGk-+69i%9ORS0n|Mv9*E24r=^I@ol425ptxkv=w|^wIB59x%_dc((628rEI>|9Ny*nB9xRsHx0GgD?z)5+9v=Su
z`Sz7}#MTQxEa2Qkb&g4{(|*dng*#0x?k6xCr_p*uZ#70o9Z-VilSOmdR-ea*z+=wP
zh)0LNRz}RP2(r&w&}>)kZEd9R)H#B2P7&Le9E=wV*wH3re)S<11O9kX?5{S!@p)b5U7zXDo0Nz>UQXVF};aK7^59#>gO>y$-_5^e7#CUbT!_RU8(S%0(
zd6uge3UMjo0}AO5IMh040s|t56-~hg$-7cn9oS_8$yd^G72`(N0Z6f}uB+*T3-#?N
zLEUv&f9r&1Uf3^AHDnnwV(Bt!i@t2XIVB(
zr@O@B+O+?h>4r1klicv0e3J1hn@wRae$bE4zj%IXdLA8}3zAVighoc*r<!)bZ!snZ;zYa;8csI6r!S^Z!NGT~Huc)1`+PO+5?j_OtlH69RxQUV~mdPYn64l7v!0ugOVcH~^b#tcu!bumVl632W
z%0Q^PS}a0&@xWus@-iQA3wL^cU`K6qgz4VzUeYdVI5-wli8J8`<~H7_a~!Q!(%#}z
zPfr@oi;#pD6dZ45MF4@ova+h_i>3>TH?8^k`RP-x=zLAe0~$4?l+nRY|0yp8z8W#7
zM)#g&&5dq7J-x=WJ}3&-DB-a@fPqX!L7^N3ROOqGrsU)Tj_Wnjncn018i#(p+?Dp}
zKE5wlNbK*`Y0%la6IFF*`qyI>IVy74(?r!7)1-4;_##eM8I{5hezu-Y<&4~3
zpnSGt7w$%uJ_nBWyqp_}Uf>x_cvn|f!?BmUg9H2-3{mOSJyijONJ}^8heibi$cceB
zXcFQCZ3kX#x-&8|J|v}PUrK7gfX5~LCiNp07@s^@oN~)58?Uimuf5@ax+@{oP-Z&a
za5du^ji}pGHc`>w31updgt1dzsy9F`#MnW@?6Js4(uFlM-5H594{WBoEmh%Au%_G#!gg$(3=5AHtZvGIG
zOT+EIHtw=79HW_@NBpW%10yDI;U#KHu4>iwkjr2ZPJ4YS4)1HrT$i{`enn*|Onchc
z+1f6*QW!rXB_*AgkHhyXB;-72tVTUPHm)!If;IJN(NlOW3wfda8g@@CuU}vzq&7um+;9%QT_Q%
zq7GBfqlF94Lx$+wWNr~%yVs|VPIEH7Pz)@}zjESkncA1SMt!yv-fWFC?c9@nCA+lk
zvc*X(F$&isnA72_{3Wi@Xg+JFMyaCyXoB{43id9n$?!`^NIchB1_Gf@>cqDctsyzo
zb21;ztC1r7-M7>Cgv6)elrRF-(%h{6NXq2n>dR}lR?8Csx+YF6v*s2S7UsQf$_3}#
zt*Q#LvZ0Th>-;ES{xx%$oXz#gij#i-qei^1&@(bh$q=eNuicb7pPzPXwpqk))UARV
z>Mf=UKOAJ(;j|;9(jpT)7Ia+qeg#MK?qknzaefD#tn7`aJAuhgbl}tN!HFa4DA6rN
z)bUz_dCh6MZjggB>JD1ma8fzdyS+at{9;A=sEA}<_@Xdg0qqFUzS%v9rKTTe^v5Em
zPbF!qe`irI9$%j-Jq;nd<>IPvPpYA`prE{5b;-!9Q||bzhp+!O325gWZj4lK6xWUT
z@?|i_;M!)UOwgqBN#VC|&$gYnx3@V73vZFo?Zr1rY61WN6U~=17(*hOgj~%Bf*iMaqvud=$y}SU_ZiW~ZhzyO#W9=oUHrP>;$%8)$B(=cZ;nB@U8@+2iNCd*^
zz$!i=F&jf?AQ4!#f-=@J5`VijbFqmgIif)r+DvU{i9!C8w4CFL{M|#{_J8MP1j~iB
zDl@cHROaYwo2t*Ab#`_tk+P~jN|G!e3&_gKT2Gok7p4iXnlf=&9x%IOaB<#l?6M92
z{_)nG@GBc6B^L5n+?OwR?WBT(gCQ7CZx-L(A#&Yw6q<&EDq&nKDB`#LnrYR8$3a
zkh1;$Ug!r4=;CC&u~*4u`w46d@x0K+BSDo$Hg>j;MpJ+}c!A43D&bePi4{QfN<8i~
z#JYFyzrjqjg?v{xWrB#?TU!HzZXk;e4-a8QNh0p6-v)bogmEc^zC@L@)TE4mDtXt3
zqI{405lrgmgQjI*U>IzXQ&702okR2Im4Q2=f?MICpFf9%J>z)#^w~2tRn^D?{5jAv
zvzE45=tFPYcO
zOrp<@A&C2ETVo@doJ!nd!2j%Ys=8V@y?@uTz
zFW=X&H%lN<_c1CVGGii&I3t->46JG?D?8IlgF+<>fgb!NuiM>YhW6n@UdydFXHYO1
zIXQSXm^24Dn16nZZ9uQRo5p8njh;-S;WK|eB9Mu;#d;eXrxFM+#_GJj