From b98399a4f12960f44d5de65a9d213f5de349bc29 Mon Sep 17 00:00:00 2001 From: AlCalzone Date: Sat, 10 Feb 2024 16:10:29 +0100 Subject: [PATCH] fix: support 800 series NVM layout and new NVM3 files (#6670) --- packages/nvmedit/src/convert.test.ts.md | 38 ++++- packages/nvmedit/src/convert.test.ts.snap | Bin 35446 -> 41737 bytes packages/nvmedit/src/convert.ts | 104 +++++++++++--- .../nvmedit/src/files/ApplicationNameFile.ts | 39 +++++ .../src/files/ApplicationRFConfigFile.ts | 37 ++++- packages/nvmedit/src/files/VersionFiles.ts | 8 ++ packages/nvmedit/src/nvm3/consts.ts | 7 +- packages/nvmedit/src/nvm3/nvm.ts | 96 +++++++++---- packages/nvmedit/src/nvm3/page.ts | 134 ++++++++++++------ .../nvm_700_json/ctrlr_backup_700_7.11.json | 4 +- .../nvm_700_json/ctrlr_backup_700_7.12.json | 4 +- .../nvm_700_json/ctrlr_backup_700_7.15.2.json | 4 +- .../nvm_700_json/ctrlr_backup_700_7.16.2.json | 5 +- .../nvm_700_json/ctrlr_backup_700_7.17.2.json | 5 +- .../nvm_700_json/ctrlr_backup_700_7.18.1.json | 5 +- .../nvm_700_json/ctrlr_backup_700_7.18.2.json | 5 +- .../nvm_700_json/ctrlr_backup_700_7.18.3.json | 5 +- .../nvm_700_json/ctrlr_backup_700_7.18.4.json | 5 +- .../nvm_700_json/ctrlr_backup_700_7.19.0.json | 5 +- .../nvm_700_json/ctrlr_backup_700_7.19.1.json | 5 +- 20 files changed, 407 insertions(+), 108 deletions(-) create mode 100644 packages/nvmedit/src/files/ApplicationNameFile.ts diff --git a/packages/nvmedit/src/convert.test.ts.md b/packages/nvmedit/src/convert.test.ts.md index 708d5d6addf3..edb42938b836 100644 --- a/packages/nvmedit/src/convert.test.ts.md +++ b/packages/nvmedit/src/convert.test.ts.md @@ -11,6 +11,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'a11d19000200001e3212270efd213a04fa1d00020000000000000000fd39277c022e000100000000000000000199445b8fcb3e537977d642e808b6568700000000000000000000000000000000000000000000008756e008a3cc6f339248ef5d663f50e136e12e8fe7432265349446d6c5541bf3c500be6567027beeb0e7712b11e21ddf53d86f0b134c00a3bdcd24963a89ef0d753a35b3033f64d1b759077a24d59b45da0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + applicationName: null, applicationVersion: '7.0.0', commandClasses: { includedInsecurely: [ @@ -47,6 +48,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: null, maxTXPower: null, measured0dBm: 3.3, + nodeIdType: null, rfRegion: 5, txPower: 0, }, @@ -174,7 +176,8 @@ Generated by [AVA](https://avajs.dev). meta: { deviceFamily: 2047, memoryMapped: true, - pageSize: 65536, + pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -361,6 +364,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'a11d19000200001e321b9884fdec8bdd380e00020000000000000000fd8e8c480f1700010000000000000000014c72cc54358f3dc9ce70ac752beb3e7a0000000000000000000000000000000000000000000000873206e7a00af5746fbc07ba927a6bde014d36396481ce9cce689ceba3f12841d85ffcc430bddb814dad5874aa73866b6a1361c9802cac47fc4df1627838f5857eb334b1bb0a8565a09d46bb8e722ac7910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + applicationName: null, applicationVersion: '7.12.0', commandClasses: { includedInsecurely: [ @@ -397,6 +401,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: null, maxTXPower: null, measured0dBm: 3.3, + nodeIdType: null, rfRegion: 33, txPower: 0, }, @@ -749,6 +754,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -1104,6 +1110,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + applicationName: null, applicationVersion: '7.15.4', commandClasses: { includedInsecurely: [ @@ -1147,6 +1154,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: 3.3, + nodeIdType: null, rfRegion: 0, txPower: 0, }, @@ -1452,6 +1460,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -1600,6 +1609,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + applicationName: null, applicationVersion: '7.16.2', commandClasses: { includedInsecurely: [], @@ -1626,6 +1636,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: 3.3, + nodeIdType: null, rfRegion: 1, txPower: 0, }, @@ -2772,6 +2783,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -3286,6 +3298,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + applicationName: null, applicationVersion: '255.0.0', commandClasses: { includedInsecurely: [ @@ -3330,6 +3343,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: 3.3, + nodeIdType: null, rfRegion: 1, txPower: 0, }, @@ -4557,6 +4571,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 42, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -6971,6 +6986,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + applicationName: null, applicationVersion: '7.17.2', commandClasses: { includedInsecurely: [ @@ -7014,6 +7030,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: -2.3, + nodeIdType: null, rfRegion: 0, txPower: 9.9, }, @@ -7029,6 +7046,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -7172,6 +7190,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + applicationName: null, applicationVersion: '7.18.1', commandClasses: { includedInsecurely: [ @@ -7215,6 +7234,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: -2.3, + nodeIdType: null, rfRegion: 0, txPower: 9.9, }, @@ -7230,6 +7250,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -7372,6 +7393,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + applicationName: null, applicationVersion: '7.18.2', commandClasses: { includedInsecurely: [ @@ -7415,6 +7437,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: -2.3, + nodeIdType: null, rfRegion: 0, txPower: 9.9, }, @@ -7430,6 +7453,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -7572,6 +7596,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + applicationName: null, applicationVersion: '7.18.3', commandClasses: { includedInsecurely: [ @@ -7615,6 +7640,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: -2.3, + nodeIdType: null, rfRegion: 0, txPower: 9.9, }, @@ -7630,6 +7656,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -7772,6 +7799,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + applicationName: null, applicationVersion: '7.18.4', commandClasses: { includedInsecurely: [ @@ -7815,6 +7843,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: -2.3, + nodeIdType: null, rfRegion: 0, txPower: 9.9, }, @@ -7830,6 +7859,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -7972,6 +8002,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + applicationName: null, applicationVersion: '7.19.0', commandClasses: { includedInsecurely: [ @@ -8015,6 +8046,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: -2.3, + nodeIdType: null, rfRegion: 0, txPower: 9.9, }, @@ -8030,6 +8062,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { @@ -8172,6 +8205,7 @@ Generated by [AVA](https://avajs.dev). { controller: { applicationData: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + applicationName: null, applicationVersion: '7.19.1', commandClasses: { includedInsecurely: [ @@ -8215,6 +8249,7 @@ Generated by [AVA](https://avajs.dev). enablePTI: 0, maxTXPower: 14, measured0dBm: -2.3, + nodeIdType: null, rfRegion: 0, txPower: 9.9, }, @@ -8230,6 +8265,7 @@ Generated by [AVA](https://avajs.dev). deviceFamily: 46, memoryMapped: true, pageSize: 2048, + sharedFileSystem: false, writeSize: 1, }, nodes: { diff --git a/packages/nvmedit/src/convert.test.ts.snap b/packages/nvmedit/src/convert.test.ts.snap index d547bd8163d9d10b00094d3ad825838c271e10a7..b4d5570f19a7f5bac8486da76f093b0f6e7fed5b 100644 GIT binary patch literal 41737 zcmX6@WmFtZ)5Td9U)))O26uM}?i$=(g1ap41SdGbf(Lh50)*i1unPnUwj@A+K=Sdt z-<&gbW~!^_R`;K&y0>KwW$E=iti61kJbmf?`GKfNB$U|VDr|CTZzS&#SuLo8SpNU& z+tW3VLrn+Qx4}?ex?}*-|1Q+?;sCSkiPedrWL1;w-75Bhi$z(P7P4~)gr4KPf>k4l zlbLr$pJ?fP;P-Byih2)oPmhX6ok|m%@I~sRhNtl0hPi@2ty%U?exUt71pn;xRncD2 zvBWQ&IsW76y4K93AB&TI_)V+Jd22>a)htYG#5#T-HoY~>D%gCVmN3R9R59_f-ip2r|#9tM;(*3)^w8Uv@DVc+K5ZiE8K+ z!RKmHqfbx7isXQVk37q#_NL%_OQy<)#o&U5PbV-~WCM0<+ShZt*4xPB2Gmx~G`=8b zKZ7uLKgHN;(gMj@zT{-iT>F)doVwth2=NM3=C54H;)X6i40<<{96E~Y>Q+98aY|m{ z@~tyRuZfK`7t=3-S~=m&YQ`>DTBgvvT$mI3JHrfD^rZ%?_axLU5d4PWZ7_*zh=v0V2`G_7QY+`FeqVL*F z@mq(8d}^Vu@D^$dg7O{4@yplb%N7QDdO8+$b==KOKR(tO39g#X>s0C2<*)%`84Sy{ zS+hTM8{50NWyiK1SGYl(4eVr-n5`O8?%mkE|SA~hn=eh!oUyDBW8Vj?pym{*0cP`_d! zn^izX<=Z-_N|&f!zkUj|zdV^}p9Hcu3;iTlp2V(`S7&>m2RhK7Wc$DuE5-)aB+1hT z)g&adtECvRt7U?8iB(kU)&u?IR8>MDZ~goZod0$F`wNtQMKq>uP^DzFSDrjS^~t2! zOvBwg$j@MjqlmaM!SICnIAW4pW7fZFB`2ruwci!cz`WQ$S198+{8VMWueYutR8GE8 zv-2-9y&6&P)JoM4-LQ!%L}A&d#pT?*y9ISl?v)c?p`=!VQURiRc0tq?jZBiIDb;TR zE`DzP^9!B*Tz&mb7J3F2RYoq>+^u!mD=YYohL*%@Iu2|%C!wF-+V){d5XrskIBZ_UB?sZ}1Q;NFk@ zhI%!hitBVNsqrgRxc!_Q@Wl%_DmGXfT&He!86u0%Tm-7V+jBl7=FG1&Hdz>0Hu?1` zNz=GYfA#Rgtuk5C@A&Xq!+Zx3*PAFWNZE1ZEnn-(I%D{s%Uw0 zd1uYkw+79prUuRCbBWo?T5k8uKZyOE+q#QC!QT<#!Ye8kKgM`{npm-)L}8$ok$pcYME{ zL34KBKyTdInzW<(Kp|7TY!Kw}l)~>EK&b{5vXdnOHdW|wkoYwfsJFlSu z`qj5)4;yZ+@icc{UujEP&{nhUNK}eaMw48cMvH}o=GfPU&w$a%JC(G<62iStcb|h zH_pkC{0xV`*!nX+wSSyZF=bMgUt8mtXqGvq3HgW%c#~|CLhteqZj^YFuAK}gQj^Ww@{CQhc)p7r%=U$Jj-ceEi2zkBGogOKl34hvcg0%d~#j-uZ@}g~8i}vejBl!xd*$ zDi=W#e&4W1G_xN|w>G6ZsghiG7dw5LYdzg2j#{68)vB4_>ZQS_D?jPx=sU%w)2{!_ zQn&c@K`Qth@x%GUX0Etz({k+(N*6(w*xtPGyE7-IGXgRi7T}_E%bU5{o@wu?-cGkl z2WZu8hDeR+iq?>Vy!h2rM^@IfA#))~*`MScL*^|)q|KfcL*@`m)Ao51bJT@`T|;K7 zGEV!MDlD*l{g5nTg~nXfsQpB z=k-^x*|~Ha&RqEle~NK(+g|j1@3_USOUf1Wt{HVs}Gy%4^itvXHt~%8%e>Wg{%wEee)LL1dbqYe`Z0Zto`Nw;*T4fmW zpkz>6?V|Mk#=~UUfFrNHJ_jBg{-~%n1-ke^DmX(XO)92WBf#IGXD+Xy;paY})EE}T zt82h*@^@YMuJ)`-$H3ywTioots_$2!`k7UD4XNP2_nMq0x>%Z=`-(MOJ@1R&dRuc{ zE$@G^OVTras*Xqv>Z0g>tG|A^!WncsOEp>FY*Y95RsUn@g+*9u|6`Yb^Pq#pPGd-) zktJ30?B(v|%G$U38nZPEPTt+pKNA(j>Yd#Mk{#iV^%7we@ts+d;U24%KF$Y&p&i_a zf333|yV*yG?=5An55g54>Qa1wag32K^!bEnztKlB>DNioSRk+}dJ!_ad+*MV@F|n% zPEDmvj@Z23;=u>=Q>`KPb4r{~BRoRJf%VK}mWO^HC~?{#)`n666@-qp&M$L@eN%2u#`uhmm^(E=0#9 zuYu{Q<)C226LJpU_OE#H@8xQ=b>6CosN=*J$W8F*Y;Ny~OT6|?BB*M_ir0X9DV&hA zsfO@UTabt;CNE0i#Lq$DM&-6CtTR$5X0LF>*%X~+2?+?1Pvs_zKOZ0fUsEF=0dUBe z+T8(1O5}IK7D*IMg<&;9FU^cn`ma~_erQkR$R6)AKx`+<#D2bC(_{9PYf}ZX3*G3A z(xx#?950^a4;sV=umACx*ecGB0h7m*wv$O{DA`fC4Sn5;XpOu+SL@l%K&vUIl(e76 zfc4`^Ny#Lusri4pyWdSA{QOQ8E&?n@-((l7`x_lrO?Im-VTN^F-u6ZzO=7x;7q}Vl zdmUF7Jnh#%uvZ~E*oe<7re&@5^$S@~_JRxxW1-Mao%x8U4Odd&ReLHVJRPRxP)BbYrj@N56@- z`Xl??{Gt9bglJGrc`jag*p~~lTjIjMkoMkL6GLU-yJoWiODT#aXuVH^>M5}6{j**b zhP}Dtk&8wpqTM`@5U}s-IqNfMg*Rpr4=N-^EZa@nfNx=Wy@o3?_1DBSXIl|s&wielBn8=)M{pdDK@W}dNnC5! z*Ai?Z7CMgp;)M&4u6}{;8jH|iH;+MCJ|pxvz8;jhQY(zfDpBL4^XrpZDVSt-bDW2A z=EmlcMv)oC`t8@X7@CpHI)iLpaZ!IyHNW)uVYB7N_K;_Jrpi+8P+>Q-{MjE;@B%2)ZPb?;qoJa1xufqy`#Iv%4-p@!-P}jk zNV7ZVCkzRMzx0<&FtJTeUfa89ID03)rO9iUZ>Rp2)u6(as%4nXmh~3zdm{Hszr?AL zkglf8m8_Rno$ZoIT(?*mvkuZwDPlf-EpM5bwQoa`D3)Kx0cMl>+)%0iUcW*$QA3w0 zw^k5n-!I0+%f-YiWnxmN!p6D6$Xt`{qN@MS{@eOtV3n9?c|$|HfRv_Ag<&2e`@za< zKRIvRe$^b}yrO*L%v#-Xrq^nEnIxa9>K5-STNeZU3ix=1*hIN{IKZM{6+I9cnPmkB zn@(*e5r{}XiP$gHMn$ESnN7&h;6pY;hs>Ym=ihn%C<<6NiND!?3TZmA4H_5NN{o2^ z^0PKeSKtS+#)d%zFnj!`FX_K|cX^I<)`Rr)?*+eV#(sYJz?qj$nP#5tk*xe?` zZo#HhS~7dWQ26imk*wIGcFFMv0~6NUU+Qo3j{F|O#c_Vz@JdJdXY!Oy6dIk5MmAh9 zS<46uHZR5_7kgUd)Yj{Y3e>Bv8VqdqzgGOMQakht=Uoh2TFdrArB(ScHT)_KQT0kh zM7EXaP;>-`7oh~=I2;_t$`u{KU|GLFn<#>rump}_?fOBqieaWK-7qw7M=w8&2*(7k zI0eVA-f?b@K=$OpreEWtYp%%y#b63{p7LMC#A z;%Gj+Nn&FLUL$eng^C#k?vf1pqYDcw`w)$b>4Wlhe_(v~KtxiVd#0R!_KKGYIQfo; ze#tXKL;Eg%=MvE*?)x)R8K3+TSvY9e1wU{Wb#PwkPayF18)g0KV7Y3R>|m&wmIw^X zGZ?B>0y{;2XTh_K{cQkd!M%Qr?l@2;Zv;36zUqUfG_|y{ORSJc5xojmQqva;j_wn# z436HUqP>YL-bG{zhknQPrVI1cs>Ub&GmI+LGJ(1KGiooCewr-q4^+U?cptmwOF}6x zD5vxu8f58p6HOalb{*aKY!yu>ae#UJ1T&KM`W>$j!FnAZ@@!or-TwoBbGR6WL=HmI zL$Q*LEaS7R_!)>KL4rhw8EH#@1Bijjbc+(?qC=x(0!0Z10Wq^X^gUF>e$k>kRzAY> z9%9cOR8C!|w^w*MJLoyFpqz9+%!}}1+a379C5#;Hoh;95zz>L(2Z0+7ge4mGOy7bX z7h}Z=h}#%xVIsG{!?>WuDkV7K^zdcPtt}!(5gZB#5kO0e9i9MN5dp2sd3cCb<>9&7 z#>7BOdHAUIb8hT9&sW^&EvS|4fklibbeP{v+vK%Q0R`SOw7ma%>)&UuKyGTTm}pD1 zN`>JQKy6xNJOfM_t)C8A=sf`mmhCI}sR#_;e6wf(1_Qr2o#@iP=BlnV6{ z_*Hk<4t?5SxN|(^T(1peM%pwAfR&=s6^Li8@Pz zckXZX%$b!m{=B}oDK)fRh7|h!Elt$HCXlA;AozGxoy>kl62Pm}2yS9ia6X{5Q`4y~RIm4M?)-NS&KGK`@DRqX zzT1v>u6}){mf~F&%a^NbUmHuE0?u5ISEbF?Ji;W==O1deW!TT8MPsD7$9$VT@UaI# z&4bTMKYvJza@;7t)Q+#3|F-PZHy0TFsq757?YRCC{^_N_Z0zrS?7jPOb~-l}dvyEb zPMR#W=N8++>+G(J-e`Yy?>}Ilvjo};k1+S`VBd8Au0aQnuq#17SJ#5j0DO^k)RGHi z&%4OE;9+jbGBwKkswf8B*2TYN+w30~>A7(|RHMh7y?8X%IT>aKe!itF(um$$9A=>j zuI%~{!o*FJvxLP)rc`{cXcHP?|=}L8c4m>o+IC->NzoPJFOS9OF`CtwaLn z%bef*uq>R6-!UyE^FxmHJw^hO*4|qATST3AF+=|g&v$qpWXpJ5;s)Hr z`3=B7?IH#N?+?{Z73f;dQOm>1BIxFC2XEbF`ti$qfM4+_D zJif&l=3Y`pI4D6c0&#->=^5NCt$xNWgQ2P!65KD%af)yHIJ)o`Ar}$YB^|o4=cP); zjA6i!#DN((fi#*n8k?3&h${uw#2&3uEPmJkZ$fW?@n6ex6`9gq8 z3bbU55eH-ui)Al6f+9+^W&lmH0`5Orw12{Ya2hmojOZ(?1PYvjXxymRI-?0AJPthB z*feTi(%LXaFQVauYPs;ZQR2LbNu#{38x$e8puwTTi@U;zwioJlq=GOfEXucm z#i;mV(})yLKemFoslK&YI|yx;;;Ny~GwM8cx~*s7*2Jb|DV}=TjrMJLNl|gxMUN5y z$ZY_1#8ne`QHNk2mr@ z#JACa9S-GQ!^FVm{8-2YfQa==IuB+nh5N^{xvabHMB*Et^M{wxzI2J1&KZv#E!~X> z-Ib<0&xDnOHx`QArhPB1$7-C;hZ%dL<6dF)agWB16xjEYO%v*n6Dbh{UtNBFS2dgUemnR{wd#jIM92zY*eOcoVvesk>=eC?Sm}29Nx8(WRdv|Zl=UV zXfurXgWO+TulZ*B8yd}i+Xot($ER&*?gLxje{=P*3dY;cLQVFz^1-8?j3V=f4N%{| z#i0Xkeq9sGDN5 zdwQ}#k{B}s4BaW-`5>J86kaf@^EA0KIqLIENLG}-ls`@i9jbvXY?YVC6Q_X^HDrAF zlozo{es8SpC0L;JUHX~p9!lOqhyB-9R+Kb2HFm+a+>Jw>3j24;z|ZrF9R>8{2(o@} zj&o}4nsMlqEj;=&V#m1U8)~`)V2WRVekTFtniw@GUE=GvXu=@vOiaHZFGt$xx#-j& zFIN1&%&Y+33K@xYnee-Sk*nj8wV-)0o!L(?D_!PKYb&Y4LaC>z zF@L8=+aFl{5fS0Vv!KMhN{{xOkgY+HuL8bOwM}gwqi`nDl5PoLN4i2u;E23IAvZ*- zL#gGA6bHhtQH(8-FoCcQl)!qVzs*R0*)uc*Dg;clU7U>oT(R>51R!9!B{+psfH>bq z!3tjoRw-A@7PAqH@B%k*#SB1(1zw@>E3`?N1Lnw}8*=v*1YA#C>+dAc(&D?X=K~}T z)8erXtRDlrJta73@VCaPUSBvXIOo>h+y@4_Nc4-*N>SoVr(hN`AYMZf7?imo<%-(+ zXo8AfA%qf!XlF?{Id^;&?di3?5rov7kmF=nF~fZ;z-|ntkF%2mE+>B^8O^uJH^$*l zhDX^L8@koDHxpJpD^_hKTYK_K7~uTlh)Yj~*Vts#m(>F+^fSsK)~{I&WgCH)`XdLg z<*QIrSZNq{@6QZc4A9>gARxe9gOR+~899+YSiam*F(7&L=;r1t;WgBeGcd_7%iV+v zv@NVoBDdHwb62!~VpuEO-)ZyI#@*RJYdF4xk^TBK*Iz!tIVhNs(kDm$y9(@^;pBPw zKBDEE>NdC|y)SHA7~1{s8@?)0TD7v%gHuuif5hejF{x36z?dpUL*B@q_((u8{W|E; zL@t_%qdkU&1MZ`CVuQ|W$g>HgY_N(VId6mb7}9se>AU7T;r@O*YUmocN%_|nH(V&g z9aT^Wp?vm6@4O>wR0z?OdbuD|Mvam5M(-xuO|676{)5AWo*M{U0Aja%xF(A5fBbW2 z`Cm73{G6gr>@F3~0DfEA@m%{vNh7_mun)-(9&SfvU1q}ik^Q9}FEyK12CVXzTQsr) z{W9|vs{-4LVJsk17lT0OGZs-<-})yR&X#9r3;5&3&PL;Cgxnr$3zS$t1o3mbjfxU4 zW-(3s;l&Cx`d}Yxi<|{e?6w?hpR6V03sOZKh!T^|q*u?EGA+#at48F0VVS81`5sHB zoT1clc^Q$d?^NadqO&u+@{PjpmBADTv_^ydwe2x|F3@Uo0DikRn0@E41R4o<%zrJ> zZT^VQG@&n#9jF)9WV3fLSA6R`0#AI&3+oKY!*%)3lIoqpPaf8sp-*1LF8FQd*0GWj zj`(})(eH`r^Z3crCNYCEk(E)WbW3eAMM%2#>^|7HL#h?d1ievY@XOSwwaGi*}?i^&i2FN=&yIEwthp%aPTMz1iZpF?-(8^$0LIY9aM zj!^&ZeeI1Gx~0)q@7T#EL^nINSL~WO9MkCJ90Tl;afuP@;nhra?i;P15!695-nDwAaaW^k|yTx88Siz z>4_StGYUonScsbEN8o?c5tJbCMzs#6=K#cnML|mwgfj8vn$e(zQ3y5qK*5sFj!35* zQHTD~5DzakVdGWYv;=|>tiu@(goSX1ALhTy3~ zz$HQ_palql(Vq}8%1AI~WYXu8|3|b|(+4WW_~yt+0U>kIWokSM7^7uY$ouS3>Ns(A zR{3N&;t)7GA&5RIlosdTfWKv{9DqEh zt&A7Dt&I%gidv3`PHP)e0^i8NH3&gWQBMTGf4JyFJYNCP5FX@;3>k;Gk#inn8jKn! zOp*}967?jEBNijCEpmeu54tY;qJU-RFEWi4p9)8)i-a=D=`v>EZQ6of(KDc6C=P!C zAZIemiA^U)Vlr4c$H3jW&j)k;)=7~=7+~%5pS$KiA5ak@JkXvfk^k;*q=Ye{wK9}P zFs395WV2s(Uh?pQ>KNe2I!8!})5Y&wq(LPlc6h}0gEUyj3~&gmPm6*>7b_qclFce# zu(5xSsW^gQtxbZ&e?;q%XY>wuGcv+@Ur2A1seD$pBC8lT>;`qjH zOlaCZTH6UMKkZ)Y=v=ZUZVxPYiBOi19Udk8nWA~S#SU8kK}%th+O5cJw9UY;xBXg| z-Gk&4QCE`LriJ&rWc9ReMTeLBXmPhFS={btEDhhx-RE^df9K6gn>}Nl2!p7dE5$;B z^=GwqQJX1j8+B!%faEweafvGx`g7s;^l7>BJZMa%%mK+!nb$ZmkgiZ!HbV3byGEJz zM}c?}S|=*>0d6;e_YjLDj@1}(D9b7}vF?AY>ntyJEL*j)byFfSCBI)ss@$7NIZD?`O#@rBmHDT^0lJFP+A> z20P#FWq5p4FJ-UUMW1~0t^Rlk?xKOf{N%g*7@ z7nipA>w7T>%tN>jD)(eKWQN8l*iy%cB(`fP}qS@|VtF_$b&8wth^f4|{HmhP3 zS~h|b6lXRbM)dI-84cieE=qdk@Fwwk9?D$ha3LGQ1o)JRQmiK%5@)Rb+OC=s^p02V ziv}Yf1Ic(LG)6!FJ@9u8bWwjj7s#RuuhJLE1MXGIP0+$tQRPBpRPo7|QO9p1lW4uv z@B?e(!Gr;?6eOA@M3ZC-yU3G z5r%YSl%H5&6%{a9fPv%j8&L*%JKIXQX z6bN$+<6E@!@hrCBo0#*GxNk%$tXiO}WoU`^Cee>zsJW!Itk(KE5#DVKza-pE>%M}; z%t@k_frn_Hzuc4g&;c5wo?n9X+a8*!F3&Kjlu&6A#6T3?>HDsAXETs^oTvcd!W^27 zwdV-&BMo$r4J56!ADQQ1{Ra8K(aniXI|J!3iHjMFVIlp~3QL&(R7&VCpW2=}Xkp=E z5gfa5ui3W2K0TiIAxm$}B(vhC_k9_n|EX6G+K!nJBjSFG?QmHyn^ zeO4+=`*$q+wGL{#*6d$o*~Vm70C{~IV{WA1o$rC-mX3hqRh)NuP6-YRjd^WfnDQI6~`=UYCQa0(&B-_u0<~4YE94>|`5i1i1rGI9ccX;xI)&H0|t@gBpO)iRv ze?yb^?arrV`2J%_o{^NzRFmM^>`IzbRsr)B7DL_Jm)97alAMtUv8X;KoR*lx+?HVw zo+&hbCR0A81@b9%5{zdua%MO`LdnorK1_Mp7RR}Ys1OXb!JQS#utzm`3ApPlq2Cvz z5^+WST3$%~_|>{K<6>l=hoNZ-)jLoD@9fY^8ISubyoh=*D>{|)ejTz%`nV}q!l}Or zE#wy0bicIbfn#sHe=RbSB^HD2)9y*rcnRoy~Tz%=V!kZ~A?827+`b zvV$!)hV^^8IvAV?eBjqrK9Tr3-|nsn{`|3k%p!t~anaZI{ya_tTrO>L5`R=cf5XPe z9MGe0U#@==kWaaM`fEL<)zy%!enQGtyQZ`ucwM-8iKT4aTDvB1ZKgcP91^~kE^A)V zG`spa$UL*@(lEN$&U{CB=7-&NFU>SjQQ0CEtv}?zMhMe6Gx>$&R%2-iz^LLs6dhG} zG(O*co0;4mJ?phiQQ{Y8R0KD7ykDjm^ozqz#iBDaAKpV}Fr!~UZ#AReLLcvzNyOIg z9rh*b9!011jZ)-lSw;8n9=0YExj^CW8Q$VTT#efi4)sRnu#5CS(%EBr<%-ztx}h>g zH1b%kN!L2!rx z6h48ksxqX7dt_W-ta!A1#VzrTPTwxe5`XzwY6W}^h{p&BoTkz29i2#hV6u@cYvCRG z;(#CcnYSxuMDDrP?)qwTg$PBWJe@^92r8!~a*pL01f46fx9U{`y1$yz=nQ=)QtoBv8IixOTugO}OEAT+IO7-Sd8zO6-qJ zC4S0nlxdjN0RGbq=HM@6Ps@`FY@$%>rslF=?fSkRh}Dy2YD-&wZ#?K1ltPNJHq6 z5%hK#a_{H`(4hS?#&iHJOz2t^Yy+3CFRGVHVj1@?AUc5ZpjIv>k~KN6QY_v-eqqP@ zZGiC#jm0V6o*(8Ky)pnID_e#IDTG+5*xoNa(0k#=Wm{=ujy{jHh?84j$63Y>GbOK8 ziuJ|H7z6C$hnESADNwXxhW~)A2!WU71XMs&IcpnMiB)ptn{Za+xF|lH@wkyj>lS95 z5+b<>j#*W|a1xBY_$Wt_8@%{$UV*IC{xPF_qwrC$ZUVd}!VCiBIzTrIioe1zJ0Zdp z4NXzbpK)0M8VWWZ+YkFRYx^Ey$M_@;qOPD91Oh9p42d~XA?7-WP~v_%bkYR^8eGu@ z9(GDYrO^VXdofB0TY5;;QdPfQvj2otEu4NLR6`&@Z&(IBn;k~_pK^+a{$!3k z#7eJ?g_@)NDJE7`q&y~qU6vL*$yoL{Pq*0Crksb=VFG$&94JWIZtAnMPtS{oF(GS0 zJ)IO?^$y`i9ZG@eah*Yl{~<7tp7!p`=-D-5FHrV4K(}~@h+YCYj&Zmh%{T{1i+LCm zYaUD}K`E?`s~+=HAy9%ajTwrWXqAKZjgh<%t&4f&17jeU%KSs}4O8sjoH-+vMwY45 zqEM1aZ@K@NdX?N)CdQrFoHg-W$Lghr$s6A7A^ntX-`zAlzUBVX^w#U7j?b=k6CKd| z(E43n!}(io8(S5d>FmaT&bv<<8{WZHLiSV6%I+^Cyd5tiTmL!Fg9YrTCVwove0cDU zUS|=m_GPZ`~KvjLd2{{Z~l#=1B+q6t{3P9!`=dHY=K&L=;VLmPpoIlK=MZpKaPi zHnCn|ZFl#K4r=LQ+oswPK$LP(k1>Jd#joK&CE?B}}a5YSERz};$cm{;r zdCjzRO;hI6IkD~D2WL4Y>jbMgoT8lilF68+ELaM=>y!^|56JWduZkshlGn3qu8|)2 zjx}!D^f%peyYtE#`JUpoDum^J-0cm^=si^4v}u*9$?VLp&>E}ctlnM6N|$)tmcdH@ zTd9whYPvEZ%zt~EXE=J@{C)YQEt8x%-^eyRfZ0E7XfprlHCal{Hk9vYnR#z8+I4k% zJ{2)=XpZ{W37fhN<35{;|FfGv_!M86@X)YRF!N)Y>-nwM(R6s8-_h2e4)L~)qM(o= ze@CGj{-K3Te$(GW4gB~&{=cvL^xW*|INPu5xEijk|C%^Sb@KSLH0!IKZ+|&OZq@Pv zT)L2jYxR=%r{T*37-n;toNo{3O3PXBoJI=hsJu)Z!_Sobj-+kka`F31iXWQ0wiD>q zA^i227OMq$_-+9XZKA)DFJ|2g9sho2a>S$YHF0dBT>f82ITpQHyiqj!v|L77^iV$~ z?z0c0S}qt1RXp-KY8`o*qv=>8+>P!iC3fFB>-Ih@TI?4cFaLyt<=pJk+8+Yrj2#I7 zURKyk3fCAfDeTL`=GK<;aEW5_Ir+nXg9)V2TH}Wg!CqGxhWrPfD$8#S<9*E;9$RED%rA&o)5I;IIYMlsp?=UVcK&^=r?=u=j2otYZnZ9>^ zRkjAuPLC8<8h%a4Fq0BtgH}X~OqY%{^?p9g?j?ti)EMMf){DyB0gP@0|3TEeffl?+ zjJ^DcfzUS{FG&rvl8XUdlt$z~S{42ef*<&o7dS|PuK7`xxAz4@{>|vg0*{}7gcRjn z0)ex`Q$$MK+M7|Wk0Y-zK|U|bkQT%I>0@Px$1xf8zjgk*r4D4lD?3s7Q@ufo@7zbonfRwMvS*cKer$ph}!rB4v?WV78 zM#%4dan{pf5ubUi++4A)#dA_)lRhJ0#_K|)vk3$$gMTzj(_*33XpbeFcux5kP^~GT>|yUdz2c#a{#A1fU6Peaz^>Gp&TbB0V&@<mvJf5fkYH39EQ2iC?S2r3igWiQ7ICcjiIWsu1>UzB<_XJ-X^Kl-VxiRdH_xr-^uf zRpwu~tk=h_EhCCMhm?jTUXQT~W>iK=;Hs|;hZ6EzCT-M5jZ%u#M_CHMOqi`mRd`kG zGb}I^?Y-0}I7oQas`5wey;^a0xluRJ5QX$shRVFBL}kCx=G7y`S%zH*+ukOLiXxYk zAeE{k)h7}N=nOYx*#v9FL=jp4ROt3(a3kiWs>-inf&Ll6b2s4k& zWexlAF=~+VU^0>i&DxO*Q!s1AnPgdC+8Ikx_^ZcdWx?sP;Lpk4HxYQo)bbL)z86j+ zmh4&@dCr5(&NmjiPE7lq198R^Yk?GRtdN6;Oo5DOe7AdIr4z zjI#Y2ol{G--B-CWW?Gfp#F_P$Em2>CNxdm1MDdfBntNX(=uRJ+m4k3$3f0HjGlCe9 z1nSEglT;c~xP&U%d>%32sQ}j1!`{D^J!@P1eEta{Z{Ver@gzKHyxR!DuOF^>oAKDM zP^aM~s9-4nRuJb?-1UmKIc{4$9PVOl?p}L=p4ch5;#Es&LDn(AN;As6LSK)3Oey~< zBF~tm8-u~sN*h;y1(5jLUM5yET>!6md4$lc%iH~U?uxGvt)QTEr z%MewZzpL}5{=vrM44ej4{?+44i?1F&(6gE&4%Eng>Rs*%&qw)JjAHIG(nV_H0&XK! zT9#AcTwZ||cf`Hj%TD=z{nl6)yT%1Q)l)^_ZKytWDK=;?SNX}4)3-J{QcQMVe3AF2 zF?z(0rwQ-%57?1dU<;n%^2n^1hyf<|+RLUG+4SK5fGvr&)Wsu$WzRwuUHQ6cm6qk5 z2g(n9K$CiB)`pTCP4Nd6hxnB~Dbye#-dg2>8r$QSzMlewkV+4r%-syFy6p33k7UfVz8j}m<7met_C7h~~JY^bj+;OdFlZxf$ z$^&Cj+*PgU=OtKyGh$re-k0)80@tl3`nPYw2anooY0#Oydc4$9xt-W_0hiPBTd`c+ zA+;SL8cjgvP)^GC@27}y-+PPf#{pjs3;y8<3|0r3RUC3rR8>crXPjy3TX{J8%TQ8`u z3lQPW#qjgP&(-g3n4g4*&OK5772*i~HLB1FB4XS@6BWjyjL1r}9oO(W(?GP)-$Kfl z>qTVkE;N{_zk9b*bYH~h7yYL`#;l|>>&~mOmD;1k_Bj-c0_$H$F}ljoX$9b8l)|1H zO02AK;V97lKlSr0pzlQ}U3$?_vtrLZc_(7?!;`UyY5Ctnc7ftsN+Y_M;kz7$%H1n3 z?3agNJjv@9pDO0yngTGGJ=7hD-nVhoB6oi-q|>q*^`}6&{Cb*2kF|(5nMBHi3Z06k zd({1?O#7W_A?w#$%ZV8|_{(Vbt_L2_$HS8d-IOM zW7Iy{Utdt4`E4p*xV=Fy$1T?N)95eLawA6`M675#?s!1_&Q!<%UjGIManTiTl-#uB zQCUmN3&&@Ae)l03GB?1it=zLlO>Eee3i*f^y3Ii>clkmUUj2DF1?sxRDsozS^RlyZ zY2W^6l<^#f`)IRzzTjyDy$Hn(FN*Xt&AVw1;$62FUQ#^Vk>SOPNzO9^XCF7Nk$tp{ z?SQe*FVign|9W0Q>rNf7wWvKIZ1lqTErk(zOuX=Q zYT~084ZP5VwOe|T8Cdc-eEH^O34?6JcQ5+)*+=&ZSQUO)@G>i!Ydh}zsE@giJXHjN-#(8Oj=Xvtv z_t{tzD&edUSO1v4Ym*BZJ6A~VNhI|l<2(Ytoz`p5@A6Q$3Erru(~GYc{Me(P6wXA{ zxUAEjY1W>3w(=+EIOje`v`CQ-MD{a~eb8G2*Rx#DIcz1a>rb@DiS$I&j3EAv^Tnpc zK=}+D{!cz`bx%I)ZCe|K14w*fwyC0cM?pL!!T%2An90ubWZyPm{`W4Y!xwp4MDj^= z)ptnF^}}S%rO-jY+hb_O9&1OZpyqzBoVWeqevWh4{vD_}rGPdf)#ordf=&EPG|cty z!xw7yU3T+={4=Q`uG~-%X08Omj>2efa-4fug;3ty*_CbcLqwHe=?3YRd;T&L*Ykwt zkAk(2@PGY7CI4c2zVQ5x+g7%~GkxW5{sk2QJeEHVtu4e4n2mq*O1C32$6F**Qu2~+N5`0y==VZzUb)Zi)2DGo zvXBl>VZ)-)5j!X?ZvnK}U^j3jSIl{=b~iyC8Ppvc{yw(F0eo%_s3C*8V#5z&5eIS^ z+SCTPi|Be{xRzJ&eVfWIAp zzij{x(&%3{Cxhf5Qu(1V9tYlRZXxQJJVL%*6pG`5Wa~Sd{4R1s&N#_r_@^<%+!*58 z=KdY;ItOwy6TxS+#oXa}ChdN-YL2L_yy1^(Ru>?7kd%`0J%#fx;YCu`%)KtOG>#~K zHP|^wWC)Fm13A8mpqqFq^(SmAI2D)>aKZR)yHrmH)Yuk^$gb zBz3Fg)Mxy+qI)0CX3T~9+n%5kM>lT-X0P3iQBGr%mv%^G2(`dj*OXncz9* zjgn2lq269*$WiR{9_TkF$fE2xlN03Na)Cus*Gf(cM$1l=*M`FlBs>A=4aUggM#G;- z5Z{3JUg)7+C>%zRKdJz8tWWIV5GLZLn7SOVGu8aA#f(r0AxLGPqs4{E%@_;Q5ZcBL zZ_GhNu)~MgM?6UG8&ST$KIs4|HA7krc-%?0+km8vkePbe*VlpJB>io`K{I=0<_$oB z{(GGI5pTin#<+}?j8;mF<~YcTb`Pb83GOe$(YlouN5LWs+~&r(bfeMq`Vj}*z{aQq z!HiCfxF%l4rBOhE@AXgOM&ubvCu3Bf)nTY$i!&~@1?pULRKV)+gP@l+u1G^{WCuYP z>0?vub_b6&r@AHf?u!K+&xIrl>##Eb{OvAs+qAdMQ|>mA1qZ|EeMW*BKldEdTR4HG`Zr(`y~cgNi;7 zmC-#iii$o0Recvp*fSDScsL2S#Rs)$6N%e15?^@uH`TDqt3bDymeh>ig^VxsuNYeu zLD9m{gw(Q4KnE3kHWhKNWIRNO=Mi%(1U03C|4K!iDV?-pJqbm56Wwg0eH4lcCK7Pt zW90n;NVH~16fJ~BX|(tfxox4b2#u%}!nT?39f*9laheLjf&7f_ama<>2!4IHxI*F4 z=tAo;hxML~j4xiV7?miUsq8B`CzMT_-gkah+WeW)o=TMJ=fW@1Mq#msQ|cC1Dja=5 zir7V2FfBVKB_BlBH!btW-u{eEyN5#6IXuFN*d`5h#SR@Dn>R*RQcfXLdFn;y=!7g8 zo^+CcI^~8Mc^ufYJ!1<@;eQ)jeA(T$fD>I%HB$lBE2*g>v&i0@y(slZkQq$ksjjo;g~mD$hHA84|w@K zsF!=lY60Y#^WFv*!zW;JBS+l^|v8Hi)7CI{=VWE!`V8J@?| zguo9i0)x0iTgV1?uyg+mhtb7cMrVidIMJnSVdngSt%mV<(lu;i_Wd5o`h%mgOaOB z4JYrRQ~fRf9Nz6JJ-vrd^?MZl?ByU`w1aPX9=~@-g|V||oic6?qP)W#zC}W#iTr}f z14BBbiB!R~T1CzeLCU3zq``z8BHvFS-@}kX1CTiIA%A26k^nYLT<2+Cr2|^q)Zdh@ z{g!-@vY6KQvaC`7Jv=B4Cj4`B%OyRv2w;vjMi?LJhzZY&o_`>?r$re9e-%S}g)e&w zu9dbEiNs7<2-KE4Xp;B(2R8Nwbkaf&;$c_uFw1z@nfyGQr<*#iY&0W~{E;rMf0XBe zXIc!$2Y>YEXv;whI5qxdva#I3p>^ORPrpC8loXCM4aNiENibSPn#?#Mxj$M``f&Cu zuRnx==YR%j6wI{Ywl}buSBMQldCGM1kJtGz7!E5Y;b4MG!Gy&_dMO^dVUz2}LkN*8GK@5*#!g~E3tCWXGB-6MPN7j74 zH+3~ld|&z~^q}QIgjy7DjxIhReKc<(iU<~nf}$m}jdc=&GF}v!$YM2))qRD=A!@B` z+rvxA&XlOpSrWO!0-Gd4)X}@-@aniSzIyzPbw5OeIKyfY#|meW4FUxh$LO%ghJmU} zV*0e86=GDNWt3XLjDP2xI@mF4Fl`5|KJ8 zHTSF7QA+&f>LcsK`rrXs*Er%U87fX8GoYx#^n_R!T0Jr6_hFT+qcyuh(uGFy3Ssli zB3)Q+LeXmufOQ;PA^EzUibUay4*7!=w3|5f!lR~z)@KguT@-1a zaqNX7&e;0vDCMSQr=$rxC|IWSw%F6#Hniav7to>VxPS;dY>7d1i%k?dx2XT4>?{15 ze*VWnYJoJ24(SGIDIL-vATb&SN|(}I8%PPf5gauH1nH1&HWZ8QhKYcZLmCBs^Yi@+ zevjSmZgT2-y zz>X|~QrfVSHn@}826xfj6_9otwyf5%@Ag-pc-BSk=WGE>F@aw**?a~4-fa)Me50BxYd_x%k~m%6PfwJ+OT8PTp}bZ@w_c%@v`hM@a8vuL zN~vn-QN>&Kz{mb(KOa?;vIkxVVe3&h(`G}BB&by!U>^;K{j*i0^a#jN5dgeXCd^d{U zF7UVJ$<9@}H^3&>-jwqwbUn7w-LKWU=NY!5Ie9d=ds#itQRxz#nzvl#5hQ4B>S|ah z7dSI@)u&r{BH~r}W2x^~3;KLUdNS{x=XOnHQ~AjMcjmXD9q?#sBT2%8*ZcPmT(nLY znticCNnUNEusrl@e%+HR3%xy`U-J54=&iR@RX=VO{r>94ztquCP@cye%`Z(?f%g98VGW&XCareAh+g_Rfs|Wt@NV8@_$>21 z+bsVHyH&VQ+DO*DaJfJ#k8SqpZicz-agS3kMaihYybG zE}}R8&M4r1M_kHqIk!c49;vtPZvUuxRg?K;olOovO+9QdqN6)PdB|4qUrvTJM$+?@ zL!ytJ(_d)m6xD3(=X>;qY6=l%EK)Zkb$iG~TXmFKY>68Ii)L0~Lho$(-J zoLzCHXn;Sm_}_vyQy10)7V?QPr~{i`hffrp>wKW300@lV^ch>eozN-ly?{)J2kAL< z3BG-oZlG)MS&t=qMubO{r)?$SKio|8zt4^D&9cjz7rHuf5gpBl>gTVt(WPMmu20HS z^<=KU^ak~W!EtchCHT|BHX8_4+Xs`%N}#*0xVFF(7lG;`KS}?cyVK9j7BXHHJKsHC z@vnbmvTfAG$1lLoN;Op2zw~fgQC3M@iI>08{P*0e4^JYeY+bh#ZTAw=^yIFGQbvN$ z&p&*4aql*(Y(+Ku&w~Hvh52Pfm4=U}VZr9JpAkbfsO~;i`r0VS=?rb*chJN>Do^UV z)xN-xg1N9lVko*x>s4P^y58(l1^APEY4@ar$9gk}zl%RI(U~fIO1!*E!V+gPnA{6f z6A4vbemNdz=sOd4jrD-O?#bttP;2YoI;9}Wz|Rb?i#=uH!TB&Osk7Y)@QY8W^oJNgHgBqr5zo$2z^ z^*`%8(jOU0<;YSJ6HrnTRuaCU?0oW4clT9B?zEb?aA-uGhRpzVO>aZ z`~Pg-J^kf^7Gck&zuWYmY1h+@s~=6G_l!2j|2y{f&dSKU`yA@ioVP7q`K7Y-u0X&e z9ivgkTHFASD%|aP+pDCGMlU~ODxqv8F&hGCpg};w0tn5ez zs2jpIYdtIK!)I#hGJER^V4PnP8o)fp(G1Jo?80}1 zWjMPp;g+iL-Da!Zfe9mug!M-^Z|Ximo<{lK$j!Rhgpm~xAp9D+AXHK%ZJyzNI{F^znC-6NNjDxd+O0;S~a2hwey|zaE z;5xao$77*8O+DauBKkUGjhgogUZ6gNPefkhE7WTa6Jb~I9(Aw7M9C{$j5_;KV$-$X zFxT#_HvvRulrjB86&yr{x8B$h1%P9Si8JVktca!Lh&IXkCx|Rrh$Jccm5CdqiPXR` zz9ef~M2Z|l(d74&?)!le&tr{MX*|fFPq>?@5OeomP$PI^rS8!PP+)iOhbYomkYd5H z4H7hJREWaZ20@xA5MuQf&WW4m$#sVk#fB*R%E$xbdw^|nObj=Qo>Y%0tyuxqB3`iDo(rb5b9_}!iUCi#am3B)aMAMcPJ`3M`f zy6FUwz*i`WX6eQ0SkyhKPAU}>iq@G}hn<*6J3tNCB(NA}r&9|C?_e)G{VF8pX5-hw z#+o=)jH%I;6w2F}gOgXN#1`qE9S!6qjU89QbYkMpfXxZqD6-v{i=FNM2|3L?(WQJ$ z0eM3!@vb{jw0w-m?P3iL=4F~3c?319h;+KA^Ys$VO9j#`E#rDxN-xq$HcXXPLnH03 zC+QYzY$PA47PL(V#SE;z1NY=BNJHFB{2rk6v+f=MFk+%>IVZj4!=BAi>y}{AV zWQjpEQ&gR8@w$7Cfy#3;R3k0%@Arz`!*#r<{TD^0mz$*>e5ntb6Auo;fX1NSZ7%zlBaJ5`!kq=B*RgMp)eE6~d4Ks?1#CNbiSlW-5yeiPd zDQ9+YcZ|%b>%I%ba-6I+IF{b7Uz*9|12jPFI0(JFjUuN#A;gP!EH4*pJmf_)g+NdtRa73n<^?xZrS1tiADj1;k0h+)Bm@8|Uur z(bI(6J#Yu#_9?ci)7aBU?jCBD2@17eBz?!kv%NIqkgyYTr1#wvSFmkFCij z`sXBXUs zP{dI_c4{3Pq+}(9$G_R(M#%zZsNy6kFu4!b&_vVpZ`^Mk>%>R{8$^hM`1*56@$8i2 z@jRhYV$78F)CrOC*{Ho1X5IGXvGgM2bUSUTLpSxudChAO^30W%G!`R|sra7NCp zl*f*SpooH7;g8p#p!3^_tphyXiYhAXYOGY+iSb8(3b|Whsm4yH1a7O`a!HMG)$V`I zyY>}OAw|cUjyTWEP@~&SN0{@%*L4(C>AD{mKNF!eK!#T0wM2G}kUN#ea)wDtmTXOt ztO2_5sj?w=Z};lNH@O>oFd)+7W=b8$gqW2OEfW;Ykwo9-w>iR zm!=3Pa~IcPa4u$=lv|z_szzV;1o~0TEsJcuY3)!fL>)}^1d}V~$4V0A{AQk+S&2L+ zHTLXNf4X!3GciOu(%u<9VQDF6k(67O*5ND`AHJi|{a zwkuL~f6_QQl=4y$Xy#LNMug5v1>OXN3`fekLVyz+@$1@BKMjd|SR zGelU?;~JCjGY{wFXruB0YFTf-@ag1{`U_w>b^RRaK0m=1QF0I@{m$Ll#USA@3zzhz zA@Hs(nsS3PMvMA>5e4@iG3pPI$`w(>Z=!+-B9-#{rNU#;prPDb^@g#Lrfb^_`24C5 zL*s*9%8d7nkjItybF;a-j8VCuph<2=R#`N;>O0J5_XbDSZiU-XdE`Np#hU>?r8xwQ z66Gf0e*zR$?UIxn*d{&6UlkD>y7Z5+;KwK}6-a_cV~%9{;R0s)z%&l4EHo-OIcZU<2<{e*? z5G&EVCZT`s_>{`)ORS92nhaasPy%9JD!i5M$i#aH<~m^0gtJ-Z>{6mpp}031JEhd% zM^%F+;Tn!z_FwzUjxPjzZ$h_iL);`H6d^B%$lit0$WwQYnmVbKr75{{8Wd5C4#i7u zVv3I5{Ec`~K=_Y4P;nvUt5#D$&9*sEd9l_(bO+KOLnakW+}%smYezK8bUz!ZH{?pV zWs4(FNU1O$l}4IY34{YA?&=P}meeHW&Fmc=J5n$NbE)a)Mmr~&u=a7xUs|Ps8Er+W z%rtP2l8usdcMekrFmfV(Qo!fp@%VWBOnk%EgLXW(q8jNmSKQ~sHwPLSM>I8&fKwIH zXhIoh0u}YZ&qVmI0X$|vZ)mnfIy#E^r8?z^{+ks#=62F@$yjrJ$91~7HqsGs;y>El zc-o(*0D}lp3)NdTT(M2*_jAi=dKkzhkxKg6r~?n@-d2Vcd(fZPal>~3R^-y(xV>4# ztjRrdFrU6Tj^1r=p!}PovAB`Z%Fby|#U-9t`VDhoQgI@59AcJqVWKuWstq43#qXBl zH%k3BOvbKCY}Y?=UrXymQ*Nr0S98XvrDJ}5>fd?h_E(WIf_+n!%2$Qz4_D$&y2iBN zE0oRejwm%^J9JDcVQNp%agpBdFVHW9E)Il)d&Iv|S(fpxSXz#Igq@UmNEO z!*Esi!{tb86ZWg&6CRd5tgW>P{?*01tZtp;bhG_Sa(Y9)EjGcFY<~6*{+@<2y!_(N zexTm|czf!e`z6Ww?tj{kq{RBv{dZ8HLFdj5PPj_z({Ba?lgTO+uT81KVF^^qE!eDz%3H`ODR=R3?ymu%a9^)&3*Z#-?KGoi;F+&{q~V%bFQ|`KtLfT_AS5 z0!>LR+GV68xfa``F__W*qqq%CQEfE8+cdZ}4xfu!qI|~m>u+k5a(2__X4f&_AJ3Vr z-ia>!OzHcX%zymx`Dn@NgAK6>U0Cxp zu7EwUyPB|o8OUnLqdvF}Oy#lwXHw9lle;zUyYJ8R3*W8Q(pj=k(HQV2zECruFR^S< z@R!*0hp^)@NTfZ{;S^+XC)xh;`xCoy8;1x(*zq_ddWP}a&y*F(IG;&EN6L1M1-**8 zFtK{c-YQXxF-V}gcG;rdme}_bIvxJV#@aedD~Ey#(aY@=&p=J}$is{}OHGI42$q2G zh(gVUpUKn5AAy|&pQVS4cH<5Xe|2G$gg*M-zg>LzQ*6Q-MtK+YD_M?mJm6y__EQL0v}#GOv!8hyW#aS8h~S577fVmiCV)?P(BSWT&9Z>{Le zG{op<^2zZ>z53XF+O#Gem|bIRFRE5lehM2AWgB!@%PCJCh{d-_b8G`+Ott24B3gGF8G1o?GX< zuYYi2bv{Dz>6JlY-Qrb`tDe>j3XyrCEhPQiHsROOtm;hI`b_%%&VwC=k3ee)s0ZjiW-GkIem=2SsqB``6!>48qBO?~0H4syw5&DiECI%ypia)PDMe zU+~u{a678o(y%jppEg(g_w{w7fcs$S@hr2ckG>V!CRU0$V6lE_UV zb4cN6x6^QvZRzEP)81ysk(B4UDVaeUwAgw}0ho=QCH7M?DI|4Ux)RsGS}=?jik^R;-saN}>tCbbi#bpe zKOBvJrY6;Q{w!9is2S^}gc6N#`Ul>2&BulM6!DmQs6LWV;3RcJ=%qwT+2=FGrWP9r zq2wR`52J3Efq%?v%R3B>l3EpF-qdCL9|^A&2&}jnr8W#$jZ7s>avDuX4CATN#=;dg zNm};G*MZy1J9DVWeit?nV?N#tbN`zzG z;nP@x2!GcN{9U#BntxgLPq+Vme|^#4-R6i2j|`lJUmti$7hYxmuVN5JFoyH$TkzJK z%YRK+a(5#Br`%^Z_qb47Q3RzQwSu>@5B=HqBnE2id?|nTJ@q2m+_u6b#-XIdbg+Ba~dy|0#ybQ$j+(2#bzzTZNV^@@j#bgvSuYIEq%|I8;nx358+3w5?DNwZ13N}yq>;6nMIm0a{3 z{LYt&hH(#RP+9)N^c&URd@1D@pAtwK_K0?si9S*H6CS7nXhhf%8SylcG@a}S!m{h} z1JpB`9Cm~&6?TyVzW8A7Cb;n3TsG6L~TS$%gC$q^~@P50hD%eYV#yW(8Ae%!uU8}S&CtR3K!HR48=D$F?sK*8(ZU*Jor1R>SBXvw`(OQMaV=HGT ze*inxgJF%aYZ^+`wh4_p?(Z$|xe<$$xO z5RTa2+T7cK4_vW8ZHBCStXUh{jvr~ye*pf5kk(ZToX81mq{pqAxIJT_dx@PYP1fa2 z`;uJRuqouF3erxG8Bd)*&S7b|3<^~Jy2GA(vLLc@p!kGKT=%({k`3KLoOIal9)x~_gI?ct+aa}-Ms=trXc)UH^f9vcM9dD4lF7{$OvNg7!U=I z4HDc8?iIw%nPxl#ao!`VuM`kw%^Eer?3?->GK3T+EWBgP%4E%&n;bimO;x}B&1hh; z>Wfg?m;FinvU__F>(?8q+tDzCyRrhR(TP!g1Fu%$9}n=c9(T2ze=i^4Cl9z?`wu7| z7MU0fdKz37#$sF@XIL!#$>pmAvSbC+3uB#K`>(}F3y>DBj9G-CF|P1AD^xI(y$X1d zkv{*Io7c-iWR@%DgdI^3PqoF6Z)Kei-{Rh5R|%oASEeYcmTzj27aYYXEkBFCzo*W9 zO8wCVJtMG3{rQq4=Ze_(hPcZ-A8DQMAKky9{$?rEErc@+4fEohT6j{Jn6!oaa)if( zoJGc9H+p8_RXgd+*WBlH0qvv%62kJ;E%HjQ9WneNCv*`} zz(-Z`qaNPulJS3@zG$axe9g1>-svcA#s%{<1X9AZJRH(wZk29pWcn|Q5EEU1K$p*wG} z)%6>}))G99>SoHZ<`vHwt?iK*7<|F}<7Q;-uqh0eTiviH!rlequM?K%a`&#Xjqmpy zyJn^AB3G&!Ca)cqnO!UM#LvqqhTdkc7nRR%k&m6_IldRrLFGORkM(FWbY8!h2n@Np z=haT-;E-5UKX9>Q{F^*vH715_Y>m9Ri#XD!AI~QBi(IUoSk$M#T461V4L^OmiA^$p z)Oi1m9(ylw-%5<=*UX}7?VNxMu*!8DzVFQ+2R*jlspeuVs?Tx4LFz^_14t+cni5ajYuWwzqY%sXb#{o4@mSLvS~D$td5=oL@xl;_z|D!^z?hDHwAkU8OG4hV(|S7 z<+QB=I&2&rR-YdsX*NnBhZZdq=CKvynag2_&;!NtBNOq=i9G5ZJ(HPYLgsNU2Z+HU(R z!`lk|K0Io76r5WCtDQpM^o)(!yZK5Uw?MS!z*&1ph{0G1ZHY|< zFtI9w3k#6fBhb7iscEZ_F)ParvF=}DUO`N!ir`NLNd1wxo)qI5%?jL|hn)ZpJ4BSk zrrxOgtMX1jt^`&?0=p=YJfYsKGN>$AWr*Z5#MonKfN-(CFx*%e9v}?Y5{Byv<8mKk z7t0XdWkcD^W5-|H$`D+7z*#+DZy94?wEN;xP4ifJ^H^7NhwDS{qZbp{pA%T8>FTr! z`|27|@fu0-T`_TXA@Kq+aa&38_Ao%UD#Dr*DnngdohUV@@%fm>B^02qir7*?1gj!A zII+Q;SYJ-895v>nX~hp=L@3Bm6=`Y2gE9S#XK)DvrH6n5k zHXV%(G{Vg4yPN15rs&BY(Jh1kdwPac7u{9T@pM|@z?2?DV3jLH+Sc#zZUl)v*4G{@ zCyDuJQ}II_5ehc!L0bCqU~E3)nOwra=^^0JFz`VLc(Dh0wSoou;;P!#c6rT?X`zt_ zH?HE8bg9qU%zMst3%aFY3F%Uwv_nR;=Qc_!f@U_?f2`V%UI6&NqQZlwLr#Tx&BS;g z=FpPAGEwRBR9Q3-=Y1k-ukYz*YpoShlG%^o#9tCHO-nxQ`OtTS?P|#ap@Wd~pZ;94nc;^_+DS_7$k`4Ve8EJp4@* zE$XJyMI|9gDJq#NDLEuAsbX&*($S5FhvJTYW79W~G8<$ffHF~lxhP7s;_a7!LJ+hR z1g!_@9e-U2GOXe@xcSr0pA2&_>_S&_cRzkGXa3;a?!;DeeSW;BWQ}m_x?X6iUZ}ZN z=(tYktr>%W1;ZvxHr>*Y{_smOb~_oHkc=Hq*88x%&^l*9S0D<^7Re2#8VjMS=bNhM z3#jKyt$!OrH4)MpUGpD4fFIYQhfUDK&SoQuM1fn`I&yNEdKOFtBH#zv$Vb`PI+z9d zw-!uyMZxpg!>WlMD(co&Ayx13@Ta(p?T(z*+uud!{(zoFAh{iiGwa7Nuoq`?=?uk5 zvJ+Eu7(?+TOf;$**;WaHK<8gp}#MVDlDpM6V2wSGFmAjRwdGH zZa!BZ=2LQLi_m^44I6FDe9@D+B_n1^CSA2hHf8R{_6O10~JqXJGU}=JZq+ z^pDKxeaz^Ws=&R|Nc=YRXd7x9$kW)FVQ%-iPC~3&Ld9X(Hq><3^2k0Ax4w-X-%j3k zS%^?P2m4&d74>z@ZstWy9YRmA;kVSWaSK^b^_@=gFN~Jj=liz z6URBk(9m)>186$Q0J_9j6cLZ$eM?U6ZW`_yYMLN200jxclo*>vgb_E!-piv6Y4&&&aELt7R&~^# z53ne19zh*TPQGp$z8Y$}ATl6DJi_z=HjNuoo3Li10jTGZt>^hLO+)7iu#!XUvSQz} zVvpnyXC44$PXL7nK+qE~>j|in8@3tK9njv$gP!C;6Z4WUM;5x@PBXms04XKUG8@`+ zRtu}xna)|8Di(*mBv^3}h)ItO9EE{CY#6&^`IAYEj|}V_hb(Y}hc@7$4Gn6RbBto_ zluVDvzzT6>Z8R8#hX88YyhOk=o=woYEQnqM@rnli>_vmbLz6l2B59e2iZpi!+I2Se zGM6XLyMl&YBmiixayIdj@mDc+&X`Bg%#u^2n?|IDnlT7T@GgurEyku9W5f;cx9PD1 zh)p=u7L~y)@B|5*hhyJM;Vz_bJyLL2lpnW&B8z}6HNCATFxxX%^q>@8Y$0B3FV54O zQ_@*4&t>WfoNqyFB+rHzs@YfZciZdF!Svg!!uIQjwUK_sdhIl{63qZeClaiS!=n6n z1Z^!jCAw)OYN#PWNHE0!(iDeH^TUWk@o6+zUc@FX)E1G!%=1JOFi(qp55Qdja6JIH zE286fY+eNW3mPg-Ku`-Y4J*Won@n5|$TZ|WK<>hJ+}xRXxoU?)}~5Xl>e1P78W5_Z4n z&#W9y(TmK`-`N3P?FiShl?*Qu++f#)VefuCk}~w|wloT8)0#g zk;Pt-#afX(?|a7@d&lZ~Gprp@j~y&+9SBpgA*H?CnkiM0Db<-NRhrpx*2uc7&k9VJqg(OjV>jkao!su7(aF%k$V@C9k*4j( z=ENn$aDH#`+HZ|Z8rP;R@xEeHzGBVZ zV#hvWZ)KSTG?ynfYYUjFcWCLkpD@RT<9-G z{^N8y7cJnZwy=1}{ruM)CRm6GmgnPWs+2Pk`!Sj zw=W6*gdXlqk6RbOzBWW?7$W=)N%P$>GS(HG;!`P13lG6PB}n)<7U2fBZ^l1t#_KiX zO`7qV&3MyhKY8nn^35t&kFd$oO5@f_nq@N+75)4aj3E+kh)hbJ^-7yXMsqd3t;8p6 z2euA+ZuA%;;|-BnhR7X5vRN1Ch6}XT1={2Sopr&kxjEB@lMB@b_gk-4a{lY;1Vm*3v9mJZsexeHLH?x3z)$*!U-THm5jwBd5KQx4n_2Ra>rdXb!JM z;K&{Vw1>zDf@TFl4V2-I$~--Vq0L)zz}%HbsO3i?t%Y>I$h_HtTIqYe1lcXRdn*pZ ziVOW(3XNNPzMnkZ`|V~HUaT3;Q`eI*XaCtl@<|&crv-xcmF%9ipPRQ=9J5!Pw{Krr zQMnY&qwEZ#QBelaav=6O7|1+Z_E;w$pr#&J&S930JXuFYl>wuK15E)mFRRh3W9ZYD z9AsxN<9xMwx=Y8pOKE0JbasWF1Twr=27S8+8VzPx*%8{^6=MG>RIn>#dmz*vL?;qV z=MhMk7f9C`L`NP>cUKwMbPuSnoGWVo&TfjZ#d|_`Zd&)eC#&RK+*@Kv8N5=6>>t@g zuZ~j*6(U^ZKx z(qx{|{QRq=;`)Am`s+?WeK4)Ou)X@!4`*Kp&JlvsgA_lm`F`P?=34*Lve>+4Ow~f? zCF3ArGoLe3+ZhRQMxHq%jhvAO&dA9|tV3g5I1E!?O*3xpHg5iN#$0DxB=wg^olm@$ z-6I(M0Ss4GhuyMc3}kEByY8v>E3S5gxbBBG4f=N|ViX>^aR|QsAdGJFP*EOEq32Ac zw-^NaegNiwM=U?Xjw|Av3LIw*g(inpwu210$OGxIoxs9QVcKA~#s5|enHLRFr6J3e z?%(K_5$4MXqfVf<*=Ugm*L2RVgkm7%YcM3P3v9BC99c#ZFCz&V_hn>aC%C!`yweG` z=>&&&f%^g=62TDmFu+C_KrS4R77i#316+jz+*J{kstAg3Ky?_v_moEdjOO&1=H&^E z#0kxAIOu73UfWN9!xWEW29FblduI$6b&ECm48mphYRWGZGH!*_y8{rzZ zPuTW4d>8fo_W8|z@*|Gv@{Z}8!hj^q4($ul4R_{(hjZZ;)v$+Z*le{pQ-@-x1JB#~ zvA6X!lQ8Bvn9hNy!GWmC63lWE7E)c`&{E$}Uyt{6z>W6CId>bY*#lleO1=+IbBpdE%p4-iVcNE2(P4O3Zq;eyNV!=ZQ>Zr0QV&H3<5&l#Ct(y<1A| z9RzJHC1(zTUN0qc4uW9jRW?4FIgMCV*nFwL)3WEDXssJoFWn6}jdvg5KzEI71=T>V z^fbt%Xj)xT>BRfHT50UL1yk?KF6B!L_cg~)bvp*rP6iczGk2j@5~migNr0+<71X`S{8aCCNuEI#}a=DW$Jt zX(9_uxWI;`=*-y=a-tg@PI^)eYk80Pfbay-$Yg##F_D*u*J5`tks;E2q||MsU}`39 ztSD1vL#Z2`$FH<>CeyfLUS<e!z0qdOc(Z!$p{MUd7YjtfEi0!wR(sxE75J3WD761fGQ zisgiOCbIa~#|)`z6dk3NrMWEdLX>ZuxK^ zQ1@e|R1X23Gw7X=Ay&4wz z50MbI9%e<5H$4G8OhbT;0Wd*qS3D1)m9QZ}kcmP$Go3(c<3nwB;g_U?)_1_!g9HJ; zT~VC4Lx&cAiAW>U_k*guD&&;^`iQzv>nM#gXj_XqJg_vesdIcld;TZS)2T?#?CD6( zsBN|Ms%-%p!VQ77u?-x;Ud->4wn{ zb#0Tfl}ZktoP;l)#vetMTVF}ErW}?oKN~c1W%DhK`?S2ReU|#;_y?lqM=G;jblcs4 zrx)1H_lSjT{^`1A^R9_UdwSt5q8w9o0cKqjR(pDo7E%35J1grwJ?a)w)#Y)qu(2>PIlo<8U`Fi%k+1(S!|F+8h+aiEy@z=lCL)Yt}i}dWxvsI$A zyNR;9xwE?+vsEU~VfIg(;_h9WcgtO~h=}Bldsdp%dBRJV?3hD8F_u?;SKqu@WeJu0 zs|@+tm-w~s_1C`iuhA^oH(y0=dPQ!cL~hK@udmFnNzAU}3BmkY!|Ym)*Vj4wMkqV_ z+eFVcx@1x6<8`x?;XY`&Rb=^8WSL52SwdvF%&fD=tncz=M39iCg3y{GV>DbS9ofm$OS;m(l zLMl>2s!~HLQ_m|>%`8|B%~=jjSt_gUey_jlbZ0ySDErK%n>0^R#{QOg;Iq5704>Iu zPr>P4TAgjC9nDbX<)8eHG#B72%5#;UgB|!-((|i}2+X zl1DpYG6x^0o(reC2`C|DoZj7as=xdF&E4m2|RSSSCw`Qg8q%sc5r7jGD)>*aQ zHkLg1LH<%3n|&`BgFCxTy=n@x9*{}s15KLMHPFAsYf=pZOFF<(7;lva25n@6^dADY z+z8ooh~j|E2rY>7p<(k)my8O1=f5g(c{H~`PMYA0Uo+T{IFybYnmdQJ%3s0Vp#8P6 zoUPhDhH_m7v!4AkveU;O)z9`PZk48l?RQjepPV+T5s^i@wwt?xYsSi-u zdB#3Ly=qll@hPJ0x7Qod_YLyPWZ$!{-O>6Lp%M{a&Khv*NInt#&A{d)_^5z6m3q+!9uKm_=@6=dbR zEDb7kJat`ixUu2hK26a?BqqMA>iP`gJd%Wz8!pEOybg*}thj%#>i)gT`}eBvcUIib zc^oTNd+S&6tzVV5ewE#FPg2#vh-8#6>Z}`<06qRM64495Wi>>9{kE*xGV%8N%fhqW zxFVNHE!x&^?(*X9^4{l_6&B_uCoq%Sk4>gk8k5aT(t3FdSKl{`^rbkKGnDTY9SC$r z4;m{l4m}n@m6=Pann|geOZAvZfgO@0A{6X!e-sT%Yo1Zcjr-Up$^VP4N7LS?faB-C zfsVZ4GX{X`ceTaAZvGjffGZ@8P{>iz#38RZYro|w>zm)^0q*K96HcH?Ip|0+__D^e0A zQetlY&=AEYNI0jsphztD%y$U{|Gv`Bi2cy>Ocdd6;Ys+NH+{KbfkNxTIs&VhMXEL} zECbFS&SKB6U|eGhKe}!o_8rGqH0_(8Q_0Zh4w?==EI)iDo$0Rf)PS3*{pzHSx<7}? z4jL<9i4-tHZbpZ&6a)Nonxl6RBG8w5OgW`Aa@xh)Nl%Lv6e;6JOV9l3_CI*K1-omS z`Y%ghlgr%~VX=}#tC_Q79u>2DdB{iNa$xOp(W=AFNY_Vy+r$A)9}h0T1eXF)AMQkS z^gk$DHYu|^+MU!aTQ)4~d8HSQV+)d#v^9oVL~YOYe7|gQD0; zN#H)kjyM2aHuCYArZVK<8{|MtE|odV|D)<$em;2eN&TMT(X(>=Z2|PQqNx>!YsB=k z!Goyi+2XOny}Zz#ro7fW5kA;gmg{&g)`rx9Cie+PcC;Zc>RE`qcsOgKYl=iTy7%1( z@xaEiyB<&8l&3fCNG#TO0<`+3szZ0OTef`u&30MPX3y^l)TY3&EU~=3r{P5)%+$Efv|GB>bY$2#qRdMHD0%6ExKV{8D6 zj07Z4!g+85I{9>{-PWx$l_l5&CE*-=8Bf_iOYLTWzwX-cLXI{VxaEyDh{+ktzvs@&nUHOeGGq!-ssN-<6q*Hr`;^Bb zcHiRv5SC7*ztRO$Xr9j{J?-;-?JZ2hfoJHNa9UL1<%P#7vgq&c@4tv|?^7`kajt53 zR)rrn!+kcxVa+f>d22F;fC2&8Jb?g|zy~Ax$M1lq<-nA8Nx9Ch{-0c;{mtX+3ItRX z3`1P=8Y1%=qVxQm^85nx)>P~&6zu@{60(I7A09!-jUad5ft$+nDFV9;#~$mAJ=T8* zHZp+NqY1m9?arM#{oFeJd^#OvH1K&m=c6>+qcjU6G-0DOk6i#+E #ib5hXzaOpV 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 z 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 JXb2FH1OVMM(-Z&z diff --git a/packages/nvmedit/src/convert.ts b/packages/nvmedit/src/convert.ts index 426f3f6b8259..7ae67ce4cf2c 100644 --- a/packages/nvmedit/src/convert.ts +++ b/packages/nvmedit/src/convert.ts @@ -1,6 +1,7 @@ import { type CommandClasses, ControllerCapabilityFlags, + NodeIDType, type NodeProtocolInfo, NodeType, RFRegion, @@ -9,7 +10,7 @@ import { isZWaveError, stripUndefined, } from "@zwave-js/core/safe"; -import { cloneDeep, pick } from "@zwave-js/shared/safe"; +import { cloneDeep, num2hex, pick } from "@zwave-js/shared/safe"; import { isObject } from "alcalzone-shared/typeguards"; import semver from "semver"; import { MAX_PROTOCOL_FILE_FORMAT, SUC_MAX_UPDATES } from "./consts"; @@ -23,6 +24,8 @@ import { ApplicationTypeFile, ApplicationTypeFileID, ApplicationVersionFile, + ApplicationVersionFile800, + ApplicationVersionFile800ID, ApplicationVersionFileID, ControllerInfoFile, ControllerInfoFileID, @@ -65,6 +68,10 @@ import { nodeIdToRouteCacheFileIDV1, sucUpdateIndexToSUCUpdateEntriesFileIDV5, } from "./files"; +import { + ApplicationNameFile, + ApplicationNameFileID, +} from "./files/ApplicationNameFile"; import { type NVM3Objects, type NVMMeta, @@ -122,6 +129,7 @@ export interface NVMJSONController { }; applicationData?: string | null; + applicationName?: string | null; } export interface NVMJSONControllerRFConfig { @@ -130,6 +138,7 @@ export interface NVMJSONControllerRFConfig { measured0dBm: number; enablePTI: number | null; maxTXPower: number | null; + nodeIdType: NodeIDType | null; } export interface NVMJSONNodeWithInfo @@ -202,8 +211,7 @@ function createEmptyPhysicalNode(): NVMJSONNodeWithInfo { /** Converts a compressed set of NVM objects to a JSON representation */ export function nvmObjectsToJSON( - applicationObjects: ReadonlyMap, - protocolObjects: ReadonlyMap, + objects: ReadonlyMap, ): NVMJSON { const nodes = new Map(); const getNode = (id: number): NVMJSONNode => { @@ -215,12 +223,9 @@ export function nvmObjectsToJSON( id: number | ((id: number) => boolean), ): NVM3Object | undefined => { if (typeof id === "number") { - return protocolObjects.get(id) ?? applicationObjects.get(id); + return objects.get(id); } else { - for (const [key, obj] of protocolObjects) { - if (id(key)) return obj; - } - for (const [key, obj] of applicationObjects) { + for (const [key, obj] of objects) { if (id(key)) return obj; } } @@ -232,7 +237,9 @@ export function nvmObjectsToJSON( const ret = getObject(id); if (ret) return ret; throw new ZWaveError( - `Object${typeof id === "number" ? ` ${id}` : ""} not found!`, + `Object${ + typeof id === "number" ? ` ${num2hex(id)} (${id})` : "" + } not found!`, ZWaveErrorCodes.NVM_ObjectNotFound, ); }; @@ -414,10 +421,22 @@ export function nvmObjectsToJSON( // === Application NVM files === - const applicationVersionFile = getFileOrThrow( + const applicationVersionFile700 = getFile( ApplicationVersionFileID, "7.0.0", // We don't know the version here yet ); + const applicationVersionFile800 = getFile( + ApplicationVersionFile800ID, + "7.0.0", // We don't know the version here yet + ); + const applicationVersionFile = applicationVersionFile700 + ?? applicationVersionFile800; + if (!applicationVersionFile) { + throw new ZWaveError( + "ApplicationVersionFile not found!", + ZWaveErrorCodes.NVM_ObjectNotFound, + ); + } const applicationVersion = `${applicationVersionFile.major}.${applicationVersionFile.minor}.${applicationVersionFile.patch}`; @@ -437,6 +456,11 @@ export function nvmObjectsToJSON( ApplicationTypeFileID, applicationVersion, ); + const applicationNameFile = getFile( + ApplicationNameFileID, + applicationVersion, + ); + const preferredRepeaters = getFile( ProtocolPreferredRepeatersFileID, applicationVersion, @@ -459,10 +483,8 @@ export function nvmObjectsToJSON( "dcdcConfig", ] as const; const controller: NVMJSONController = { - protocolVersion: - `${protocolVersionFile.major}.${protocolVersionFile.minor}.${protocolVersionFile.patch}`, - applicationVersion: - `${applicationVersionFile.major}.${applicationVersionFile.minor}.${applicationVersionFile.patch}`, + protocolVersion, + applicationVersion, homeId: `0x${controllerInfoFile.homeId.toString("hex")}`, ...pick(controllerInfoFile, controllerProps), ...pick(applicationTypeFile, [ @@ -485,11 +507,13 @@ export function nvmObjectsToJSON( measured0dBm: rfConfigFile.measured0dBm, enablePTI: rfConfigFile.enablePTI ?? null, maxTXPower: rfConfigFile.maxTXPower ?? null, + nodeIdType: rfConfigFile.nodeIdType ?? null, }, } : {}), sucUpdateEntries, applicationData: applicationDataFile?.data.toString("hex") ?? null, + applicationName: applicationNameFile?.name ?? null, }; // Make sure all props are defined @@ -609,6 +633,7 @@ function serializeCommonApplicationObjects(nvm: NVMJSON): NVM3Object[] { ]), enablePTI: nvm.controller.rfConfig.enablePTI ?? undefined, maxTXPower: nvm.controller.rfConfig.maxTXPower ?? undefined, + nodeIdType: nvm.controller.rfConfig.nodeIdType ?? undefined, fileVersion: nvm.controller.applicationVersion, }); ret.push(applRFConfigFile.serialize()); @@ -623,6 +648,15 @@ function serializeCommonApplicationObjects(nvm: NVMJSON): NVM3Object[] { ret.push(applDataFile.serialize()); } + if (nvm.controller.applicationName && nvm.meta?.sharedFileSystem) { + // The application name only seems to be used with the shared file system + const applNameFile = new ApplicationNameFile({ + name: nvm.controller.applicationName, + fileVersion: nvm.controller.applicationVersion, + }); + ret.push(applNameFile.serialize()); + } + return ret; } @@ -858,12 +892,13 @@ export function jsonToNVMObjects_v7_11_0( let targetProtocolVersion: semver.SemVer; let targetProtocolFormat: number; - // We currently support application version migrations up to 7.19.1 + // We currently support application version migrations up to: + const HIGHEST_SUPPORTED_SDK_VERSION = "7.21.0"; // For all higher ones, set the highest version we support and let the controller handle the migration itself - if (semver.lte(targetSDKVersion, "7.19.1")) { + if (semver.lte(targetSDKVersion, HIGHEST_SUPPORTED_SDK_VERSION)) { targetApplicationVersion = semver.parse(targetSDKVersion)!; } else { - targetApplicationVersion = semver.parse("7.19.1")!; + targetApplicationVersion = semver.parse(HIGHEST_SUPPORTED_SDK_VERSION)!; } // The protocol version file only seems to be updated when the format of the protocol file system changes @@ -905,7 +940,10 @@ export function jsonToNVMObjects_v7_11_0( }; // Application files - const applVersionFile = new ApplicationVersionFile({ + const ApplicationVersionConstructor = json.meta?.sharedFileSystem + ? ApplicationVersionFile800 + : ApplicationVersionFile; + const applVersionFile = new ApplicationVersionConstructor({ // The SDK compares 4-byte values where the format is set to 0 to determine whether a migration is needed format: 0, major: targetApplicationVersion.major, @@ -923,6 +961,7 @@ export function jsonToNVMObjects_v7_11_0( measured0dBm: +3.3, enablePTI: null, maxTXPower: null, + nodeIdType: null, }; // Make sure the RF config format matches the application version. @@ -931,6 +970,9 @@ export function jsonToNVMObjects_v7_11_0( target.controller.rfConfig.enablePTI ??= 0; target.controller.rfConfig.maxTXPower ??= 14.0; } + if (semver.gte(targetSDKVersion, "7.21.0")) { + target.controller.rfConfig.nodeIdType ??= NodeIDType.Short; + } addApplicationObjects(...serializeCommonApplicationObjects(target)); @@ -1041,8 +1083,18 @@ export function nvmToJSON( debugLogs: boolean = false, ): Required { const nvm = parseNVM(buffer, debugLogs); - const ret = nvmObjectsToJSON(nvm.applicationObjects, nvm.protocolObjects); - ret.meta = getNVMMeta(nvm.protocolPages[0]); + const objects = new Map([ + ...nvm.applicationObjects, + ...nvm.protocolObjects, + ]); + // 800 series doesn't distinguish between the storage for application and protocol objects + const sharedFileSystem = nvm.applicationObjects.size > 0 + && nvm.protocolObjects.size === 0; + const ret = nvmObjectsToJSON(objects); + const firstPage = sharedFileSystem + ? nvm.applicationPages[0] + : nvm.protocolPages[0]; + ret.meta = getNVMMeta(firstPage, sharedFileSystem); return ret as Required; } @@ -1374,12 +1426,20 @@ export function migrateNVM(sourceNVM: Buffer, targetNVM: Buffer): Buffer { && targetProtocolFileFormat > MAX_PROTOCOL_FILE_FORMAT && sourceProtocolFileFormat && sourceProtocolFileFormat <= targetProtocolFileFormat + && sourceNVM.length === targetNVM.length ) { // ...both the source and the target are 700 series, but at least the target uses an unsupported protocol version. - // We can be sure hwoever that the target can upgrade any 700 series NVM to its protocol version, as long as the + // We can be sure however that the target can upgrade any 700 series NVM to its protocol version, as long as the // source protocol version is not higher than the target's return sourceNVM; - } else if (source.type === 700 && target.type === 700) { + } else if ( + source.type === 700 + && target.type === 700 + // ...the source and target NVMs have the same size and structure + && sourceNVM.length === targetNVM.length + && source.json.meta.sharedFileSystem + === target.json.meta.sharedFileSystem + ) { // ... the source and target protocol versions are compatible without conversion const sourceProtocolVersion = source.json.controller.protocolVersion; const targetProtocolVersion = target.json.controller.protocolVersion; diff --git a/packages/nvmedit/src/files/ApplicationNameFile.ts b/packages/nvmedit/src/files/ApplicationNameFile.ts new file mode 100644 index 000000000000..a40bcf0f855a --- /dev/null +++ b/packages/nvmedit/src/files/ApplicationNameFile.ts @@ -0,0 +1,39 @@ +import { cpp2js } from "@zwave-js/shared"; +import { type NVMObject } from ".."; +import { + NVMFile, + type NVMFileCreationOptions, + type NVMFileDeserializationOptions, + getNVMFileIDStatic, + gotDeserializationOptions, + nvmFileID, +} from "./NVMFile"; + +export interface ApplicationNameFileOptions extends NVMFileCreationOptions { + name: string; +} + +@nvmFileID(0x4100c) +export class ApplicationNameFile extends NVMFile { + public constructor( + options: NVMFileDeserializationOptions | ApplicationNameFileOptions, + ) { + super(options); + if (gotDeserializationOptions(options)) { + this.name = cpp2js(this.payload.toString("utf8")); + } else { + this.name = options.name; + } + } + + public name: string; + + public serialize(): NVMObject { + // Return a zero-terminated string with a fixed length of 30 bytes + const nameAsString = Buffer.from(this.name, "utf8"); + this.payload = Buffer.alloc(30, 0); + nameAsString.subarray(0, this.payload.length - 1).copy(this.payload); + return super.serialize(); + } +} +export const ApplicationNameFileID = getNVMFileIDStatic(ApplicationNameFile); diff --git a/packages/nvmedit/src/files/ApplicationRFConfigFile.ts b/packages/nvmedit/src/files/ApplicationRFConfigFile.ts index b6ffadd831e4..5c824be842b4 100644 --- a/packages/nvmedit/src/files/ApplicationRFConfigFile.ts +++ b/packages/nvmedit/src/files/ApplicationRFConfigFile.ts @@ -1,4 +1,9 @@ -import { RFRegion, ZWaveError, ZWaveErrorCodes } from "@zwave-js/core/safe"; +import { + NodeIDType, + RFRegion, + ZWaveError, + ZWaveErrorCodes, +} from "@zwave-js/core/safe"; import { type AllOrNone, getEnumMemberName } from "@zwave-js/shared/safe"; import semver from "semver"; import type { NVM3Object } from "../nvm3/object"; @@ -21,7 +26,10 @@ export type ApplicationRFConfigFileOptions = & AllOrNone<{ enablePTI?: number; maxTXPower?: number; - }>; + }> + & { + nodeIdType?: number; + }; @nvmFileID(104) export class ApplicationRFConfigFile extends NVMFile { @@ -44,6 +52,13 @@ export class ApplicationRFConfigFile extends NVMFile { this.measured0dBm = this.payload.readInt16LE(3) / 10; this.enablePTI = this.payload[5]; this.maxTXPower = this.payload.readInt16LE(6) / 10; + } else if (this.payload.length === 9) { + this.rfRegion = this.payload[0]; + this.txPower = this.payload.readInt16LE(1) / 10; + this.measured0dBm = this.payload.readInt16LE(3) / 10; + this.enablePTI = this.payload[5]; + this.maxTXPower = this.payload.readInt16LE(6) / 10; + this.nodeIdType = this.payload[8]; } else { throw new ZWaveError( `ApplicationRFConfigFile has unsupported length ${this.payload.length}`, @@ -56,6 +71,7 @@ export class ApplicationRFConfigFile extends NVMFile { this.measured0dBm = options.measured0dBm; this.enablePTI = options.enablePTI; this.maxTXPower = options.maxTXPower; + this.nodeIdType = options.nodeIdType; } } @@ -64,6 +80,7 @@ export class ApplicationRFConfigFile extends NVMFile { public measured0dBm: number; public enablePTI?: number; public maxTXPower?: number; + public nodeIdType?: NodeIDType; public serialize(): NVM3Object { if (semver.lt(this.fileVersion, "7.18.1")) { @@ -78,13 +95,21 @@ export class ApplicationRFConfigFile extends NVMFile { this.payload[3] = this.enablePTI ?? 0; this.payload.writeInt16LE((this.maxTXPower ?? 0) * 10, 4); } - } else { + } else if (semver.lt(this.fileVersion, "7.21.0")) { this.payload = Buffer.alloc(8, 0); this.payload[0] = this.rfRegion; this.payload.writeInt16LE(this.txPower * 10, 1); this.payload.writeInt16LE(this.measured0dBm * 10, 3); this.payload[5] = this.enablePTI ?? 0; this.payload.writeInt16LE((this.maxTXPower ?? 0) * 10, 6); + } else { + this.payload = Buffer.alloc(9, 0); + this.payload[0] = this.rfRegion; + this.payload.writeInt16LE(this.txPower * 10, 1); + this.payload.writeInt16LE(this.measured0dBm * 10, 3); + this.payload[5] = this.enablePTI ?? 0; + this.payload.writeInt16LE((this.maxTXPower ?? 0) * 10, 6); + this.payload[8] = this.nodeIdType ?? NodeIDType.Short; } return super.serialize(); } @@ -103,6 +128,12 @@ export class ApplicationRFConfigFile extends NVMFile { if (this.maxTXPower != undefined) { ret["max TX power"] = `${this.maxTXPower.toFixed(1)} dBm`; } + if (this.nodeIdType != undefined) { + ret["node ID type"] = getEnumMemberName( + NodeIDType, + this.nodeIdType, + ); + } return ret; } } diff --git a/packages/nvmedit/src/files/VersionFiles.ts b/packages/nvmedit/src/files/VersionFiles.ts index 47a9e63d68c3..6ef0d0467c21 100644 --- a/packages/nvmedit/src/files/VersionFiles.ts +++ b/packages/nvmedit/src/files/VersionFiles.ts @@ -64,6 +64,14 @@ export const ApplicationVersionFileID = getNVMFileIDStatic( ApplicationVersionFile, ); +// The 800 series has a shared application/protocol file system +// and uses a different ID for the application version file +@nvmFileID(0x41000) +export class ApplicationVersionFile800 extends VersionFile {} +export const ApplicationVersionFile800ID = getNVMFileIDStatic( + ApplicationVersionFile800, +); + @nvmFileID(0x50000) export class ProtocolVersionFile extends VersionFile {} export const ProtocolVersionFileID = getNVMFileIDStatic(ProtocolVersionFile); diff --git a/packages/nvmedit/src/nvm3/consts.ts b/packages/nvmedit/src/nvm3/consts.ts index af2f8a80e2b1..3701475f70f1 100644 --- a/packages/nvmedit/src/nvm3/consts.ts +++ b/packages/nvmedit/src/nvm3/consts.ts @@ -1,6 +1,9 @@ // NVM area sizes export const ZWAVE_APPLICATION_NVM_SIZE = 0x3000; export const ZWAVE_PROTOCOL_NVM_SIZE = 0xc000 - ZWAVE_APPLICATION_NVM_SIZE; +// The 800 series has a shared application/protocol NVM, which is 8 KB smaller +// than the 700 series +export const ZWAVE_SHARED_NVM_SIZE = 0xA000; // Everything must be word-aligned export const NVM3_WORD_SIZE = 4; @@ -11,7 +14,9 @@ export const NVM3_PAGE_HEADER_SIZE = 20; export const NVM3_PAGE_COUNTER_SIZE = 27; export const NVM3_PAGE_COUNTER_MASK = (1 << NVM3_PAGE_COUNTER_SIZE) - 1; export const NVM3_PAGE_MAGIC = 0xb29a; -export const FLASH_MAX_PAGE_SIZE = 2048; + +export const FLASH_MAX_PAGE_SIZE_700 = 2048; // not sure if this is true for all 700 series chips +export const FLASH_MAX_PAGE_SIZE_800 = 8192; export enum PageStatus { OK = 0xffffffff, diff --git a/packages/nvmedit/src/nvm3/nvm.ts b/packages/nvmedit/src/nvm3/nvm.ts index bdec6c5aad21..149875483ef9 100644 --- a/packages/nvmedit/src/nvm3/nvm.ts +++ b/packages/nvmedit/src/nvm3/nvm.ts @@ -1,7 +1,9 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core/safe"; import { pick } from "@zwave-js/shared/safe"; +import { ApplicationVersionFile800ID } from "../files"; import { - FLASH_MAX_PAGE_SIZE, + FLASH_MAX_PAGE_SIZE_700, + FLASH_MAX_PAGE_SIZE_800, NVM3_COUNTER_SIZE, NVM3_OBJ_HEADER_SIZE_SMALL, NVM3_PAGE_HEADER_SIZE, @@ -11,6 +13,7 @@ import { PageWriteSize, ZWAVE_APPLICATION_NVM_SIZE, ZWAVE_PROTOCOL_NVM_SIZE, + ZWAVE_SHARED_NVM_SIZE, } from "./consts"; import { type NVM3Object, @@ -30,6 +33,7 @@ function comparePages(p1: NVM3Page, p2: NVM3Page) { } export interface NVMMeta { + sharedFileSystem: boolean; pageSize: number; deviceFamily: number; writeSize: PageWriteSize; @@ -63,12 +67,27 @@ export function parseNVM( offset += bytesRead; } - const applicationPages = pages.filter( - (p) => p.header.offset < ZWAVE_APPLICATION_NVM_SIZE, - ); - const protocolPages = pages.filter( - (p) => p.header.offset >= ZWAVE_APPLICATION_NVM_SIZE, + // 800 series has a shared NVM for protocol and application data. + // We can distinguish between the two, because the application version is stored in a different file ID + + const isSharedFileSystem = pages.some( + (p) => p.objects.some((o) => o.key === ApplicationVersionFile800ID), ); + // By convention, we only use the applicationPages in that case + let applicationPages: NVM3Page[]; + let protocolPages: NVM3Page[]; + + if (isSharedFileSystem) { + applicationPages = pages; + protocolPages = []; + } else { + applicationPages = pages.filter( + (p) => p.header.offset < ZWAVE_APPLICATION_NVM_SIZE, + ); + protocolPages = pages.filter( + (p) => p.header.offset >= ZWAVE_APPLICATION_NVM_SIZE, + ); + } // The pages are written in a ring buffer, find the one with the lowest erase count and start reading from there in order applicationPages.sort(comparePages); @@ -121,9 +140,12 @@ export function encodeNVM( writeSize = PageWriteSize.WRITE_SIZE_16, memoryMapped = true, } = options ?? {}; + const maxPageSize = options?.sharedFileSystem + ? FLASH_MAX_PAGE_SIZE_800 + : FLASH_MAX_PAGE_SIZE_700; const pageSize = Math.min( - options?.pageSize ?? FLASH_MAX_PAGE_SIZE, - FLASH_MAX_PAGE_SIZE, + options?.pageSize ?? maxPageSize, + maxPageSize, ); const createEmptyPage = (): Buffer => { @@ -141,16 +163,6 @@ export function encodeNVM( return ret; }; - const applicationPages: Buffer[] = []; - for (let i = 0; i < ZWAVE_APPLICATION_NVM_SIZE / pageSize; i++) { - applicationPages.push(createEmptyPage()); - } - - const protocolPages: Buffer[] = []; - for (let i = 0; i < ZWAVE_PROTOCOL_NVM_SIZE / pageSize; i++) { - protocolPages.push(createEmptyPage()); - } - const writeObjects = ( pages: Buffer[], objects: Map, @@ -219,17 +231,45 @@ export function encodeNVM( } }; - writeObjects(applicationPages, applicationObjects); - writeObjects(protocolPages, protocolObjects); + if (options?.sharedFileSystem) { + const pages: Buffer[] = []; + for (let i = 0; i < ZWAVE_SHARED_NVM_SIZE / pageSize; i++) { + pages.push(createEmptyPage()); + } + + const objects = new Map([ + ...applicationObjects, + ...protocolObjects, + ]); + writeObjects(pages, objects); + + return Buffer.concat(pages); + } else { + const applicationPages: Buffer[] = []; + for (let i = 0; i < ZWAVE_APPLICATION_NVM_SIZE / pageSize; i++) { + applicationPages.push(createEmptyPage()); + } + + const protocolPages: Buffer[] = []; + for (let i = 0; i < ZWAVE_PROTOCOL_NVM_SIZE / pageSize; i++) { + protocolPages.push(createEmptyPage()); + } + + writeObjects(applicationPages, applicationObjects); + writeObjects(protocolPages, protocolObjects); - return Buffer.concat([...applicationPages, ...protocolPages]); + return Buffer.concat([...applicationPages, ...protocolPages]); + } } -export function getNVMMeta(page: NVM3Page): NVMMeta { - return pick(page.header, [ - "pageSize", - "writeSize", - "memoryMapped", - "deviceFamily", - ]); +export function getNVMMeta(page: NVM3Page, sharedFileSystem: boolean): NVMMeta { + return { + sharedFileSystem, + ...pick(page.header, [ + "pageSize", + "writeSize", + "memoryMapped", + "deviceFamily", + ]), + }; } diff --git a/packages/nvmedit/src/nvm3/page.ts b/packages/nvmedit/src/nvm3/page.ts index 49fa65f0388a..4e967f1b80a6 100644 --- a/packages/nvmedit/src/nvm3/page.ts +++ b/packages/nvmedit/src/nvm3/page.ts @@ -1,6 +1,5 @@ import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core/safe"; import { - FLASH_MAX_PAGE_SIZE, NVM3_MIN_PAGE_SIZE, NVM3_PAGE_COUNTER_MASK, NVM3_PAGE_COUNTER_SIZE, @@ -42,6 +41,87 @@ export function readPage( buffer: Buffer, offset: number, ): { page: NVM3Page; bytesRead: number } { + const { version, eraseCount } = tryGetVersionAndEraseCount(buffer, offset); + + // Page status + const status = buffer.readUInt32LE(offset + 12); + + const devInfo = buffer.readUInt16LE(offset + 16); + const deviceFamily = devInfo & 0x7ff; + const writeSize = (devInfo >> 11) & 0b1; + const memoryMapped = !!((devInfo >> 12) & 0b1); + let pageSize = pageSizeFromBits((devInfo >> 13) & 0b111); + + if (pageSize > 0xffff) { + // Some controllers have no valid info in the page size bits, resulting + // in an impossibly large page size. To try and figure out the actual page + // size without knowing the hardware, we scan the buffer for the next valid + // page start. + for (let exponent = 0; exponent < 0b111; exponent++) { + const testPageSize = pageSizeFromBits(exponent); + const nextOffset = offset + testPageSize; + if ( + // exactly end of NVM OR + buffer.length === nextOffset + // next page + || isValidPageHeaderAtOffset(buffer, nextOffset) + ) { + pageSize = testPageSize; + break; + } + } + } + if (pageSize > 0xffff) { + throw new ZWaveError( + "Could not determine page size!", + ZWaveErrorCodes.NVM_InvalidFormat, + ); + } + + if (buffer.length < offset + pageSize) { + throw new ZWaveError( + "Incomplete page in buffer!", + ZWaveErrorCodes.NVM_InvalidFormat, + ); + } + + const formatInfo = buffer.readUInt16LE(offset + 18); + + const encrypted = !(formatInfo & 0b1); + + const header: NVM3PageHeader = { + offset, + version, + eraseCount, + status, + encrypted, + pageSize, + writeSize, + memoryMapped, + deviceFamily, + }; + const bytesRead = pageSize; + const data = buffer.subarray(offset + 20, offset + bytesRead); + + const { objects } = readObjects(data); + + return { + page: { header, objects }, + bytesRead, + }; +} + +function tryGetVersionAndEraseCount( + buffer: Buffer, + offset: number, +): { version: number; eraseCount: number } { + if (offset > buffer.length - NVM3_PAGE_HEADER_SIZE) { + throw new ZWaveError( + "Incomplete page in buffer!", + ZWaveErrorCodes.NVM_InvalidFormat, + ); + } + const version = buffer.readUInt16LE(offset); const magic = buffer.readUInt16LE(offset + 2); if (magic !== NVM3_PAGE_MAGIC) { @@ -79,49 +159,19 @@ export function readPage( ); } - // Page status - const status = buffer.readUInt32LE(offset + 12); - - const devInfo = buffer.readUInt16LE(offset + 16); - const deviceFamily = devInfo & 0x7ff; - const writeSize = (devInfo >> 11) & 0b1; - const memoryMapped = !!((devInfo >> 12) & 0b1); - const pageSize = pageSizeFromBits((devInfo >> 13) & 0b111); - - // Application NVM pages seem to get written with a page size of 0xffff - const actualPageSize = Math.min(pageSize, FLASH_MAX_PAGE_SIZE); + return { version, eraseCount }; +} - if (buffer.length < offset + actualPageSize) { - throw new ZWaveError( - "Incomplete page in buffer!", - ZWaveErrorCodes.NVM_InvalidFormat, - ); +function isValidPageHeaderAtOffset( + buffer: Buffer, + offset: number, +): boolean { + try { + tryGetVersionAndEraseCount(buffer, offset); + return true; + } catch { + return false; } - - const formatInfo = buffer.readUInt16LE(offset + 18); - - const encrypted = !(formatInfo & 0b1); - - const header: NVM3PageHeader = { - offset, - version, - eraseCount, - status, - encrypted, - pageSize, - writeSize, - memoryMapped, - deviceFamily, - }; - const bytesRead = actualPageSize; - const data = buffer.subarray(offset + 20, offset + bytesRead); - - const { objects } = readObjects(data); - - return { - page: { header, objects }, - bytesRead, - }; } export function writePageHeader( diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.11.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.11.json index ff1720e42371..8f680ba780c7 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.11.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.11.json @@ -28,7 +28,8 @@ "txPower": 0, "measured0dBm": 3.3, "enablePTI": null, - "maxTXPower": null + "maxTXPower": null, + "nodeIdType": null }, "sucUpdateEntries": [ { @@ -87,6 +88,7 @@ "controlledCCs": [] } ], + "applicationName": null, "applicationData": "a11d19000200001e3212270efd213a04fa1d00020000000000000000fd39277c022e000100000000000000000199445b8fcb3e537977d642e808b6568700000000000000000000000000000000000000000000008756e008a3cc6f339248ef5d663f50e136e12e8fe7432265349446d6c5541bf3c500be6567027beeb0e7712b11e21ddf53d86f0b134c00a3bdcd24963a89ef0d753a35b3033f64d1b759077a24d59b45da0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "lastNodeIdLR": null, "maxNodeIdLR": null, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.12.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.12.json index a6cb369c78cc..fbeb80d746a0 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.12.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.12.json @@ -28,7 +28,8 @@ "txPower": 0, "measured0dBm": 3.3, "enablePTI": null, - "maxTXPower": null + "maxTXPower": null, + "nodeIdType": null }, "sucUpdateEntries": [ { @@ -182,6 +183,7 @@ "controlledCCs": [] } ], + "applicationName": null, "applicationData": "a11d19000200001e321b9884fdec8bdd380e00020000000000000000fd8e8c480f1700010000000000000000014c72cc54358f3dc9ce70ac752beb3e7a0000000000000000000000000000000000000000000000873206e7a00af5746fbc07ba927a6bde014d36396481ce9cce689ceba3f12841d85ffcc430bddb814dad5874aa73866b6a1361c9802cac47fc4df1627838f5857eb334b1bb0a8565a09d46bb8e722ac7910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "lastNodeIdLR": null, "maxNodeIdLR": null, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.15.2.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.15.2.json index b0605fac22f0..5cdc7b73231a 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.15.2.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.15.2.json @@ -35,7 +35,8 @@ "txPower": 0, "measured0dBm": 3.3, "enablePTI": null, - "maxTXPower": null + "maxTXPower": null, + "nodeIdType": null }, "sucUpdateEntries": [ { @@ -176,6 +177,7 @@ "controlledCCs": [] } ], + "applicationName": null, "applicationData": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "sucAwarenessPushNeeded": null }, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.16.2.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.16.2.json index bc0846fb95d7..a8d4c2f6631f 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.16.2.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.16.2.json @@ -1,6 +1,7 @@ { "format": 3, "meta": { + "sharedFileSystem": false, "deviceFamily": 1234, "memoryMapped": true, "pageSize": 1024, @@ -38,7 +39,8 @@ "txPower": 0, "measured0dBm": 3.3, "enablePTI": 0, - "maxTXPower": 14 + "maxTXPower": 14, + "nodeIdType": null }, "sucUpdateEntries": [ { @@ -516,6 +518,7 @@ "controlledCCs": [] } ], + "applicationName": null, "applicationData": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "sucAwarenessPushNeeded": null }, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.17.2.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.17.2.json index b135863ef374..cc712d18d5fa 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.17.2.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.17.2.json @@ -35,9 +35,11 @@ "txPower": 9.9, "measured0dBm": -2.3, "enablePTI": 0, - "maxTXPower": 14 + "maxTXPower": 14, + "nodeIdType": null }, "sucUpdateEntries": [], + "applicationName": null, "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sucAwarenessPushNeeded": null }, @@ -156,6 +158,7 @@ } }, "meta": { + "sharedFileSystem": false, "pageSize": 2048, "writeSize": 1, "memoryMapped": true, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.1.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.1.json index 332a46273fab..74d727c3780f 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.1.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.1.json @@ -35,9 +35,11 @@ "txPower": 9.9, "measured0dBm": 0, "enablePTI": 233, - "maxTXPower": 25.5 + "maxTXPower": 25.5, + "nodeIdType": null }, "sucUpdateEntries": [], + "applicationName": null, "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sucAwarenessPushNeeded": null }, @@ -155,6 +157,7 @@ } }, "meta": { + "sharedFileSystem": false, "pageSize": 2048, "writeSize": 1, "memoryMapped": true, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.2.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.2.json index 8aaa5ae3404b..f9fb554ad65b 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.2.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.2.json @@ -35,9 +35,11 @@ "txPower": 9.9, "measured0dBm": 0, "enablePTI": 233, - "maxTXPower": 25.5 + "maxTXPower": 25.5, + "nodeIdType": null }, "sucUpdateEntries": [], + "applicationName": null, "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sucAwarenessPushNeeded": null }, @@ -155,6 +157,7 @@ } }, "meta": { + "sharedFileSystem": false, "pageSize": 2048, "writeSize": 1, "memoryMapped": true, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.3.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.3.json index 8991129b5d92..a4ec070d94e5 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.3.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.3.json @@ -35,9 +35,11 @@ "txPower": 9.9, "measured0dBm": 0, "enablePTI": 233, - "maxTXPower": 25.5 + "maxTXPower": 25.5, + "nodeIdType": null }, "sucUpdateEntries": [], + "applicationName": null, "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sucAwarenessPushNeeded": null }, @@ -155,6 +157,7 @@ } }, "meta": { + "sharedFileSystem": false, "pageSize": 2048, "writeSize": 1, "memoryMapped": true, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.4.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.4.json index d9721e616135..d9c7d49c4fb8 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.4.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.18.4.json @@ -35,9 +35,11 @@ "txPower": 9.9, "measured0dBm": -2.3, "enablePTI": 0, - "maxTXPower": 14 + "maxTXPower": 14, + "nodeIdType": null }, "sucUpdateEntries": [], + "applicationName": null, "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sucAwarenessPushNeeded": null }, @@ -155,6 +157,7 @@ } }, "meta": { + "sharedFileSystem": false, "pageSize": 2048, "writeSize": 1, "memoryMapped": true, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.0.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.0.json index a06f327c60e1..1f94ce144f10 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.0.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.0.json @@ -35,9 +35,11 @@ "txPower": 9.9, "measured0dBm": -2.3, "enablePTI": 0, - "maxTXPower": 14 + "maxTXPower": 14, + "nodeIdType": null }, "sucUpdateEntries": [], + "applicationName": null, "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sucAwarenessPushNeeded": null }, @@ -155,6 +157,7 @@ } }, "meta": { + "sharedFileSystem": false, "pageSize": 2048, "writeSize": 1, "memoryMapped": true, diff --git a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.1.json b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.1.json index f1ae4979c4b0..3d45963b7cf5 100644 --- a/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.1.json +++ b/packages/nvmedit/test/fixtures/nvm_700_json/ctrlr_backup_700_7.19.1.json @@ -35,9 +35,11 @@ "txPower": 9.9, "measured0dBm": -2.3, "enablePTI": 0, - "maxTXPower": 14 + "maxTXPower": 14, + "nodeIdType": null }, "sucUpdateEntries": [], + "applicationName": null, "applicationData": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sucAwarenessPushNeeded": null }, @@ -155,6 +157,7 @@ } }, "meta": { + "sharedFileSystem": false, "pageSize": 2048, "writeSize": 1, "memoryMapped": true,