From 5f101a4bea09e441afd28b119511a62985a981f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wenkai=20Yin=28=E5=B0=B9=E6=96=87=E5=BC=80=29?= Date: Thu, 23 Jul 2026 14:57:10 +0800 Subject: [PATCH] Update CRDs and CLI to support in-place restore (#10038) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update CRDs(Restore, DataDownload, PodVolumeRestore) and restore create CLI to support in-place restore Signed-off-by: Wenkai Yin(尹文开) --- .../v1/bases/velero.io_podvolumerestores.yaml | 4 ++ config/crd/v1/bases/velero.io_restores.yaml | 11 +++++ config/crd/v1/crds/crds.go | 4 +- .../bases/velero.io_datadownloads.yaml | 28 ++++++++++++ config/crd/v2alpha1/crds/crds.go | 2 +- pkg/apis/velero/v1/pod_volume_restore_type.go | 3 ++ pkg/apis/velero/v1/restore_types.go | 40 ++++++++++++++--- pkg/apis/velero/v1/zz_generated.deepcopy.go | 5 +++ .../velero/v2alpha1/data_download_types.go | 8 ++++ .../velero/v2alpha1/zz_generated.deepcopy.go | 5 +++ pkg/builder/restore_builder.go | 8 +++- pkg/cmd/cli/restore/create.go | 45 ++++++++++++------- pkg/cmd/cli/restore/create_test.go | 6 +++ pkg/controller/restore_controller.go | 7 ++- pkg/controller/restore_controller_test.go | 33 ++++++++++++++ pkg/restore/restore.go | 8 ++-- pkg/util/velero/restore/util.go | 14 ++++-- pkg/util/velero/restore/util_test.go | 15 +++++-- 18 files changed, 207 insertions(+), 39 deletions(-) diff --git a/config/crd/v1/bases/velero.io_podvolumerestores.yaml b/config/crd/v1/bases/velero.io_podvolumerestores.yaml index 015d143fe..2eea696c2 100644 --- a/config/crd/v1/bases/velero.io_podvolumerestores.yaml +++ b/config/crd/v1/bases/velero.io_podvolumerestores.yaml @@ -132,6 +132,9 @@ spec: repoIdentifier: description: RepoIdentifier is the backup repository identifier. type: string + restoreType: + description: RestoreType indicates the type of the restore. + type: string snapshotID: description: SnapshotID is the ID of the volume snapshot to be restored. type: string @@ -167,6 +170,7 @@ spec: - backupStorageLocation - pod - repoIdentifier + - restoreType - snapshotID - sourceNamespace - volume diff --git a/config/crd/v1/bases/velero.io_restores.yaml b/config/crd/v1/bases/velero.io_restores.yaml index 89f4baff8..0ba22b4a3 100644 --- a/config/crd/v1/bases/velero.io_restores.yaml +++ b/config/crd/v1/bases/velero.io_restores.yaml @@ -69,6 +69,11 @@ spec: for the Kubernetes resource to be restored nullable: true type: string + existingVolumeDataPolicy: + description: ExistingVolumeDataPolicy specifies the restore behavior + for the volume data to be restored + nullable: true + type: string hooks: description: Hooks represent custom behaviors that should be executed during or post restore. @@ -471,6 +476,12 @@ spec: description: UploaderConfig specifies the configuration for the restore. nullable: true properties: + deleteExtraFiles: + description: |- + DeleteExtraFiles specifies whether to delete the extra files in the target volume that do not exist in the backup. + This setting is only applicable to File System restores (PodVolumeBackup or CSI File System Data Move) and has no effect on Block Data Move restores. + nullable: true + type: boolean parallelFilesDownload: description: ParallelFilesDownload is the concurrency number setting for restore. diff --git a/config/crd/v1/crds/crds.go b/config/crd/v1/crds/crds.go index 5ecc27bcc..20c3f3caf 100644 --- a/config/crd/v1/crds/crds.go +++ b/config/crd/v1/crds/crds.go @@ -35,8 +35,8 @@ var rawCRDs = [][]byte{ []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcVK\x8f\xdb6\x10\xbe\xfbW\f\xd0k%wQ\xb4(tk69,\xda\x06\xc6n\x90;M\x8e-f)\x92\x9d\x19z\xeb>\xfe{AR\xf2C\xb67\xc9%\xba\x99\xf3\xe4\xf7\xcd|t\xd34\v\x15\xedG$\xb6\xc1w\xa0\xa2ſ\x04}\xfe\xc5\xed\xf3/\xdcڰ\xdc\xdd-\x9e\xad7\x1d\xdc'\x960<\"\x87D\x1a\xdf\xe2\xc6z+6\xf8ŀ\xa2\x8c\x12\xd5-\x00\x94\xf7AT>\xe6\xfc\x13@\a/\x14\x9cCj\xb6\xe8\xdb\xe7\xb4\xc6u\xb2\xce \x95\xe4S\xe9\xdd\x0f\xed\xdd\xcf\xedO\v\x00\xaf\x06\xec\xc0\xa0C\xc1\xb5\xd2\xcf)\x12\xfe\x99\x90\x85\xdb\x1d:\xa4\xd0ڰ\xe0\x88:\xe7\xdfRH\xb1\x83\xa3\xa1Ə\xb5k\xdfoK\xaa7%\xd5cMU\xacβ\xfcv\xcb\xe3w;zE\x97H\xb9\xeb\r\x15\a\xee\x03\xc9\xfbc\xd1\x06̚\xaa\xc5\xfamr\x8a\xae\x06/\x00X\x87\x88\x1d\x94ب4\x9a\x05\xc0\bH\xc9Հ2\xa6@\xac܊\xac\x17\xa4\xfb\xe0\xd2\xe0\x8f\x95\x905\xd9(\x05\xc2\x0f=\x96\xcbC\u0600\xf4\b\xb5\x1cH\x805\x8e\x1d\x98\x12\a\xf0\x89\x83_)\xe9;h3\x92mu͍\x8c\x0e\x95\x847\xf3c\xd9\xe7\x86Y\xc8\xfa\xed\xad\x16X\x94$\x9e\x9a(um\xf0@'ȟ7P\xfc\xdb\xd8+>\xaf\xfeT\f\xb7*W\x9f\xdd]EZ\xf78\xa8n\xf4\r\x11\xfd\xaf\xab\x87\x8f?>\x9d\x1d\xc3y\xafWH\aˠ\xa6N3p\x155\b\x1e!\x10\f\x81&T\xb9=$\x8d\x14\"\x92؉\xff\xfa\x9d\xac\xd5\xc9鬅\x7f\x9b3\x1b@\xee\xbaF\x81\xc9\xfb\x85\\@\x1c\x87\x02\xcdx\xd1\n\xaee \x8c\x84\x8c\xben\\>V\x1e\xc2\xfa\x13jig\xa9\x9f\x90r\x9a<\xaeə\xbc\x96;$\x01B\x1d\xb6\xde\xfe}\xc8\xcd\xf9\u07b9\xa8SR \xc9c畃\x9dr\t\xbf\a\xe5\xcd,\xf3\xa0\xf6@\x98kB\xf2'\xf9J\x00\xcf\xfb\xf8#\x83h\xfd&tЋD\xee\x96˭\x95Ilt\x18\x86\xe4\xad\xec\x97E7\xec:I ^\x1aܡ[\xb2\xdd6\x8ato\x05\xb5$¥\x8a\xb6)\x17\xf1Ep\xda\xc1|G\xa3<\xf1Yً\xe9\xa9_ч\xaf\xa0'\xabE\x9d\x91\x9a\xaa^\xf1\xc8B>\xca\xd0=\xbe{\xfa\x00S'\x95\xa9J\xca\xd1\xf5\x02\x97\x89\x9f\x8c\xa6\xf5\x1b\xa4\x1a\xb7\xa10\x94\x9c\xe8M\f\xd6K\xf9\xa1\x9dE/\xc0i=X\xe1ib3u\xf3\xb4\xf7E\x90\xb3\x02\xa4h\x94\xa0\x99;b\xa3\x13Q\x19\xbe\x83ΫkA_\x8a\x05\x12\x05\xba8\x9d5\xf5\xae8\x95\xff\x12\xcaz\x06\xe5\xf7c H\xaf\x04^\x90\xf2\x86萲Z\xa1\x01\x93.\xf0\x1ba9}\x93\"\x05\x8d|\xb1\x8a\x00Vp\xb8\xd2\xd3+\xec\xe4\xcf'\xe7\xd4\xdaa\aB\to0\xab\x88\xd4~f+o\xdfg Xe\x9fk\x1c\x1c\xde\xfbϒP\xe0\xf6i\xb8\xac\xd4\xc0{|\xb9r\xfa\xe0W\x14\xb6\x84<\x1f\xf9l\\U\xf4p\xfe\x1e\xbc\x82\xd2ա\xbc8\xe4,\x85\xe6\x04E\x96@j{\x8a+\xa7\xf5A\xe9;\xf8\xe7\xbf\xc5\xff\x01\x00\x00\xff\xffߙ6&\xcb\n\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcW\xcdn\xe36\x10\xbe\xfb)\x06\xe8\xa5\x05Vr\x83\xa2E\xe1[\xeb\xec!\xd8t\x1b\xc4\xdb\xdc)j$\xb1\xa1H\x96\x1c:\x9b\xa2\x0f_\f)\xf9G\x96\x1d粺y8\x9c\x9fof\xbe\xa1\x8b\xa2X\b\xa7\x9e\xd0\ae\xcd\n\x84S\xf8\x95\xd0\xf0\xafP>\xff\x1aJe\x97ۛų2\xf5\n\xd61\x90\xed\x1f1\xd8\xe8%\xdeb\xa3\x8c\"e͢G\x12\xb5 \xb1Z\x00\bc,\t\x16\a\xfe\t \xad!o\xb5F_\xb4h\xca\xe7Xa\x15\x95\xae\xd1'\xe3\xa3\xeb\xed\x8f\xe5\xcd/\xe5\xcf\v\x00#z\\Am_\x8c\xb6\xa2\xf6\xf8O\xc4@\xa1ܢFoKe\x17\xc1\xa1dۭ\xb7ѭ`\x7f\x90\xef\x0e~s̷\x83\x99\xc7l&\x9dh\x15\xe8\xd3\xdc\xe9\xbd\x1a4\x9c\x8e^\xe8\xd3 \xd2a謧\xcf{G\x05\xf0y>R\xa6\x8dZ\xf8\x93\x9b\v\x80 \xad\xc3\x15\xa4\x8bNH\xac\x17\x00C\xf6\xc9P1$\xbe\xbdɦd\x87\xbd\xc8\x1e\x00\xacC\xf3\xdb\xc3\xdd\xd3O\x9b#1@\x8dAz\xe5(a\xf8_\xb1\x93\xc347P\x01\x04\f\xe1\x00\xd9]\x84 \f\bO\xaa\x11\x92\xa0\xf1\xb6\x87J\xc8\xe7\xe8\xc0V\x7f\xa3$\bd\xbdh\xf1\x03\x84(;\x10l%+\x1c\xf8Ҷ\x85Fi,w2\xe7\xadCOj\x04)\x7f\a\xbdv \xbd\x94\x05\x7f\x9cx\xbe\x0557\x1d\x06\xa0\x0eG\xf0\xb0\x1e\xb0\x02\xdb\x00u*\x80G\xe71\xa0\xc9m\xc8ba\x86lʉ\xe9\rz6\xc35\x8d\xba\xe6^ݢ'\xf0(mkԿ;ہ\x11c\xa7ZP\x02\xd3\x10z#4l\x85\x8e\xf8\x01\x84\xa9'\x96{\xf1\n\x1e\x13\x82\xd1\x1c\xd8K\x17\xc24\x8e?\xacGP\xa6\xb1+\xe8\x88\\X-\x97\xad\xa2q\x02\xa5\xed\xfbh\x14\xbd.\xd30\xa9*\x92\xf5aY\xe3\x16\xf52\xa8\xb6\x10^v\x8aPR\xf4\xb8\x14N\x15)\x11\x93\xa6\xb0\xec\xeb\xef\xfc0\xb3\xe1\xc8-\xbdrC\x06\xf2ʴ\a\aip\xdeQ\x1e\x1e\xa5\xdc]\xd9TNq_\x05\x161t\x8f\x1f7_`\x8c$Wjh\xb1\x9d\xea\t.c}\x18Me\x1a\xf4\xf9^jS\xb6\x89\xa6vV\x19J?\xa4Vh\bB\xaczEa\xecu.\xdd\xd4\xec:\xb1\x14T\b\xd1Ղ\xb0\x9e*\xdc\x19X\x8b\x1e\xf5Z\x04\xfcƵ⪄\x82\x8bpU\xb5\x0e\xb9w\xaa\x9c\xe1=8\x18\x99\xf3Li'\x94\xb1q(\xb9\xb0\x8c-\xdfT\x8d\x92y\xa4\x1a\xebA\xec\x19d@\xfa\x18\xa8y\x06H\xc1\t\xdf\"M\xa5\x93X\xbe$%v\xff҉c\xc2\xfa\x1e˶d\xce\tC \x99\x8f~\x98\x16\xeaR\f0\xdb賑\x8c\xfd\xcd00\xaeL(Lv\x871\x9d\xba\xe6\x0fM\xec\xe7\x1d\x14\xf0{\x8a\xf9\u07b6\x17\xcf\xd7\xd6\x10\xcf\xc5E\xa5'\xabc\x8f\x1b#\\\xe8\xec\x1b\xbaw\x84\xfd\x9f\x0e}\xde\xd0\x17U\xc7E\xbfۊ\x17\x14\xa3>\xeb\xf7\x11y\x83\xe0\xf9L\a\x85\xab\xac\\\x11ӠyU\xa2\xeb\xcd\xdd{ <\xa3\xfe\x8e\"ݙƾ\x91\xe2^qV\xef\f\r\x8c_zC\xbc\xdd\xd3\xfc\n\x19{\x9a\xaf\xe4݉\xf0)V\xe8\r\x12\x86=S\xbf(\xeaf-\x02\xbctJv\xe9b\x1a\b^\x02!X\xa9\xe6(\xf5\x8a\xf0\x99G\x94Ǚ\xa1,ҰΈ9\xf8\x13\xf1\x19\xf6;\xe7\xa0\x18\x18\xe9*\x06%A1\xbc\x83C\x93\xfe\b\xb5\x8cާ\x15\x95\xa5\xfc2\x99^\xb8\x96DG\xe6\xf9\xeb\xf1\xfe\r&\xbd\xddk\xa6ǸP&G\xe3<\x16A\xb5\xfc\x82\xe23\xe6\xd2\xc4q\xa7`\xe4\xef\xf8\x85w\f\xd4lE\xf1\xabSy\x00\xdf\b\xf1\xe3N1\x13>\x9a\xbc\xe7\xa7o\xd8d\x10\x03?\xb7@\n3\x13c\x85P\xa3F\xc2\x1a\xaa\u05fc\xb9^\x03a\x7f\x1awc}/h\x05\xbc\xff\vR3md\xa2֢Ҹ\x02\xf2\xf1\\\x97\xcd&\xee:\x11f\xc6\xf0(\xe7\a֙k\x8c\xdd0^\xec\f8\xbb_\n\xf8\x8c/3\xd2\ao%\x86\x80\xa7ct6\x93\xd9!8\x11\x06~\xa4\xd5\a(\r\x7f\x19\x06\xc9\xff\x01\x00\x00\xff\xff\xe5\x0fY\x99e\x0e\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4:K\x93\x1b\xb7\xd1\xf7\xfd\x15]\xeb\x83\xed*\ri\xf9\xfb\xe2J\xf1&\xad\xe2\x14\x13[\xd9\x12W\xba\xb8|\xc0\f\x9a\x1cxg\x00\x04\xc0\x90b\x1c\xff\xf7T\x03\x987H\xeeR\xb6\x85\xcb.\xf1h\xf4\xfb\x85ɲ\xec\x86i\xf1\x01\x8d\x15J\xae\x80i\x81\x1f\x1dJ\xfae\x17\x8f\x7f\xb5\v\xa1\x96\xfb\x977\x8fB\xf2\x15\xdc5֩\xfa\x1dZ\u0558\x02\xdf\xe0VHᄒ75:ƙc\xab\x1b\x00&\xa5r\x8c\xa6-\xfd\x04(\x94tFU\x15\x9al\x87r\xf1\xd8\xe4\x987\xa2\xe2h<\xf0\xf6\xea\xfd7\x8b\x97\xdf-\xfer\x03 Y\x8d+Њ\xefU\xd5Ԙ\xb3\xe2\xb1\xd1v\xb1\xc7\n\x8dZ\buc5\x16\x04{gT\xa3W\xd0/\x84\xb3\xf1ހ\xf3\xbd\xe2\x1f<\x98\xd7\x1e\x8c_\xa9\x84u\xffL\xad\xfe \xac\xf3;t\xd5\x18V͑\xf0\x8b\xb6Tƽ\xed/\xca@\xef\xf3\xb0\"䮩\x98\x99\x1d\xbc\x01\xb0\x85Ҹ\x02\x7fN\xb3\x02\xf9\r@$\xde\xc3ɀq\xee\xd9ɪ{#\xa4CsG\x10dw\vG[\x18\xa1\x9dg\xd7\x04s\xb0\x8e\xb9Ƃm\x8a\x12\x98\x85\xb7xX\xae\xe5\xbdQ;\x836\xa0\r\xf0\x8bU\xf2\x9e\xb9r\x05\x8b\xb0}\xa1Kf1\xae\x06\xb6o\xfcB\x9crGB\xd9:#\xe4.\x85ă\xa8\x11xc\xbc\xb8\x89\xfa\x02\xc1\x95\xc2ΰ;0K\x18\x1a\xe7\xc9N\xe3\xe2\xd7\t\xa2u\xac\xd6S\xa4\x06G\x03V\x9c9L\xe1t\xa7j]\xa1C\x0e\xf9\xd1aK\xc9V\x99\x9a\xb9\x15\b\xe9\xbe\xfb\xff\xd3\xec\x88\xfcZ\xf8\xa3o\x94\x1c\xf3\xe65\xcd\xc2`:`B\xb2ڡI2H9V}\n\"\x8e\x00\xbc\x1e\x9c\x0f\x98\x04\xb8\xc3\xf9\x8b\xa8\xacea\xb0Fy\x1dB\xa2?=\xc7f\bz\xb8\xaa\x8dPF\xb8\xe3\n^~\xf3T4\xc9>@m\xc1\x95\bQy6N\x19\xb6C\xf8A\x15A\xd1\x0e%\x9a\xa8hy\xd4\xfeR5\x15\x87\xbc\x15\f\x80u\xca$\x95Mc\xb1\b\xa7\"\xdc\x16\xecD\xe3\xc6w\xfe\x11\x06Q\x18dI\x83h\xdd\xe9\xc2\xef\x10J\xa6\xad\xe2\xd5\x0e\x9fd\x11C\x96Jű\xe3\x1f\xce\xd0\x12\x16\xb4Q\x05Z{\xc6P\t\xc6\b\x91\xb7\xfd\xc4E\x06\x95\xe8\xf7\xb4\xf84\xbaR\x8c\xa3\x01\xa7\xa0d\x92WHd0p\x86I\xbb\x8d*2\x17`{\xec\xe1\xa8Ǩ\xbc\x8f\v\xa7\xd0\t\xbb\xf6/\x83\xbb.J\xac\xd9*\xeeU\x1a\xe5\xab\xfb\xf5\x87\xffی\xa6I\x8d\x95F\xe3D\xeb\xef\xc3\x18\x84\xcd\xc1,\x8c\xc9\xfdo6Z\x03\xa0\v\xc2)\xe0\x14?\xd1z6\xc4@\x80<\xe2\x14\xd8#,\x18\xd4\x06-\x99\x96\xd7(\xb5\x05&A\xe5\xbf`\xe1\x16\x13\xd0\x1b4\x04\xa6\xb5\x85B\xc9=\x1a\a\x06\v\xb5\x93\xe2?\x1dlK\xbc\xa6K+\xe6\xd0:o\x8cF\xb2\n\xf6\xacj\xf0\x050\xc9'\x90kv\x04\x83t'4r\x00\xcf\x1f\xb0S<~T\x06AȭZA霶\xab\xe5r'\\\x9bL\x14\xaa\xae\x1b)\xdcq\xe9\xf3\x02\x917N\x19\xbb\xe4\xb8\xc7ji\xc5.c\xa6(\x85\xc3\xc25\x06\x97L\x8b\xcc\x13\"}B\xb1\xa8\xf9\x17&\xa6\x1fvt\xedL\xd0a\xf8\x1c\xe0\x19⡬\x80\x8c\x80EP\x81\xc4^\n4E\xac{\xf7\xb7\xcd\x03\xb4\x98\x04I\x05\xa1\xf4[g|i\xe5C\xdc\x14rK:O\xe7\xb6F\xd5\x1e&J\xae\x95\x90\xce\xff(*\x81ҁm\xf2Z8R\x83\x7f7h\x1d\x89n\n\xf6\xce'\\\x90\x93-\x91\a\xe0\xd3\rk\tw\xac\xc6\xea\x8eY\xfc\x93eER\xb1\x19\t\xe1I\xd2\x1a\xa6\x91\xd3́\xbd\x83\x856\t\x13\x86a\xc6;%:W\xaaB6\xe5%\x85\xbb\v4S\x00L\t\xcbG[W2\xd7\xe2F\x9bL#圷4\x94|\x968\xb4\xe2\x17\xf0\x8a720\xb8E\x83>\x1b\t\xbe_+\x1f!\x1c\x13\xb2\xf5i\xa1^\x01\xa7\x12\x98\xe5A\x89\x90\xc3\xd46\xe0\xac}\xc0\x99@\x99\xc4\xf8\xd5\xfd\xba\r\x86-\x13#\xee\xb3xw\x91?4\xb6\x02+\xee3\x87\xcbw'5\x97\xc6z\x1b\x90\xf0\x11\xc1)`\xa0\x05\x168\x8a\xc6 \xa4u\xc8x\x9c$'h0\xae\xbd\b\x9e\xfe$\x92\x10\x8a\xca\x18\xb5I&\xc0(\xf2\b\x0e\xff\xd8\xfc\xeb\xed\xf2\xef*\xd0\x01\xac\xa0\xd4\xcc\xd7z>\xdf~\xd1\xd5{\x1c\xad0ȩz\xc3Eͤآu\x8b\b\r\x8d\xfd\xe9۟\xd3\xfc\x03\xf8^\x19\xc0\x8f\x8c\xaa\xa6\x17 \x02ϻ`֪\x8d\xb0\x81\xf0\x0e\"\x1c\x84+=\xa2Z\xf1H\xe0\xc1\x93\xe0\xd8#Yr \xa1A\xa8\xc4c\xc2~¸\xf5\xd9\\\x8f\xe6\xafd=\xbf\xdd\xc2W\xc1y\xdd\xd2\xcfۀF\x97\xb6\f\r\xacG'X\x99\x11\xbb\x1d\xf6y\xffLY(\xccR\x80\xfa\x1a\x94!Z\xa5\x1a\x80\xf0\x80IN!> \x9f\xa1\xf7ӷ?\xdf\xc2Wc\x1e\x9c\xb8JH\x8e\x1f\xe1[\xf2>\x9e7Z\xf1\xaf\x17\xf0\xe0\xf5\xe0(\x1d\xfbH7\x15\xa5\xb2(A\xc9\xea\x18\x12\xe0=\x82U5\xc2\x01\xab*\v\t\"\x87\x03;\x82ڞ\xb8\xa7\x15\x11\xa9&\x03͌;\x9b$F>\x9c7\x9ay\xd6Ԏ\xa7ًϢ\x9ed\xbd\x9f-\x03y\"'|\xb9\xf0\t\x9c\x18\x96^Wp\xe2\xb1\xc9\xd1Ht\xe8\x99\xc1Ua\x89\x0f\x05jg\x97j\x8ff/\xf0\xb0<(\xf3(\xe4.#ê\xd4\xed\xd2\xf7\xc1\x96_\xf8?\xd7\x12\xee\xdbT\x9fJ\xbd\a\xf2\xf9X@\xb7\xdb\xe55\x1ch\xb3\xfb\xa7Ǯ\x93|\xd8Ąs\n\x93l\xfeP\x8a\xa2lk\xbd\x81\xb7\xad\x19\x0f\xee\x98\xc9\xe3g\xb2\x1d\xe2sc\b\xa3c\x16\x9b\xb8\x19\x93\x9c\xfe\xb7\xc2:\x9a\xbf\x86\xb1\x8d\xf8$\xe7\xf2~\xfd\xe6sZT#\xae\xf1$'j\x980>f=VY\xcdt\x16v3\xa7jQLvS\x0e\xbf\xe6$\xa4\xad@s!\xfd{7\xda\xdc&\xa8\x89j\xa0\xdb\xf3\xac\xfcӱ]\"\xe1\x1bv\xb1ϥ\x85g\xf9uY\x15\x1e\xd8\xce\x023\b\fj\xa6I#\x1e\U0005814cC3A\xe9\x02e\x04]c\x10\x98\xd6\x15\xc5\xf4\x90E$ \xc6\xfc7\xb2\x87YO\xdf)\x86$E\xd9v\xa56蜐\x9f\x919\xef'\x88\xfc\xbe\x8c\xeazv\x85\x92[\xb1\x8b\xdd\xce9\xa7dSU,\xafp\x05\xce4\xa7j\xae\xb3\x8c|\xa0-\xe7\xe9\x7f?\xd8\xdaj\xf8\x85\x06c\x9a\xaaQ\xdbqN\fʦ\x9e\xa3\x92\xc1\xa3҂%\xe6\rZ7\xb3^Z\xb8\xbd}\x8e\x8d\x05\xa5\xbc\xa6\xe4\x0eep\xaa*\x8d\x8a\x1e\x13\xf8\xb62u\xaa\xaf\xf2\x92B\x7f\x86o\xa0\xea\x9eʑ1\xdeY\xba]2\xd93\xe8.\xb7SZ\xf1\xc9\xcc\xd8\rN\x16\x03}O\xea!\xf9\x86\xf63\xbaH\xe1\x91-\xf24\x04G\xd7>\xbdQ\xda}m\x1f\x89\n;\xed\x90w\x8d\xfek$\xfej\n\xc4\xf7~\r\x8fF!j\xecJ\xff\xb1\xaf\v\xc5]\x8e\xa0\rj\x96\xec\n\x81\xef\xdc[\xdf\xc2\xfc\xd2\x06`\xc2Bc\x91\xfb\x0e\xda\xec\xee\x19\x84\xf6\x9d\x893\x87\x19\x9d\xbf\xce_\xa4\x1bS\xe1\xcdo\xf8RrU\x97j\x0ef\xceB\xd6r\xcd?ᴏ\x8d)\x8e\xf5\xe0:~\x05h\xc8}\x15JE\xf2\x96\x89\n9\xb4o\xdcτ\x92\xe3\x96R\x9c\xe0\xe3\xda>ND\xeft\xfdw^\x92\t&\xcc\x13\x9e?R\x98ӧ\xc6\v\x92\\O\xb6C\xa9\xaa(/\xd9\xd49\x1a2L\xff\xe0\t\x12\x0fT\xf7\x17%\x93\xbb\xa4\x93k\x1f\xec\x10*f\x1d\xe4\xfd'\x03)\xe2\x87/\xa6Sʆ/\x9c\xfd\xa8\xd1Z\xb6\xbb\xe4\xce\x7f\f\xbbB\xe7.\x1e\x01\x96\xabƥ\xed\xf7K\x1b]\xd0\xf3\xba\x87ɦ\xd8\xd8\xfb1W\xb6\xcen\xdbT\x95?3\x8c\x1b\xfd\xa7\x1d\x1e\xab\x1c\xd3\x19\xff\x99\xd6\xe19\x04Kf/\xb1\xea\x9e\xf6\xa4\xfcq\x17\xec\xce:d8\x13\xd8\xdf\xe2!1\xdb\xfa\xb9\xc4\xd2}t\x9e\x89\xa5ٗ\x18\xc3\xc5\xd0\x1bOq\xae]K\xc2\xec\xbesH\xac}\xef\xbdʳ\x98\x1d\xf1\xbb\xc6mv\xbd\xf5\xde\xf2\xfcg\v3\xfb\x1b\xe7\x1fL\xf2\xa1\xd8RM\x88\xfe|\xabA\x01Rl\xa4\xc5'\x01ﺜ\x02.\xac\xaeر\xa3ŗ~d\xaa\xe9\xf7\x91ޢZ\x8f\xa9\xf1T*{\xbe\xc3\xdd}-\x92\xaek\xcf\xfb\v\xb8\xe03\xfc\xba:\xed\f\x7f\x8f\x1bΤ\xe2V2mK\xe5\xd6o.\xa8Ʀ\xdb\xd8\xdac_V\xfa\xc0\xe2\x9f\xde⦨\n\tT{\xef\xf6,g1\xfex\xe8\x1a-ތ \\\x88\xfb\xf1[\xa6Ttݐ\x17 \a\xe4\x1fv\xef\xa6_p\xbc\xe8\x82\fs\xb1A\x1e\xe2Q\xaa\xab\xa0\xa4\xaf#\x94\x99\xbf\xb2\xc3\xc5@>&\xe8ό\xe1Iu\x9aMz\xcc\xf9\x00v|\xd3\x1c\xce4y\xf7ܿ\x82_\x7f\xbb\xf9_\x00\x00\x00\xff\xff\xfc¬w\xb0(\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4Z͒\x1b\xb7\x11\xbe\xefSt\xad\x0f\xb6\xab4d\xa4$\xae\x14o\xd2*Nmbo\xb6DI\x17\x97\x0f\xe0\xa09\x03s\x06\x80\x01\f\xb9\xb4\xe3wO5\x80\x19\xce\x0fH.\xa9\x925\x17i\xf1\xd3\xf8\xf0u\xa3\xbb\xd1`\x96e7L\x8b\x8fh\xacPr\x01L\v|r(\xe9/;\xdb\xfc\xc3΄\x9ao_\xdel\x84\xe4\v\xb8k\xacS\xf5;\xb4\xaa19\xbeŵ\x90\xc2\t%ojt\x8c3\xc7\x167\x00LJ\xe5\x185[\xfa\x13 W\xd2\x19UUh\xb2\x02\xe5lӬpՈ\x8a\xa3\xf1\xc2ۥ\xb7\x7f\x99\xbd\xfcn\xf6\xf7\x1b\x00\xc9j\\\x80V|\xab\xaa\xa6F\x83\xd6)\x83v\xb6\xc5\n\x8d\x9a\tuc5\xe6$\xbc0\xaa\xd1\v8t\x84\xc9q\xe1\x00\xfaQ\xf1\x8f^λ \xc7wUº\xff$\xbb\x7f\x10\xd6\xf9!\xbaj\f\xab\x128|\xaf-\x95q\x0f\x87\xb52\xd0[\x13z\x84,\x9a\x8a\x99\xe9\xcc\x1b\x00\x9b+\x8d\v\xf0\x135ˑ\xdf\x00D\x06\xbc\xa0\f\x18\xe7\x9eSV=\x1a!\x1d\x9a;\x12!\xbbe8\xda\xdc\b\xed\xd3%\xb3\x18{\x03\xf9K\xdf\x11\x9bܞ0[g\x84,R(ދ\x1a\x817\xc6+\x9d\xf6\x9f#\xb8R\xd8)\xbc\x1d\xb3\x04\xd18\xbf\xf14\x18\xdfO\"\xadc\xb5\x1e\xa3\xeaM\r\xb08s\x98\x02u\xa7j]\xa1C\x0e\xab\xbd\xc3v+kej\xe6\x16 \xa4\xfb\xeeo\xc7\xf9\x88\x84\xcd\xfcԷJ\x0e\xc9yC\xad\xd0k\x0eHH[\x05\x9a$Cʱ\xeaS\x808\x12\xf0\xa67? \tr\xfb\xedg\xa1\x90\xe9\x81Z\x83+\x11ް|\xd3hX:eX\x81\xf0\x83ʃ\nw%\x1a\xf4#Va\x04\x9dm\x10\xa4;e\x92\xaaӘ\xcf\xc2\xd8(\xac\x955\xd2\xdfp\xa1\xcfb_\xb9A\x96\xb4\xaf\xd6I\xcd\xfc\b\xa1d\xda\xc8^\x17\xf8,\x03\xeb\x13)\x15\xc7\x1ek\x13\\\u00826*GkO\x18>\t\x19 y84\x9c\xa5\xa8D?\xa6\x05\xd4\xe8J1\x8e\x06\x9c\x82\x92I^aС3L\xdau\xb4\x8c\xa9\n\xdbi\xef\xf7z\b\xe5C+\xaf\xd73\xc1\x14\x86n_\x067\x98\x97X\xb3E\x1c\xab4\xca\u05cf\xf7\x1f\xff\xba\x1c4\x03Ѣ\xd18\xd1\xfa\xd1\xf0\xf5BR\xaf\x15\x86{\xfe_6\xe8\x03\xa0\x05\xc2,\xe0\x14\x9b\xd0z.\xa2\x7fE\x1e1\x05\x8e\x84\x05\x83ڠE\x19\xa2\x1553\tj\xf5\v\xe6n6\x12\xbdDCb\xc8\xed7\x15\xa7\x90\xb6E\xe3\xc0`\xae\n)~\xebd[\"\x9c\x16\xad\x98C\xeb\xfcA4\x92U\xb0eU\x83/\x80I>\x92\\\xb3=\x18\xa45\xa1\x91=y~\x82\x1d\xe3\xf8\xd1[\x93\\\xab\x05\x94\xcei\xbb\x98\xcf\v\xe1\xda@\x9d\xab\xban\xa4p\xfb\xb9\x8f\xb9b\xd58e\xec\x9c\xe3\x16\xab\xb9\x15E\xc6L^\n\x87\xb9k\fΙ\x16\x99߈\xf4\xc1zV\xf3\xafL\f\xedv\xb0\xecD\xd1\xe1\xf3\xe1\xf5\x02\xf5P\xbc\xa5\x93\xc0\xa2\xa8\xb0Ń\x16\xa8\x89\xa8{\xf7\xcf\xe5{h\x91\x04M\x05\xa5\x1c\x86Nxi\xf5Cl\n\xb9&çyk\xa3j/\x13%\xd7JH\xe7\xff\xc8+\x81ҁmV\xb5pd\x06\xbf6h\x1d\xa9n,\xf6\xce'3\xb0\xa2\x03E~\x80\x8f\a\xdcK\xb8c5Vw\xcc⟬+Ҋ\xcdH\t\xcf\xd2V?E\x1b\x0f\x0e\xf4\xf6:\xda\xfc\xea\x88j\xc7\xfem\xa91'\xcd\x12\xb94U\xacE\x8c$ke\x80M\xc6\x0f\x99J\xbb\x00\xfa\x92\x11e<\xe8\x9c\xd9\xd1\xf7&%\xa8E,{\x8e<\xc6;\x1b\x03U5\fT\xfdo\x12#\rje\x85Sf\x7f\x88\x94c\x938\xaa\x1d\xfar&s\xac\xae\xd9ޝ\x9f\tBr\xe2\x1d;\x93&g\x14\xa4z\xa0J\x16\x8a\x0e\xd9D\x1dp\xefh\x1cٹE\x97ެ<\x1aل\x84C\x8e\t\xfd\\r\xbc\xed\x95R\x15\xb21\x9bZ\xf13\x9b~T\xd1q\x18\\\xa3A\x1f\xff\x83\x9b\xd5\xca;cDŽl\xddGH\xb9\xc1\xa9\xc4>V\xe4n\x8e\xa9\xe6\xb8\x1d\u0089\x90\x94\x04\xfc\xfa\xf1\xbe\r;\xadeE\xe8\x93\xc8\xd2\xe7'i\x16\xf4\xad\x05V\xdc\a\xea\xf3k'-\x84\xbe\xfbu\x00\xe1}\xafS\xc0@\v\xccq\x10\xf7@H\xeb\x90\xf1\xd8H\xee\xc6`\xec{\x11|\xeaQ\x90\x10\xaeE1>\x92J\x80\x91\x8f\x17\x1c\xfe\xbd\xfc\xef\xc3\xfc_*\xec\x03XN\x99\x90\xbf\xab`\x8dҽ\xe8\xee+\x1c\xad0\xc8\xe9\xf6\x81\xb3\x9aI\xb1F\xebfQ\x1a\x1a\xfbӫ\x9f\xd3\xfc\x01|\xaf\f\xe0\x13\xa3\xa4\xff\x05\x88\xc0y\x176Z\xab\x116l\xbc\x93\b;\xe1J\x0fT+\x1e7\xb8\xf3[plC'&l\xa1A\xa8\xc4\x06\xd3\xec\x03\xdc\xfa\xe4\xe9\x00\xf3wr)\x7f\xdc\xc27\xc1I\xdcҟ\xb7\x01F\x97 \xf4\xbd\xce\x01\x8e+\x99\x03gDQ\xe0!ў\x18\v\x054\n\x05߂2\xb4W\xa9z\"\xbc`\xd2Sp\xc4\xc8'\xf0~z\xf5\xf3-|3\xe4\xe0\xc8RBr|\x82Wt\xc6=7Z\xf1og\xf0\xde\xdb\xc1^:\xf6D+奲(A\xc9j\x1f\xf2\xcd-\x82U5\xc2\x0e\xab*\v\xa9\x18\x87\x1dۃZ\x1fY\xa7U\x11\x99&\x03͌;\x99\x8eE\x1eN\x1f\x9ai~\xd2~\xcf;/>_y\xd6\xe9\xfdb\xb1\xfe\x99L\xf8\xc4\xfc\x13\x98\xe8_u\xae`bӬ\xd0Ht\xe8\xc9\xe0*\xb7\xc4C\x8e\xdaٹڢ\xd9\n\xdc\xcdw\xcal\x84,22\xc6,h\xdd\xce}1g\xfe\x95\xff\xe7ڍ\xfb:˧\xee\xde\v\xf9r\x14\xd0\xeav~\r\x03m\x1e\xfd\xfc\xd8u\x94\x87e\xcc\xec\xc62\xe9\xcc\xefJ\x91\x97\xed\xad\xaa\xe7mkƃ;fr\xff\x85\xce\x0e\xf1\xdc\x18B\xb4\xcfb)2c\x92\xd3\xff\xad\xb0\x8eگ!\xb6\x11\x9f\xe4\\>ܿ\xfd\x92'\xaa\x11\xd7x\x92#\xb7\x85\xf0=e\aTY\xcdt\x16F3\xa7j\x91\x8fFS\xae|\xcfIIk\x81\xe6L\xf6\xf7n0\xb8\xcd\xda\x13Yw7梴\xdbJ\xa6m\xa9\xdc\xfd\xdb38\x96\xdd\xc0\x16\xc3A\x871\xe9leё8\x99k>\x03\xcfR\xfc\x96p[ID4\xb4\xc5T\xa9B\xe4\xac\x02\xeb\xdbd,VF\x98\xad\xec)\xa0T=r\f\xb7_U\xec\xe1\xf5\xbe\xe0ḧ\x1dB\x1e\x8enQ+#\n!Yu\xf0\xd8\xfe\xea(Y\xcd\xfc_\t[\xad\x99\xd6B\x16\x17q\xdbַ\x96蜐E\"\xd1\xef\x97\xdfO]\aN\x9e\x93\xf3.\xe0\xc3\b\b0\x83\xc0hO\xa4\xaa\r\uecd0uj&(e\xa4\xac0\xa6\xd6+\x04\xa6uEy]\xc8$S\xbe\xa9\xad\xd6\xe5J\xaeE\x11+\xa7S\xa6dSUlU\xe1\x02\x9ci\x8e]ڒǽ_(<\xa3\xf1\x0f\xbd\xa1\xad\xbaϔ*ӻ\x1a\x140\xa7\x9bA\xd9\xd4S(\x19l\x94\x16,\xd1N\x87s☨\xe3\xf6\xf6\x12\x93\n'\xff\f\a\xe1Μ*8D\xc7\x11\xaf!\xf1\x8a\x1d\xdcG:\x9a_\xeaP\f\xfe\xdaНj\x880K\xd7VFc\xb4\xe27c\xd2\xfa\xbex\xd4y\xf0\xa4\xe3\x8e\xe1\xa1\x1f\xf5\x06\n\x9eU\x96\xf2\x85\xf2K\nS\xe19,\xf2\x1e\xd2\x00\xd7>\x92\xd1\x05\xe3\xea\xd2\x14\xdda\xb5C\u07bd!\\S\xb7y=\x16\xe2\vʆ\xc7C\"j\xec\x8a\x1c\xd1N̡\xec\x12B\x8c6\xa8Y\xd2\"\xc0?\nX_\x18\xfd\xda\x06i\xc2Bc\x91{\xdf:Y\xfchL\xe0\xccaF\xf3\xafs \xe9bWx\x9e\xeb\xbf\xc2\\U\xf9\x9a\x8a\x99r\xc8:\xda\xfc\xfbP\xfb0\x98\xa2\xec \xaf#,\x88C\xee\xafܠ$\xac\x99\xa8\x90C\xf7,}1\xf3\t\xd0\xd3d\xecs\x92_\xa3\xb5\xac8\xe7\xb4~\f\xa3B\xe5-N\x01\xb6R\x8d;b\x95_\xdbx\xb4.\x8a\xc9R\xf1sH\x1e\x14\xf70\xe4\xf1'\xb7)\x9a\x84Z\xfa\xcfp\x17a\xf4E\xcdsEJ\x1a\x93r5\x1d\xe4Ӿ\x06Nİ\a\xdc%Z\xdb\x13\x9c\xe8z\x8cn!\xd15\xf9=@\xbf3T\x92S9Mۗ\x94\xd9=\xb6'\xfa\xbe\xf7\xc7\xe5\"\xb6#\xbek\x1cBW\x87.U\xd5\xfa\x00\xffH.\x9bz\x85\x86T\xb1Je\xc4\xc0$\xefk.UL\xe8$\xb4a8\x88\x8a\xf5\xb0X@\xf7\xa7\xdc)\xe0\xc2\xea\x8a\xed\xbb\xcd\xf8\x1b\x1c\x1d\xe9\xf4s\xc2\xe1\\\xb5\xbe\x8a\"ϑ\xbc\xedt\xa5\xba\xfb\xd1B\xfa~z:Ӈ3پ\xef\xef~\x8c\xf0yV8\x91w\x0e\x7f\x1cr\x8d\x81,\a\x12\xce\x05\x8b\xf8c\x95\xcb}\xfcp\x99?ӽ'ٛ4z\xe4\xbc';>y\xf5[\x9aU\xf7\x1e\xbc\x80\xdf\xff\xb8\xf9\x7f\x00\x00\x00\xff\xffϡa\xa5-&\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=Ks\xdc8sw\xff\n\x94sؤJ#ǕG\xa5ts\xb4v\xac|\xdf\xca*\xc9\xf1\x9e1d\xcf\x10\x9f@\x80\v\x80\x1a\xcf&\xf9\xef)4\x1e|\fHbF\x1a\xednjyQ\x89\x04\x1a@\xbf\xbb\xd1\xc0\xacV\xab7\xb4a\xdf@i&\xc5\x15\xa1\r\x83\xef\x06\x84\xfdO_>\xfe\x9b\xbed\xf2\xdd\xd3\xfb7\x8fL\x94W\xe4\xba\xd5F\xd6\xf7\xa0e\xab\n\xf8\x116L0äxS\x83\xa1%5\xf4\xea\r!T\bi\xa8}\xad\xed\xbf\x84\x14R\x18%9\a\xb5ڂ\xb8|lװn\x19/A!\xf00\xf4\xd3?^\xbe\xff\xd7\xcb\x7fyC\x88\xa05\\\x11\x05\xdaH\x05\xfa\xf2\t8(y\xc9\xe4\x1b\xdd@aan\x95l\x9b+\xd2}p}\xfcxn\xae\xf7\xae;\xbe\xe1L\x9b\xbf\xf4\xdf\xfe\x95i\x83_\x1a\xde*ʻ\xc1𥮤2\xb7\x1d\xc0\x15Q\xbe\xb9fb\xdbr\xaab\x877\x84\xe8B6pE\xb0}C\v(\xdf\x10\xe2\x17\x85\xfdW~=O\xef\x1d\x88\xa2\x82\x9a:\xc0\x84\xc8\x06ć\xbb\x9bo\xff\xf40xMH\t\xbaP\xac1\x88\x9a\xffY\xc5\xf7$,\x810M(\xf9\x86(\xb0\xb3A\x92\x10SQC\x144\n4\b\xa3\x89\xa9\x80Ц\xe1\xac@\x8a\x10\xb9\xe9A\n\xbd4\xd9(Yw\xd0ִxl\x1bb$\xa1\xc4P\xb5\x05C\xfeҮA\t0\xa0I\xc1[m@]F@\x8d\x92\r(\xc3\x02\xba\xdc\xd3\xe3\xaa\xde۹\x85\xd9\xc7\xe2\xc2\xf5\"\xa5e/pK\xf0\xf8\x84ң\x8f\xc8\r1\x15\xd3\xddR\xc3\xf2\b\x15D\xae\xff\x06\x85\xb9\x1c\x81~\x00e\xc1X궼\xb4\\\xf9\x04\xca\"\xab\x90[\xc1~\x8d\xb0\xb5]\xb8\x1d\x94S\x03\xda\x10&\f(A9y\xa2\xbc\x85\vBE9\x82\\\xd3=Q`\xc7$\xad\xe8\xc1\xc3\x0ez<\x8f\x9f\x90xb#\xafHeL\xa3\xaf\u07bd\xdb2\x13d\xad\x90u\xdd\nf\xf6\xefPlغ5R\xe9w%<\x01\x7f\xa7\xd9vEUQ1\x03\x85i\x15\xbc\xa3\r[\xe1B\x04\xca\xdbe]\xfe]$\xea`X\xb3\xb7<\xaa\x8dbb\xdb\xfb\x80\xa2r\x04y\xac\x109\xc6s\xa0\xdc\x12;*\xd8W\x16u\xf7\x1f\x1f\xbe\xf6\x99\x92iO\x94\x1eoN\xd1\xc7b\x93\x89\r(\xd7\x0fY\xd3\xc2\x04Q6\x92\t\x83\xff\x14\x9c\x810D\xb7\xeb\x9a\x19\xcb\x06\xbf\xb4\xa0-\xbf\xcb1\xd8k\xd4Gd\r\xa4mJj\xa0\x1c7\xb8\x11\xe4\x9a\xd6\xc0\xaf\xa9\x86W\xa6\x95\xa5\x8a^Y\"dQ\xab\xafeǍ\x1dz{\x1f\x82\xae\x9c \xad\xd7\"\x0f\r\x14\x03I\xb3\xdd\xd8&\xa8\x8b\x8dT\x03%c\xbb\fq\x94\x16~\xfb8-b\xd5\xe2\xf8\xcb\x12\x97\xd9\xe7\xdfco\xcbovf\xad`\xbf\xb4\x80\xcaԉ?\x1c\xea+\xd5S\xfa\xc3Dzј\xba\x93\x88\xb6\x0f|/x[B\x19\xf5\xfa\xc1\x02s\x96\xf1\xf1\x00\n\x9aCʄ\x15\"k\x97\xecZD\xf7\x15\x158U@\x844\txL8x\x84\t\xc4@\x92&\xd8\xd0@\x9d\x98\xf1\xec\x92\t\x11-\xe7t\xcd\xe1\x8a\x18\xd5\x1e\xa2\xd1\xf5\xa5J\xd1\xfd\x04\xb6\x82o\xf0,dE ^\xd5pV ɣBA|\xfdqQŴU\x94a\x95w\x92\xb3b\xbf\x80\xaf\x8f\xc9NAZ\xbd\xec\xfa\x15\x925T\xf4\x89I\x95\x12\x03\xa9\xb0iϞwjZZ-遌m\\悓Ȫ\xa4|\\b\x88϶Mg\x1dH\x81\xaef\\\x8a\xa7\xb6\xb7\xddk \xf0\x1d\x8a\xd6$\xa6IH٢i\x92\x8a4R\x9bi\xbaO\xab.\xd2w\x8eR\x1fg\x98\xe6`eIVw\x8fW\u0081\xa8\x16\a\x03\x85,\x05\xd8eԖ\xa8][%[\xd7v\x12)dM5\x94D\x8aɑ\x91]Z\x0eڏU\"gtz\xe8\xa2[?z<\x84\xd35p\xa2\x81Ca\xa4:Df\x0eJݓ\xa3X'P\x99ЦC\t\xe8\x160\x03\x92XN\xdfU\xac\xa8\x9c\x87a\xd9\x13\xe1\x90R\x82\xb6\xda\x04]\xe6\xfd\xd4\"\xc9\x12\xf9\xfd sڣ{\x16\xc4j\f/\xa5Q\xba'C\rwO\x12\xb5\x9d\xee=\xd0-\xfe\xbd\x91\xb3\xcb\xfe\xff\x89\xd8`LN`\xda\x19\xf9'\xe8~f\xf3\xf4$\xdfb\x84\a\xfa\x92\xdcl\bԍ\xd9_\x10f\xc2\xdb%I\xa0\x9c\xf7\xc6\xf8\x03\xd3\xe6x\xa6\xcf$M\x8eL\x9c\x890q\x88? ]\xd0d{\x84=\x82Igs\x0e\x9f\\np\xcf#$\\\xff\xd43\xc0\xa1\x9d\x93\x0f\x8b\x1d\x9e\xec\vD\x04\xc6\xf0\xb9l\xe0\x1e/\n\x89\xdcI\xfa\xc9\xd4%\xe1\t\xb8?a\x99Y\xac\xd2\x1f\xa3\x9f\xfaD\x0e\xf8A;ZZ\x89\xa9\x98\xcfij@\x99\xc9%\xa8{\xbeQ\xce\xca8\x90\x93\x91\x1bqAn\xa5\xb1\x7f0@\xd3\xc8(?Jз\xd2\xe0\x9b\xb3`\xd4M\xfc\x9c\xf8t#\xa0\xa0\t\xa7\xe5-\xc2\xfa9?g\xd3,\xb7E\xdc3Mn\x84\x8dW\x1cJ2\x87\xc2\xf4\xae\x1b\xce\rT\xb7\x1a\xd3uB\x8a\x15\xda\xcc\xe4H\x1e\xdfR\r\xd0\xfd\xecA\xfd\x80_\xad\xb1p_\\\x92\x99\xd3\x02\xca\x10Yb\xf6\x93\x1aز\"s\xbc\x1a\xd4\x16HcUx\x1eGd*V\xbf\x9a\xe3\xd8'\xcfz\xf7\x9f\xef\xabǘ/XY\x93\xb3\xf2\x10\x8c\xac3p\xe0uw\xb9\xbc\x9e\x95\x95ٌV\x81\x13\x16\x9bN$G\xa7\x9b\xe6 \xe5\x19\xe8@+\x8e.\xce\"uiY\xe2\xe6\x1a\xe5wGX\x94#x\xe1X\xd5Л\xbb3\xc15m\xacZ\xf8okiQ\x9a\xfe\x974\x94)}I>\xe0N\x19\x87\xc17\x9f\x87\xeb\x81\xc9\x18\xb2\xb1CY\xfey\xa2\xdc\xda~\xab\xc0\x05\x01\xee<\x01\xb99\xf0\x8b.Ȯ\x92ڙ\xed\r\x03\x8e\xfb\x15o\x1fa\xff\xf6\xc2\x0e\xbf8d_ɼ\xbd\x11o\x9d\x0fq\xa00\xa2\xc3!\x05ߓ\xb7\xf8\xed\xeds\\\xa9LN\xcdl6`њ6y\x1c*\x92\xc9\xfa\xee\x19pL?7\xdf%当=\xb7\xda,\x16m\xa46\x9f\xd3yÉ\xf9܅\x1eC\xcf8\x91c[\x8c\x18|\x1e-\xea{\xebDn\f(\x9fKt6 \xc4\x1fό\xccR\xbb2\xfd\xc9\xc6d \x8d\xf9]\x8b\xe0\x05nr\x1b79S<\xc6a\xb5x9\xd2\xdb\xff\xf8\xbd\x97ϴ\x92k\xff\xef/\xe4\xa5\x1d\xeaB\xd65\x1d\xefjfM\xf5\xda\xf5\f<\xed\x019\xea\xabm\x8b\xf2\x9ck\x91;\x1e\xc2\xfd\xcb\x1d3\x15\x13\x84\x06\xb5\x01\xca3\x14%\x8dL\xe5\xb0SOE5Y\x03\x88\x98\xa2\xff=\xb8\x125\x1378\x00y\x7f\x06\xd7#\xa2\xeb\x9c\xce\xeeu\xa4I\xa4||\xe1LV#K\xb2\xab@\xc1\x801\x0e\xf3\xee\xe8\xa9\niz)\x8b#\x1c\xd2F\x96?h\xb2aJ\x9b\xfe\x144iu.\xad\x8f$\x9f\x9d\xf7WV\x83l\xcd9\x11\xfc\xb1\x1bf\xb0\xd7\\\xd3\xef\xacnkBk\xd9:cnX\x1dwu=zw\x94\x99\xb8m\x85\xf9\x1b#-\t\x1a\x0e\x06\xc8\x1a6\xe9\xfd\xde\xd4SH\xa1Y\t*T)8\xb21i\x05sC\x19oS\xbbD\xa9\xe7\xd8\bX|T\xea\xa4\x00\xf8\x8b\xeb\xd9\xcb;Vr7DP\xe6\xdaq#\r\b\xdb\x10f\b\x88\xc2b\x1c\x94S\xc98\x84G\x06\xa2\x86\xe5\xea\xb9<\x05n\x1f\x10m\x9d\x87\x80\x15\n$\x13\xb3)\xb7~\xf3O\x94\xf1s\x90\xcdr\xde'\xa9\ue056\xa7\xe4h~\xeeu' t\xabp\xf3\xdf\xe9\x8e\x1d\xe3ys\xb6\x94#\x9c\xb6\xa2\xa8\x00\x95\x90\x18\xea\x06\a\x9e\tm\x80\xe6\xf2\x82\xf5\x8aZ!\x98\xd8\xe6\xd1.;\x11\xda=\x0e\xd5k)9\xd0\xe9]\xc8\uec78~\x05M\xf4s7\xcc35QG\x04\xb7m\x8etȦ\xa8UZ\x84\x1a\x03u\xe3DN\x12Պ\xbeu9\x83\":&\f\xf7\xb3x\xc9\xf8\x9a\t\x96A\xdb\x01]o\x043}\xe7т8\xab\xf3h\a\x88\xee\xc0)\x19\xb6\x9b\x01\x00+\xa0!\x0e\xc1\xb9G\xae9\u0091\\\x03\xa1e\t\xa5\xcb]ZWć%\xae\xf0m\xa2\xb8!\xb9\xba\xe3=\xc1,ʆg\x10tb\x1eV=\xc1\xaa\x15\x8fB\xee\xc4\n\x83q}\xb4\x0e91K\xf5\xdc\xe1\xcd\xc9\xcahY\xbf\xe4\xab\xe9%-4\xe4\xd7|\x9e\n\xfe\xd3\x19\xb4L6\xdf\x1c\x95\xf0\x98\xe3\x82%\xbd\xe6\n\xb0'>.\xcebn\xfc\x99\xce~S\xfa\xda\x15K?\xab,\xee&\r\xaa\xe7\x14\xee*0\x15\xa8P\x9a\xbd\u0092\xf4rv\x87\xb4\v^b\x9d\x9ce\xaa\xe0\"\xbb\xf2\xcfQ\xe5\x1cF7-\xe7\x17\x96\xb7i˓ᰑ(b\x87\x9c\x95U?\x96\xf6\x18r\xaa/\xb2\xf1د\xb4\x18\xd6\x17\xc6*\x88P`(\xc3ȞƩ\xf5baio\x7f\x7fXN\x81\xf9\xbf0\xfd\u07fc\xf40\xa3R\"\x1f\x8d\xb9U\x9a\x11\x89\tX\t\x06롱\xab\xaf\xf0\xed|\xa1\xef\xef\v\xa7\x06\xea/\x8d\x97\x98I\x176\x03\xad\t8\xa3z\x13\xb4\x06\xadv\xae@\xb4\x03>gh\xfb\x7f(\xdc)\x88\x00&ů_+\b\xe2\xeb\xab\xf7\x99&\xffL*\xd9&\xaa\xfafP\xb6Pݱ\xbc\xe0A\xa1\x87\xdfP\x00C\x9f\xde_\x0e\xbf\x18\xe9\xcb>0\x8b\x96\x00\x84AQ\x97\x99e\xa2dO\xacl)\x0fR\u06dd!p\f\xd4\xf1Y\x02\x9aTD0\xee\x180\xf4\x1f0\x1c\xf9Ҹm\x99\xa3Uܼ/\x9aW\x1drrMȰ\xe6c\xc2\x1a\x1e\xbb}\xf1\"U\xb0\xbfI\xad\xc7\xf1\x15\x1e9\x91\xc4B5\xc7\t5\x1c\x99\xc5b\xcf\xdeoɩ\xd28&\xe6>[E\xc6\xcb\xd7ad\xe1g\xb9\xe6\xe2\x18윽\xbe\xe2\x15\xab*^\xa7\x96\"\xb3\x82\xe2\xe5J!\xf3\xa2ϓJ\x01\x96\x03\x96\xe9*\x88\xc5ڇg\x054'-i\xb1\xa6\xe1\x98J\x86E\xea\xe4\x89٫\xd5*\xbcZ\x85\xc2\xeb\xd6%\xccr\xd1\xec\xc7c*\x0fb\x9c\xf4\x13m\x1a&\xb6\x87L\x91\xcb:\xb3l\xb3\xcc2\xb7\xa3\x89\fx\xa6\x1f\xcet\xd1\xe1D\xe8\xeb\x8eK'\"ɐ\xb6d\xc2\xc8K\xf2A\xec=\xdc\x04\x9c^\xf8(\xa498\xc8f\xa7\xb5c\x9c\xf7Ok!\xd8yP\xfe̤\xa6\xb5\x9bՔ\xb7\x9f\xa4\xabT\x03\xa7\xfc\xa4\xc0\xf1\xcb\bF?;\xfa\x9a\x9e\x7f\xddr\xc3\x1a\x0e֣{be\xf2\f\x99\xa9`\x1f\x91\xfc7\x89'\xa4\xd6{\x84\xf4\xe5>\xca\xe2\xe5(\x88\xa1\x9a\xec\x80sBS\xdcq\xb0\xfc\u009dL.\xe4\n\x8f\x04Z\xf2\x06&\xf1\xe7\x99/\x9c\x14\xe310\xa4^\x9d\x80[P\x81\xa7\x9bub!\x93\xe60G\x8b\x1e\xf8\xe5.\xba\xc0w\xbf\xb4\xa0\xf6D>a\t\x83\xf7\u07ba\xb3\n^\xddh\x1bc\x06\x05\xe8\x95\xf1Ԧ\xc2A(\xd3)(\xf2A8_b<\x1f\xecc5_\x17\xaaYun\xa3\xb0\xe4\x18\x13݅\x8c\xbd\x13ݖ\xdc\xfeܢ\xfe\xf3\x06nLJn\x8b\xbeR\xbe?\xfb\x1b\x15\xeb\x9fR\xa4\x9f\xb7\x1d\xb4X\x94\x7f\xae@n)\x94\xcb\xf6^\xf3\x8a\xee\x8f\xdbD=c\x91\xfd9\x8a\xeb31\x95SL\x7f\x1c\x9e^\xa1x\xfeU\x8b\xe6_\xabX>\xbbH>k\x1f3{\xd3*w\x9b\xf1Ī\xef\xe5]\xf7\xf9\xa2\xf7\x8cb\xf7\x8c\x9d\xb4\xe5E\x9e\xb0\xbc\x8cb\xf6\xe3\x8a\xd83h\x96+\x8a\xafX\xac\xfe\x8aE\xea\xaf]\x9c\xbe\xc0Y\v\x9f\x8f+B?y\a&l\xf5\xdf\xca\x12\xee\xa42K\xc1\xc9ݸ}b'\xb5\x17\xb0I^\x12\x11\x9a&V\x89!\x86\x0f/N[Tz\xd33\xb8\xd3?\xc9\xd2\xcemi\x8f\xe5~\xd4\xfc\xe0\xac\xf2\x06\x14\bw\xcd\xc7\x7f>|\xb9\x8d\xf0S>\xaf\xf7\x8cG\xd7K8\x0f\xa6\xf4\xc8\xf1[s\xbe\x98\xc9a\v}\x80\x17\xde\x17\xa1\r\xfb\x0f\xbc\xef\xed\x19\xe9\xa0\x0fw7\b#\xf8ix\x81\\\xac\xa2\x88;\x96k\xb0\x16+\xa2jR,n6\x03\x88Ê\xdf\xfe5JP\xba+\xb3\x82\xc5d\xa1\xc6\xcb\n\xdeݍ\x9b\xc7\xd4(\x9f\xac\xd3(\xf6D:\x8e\xac\x98*W\rUf\x8fl\xa3/\x06s\bff.\x9d3\xa9X\x0f\xaf\x01K\xa27\xdc\xfe\x85{\x91\xfbf\xb8\xdb;\xc6\xdd)\xf3\x98>\x7f\xb2x\xf2\xe4\x05\xe71m\xb1W\x88\xa9\xc4\xebd\x81ɋ\xa5\xc9\xd417\x05%e`\xe1ڠ\x9ej\xa0\xe4Z\x8a\r\xdb\xfeD\x9b`F\x1c>'\x95\x85O\xd14\x16\xb4\x05養u\xb5ihwzPi,a%t.eU~B\xc8w\x01\xb0\x06\xb7\xbd\xed\xb4R\\B\x03j\xd5\xe5ۺی\xf6\xcd\xf4l\xf5\xc5(d\xf5\xb7\xdc\fj\x17\xac\x1a4\xa0\x84\xff\x96\x9a\xab/\xb8y\xc0z\x9b\xdet\xf7q\xb2\x16\x1bv\x86\x96q\xfc\xe0x9\xd1fT\xac\x93\x00>ʧt\x18\xdcHUS\x13$\x00\x13z\xd4\xe1\xddݚ\xf6\xd0@q9$\xf9\x9f:\xf9O\x9d\xfc\xa7N~Y\x9dl\x95\xdbݷ\x93R\xe1\xf7\xb1\xf7\xbc\xefI9\x8f\xe9\xff\x04\x18\xdb\x1f\xddO-h\xa3\xab\xc45x\xcf\xf3?\xf1\x86HCM\xfb\x9cE:\x00\x83u\xb2\xa2\xeay\x90;\b>fX6J+vKjp\xe0\xfe\xa4\x15\xe3\x17\xbd\xec\xed\xeb\x94\xe9d^\xb1u\xf2\xe5Z\x0e=\x13\xea\aw$\xacj;\xc4\xd4\t\x05:\x8b\xe1v\xc6\xc1\x8f\xf9\xc4B\xe6\xd5Ly\x06\xe3\x84\xeb\x98\x10_\xb9\xb8\"\xc9[\x9a2ob\xfaM\x11=\xa3\xd5tQA\xd9r8\xf5\x1eև^\xff\xe5\x9bX\xc3h\x19w\xb1Zd\xf7\f\xb4\xf5\xb0\x86w\xbezJx\xc8}JN\x05ᘰqW>\x16\xeev\xe0\xa2\x00\xad7-\x0f\x95\xa3\x85\x02j\xa0\f͙\x8e3>\xaa\xf6\xb1m\xb8\xa4%(\xe7\x92-\xa0\xf5\xbf\x06\x8dG<[\xe0\xcbVu\xd7\xed\xce^U\xfa,\xcd\xd5PE9\a\xfe\x89q\xd0?ʝ\xb0\xf3\xca\x10ȻT\xbf\xdeY٢U֬\xef\x89h\xeb5(\xa2\xc1\x98\xe9\x04\xdeF\xaa\xf9S+\x0e\xefL\x18\xd8B*\xe7\xb9S\xcc\xc0CC\x95\x06\x9cQ\xc6\n~\x1euq\x19\xc1\r\xa7[W\x9e\\\xb2\x82\x1a\x88\x06\x18G\x98\x9a>\xf6\xd7\b\x8b\xef\xb1ZTNlDd\v\xf5\xd41\xb9I\xb1\x9e\xba\xf29a\xaa\x93\x97>;\x8b\\\xd0\xc6\xe0\xa1D\xa4#\x12\xd1x\x18x\x91\xfa\xe8\xde\xe7\x01\xd8iN\xf3GK|\x11\xb36\xb4ND\t\xcbz\xe7\xfa\x10\f^ծ\xca^-t\xff\xd2\xdbX\xf4LvT\xc7\x03.I\u07fb\x83\xed\xc0\xa0\xabnACI\xe0\t\x04\xb1\xa2H\x19\x87r\x8eS\xbf\xe2\xe6\x9ez\x02\xf5\x83\x8ep\xb0:۲\xf8\x83\xa1\xcaĩ\x1f\xfa1.\x86\xbb\"%5\xb0\xb2\xbdOs\xdd\xd2WW+ub\x89\x06\x9e6\xf6\xe2Q\x84\xa3\x90\xd6\xfa\xb93\xc25hM\xb7!1\xb8\x03\x05d\v\xc2\xe2=\xee\xf7$=\xa6p\xcc\xda\x1b\x8bAb\x80\x16\xa6\xa5~\x00\xe7\xc2Ŋ\x96pg\x10\x9cC\x1d^1\xe2\f:\x9f\xaa3\x18\xdc`D\xb4\xc5\xde)ʄ85v3\x1dv癚\xaf\x11ʔz\xf4\xeb\x1b\xfc8\x82/z\xf1\x8d,ي\x8a\x8a\xed\xe4!\xe3J\xc9v[\x05ޜr\x88H\xd9b\xe4ܠ*\xd0\xe1ǜL\xabD\xaf\x90\xc2\u05fdMi\xe98\xddi\x1f\xe5\x19\x8aZu\x87\r;U5c\U000f3cc4\x13\x10\x17m\x7f\x02\"\xd5{Q\xcc\x1e\x8b<ܣ:ʵL\"!j\xe3\x17CB\x848\x85\x84\xbe/\xd1E<\xbf\x1b\x8cL\xf9('\xa2cމ\xc1%\u0383Z^t\xdf\t\x1a\xba;ǡC\x0f\x82\xbf\x93\xd2n\x03\b\xc7D\xbe8v:\xee\xfd\xfdF\xacO\xd1\xdb\xfaxr\xec\xfam\x04ct,\xddF\xb1\xdd0!\xde\xfc{\xb6Iɋ\xfbż5\x87\x7f8\xf8\xfa\xca\xc7\xcbwT\t&\xb6'a\xe4g\xdf7\x11\xcf{\xb0\xe7\x8c\xe8\xc3\xcc_,\xa6O\x9a\xa5\x83\x97\xc8\xe0e\x0f\xcf~$\xff\xe6\xff\x02\x00\x00\xff\xffJ\xb7g~\xf1r\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4Z͒\x1b\xb7\x11\xbe\xefSt\xad\x0f\xb6\xab4d\xa4$\xae\x14o\xd2*Nmbo\xb6DI\x17\x97\x0f\xe0\xa09\x849\x03\xc0\x00\x86\\\xda\xf1\xbb\xa7\x1a\xc0\f\xe7\a\xe4,\xa9\x925\x17i\xf1\xd3\xf8\xf0u\xa3\xbb\xd1`\x96e7L\x8b\x8fh\xacPr\x01L\v|r(\xe9/;\xdb\xfe\xc3΄\x9a\xef^\xdel\x85\xe4\v\xb8\xab\xadS\xd5;\xb4\xaa69\xbeŵ\x90\xc2\t%o*t\x8c3\xc7\x167\x00LJ\xe5\x185[\xfa\x13 W\xd2\x19U\x96h\xb2\x02\xe5l[\xafpU\x8b\x92\xa3\xf1\u009b\xa5w\x7f\x99\xbd\xfcn\xf6\xf7\x1b\x00\xc9*\\\x80V|\xa7ʺB\x83\xd6)\x83v\xb6\xc3\x12\x8d\x9a\tuc5\xe6$\xbc0\xaa\xd6\v8v\x84\xc9q\xe1\x00\xfaQ\xf1\x8f^λ \xc7w\x95º\xff$\xbb\x7f\x10\xd6\xf9!\xba\xac\r+\x138|\xaf\xdd(\xe3\x1e\x8eke\xa0w&\xf4\bY\xd4%3\xe3\x997\x006W\x1a\x17\xe0'j\x96#\xbf\x01\x88\fxA\x190\xce=\xa7\xac|4B:4w$B\xb6\xcbp\xb4\xb9\x11\xdayΆ\xe0\xc1:\xe6j\v\xb6\xce7\xc0,<\xe0~~/\x1f\x8d*\f\xda\x00\x1c\xe0\x17\xab\xe4#s\x9b\x05\xcc\xc2\xf0\x99\xde0\x8b\xb17\x90\xbf\xf4\x1d\xb1\xc9\x1d\b\xb3uF\xc8\"\x85⽨\x10xm\xbc\xd2i\xff9\x82\xdb\b;\x86\xb7g\x96 \x1a\xe77\x9e\x06\xe3\xfbI\xa4u\xac\xd2CT\x9d\xa9\x01\x16g\x0eS\xa0\xeeT\xa5Kt\xc8aup\xd8le\xadL\xc5\xdc\x02\x84t\xdf\xfd\xed4\x1f\x91\xb0\x99\x9f\xfaV\xc9>9o\xa8\x15:\xcd\x01\ti\xab@\x93dH9V~\n\x10G\x02\xdet\xe6\a$An\xb7}\x12\n\x99\x1e\xa85\xb8\r\xc2\x1b\x96ok\rK\xa7\f+\x10~PyP\xe1~\x83\x06\xfd\x88U\x18Ag\x1b\x04\xe9N\x99\xa4\xea4\xe6\xb306\nkd\r\xf4\xd7_\xe8\xb3\xd8Wn\x90%\xed\xabqR3?B(\x996\xb2\xd7\x05>\xcb\xc0\xbaDJű\xc3\xda\b\x97\xb0\xa0\x8d\xca\xd1\xda3\x86OBzH\x1e\x8e\r\x93\x14mЏi\x00պT\x8c\xa3\x01\xa7`\xc3$/1\xe8\xd0\x19&\xed:Z\xc6X\x85ʹ\xf7\a݇\xf2\xa1\x91\xd7\xe9\x19a\nCw/\x83\x1b\xcc7X\xb1E\x1c\xab4\xca\u05cf\xf7\x1f\xff\xba\xec5\x03Ѣ\xd18\xd1\xf8\xd1\xf0uBR\xa7\x15\xfa{\xfe_\xd6\xeb\x03\xa0\x05\xc2,\xe0\x14\x9b\xd0z.\xa2\x7fE\x1e1\x05\x8e\x84\x05\x83ڠE\x19\xa2\x1553\tj\xf5\v\xe6n6\x10\xbdDCb\xc8\xed\xd7%\xa7\x90\xb6C\xe3\xc0`\xae\n)~ke[\"\x9c\x16-\x99C\xeb\xfcA4\x92\x95\xb0ce\x8d/\x80I>\x90\\\xb1\x03\x18\xa45\xa1\x96\x1dy~\x82\x1d\xe2\xf8\xd1[\x93\\\xab\x05l\x9c\xd3v1\x9f\x17\xc25\x81:WUUK\xe1\x0es\x1fsŪv\xca\xd89\xc7\x1d\x96s+\x8a\x8c\x99|#\x1c\xe6\xae68gZd~#\xd2\a\xebYſ21\xb4\xdb\u07b2#E\x87χ\xd7\v\xd4C\xf1\x96N\x02\x8b\xa2\xc2\x16\x8fZ\xa0&\xa2\xee\xdd?\x97\xef\xa1A\x124\x15\x94r\x1c:\xe2\xa5\xd1\x0f\xb1)\xe4\x9a\f\x9f歍\xaa\xbcL\x94\\+!\x9d\xff#/\x05J\a\xb6^U\u0091\x19\xfcZ\xa3u\xa4\xba\xa1\xd8;\x9f\xcc\xc0\x8a\x0e\x14\xf9\x01>\x1cp/\xe1\x8eUX\xde1\x8b\x7f\xb2\xaeH+6#%V\xe4nN\xa9\xe6\xb4\x1d\u0099\x90\x94\x04\xfc\xfa\xf1\xbe\t;\x8deE\xe8\xa3\xc8\xd2\xe5'i\x16\xf4\xad\x05\x96\xdc\a\xea鵓\x16B\xdf\xfd:\x80\xf0\xbe\xd7)`\xa0\x05\xe6؋{ \xa4u\xc8xl$wc0\xf6\xbd\b>\xf5$H\bע\x18\x1fI%\xc0\xc8\xc7\v\x0e\xff^\xfe\xf7a\xfe/\x15\xf6\x01,\xa7L\xc8\xdfU\xb0B\xe9^\xb4\xf7\x15\x8eV\x18\xe4t\xfb\xc0YŤX\xa3u\xb3(\r\x8d\xfd\xe9\xd5\xcfi\xfe\x00\xbeW\x06\xf0\x89Q\xd2\xff\x02D\xe0\xbc\r\x1b\x8d\xd5\b\x1b6\xdeJ\x84\xbdp\x1b\x0fT+\x1e7\xb8\xf7[plK'&l\xa1F(\xc5\x16\xd3\xec\x03\xdc\xfa\xe4\xe9\b\xf3wr)\x7f\xdc\xc27\xc1I\xdcҟ\xb7\x01F\x9b t\xbd\xce\x11\x8e\xdb0\aΈ\xa2\xc0c\xa2=2\x16\nh\x14\n\xbe\x05eh\xafRuDx\xc1\xa4\xa7\xe0\x88\x91\x8f\xe0\xfd\xf4\xea\xe7[\xf8\xa6\xcf\xc1\x89\xa5\x84\xe4\xf8\x04\xaf\xe8\x8c{n\xb4\xe2\xdf\xceཷ\x83\x83t\xec\x89V\xca7ʢ\x04%\xcbC\xc87w\bVU\b{,\xcb,\xa4b\x1c\xf6\xec\x00j}b\x9dFEd\x9a\f43\xeel:\x16y8\x7fh\xc6\xf9I\xf3=\xef\xbc\xf8|\xe5Y\xa7\xf7\x8b\xc5\xfag2\xe1\x13\xf3O`\xa2{չ\x82\x89m\xbdB#ѡ'\x83\xab\xdc\x12\x0f9jg\xe7j\x87f'p?\xdf+\xb3\x15\xb2\xc8\xc8\x18\xb3\xa0u;\xf7Ŝ\xf9W\xfe\x9fk7\xee\xeb,\x9f\xba{/\xe4\xcbQ@\xab\xdb\xf95\f4y\xf4\xf3c\xd7I\x1e\x961\xb3\x1bʤ3\xbf߈|\xd3ܪ:\u07b6b<\xb8c&\x0f_\xe8\xec\x10ϵ!D\x87,\x96\"3&9\xfd\xdf\n\xeb\xa8\xfd\x1abk\xf1I\xce\xe5\xc3\xfd\xdb/y\xa2jq\x8d'9q[\b\xdfSvD\x95ULga4s\xaa\x12\xf9`4\xe5\xca\xf7\x9c\x94\xb4\x16h&\xb2\xbfw\xbd\xc1M֞Ⱥ\xdb1\x17\xa5\xdd1!|O#\xa6\x80\xb4#;\xb9\xb6\x1b\x94^L\xea\x8e3\x81\xc1J\xa6\xedF\xb9\xfb\xb7\x13\x10\x96\xed\xc0\x86\x87\xa3\x1d\xc5ķ\x91E\xc7\xf2l\xbe\xfb\f\f\x80\x003\b\x8c\xf6D\xaa\xda\xe2!\v\x99\xaff\x82\xd2V\xcaLcz\xbfB`Z\x97\x94[\x86l6\xe5\x1f\x9b\x8aa\xae\xe4Z\x14\xb1z;fJ\xd6e\xc9V%.\xc0\x99\xfa\xd4\xc51\xe9r\xba\xc5\xca\t\x8d\x7f\xe8\fm\xd4=Q.M\xef\xaaWD\x1do\x06e]\x8d\xa1d\xb0UZ\xb0D;\x1dΑs\xa4\x8e\xdb\xdbKL*\x9c\xfc\t\x0e½=U\xf4\x88\x8e#^\x85\xe25?\xb8\x8ftFq\xa9C1\xf8kM\xf7\xba>\xc2,]\xdf\x19\x8cъ\xdf\fI\xebƃQg\xeb\xa3\a=G\x1f;\xec軃Ao \xe7YE3_ƿ\xa4l\x16\x1e\xeb\xa2FB\x92\xe2\x9a'<\xba\xfe\\]8\xa3\x1b\xb6v\xc8\xdb\x17\x8ek\xaaJ\xaf\x87B|\xb9\xdb\xf0x|D\x85m\t&Z\x909\x16\x85B\xf0\xd1\x065K\xda\n\xf8'\v\xeb˶_\xdb MX\xa8-r\xefuG\x8b\x9f\x8c\x16\x9c9\xcch\xfeu\xae%]\x8a\v\x8f\x87\xdd7\xa2\xab\xearc1c\x0eYK\x9b\x7f\xbdj\x9e-S\x94\x1d嵄\x05q\xc8}A\x00\x94\x845\x13%rh\x1f\xcd/f>\x01z\x9c*~N\xf2+\xb4\x96\x15S\xee\xec\xc70*\xd4\x05\xe3\x14`+U\xbb\x13V\xf9\xb5\x8dG\xeb\xa2h-\x15\x9fB\U000a0e07!O?\b\x8e\xd1$\xd4\xd2}$\xbc\b\xa3/\xb9N\x95PiL\xcaմ\x90\xcf\xfb\x1a8\x13\xdd\x1ep\x9fhmNp\xa2\xeb1\xba\x85D\xd7\xe8\xd7\n\xdd\xceP\xe7Ne;M_Rf\xfbS\x80D\xdf\xf7\xfe\xb8\\\xc4v\xc4w\x8dCh\xab\xe4\x1bU6>\xc0?\xe1˺Z\xa1!U\xacR\xb920ɻ\x9aK\x95:Z\tM\x80\x0e\xa2b\xb5.\x96\xf7\xfd)w\n\xb8\xb0\xbad\x87v3\xfe~IG:\xfd\xd8q\xb4kX\xb7\x8c\x97\xa0\x10x\x18z\xf7\xff/\xdf\xfe\xeb忼\"D\xd0\x1a\xae\x88\x02m\xa4\x02}\xb9\x03\x0eJ^2\xf9J7PX\x98[%\xdb\xe6\x8at\x1f\\\x1f?\x9e\x9b\xeb\x9d\xeb\x8eo8\xd3\xe6\xaf\xfd\xb7\x7fc\xda\xe0\x97\x86\xb7\x8a\xf2n0|\xa9+\xa9̗\x0e\xe0\x8a(\xdf\\3\xb1m9U\xb1\xc3+Bt!\x1b\xb8\"ؾ\xa1\x05\x94\xaf\b\xf1\x8b\xc2\xfe+\xbf\x9e\xdd[\a\xa2\xa8\xa0\xa6\x0e0!\xb2\x01\xf1\xee\xf6\xe6\xfb?\xdd\x0f^\x13R\x82.\x14k\f\xa2\xe6\xbfW\xf1=\tK L\x13J\xbe#\n\xecl\x90$\xc4T\xd4\x10\x05\x8d\x02\r\xc2hb* \xb4i8+\x90\"Dnz\x90B/M6J\xd6\x1d\xb45-\x1eچ\x18I(1Tm\xc1\x90\xbf\xb6kP\x02\fhR\xf0V\x1bP\x97\x11P\xa3d\x03ʰ\x80.\xf7\xf4\xb8\xaa\xf7vna\xf6\xb1\xb8p\xbdHi\xd9\v\xdc\x12<>\xa1\xf4\xe8#rCL\xc5t\xb7\u0530\xdc\x7f\xeb3%Ӟ(=ޜ\xa2\x8f\xc5&\x13\x1bP\xae\x1f\xb2\xa6\x85\t\xa2l$\x13\x06\xff)8\x03a\x88n\xd753\x96\r~iA[~\x97c\xb0\xd7(\x8f\xc8\x1aH۔\xd4@9np#\xc85\xad\x81_S\r/L+K\x15\xbd\xb2DȢV_ʎ\x1b;\xf4\xf6>\x04Y9AZ/E\xee\x1b(\x06;\xcdvc\x9b .6R\r\x84\x8c\xed2\xc4Qz\xf3\xdb\xc7I\x11+\x16\xc7_\x96\xb8\xcc>\x7f\x89\xbd-\xbfٙ\xb5\x82\xfd\xd2\x02\nS\xb7\xfd\xe1P^\xa9\x9e\xd0\x1f>\x96\x8d\xc6ԝD\xb4}\xe0G\xc1\xdb\x12\xca(\xd7\x0f\x16\x98\xb3\x8c\x0f\aPP\x1dR&\xec&\xb2zɮEt_Q\x80S\x05DH\x93\x80DŽ\x83G\x98@\f$i\x82\r\rԉ\x19\xcf.\x99\x10\xd1rN\xd7\x1c\xae\x88Q\xed!\x1a]_\xaa\x14\xddO`+\xd8\x06g!+\x02\U000621b3\x02I\x1e\x05\n\xe2\xeb\xf7\x8b*\xa6\xad\xa0\f\xab\xbc\x95\x9c\x15\xfb\x05|}Hv\n\xbb\xd5\xef]\xbfB\xb2\x86\x8a\xee\x98T\xa9m \x156\xed\xe9\xf3NLK+%=\x90\xb1\x8e\xcb\\\xf0\xc4Vr\x93\xff.y[\xc3{j\xe8Qk\x1ew;}\xd5;\x84D\xac\f}\xbe\xd5VR>,\xb1\xff'ۦӅ\xa4@\xc3:.\xc1\xf3\xb6\xb7T\xd6@\xe0\a\x14\xadIL\x93\x90\xb2EE,\x15i\xa46\xd3\\>-\xa8I\xdf\x14L}\x9c\xd9\"\a+Knl\xf7x\x95\x13X\xd8\xe2`\xa0~\xa4\x00\xbb\x8c\xda\x12\xb3k\xabd\xeb\xdaN\"\x85\xac\xa9\x86\x92H192\xb2I\xcbA\xfb\xb1J\xe4\x88N\xea^t\xebG\xfb\x8ep\xba\x06N4p(\x8cT\x87\xc8\xccA\xa9{r\xd4\xc8\x04*\x13\xbac\xc8\xf9\xdd\x02f@\x12\xcb\xe9\x8f\x15+*gOY\xf6D8\xa4\x94\xa0\xad\xecD\aa?\xb5H\xb2D~?Ȝ\xac입m5\x86\x97\x92\x9fݓ\xa1t\xba'\x89\xdaN\xd3\x1c\xc8\x14\xff\xde\xc8\xd9e\xff\xdfDlP\x9d'0\xed\xcc\xfe'hlg\xf3\xf4$ߢ?\v\xfa\x92\xdcl\bԍ\xd9_\x10f\xc2ۥ\x9d@9\xef\x8d\xf1;\xa6\xcd\xf1L\x9fI\x9a\x9c=\xf1L\x84\x89C\xfc\x0e\xe9\x82*\xe3\xdek\x8cl\x9a\xfc\xad\xdf낰MDzyA6\x8c\x1bP#\xec\x9f$\xea\x03e\x9e\x02\x199Z\x8f`T\xc4\x14Շ\x1f\xd6\xc4\xd1]00\x13/\xe3\xce\xce\x13\b\xfe\xd2P=/\xc0%\x18\x1d`\nj\x8c:\x90o\x88\xcd\xee\r\xba\x10ᄐ?\x8c\f\x8c\x9f\f\xce;X\xc8¦sϻъ\xfa\xf3\xf3>P\xf8\x826Pt!]\x84\xe9\x82P\xf2\x00{g\xbaPA,}hh\x9c1\xbc\x02\fu!\x9f=\xc0\x1e\xc1\xa4cW\x87O.7\xb8\xe7\x01\x12F\x7f\xea\x19\xe0\xd0\xce\xc9\a\x01\x1c\x9e\xec\vD\x04F,r\xd9\xc0=~+$\"E\xe9'S\x96\x84'\xe0\xfe\x84ef\xb1J\x7f\x8c~\xa0\x179\xe0'\xedhiwL\xc5|\x04W\x03\xee\x99\\\x82\xba\xe7;嬌\x03\xb9=r#.\xc8\x17i\xec\x1ft\xcd42\xca{\t\xfa\x8b4\xf8\xe6Y0\xea&\xfe\x9c\xf8t#\xe0F\x13N\xca[\x84\xf5#\x9cN\xa7Yn\x8b\xb8g\x9a\xdc\b\xeb\xaf8\x94d\x0e\x85^\xa8\x1b\xce\rT\xb7\x1a\x83\x93B\x8a\x15\xea\xcc\xe4H\x1e\xdfR\r\xd0}\xf6\xa0~\xc0oVY\xb8/.\xa4\xcei\x01e\xf0,1\xd6K\rlY\x919^\rj\v\xa4\xb1\"<\x8f#2\x05\xab_\xcdq쓧\xbd\xfbϏ\xd5C\x8c\x8e\xac\xac\xcaYy\bF\xd6\x198\xf0\xb2\xbb\\^\xcf\xca\xeeٌV\x81\x13\x16\x9bN\x84\x82\xa7\x9b\xe6 \xe5\ft\xa0\x16G\x13g\x91\xba\xb4,1\x95H\xf9\xed\x11\x1a\xe5\b^8V4\xf4\xe6\xeeTpM\x1b+\x16\xfe\xcbjZ\xdcM\xffC\x1aʔ\xbe$\xef0/\xc8a\xf0\xcdG\x1d{`2\x86l\xecP\x96\x7fv\x94[\xddo\x05\xb8 \xc0\x9d% 7\av\xd1\x05y\xac\xa4vj{Àcv\xe6\xf5\x03\xec__\xd8\xe1\x17\x87\xec\v\x99\xd77\u2d73!\x0e\x04F48\xa4\xe0{\xf2\x1a\xbf\xbd>ǔ\xca\xe4\xd4\xccf\x03\x16\xadi\x93ǡ\"\x99\x9a\xe8\x9e\x01\xc7\xf43\x11]\n\xc2\x1b\xd9s\xab\xcdb\xd1Fj\xf3)\x1d7\x9c\x98\xcfm\xe81\xb4\x8c\x131\xb6E\x8f\xc1\xc7Ѣ\xbc\xb7F\xe4ƀ\xf2\xb1D\xa7\x03\x82\xffq\xa6g\x96\xcaA\xf5'\x1b\x83\x814\xc6u-\x82\x17\xb8ɥ\xa9r\xa6x\x8c\xc1j\xf1r\xa4\xb5\xff\xe1G/\x9eiw\xae\xfd\xbf\xbf\x90\xa76\xa8\vY\xd7t\x9c\xc3͚\xea\xb5\xeb\x19x\xda\x03r\xd4W\xdb\x16\xf7s\xaeF\xeex\b\xb3\xb5\x8f\xccTL\x10\x1a\xc4\x06(\xcfP\x9442\x15\xc3N=\x15\xd5d\r b\x88\xfe\xb7`J\xd4L\xdc\xe0\x00\xe4\xed3\x98\x1e\x11]\xcfi\xec^G\x9aD\xca\xc7\x17Ne5\xb2$\x8f\x15(\x180\xc6a\xdc\x1d-U!M/dq\x84A\xda\xc8\xf2'M6Liӟ\x82&\xadΥ\xf5\x91\xe4\xb3\xf3\xfe\xc6j\x90\xadyN\x04\x7f\xe8\x86\x19d\xd6k\xfa\x83\xd5mMh-[\xa7\xcc\r\xabc\x0eۣ\xf7\x912\x13\xd3U\x18\xbf1Ғ\xa0\xe1`\x80\xaca\x93\xcen\xa7\x9eB\n\xcdJP\xa1&Ñ\x8dI\xbb17\x94\xf16\x95%J=\xc7z\xc0\xe2\x83R'9\xc0_]\xcf^ܱ\x92\x8fC\x04e\xae\x1d\x13i@؆0C@\x14\x16㠜H\xc6!<2\x105,W\xce\xe5\tp\xfb\x80h\xeb<\x04\xacpC21\x1br\xeb7\xffH\x19\x7f\x0e\xb2Y\xce\xfb(\xd5\x1d\xd0\xf2\x94\x18\xcdϽ\xee\x04\x84n\x15\x96:8\xd9\xf1\xc8xޜ-\xe5\b\xa7\xad(*@!$\x86\xb2\xc1\x81gB\x1b\xa0\xb9\xbc`\xad\xa2V\b&\xb6y\xb4\xcb\x0e\x84v\x8fC\xf5ZJ\x0et:\v\xd9=\x16\xd7/ \x89~\xee\x869S\x12uDpis\xa4C6E\xad\xd0\"\xd4\x18\xa8\x1b\xb7\xe5$Q\xad\xe8k\x97g\x10DǸ\xe1~\x16O\xe9_3\xc12h;\xa0\xeb\x8d`\xa6oZ\x86\x9c\x18\xa5:wxs\xb20Z\x96/\xf9bzI\n\r\xf95\x9f\xa7\x82\xfd\xf4\fR&\x9bo\x8e\nx\xccq\xc1\x92\\s\xe5\xe6\x13\x1f\x17g17\xfeLg\x9f\x94\xbev\xa5\xe1g\x15\x01ޤA\xf5\x8c\xc2\xc7\nL\x05*\x14\xa2\xaf\xb0\x00\xbf\x9c͐v\xceK\xac\n\xb4L\x15LdW\xec:\xaa\x13D\xef\xa6\xe5\xfc\xc2\xf26my\xd2\x1d6\x12\xb7\xd8!geՏ\xa5-\x86\x9c\xea\x8bl<\xf6+-\x86Ք\xb1\n\"\x94S\xca0\xb2\xa7qj\xbdXF\xdb\xcb\xef\x0f\xcb)0\xfe\x17\xa6\xff\xab\x17ZfTJ\xe4\xa31\xb7&5\"1\x01+\xc1`=4v\xf5\x15\xbe\x9d/k\xfem\xe1\xd4@\xfd\xb5\xf1;f҄\xcd@k\x02Ψ\xde\x04\xb5A\xab\x9d)\x10\xf5\x80\x8f\x19\xda\xfe\xef\nw\xe6#\x80I\xf1\xeb\xb7\n\xc2\xf6\xf5g\x15\x98&\xffL*\xd9&\xaa\xfafP\xb6Pݱ\xbc\xe0A\xa1\x87O(\x80\xa1\xbb\xb7\x97\xc3/F\xfa\xb2\x0f\x8c\xa2%\x00\xa1S\xd4Ef\x99(َ\x95-\xe5a\xd7v'&\x1c\x03u|\x96\x80&\x15\x11\x8c;\x06\f\xfd\a\fG\xbe6.-s\xb4\x88\x9b\xb7E\xf3\xaaCN\xae\t\x19\xd6|Lh\xc3c\xd3\x17OR\x05\xfb\xab\xd4z\x1c_\xe1\x91\xe3I,Ts\x9cPÑY,vv\xbe%\xa7J\xe3\x18\x9f\xfb\xd9*2\x9e\xbe\x0e#\v?\xcb5\x17\xc7`\xe7\xd9\xeb+^\xb0\xaa\xe2ej)2+(\x9e\xae\x142\xcf\xfb<\xa9\x14`\xd9a\x99\xae\x82X\xac}8ˡ9iI\x8b5\r\xc7T2,R'o\x9b\xbdX\xad\u008bU(\xbcl]\xc2,\x17\xcd~<\xa6\xf2 \xfaI\x9fi\xd30\xb1=d\x8a\\֙e\x9be\x96\xf92\x9aȀg\xfa\xeeL\xe7\x1dN\xb8\xbe\xeepx\u0093\faK&\x8c\xbc$\xef\xc4\xde\xc3M\xc0鹏B\x9a\x83c{vZ\x8f\x8c\xf3\xfei-\x04;\x0fʟ\x10մv\xb3\x9a\xb2\xf6\x93t\x95j`\x94\x9f\xe48~\x1d\xc1\xe8GG_\xd2\xf2\xaf[nX\xc3\xc1Zt;V&ϐ\x99\n\xf6\x11\xc9\x7f\x97xBj\xbdGH_\xef\xe2^\xbc\x1c91T\x93G\xe0\x9c\xd0\x14w\x1c,\xbfp\xe7\xb0\v\xb9\xc2〖\xbc\x81I\xfc\xe9\xed\v\xb7\x8b\xf1\x18\x18R\xafN\xc0-\xa8\xc0\xb3\xdc:\xb1\x90Iu\x98#E\x0f\xecr\xe7]\xe0\xbb_ZP{\"wX\xc2୷\ueb02\x177\xda\xfa\x98A\x00za<\x95T8pe:\x01E\xde\tgK\x8c\xe7\x83}\xac\xe4\xeb\\5+έ\x17\x96\x1cc\xa2\xbb\x90\xb1w\xa2ےٟ[\xd4\xff\xbc\x8e\xdb\xf1\xaeۢ\xad\x94o\xcf\xfeJ\xc5\xfa\xa7\x14\xe9祃\x16\x8b\xf2\x9fˑ[r岭\u05fc\xa2\xfb㒨\xcfXd\xff\x1c\xc5\xf5\x99\x98\xca)\xa6?\x0eO/P<\xff\xa2E\xf3/U,\x9f]$\x9f\x95\xc7\xccNZ\xe5\xa6\x19O\xac\xfa^κ\xcf\x17\xbdg\x14\xbbgdҖ\x17y\xc2\xf22\x8aُ+bϠY\xeeV|\xc1b\xf5\x17,R\x7f\xe9\xe2\xf4\x05\xceZ\xf8|\\\x11\xfa\xc9\x19\x98\x90\xea\xff\"K\xb8\x95\xca,9'\xb7\xe3\xf6\x89Lj\xcfa\x93\xbc$\"4M\xac\x12]\f\xef^\x9c\xb6\xa8t\xd23\x98ӟei綔c\xb9\x1b5?8\xab\xbc\x01\x05\xc2]j\xf2\x1f\xf7_\xbfD\xf8)\x9b\xd7[ƣ\xeb%\x9c\x05Sz\xe4\xf8Ԝ/fr\xd8B\x1b\xe0\x89\xf3\"\xb4a\xff\x8e\xb7\u06dd\x11\x0ezw{\x830\x82\x9d\x86\xd7\xe5\xc5*\x8a\x98\xb1\\\x83\xd5X\x11U\x93\xdb\xe2f3\x808\xac\xf8\xed_\x1a\x05\xa5\xbb ,hL\x16j\xbc\xecƻ\xbdq\xf3\x98\x1a\xe5\xa35\x1aŞHǑ\x15S媡\xca\xec\x91m\xf4\xc5`\x0eA\xcd̅s&\x05\xeb\xe1\xa5gI\xf4\x86\xbb\xce0\x17\xb9o\x86\xd9\xde1\xeeN\x99\xc7\xf4\xf9\x93œ'O8\x8fi\x8d\xbdBL%^'\vL\x9e,L\xa6\x8e\xb9\x17)\xb9\a\x16.I\xea\x89\x06J\xae\xa5ذ\xedg\xda\x045\xe2\xf09),|\x88\xa6\xb1\xa0-H\xb7\xabXW\x9b\x86z\xa7\a\x95\xc6\x12VB\xe7BV\xe5G\x84|\x1b\x00kp\xe9m'\x95\xe2\x12\x1aP\xab.\xde\xd6\xddݴo\xa6g\xab/F.\xab\xbf\xe5fP\xbb`Š\x01%\xfc\xb7\xd4\\}\xc1\xcd=\xd6\xdb\xf4\xa6\xbb\x8f\x93\xb5ذ3\xb4\x8c\xe3\a\xc7ˉ6\xa3b\x9d\x04\xf0Q<\xa5\xc3\xe0F\xaa\x9a\x9a\xb0\x030\xa0G\x1d\xde\xdd\x1dq\xf7\r\x14\x97C\x92\xff!\x93\xff\x90\xc9\x7f\xc8䧕\xc9V\xb8\xdd~?)\x14~\x17{\xcf۞\x94\xf3\x18\xfeO\x80\xb1\xfd\xd1\xfcԂ6\xbaJ\\\xfaw\x9e\xfd\x89\xf7a\x1aj\xdas\x16\xe9\x00\f\xd6Ɋ\xaagA>B\xb01òq\xb7b\xb7\xa4\x04\a\xeeOZ1~ы\u07beL\x99N\xe6\x15['_\xae\xe5\xd03!~0#aE\xdb!\xa6N(\xd0Yt\xb73\x0e~\xcc\a\x162\xaff\xcaS\x18'\\DŽ\xf8\xca\xc5\x15I\xdeҔy\x13ӯ\x8a\xe8\x19\xa9\xa6\x8b\nʖé\xb7\xce\xde\xf7\xfa/\xdf;\x1bF˸y\xd6\"\xbb\xa7\xa0\xad\x855\xbc\xe1\xd6S\xc2C\xeeSr\xca\tǀ\x8d\xbb\xf2\xb1pw!\x17\x05h\xbdiy\xa8\x1c-\x14P\x03eh\xcet\x9c\xf1Q\xb5\x8fm\xc3%-A9\x93l\x01\xad\xff9h<\xe2\xd9\x02_\xb6\xaa\xbb\\x\xf6bֳ$W\t\x1c\f|\xf8a\x14\xfd\xc8\xf8y{\xf1\xfd\bVZ\x8d\xb9\x11\xfdYK\xa3\xa85\x80\xbbj^\x9f+\xf7W\x90\xa2U_J\x94n1\x1f\xda\xcb\xdcNL\x04\x83\xcf\x1a\x8c\xf1Y{\x8cx\xf9\xfb\xdd\u05ce\x11\xed\x04\xc9\xfd^\x1b\xa8\xe3\xad\xf6\xe4O\xb7\xb2tר:\xae#R\x91\xeb\xfb\x9bA\xe3\xf7\xd4P\xf2Y\xee\xe0\xcfȞ\x15\xc5\\!l6P\x18\"\x05\xf9\v\x97\xc5Cת\xbb\x9f\xff\xbc=>}j\xae\xa1\x8ar\x0e\x1cQ\xfe^>\n\xcbY\x19d\xbcM\xf5\xeb\x9dv.Ze\r\xb3=\x11m\xbd\x06\x15\xf09\x81\xf2\x8dT\xf3\xe7\x8e\xdc2\x980\xb0\x85T\xd4\xfaQ1\x03\xf7\rU\x1ar\x19\xf1\xe7Q\x17\x17\xd3\xddp\xbau\x05\xe6%+\xa8\x81\xc8{8\xc2\xd4\xf4=\xbfZX|\x8f\xf5\xber\"\x95t6\xc9&\x05\xf3\xd4\x15\xe5\tc+yI\xb9\xb3\xa9\n\xda\x18\x00;-+\xfc\xe1 _\x86\xae\r\xad\x13~\u07b2\x98\xb8>\x04\x83?-\xa0\xca^5{\xff\xba\xe2X\xb6N\x1e\xa9\x8eG\x94\x92\xdeS\aہAg˂\x86\x92\xc0\x0e\x84ݝ\x1b\xca8\x94s\x9c\xfa\rӳj\a\xea'\x1d\xe1`}\xbde\xf1{C\x95\x89S?\xb4D\x9d\x17~EJj`e{\x9ff|\xa7\xef\x87V\xea\xc4\"\x1b\r \xc5\x00\x854\x94\a%c\xf926\xa8f\xae\xe5\xb9\x0f?\xc0\xc0\xf9\xfeb\fy\xf4\xcb.\x1d쪻 \xdbK\x82\xeeR\x96\x89\x81B.-\t$ޭ\xddY\x95S7\x19/\xe9?\x84\xfa\x11'\x95\x81\xe3O]\xeb)<\xbai:\x97\aD:V@\xd0}4U\xdc\x19'L}\xc6\xcfh*\xaa\x97\x1c\x8c[\xdb&\x9a\x1d=u\x15݈\xbb\x89]\x99\xbe=bE\xbe\xc0c\xe2\xadC\x16֔\xe0\xaeJ4\xb9\x11\xb7Jn\x15\xe8C\xa6[\xe1-\x01Ll?Ju\xcb\xdb-\x13_\xa7\xcfS\xcd5\xbe\xa5\xca0˴n>\x89\xbe\xd7A\xc7%\xbe-\xf7\x9e\xfe\xc0\x04\xe5\xec\x1f)Y\xde\xff\xb84\u008c\xbck<\xf2N\xd1P\x01\xf1K\x02\xd0K\xe8\x9ftO\xfd\x84q/\xc9\x17\x99\xdcƾ\xec\x8a\r\x812M֠\xcd\n6\x1b\xa9\x8c\xf3\x11V+\xc26\xc1@\xb2\x12\x02=}\xf7\x8b8\x84\xa5\xd2ٱ\xa0%\x18,\x1b\x1f\fV\xa8u0hPӽ\x8b)Ӣ\xb0^\x1d\xbcц\xa6\xbc˳\xe44\x06\x1b\xfc^\xc9\x11!7\xfd\xf61J\x1b\xc5\a\x82s\xa8\xc3Kb\x9cB\xe7S\x95\"\x83;\xa8\x88\xb6\xd8;E\x98\x10'\xc6n\xa6\x03'y\xaa\xe6[\x842%\x1e\xfd\xfa\x06?o\xe1˖|#K\xb6\xa2\xa2b;yL\xbcR\xb2\xddV\x817\xa7\f\"R\xb6\xe8r6(\nt\xf8\xf11\xd3*\xd1+\x85\xf1\x95\x8bSR:Nw\xdaF9CP\xab\xee\xb8h'\xaaft~v\x9cw\x02\xe2\xa2\xeeO@\xa4z/\x8aك\xad\x87YƣL\xcb$\x12\xa24~2$D\x88SH\xe8\xdb\x12\x9d\xc7\xf3\x9b\xc1Ȕ\x8dr\":\xe6\x8d\x18\\\xe2<\xa8\xe5E\xf7\x8d\xa0\xa1\xb9s\x1c:\xf4\xc0\xf9;)p:\x80p\x8c\xe7\x8bc\xa7\xfd\xde߮Ǻ\x8b\xd6և\x93}\xd7\xef#\x18\xa3\x8b\x05\xac\x17\xdb\r\x13\xfc\xcd?\xb1Mj\xbf\xc4\b\xe0\x9f\x0f\xbe\xbe\xf0\x05\x01\x8fT\t&\xb6'a\xe4g\xdf7\xe1\xcf{\xb0\xcf\xe9ч\x99?\x99O\x9fTK\a/\x91\xc1\xcb\x1e\x9e\xfdH\xfe\xcd\xff\x06\x00\x00\xff\xff\xac\xd3dc\xa1u\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=\xdbr\x1c+\x92\xef\xfa\nB\xfb0\x97P\xb7DZ\x97\xd8ЛG\xb6g;\xc6c+,\x1d=\x0f]\x95\xad\xe6\xa8\n\xea\x00%\xb9wv\xfe}#\x13\xa8[\x17]T\xab%ϙ1/\xb6\xaa!I2\x93\xbc@\x02\x8b\xc5\xe2\x8cW\xe2\x0e\xb4\x11J^2^\t\xf8fA\xe2_f\xf9\xf0\xdff)ԛǷg\x0fB\xe6\x97\xec\xaa6V\x95_\xc1\xa8Zg\xf0\x1e6B\n+\x94<+\xc1\xf2\x9c[~y\xc6\x18\x97RY\x8e\x9f\r\xfe\xc9X\xa6\xa4ժ(@/\xeeA.\x1f\xea5\xackQ\xe4\xa0\tx\xe8\xfa\xf1\x0f˷\xff\xb5\xfc\xcf3\xc6$/ᒙl\vy]\x80Y>B\x01Z-\x85:3\x15d\b\xf4^\xab\xba\xbad\xed\x0f\xae\x91\xef\xd0!{\xe3\xdbӧB\x18\xfb\xe7\xde\xe7O\xc2X\xfa\xa9*j͋N\x7f\xf4\xd5l\x95\xb6\x9f[\x98\v\xf7\xbb\xfbM\xc8\xfb\xba\xe0\xbamsƘ\xc9T\x05\x97\x8c\x9aT<\xa3\xaa~l\x04b\xc1x\x9e\x13\xb5xq\xad\x85\xb4\xa0\xafTQ\x97\xb2\xe9 \a\x93iQY\xa2ƍ\xe5\xb66Lm\x98\xddB\xb7\x1f,?\x1b%\xaf\xb9\xdd^\xb2\xa5\xa1z\xcbj\xcbM\xf8Ց\xcf\x01\xf0\x9f\xec\x0eq3V\vy?\xd6\xdb;v\xa5\x95d\xf0\xad\xd2`\x10e\x96\x13s\xe5={ڂdV1]KB\xe5\x8f<{\xa8\xab\x11D*Ȗ\x03<=&\xfd\x8fS\xb8\xdcn\x81\x15\xdcXfE\t\x8c\xfb\x0e\xd9\x137\x84\xc3Fif\xb7\xc2L\xd3\x04\x81\xf4\xb0u\xe8|\x1a~v\b\xe5܂G\xa7\x03*\b\xf62\xd3@2}+J0\x96\x97}\x98\xef\xee!\x01\x18\x91\xa8\xe2\xb5\xf1r\x14Z_w?9\x00k\xa5\n\xe0\xf2\xac\xad\xf4\xf8\xd6\xc9^\xb6\x85\x92_\xfaʪ\x02\xf9\xeezu\xf7\xef7\xbdϬO\xd1\xff[4\xdfY\xc3\r&\f\xe3\xec\x8ef\x10\xd3~J3\xbb\xe5\x96i@1\x00i\xb1F\xa5a\x11H\x9d3\xa5;\xa0*\xd0B\xe5\"\v,\xa2\xc6f\xab\xea\"gk@n-\x9bڕV\x15h+\xc2|r\xa5\xa3z:_\x0f\xa1\x8f\x05G\xecZ91\x05C\x92\xe9g\x1b\xe4\x9eHn\xf2\bӎ\x878\x88\x9f\xb9dj\xfd3dv9\x00}\x03\x1a\xc1\x84QdJ>\x82F\x8ad\xea^\x8a\xffm`\x1b\x9c\x12\x96$Ղ\xb1\x8c\xe6\xb3\xe4\x05{\xe4E\r\x17\x8c\xcb|\x00\xb9\xe4;\xa6\x01\xfbd\xb5\xec\xc0\xa3\x06f\x88\xc7_\x94\x06&\xe4F]\xb2\xad\xb5\x95\xb9|\xf3\xe6^ؠ\x903U\x96\xb5\x14v\xf7\x86t\xabX\xd7Vi\xf3&\x87G(\xde\x18q\xbf\xe0:\xdb\n\v\x99\xad5\xbc\xe1\x95X\xd0@$)\xe5e\x99\xff[\xe0\xb7\xe9u\xbb73]!u:\x83=\xa8g\x9dt9Pn\x88-\x17\xf0\x13\x92\xee뇛ۮ\xe4\t\xe3\x99\xd2\x11\xc0\x18\x7f\x90\x9aBn\xc0낍V%\xc1\x04\x99WJHK\x7fd\x85\x00i\x99\xa9ץ\xb0(\x06\xbf\xd4`,\xb2n\b\xf6\x8a\x8c\x16\nm]\xe1\xdc͇\x15V\x92]\xf1\x12\x8a+n\xe0\x95y\x85\\1\vdB\x12\xb7\xba\xa6xXّ\xb7\xf3C\xb0\xa7\x11\xd6\x06]qSA֛j\xd8NlD\xe6&\x14\xaa\xe4F\x95\fԲ+㳟~!\xdd7\xfc:\xc0\xc3)\xc8\xd0+\x184JvK\xccom#\x8a\x9c\x83ƔfR\xd9=\x98\xfb\xaa\xb5C\t\x0fe\x02\x93=ag{*5Œ\x8e\x00im\xebP\xbe\xa2\xac&\xbc\x1fD\xb5*K\xc8\x05\xb7P\xec\x8eB\xbf\x0fb\x8c̊\xfaak\xa7\xe7ŦG\xf4\xbc\x06&:\xedi2\xfe5\xd4ط\xc6\x7f%\xcbNF\xd4Ѥ\v\xac\x96-\x0f\a\xfdHx\xda'\rc\xab\r\xb3\x1au\xae\xc7\xeeI\x14\x05\xcedĸ\x82\xbc\x87Z\xbc;\xb1a\u0086Ѭ9a \xd9\xd2yQ\xcb\xd6gh\xec?\"8\xc0\x8eԾ\xeb\x1f=\x15n\x99\x84o\xb6\xad\x85Î\x8c`\xc3\v3\x18\x82WH\xb3\x86q\xc1ֵ=\x0e\x03(+\xbb\xbbpm7\xaa(\xd4\x133\xa4l\xd1\bn\xc4}\xad\xddd\xffm\x0e\x1b^\x17\xf6\xd2\xe1\xfc\xbb\x98\xb4\x8eO3\ve\x85&\xf3\x189\xbd\xf5mq\xc08[\xf2&\xfe\bnr\xf0C\x94w?F\x80(\xe7\xc5VZ=\x8aܛ\xf3=u\xc5\x0e\xaa,,\x8eQ\xb78ґ_\a\xa3\xf9cS\xb93\xb7\xb6\xea\x89=b\x00\x00\xe8-r\x1c\x14\x02\x85\x9c\xd5\xd5\xc5(Lƞ\x84ݲJ\x19#\xd6\x05xρ\t\x99\x15u\x8e\n\xe6c]\x14$\x82+\x99i(\xd1\xe1)Ƹ\xcd\x18Ⱥ\x1cG|AP\"?u\xe0\x8e\xd68\xa0\xa7\xb0dF\xdcH^\x99\xad\xb28\x8dTm\x13\x887*\nX\xaenV\x03h\x1d\xea\"\x8f)~\xa0\xc9m\x15{\xe2\u0092\xa1\xba\xbaY\xb1;\xa2{h͜\x86b\xb6\xd6\x12\x9d\x83H\x7f_\x81\xe7\xbb[\xf5\x93\x01\x96\xd7\xe4ׄ\x98\xe0\x82\xada\x83N\x80\x06\x84\x81?\x81\xd6h\x14\r!\xa1\xea=?3\x94['\xc78\xa1\xbc\x9b$\f{\xfb\aV\nY\xdbѩ:Ie\x94\xa6R=\x82~\x0eq\xdfs\xcb\xff\x82@\x064%Q%\xe8~\x96\x11}\xd7;\xfaq\x1d1_\xae\xac6\x1d\xa8°\xf3sT\xa1\xe7.\x86?\xbfp\x10jQ\u0605\x90\xdd~\x82>Ǟ\x8e#\x88\xa3\xafc\xba\xb9U\x1f\x8d\x9b\x90ϢO\x04\xe6\x88\xf1\xacT\x1e&\xfaF\x14\xc0\xcc\xceX(\x83\xaaoåN\f8,\xe4`\x15\x85\ac\x90\xde~P\xe3\x04\x91uQ\xf0u\x01\x97d\x19\x0f\xd0l\\I\x8f\x11\xed+\x18+\xb2S\x92\xccA\x1c!\x98\xf6?\xf4(C\xf1\x16\x7f\x00\xc6#\xe0==1\xb8+\x8a\x0e\xd1\xfbԊ\xe2Vi\xc8\xd0\xf1\xbf\xf4\x01\x85\x80\x82\x82\x18\xa9X\xa1\xe4=h\x87Ec\xe0\xd1\xc0\x00\nh\xce\xd0W\xd7h\x96\x85d\x9b\x1a\xdd\xf8%C-\x11\x95\x11!\x8d\x05\x1e\x11\xe6\x13\xf0\x0e\xbe\xa1E\x80\xfc\xaa\xa8\x8d\x05}\x93\xa9\n\xf2\xb0j7j\xceRy\xf8\xe1 d\x1f\xf4\x15\"\x03\xe4C\xe6*-he,&\xdam\xfc\x87\xe6\x91\x16\xf1\x90\xd5~\bm`7\xa9[\fXlx\xfe\xfb\xf3\v\x92\x80~\xef\xfd~\f\xe3\x1a\x1a2\xcd\xd2\xcd\xe4&\x8d\xb7\x10\x16\xca\bu'u\xd4\f\xbes\xad\xf9\xee\x00כ\x15\xc8\x17\xe0{\f\xf6\x80\xf32T\xfbN\xbc\x1f\xf6\xff\xaf\xc8\xfd\xd3\xf2\xdb\xd0*>\x17\x12\xf9\\\bc{l6n\xe9\x0f\xc9:\x16w{\x02I\a\x13\xd5\xe4\x14W\xffA\x88yҹ\x13\x9b,\x8dl\xfa\t\xf0OEɭR\x0f)\xd4\xfb\x1f\xac\u05ee\xfb\xb1\x8cv\x9a\xd8\x1a\xb6\xfcQ(m\x86k\xcb\xf0\r\xb2\xdaF5\v\xb7,\x17\x9b\rh\x84E{#\xcdV\xca!b\x1d\x8e\xf9XGeE+\f\xc6\xd52\x1dYJԈ\r\x85\xa2\xfa(T\xe7\xe0`hA\x0eD.\x1eE^\xf3\x82|\t.37>\xde\xe0\x17\xd3j\x13\x02\xb1\x87\x7fT\xaa]q\x0eM\x18$2\xb1\xb7T\xa8$\xa0\x8f_bl\xb4_5N\x89\xb0\xfer\xb0od\xa6\xae\v0\xbe\xbb\x9c\xdc\xe4V']\xb4\xccr\v3\x05_C\xc1\f\x14\x90Y\xa5\xe3\x14J\x91\x03WR\x95n\x84\xb8#Z\xb6\x1fm\xb5\x83\x99\x00\xcb(\xc4݊l\xeb\xdcW\x144\x82\xc5r\x05\x86\x96\x92xU\x15\x11\xd3ՖI\xe1\xf0\x9dM鍶$h\x90!ܘ.iK\xa2~n\xcb(\xd9۹٧\xfa\xf8\xe6\xc8(\xbe\xffJD\x0fV\xe7Ha\x9f\xd0$\x8c6Y\x92\xe7C\x94\xf4Hq\x01f\xd9Y\xd2\x146|Mah\xcf\x7f\xdc\xdb\x7f\xda#ʯ\x8bw\xc7M\x98\x19\xac\x9b\x9cS/˸\xa6\x9b\x7f\x12\xbe\x91ɺ\xf1\x16k\x16\xcf>u[^\xd0V\x8agH~\xc16\xa2\xb0@N\xd5\x14\xa2l\x06\xe7NI\xa0T\v\xcchg\xddf\xdb\x0f͆[B\x8b\x01\xad\x86\x00\x9c\x83\x1e\xa2\x1c\xe2A\x02Hָ\x16\xb4\xd3,\xdcJ\xb9YR$\xd9\xfdB\xae\xe0\xbb\xcf\xef\xe3\xb1g\xb7$J\xeaޠ\x12&\xad+\xef\x06\x8eQ\x17W\x1f\xaa\x84_\xc8_k\x02A\xb7\xffp\xc18{\x80\x9ds\xb1\xb8d\xc87\x1e*'\xa2\xa0\x81\xd2(HS<\xc0\x8e@\x8d\xe7E\x8c\x979\xd2\xe2\xca\x03\x8cl\x95\xc6J\x8f\xae\x88\x9f߀rt\xc3\x0fD\x98\x94\xd9Ԗ\x86\xa8~\xfa\x8cd%\xc4\xcb\f\xbd\x14J\xe0ˑ\xc3N\x16\xa7n_\xfdL\xa2\a\xd8\xfd\xc68^\xe3,\xdb\nک\xe3\xb4z\xa36\xb3\x18\xee\xca\x1d/D\xdet\xe6\xe6\xd5J^\xb0\xcf\xca\xe2?\x1f\xbe\t\x83\x1d˜\xbdW`>+K_^\x94\xcan\x10\xafA\xe3\xb0\xfb\x87\x03t\x96\x04\x89\xd8\u0378q\xb6\x14\x05\xb5\xe1\x870l%1$s$\x9a\xd1\x1d%X\xb9.]gemh\x7fZ*\xb9p\xcbbc\xbdy\x1e(\xddc\xc1I:\xf6\x9dޢ1r\xbf\xb8T\xaf\x82g\x90\x87-:\xcaA\xe2\x16\xeeE6\xa3\xcf\x12\xf4=\xb0\n\xcdB\xba\xb4\xccP\xd4~d\xf3\xc5+\xdds\xe8\x96o\x8b\x87z\rZ\x82\x05\xb3@\xb3\xb6\xf0P\xac*\x13\xe9\xe2m\xc2H\xa2\xceXY\xe0\\O\xac\x19\xa4%\xa9z$\x8d\xe9p\xf5Tb=\x93L\xe4E\x90ە$\x05\xddl\xe0y\xd6k\xa6\xdc\x1c\xa3b:cq.@\xc9ik\xedoh\xe9i6\xfe\x9dU\\h\xb3d\xef(\x1d\xba\x80\xdeo~a\xb2\x03&\xb1ۊV\xd9\x7f\xa9\xc5#/\xd0\xff@\x03!\x19\x14\xce\x1bQ\x9b=_\xed\x82=m\x95qnC\xb3iw\xfe\x00;\xb7\xa3\x9c\xd4mWa\x9d\xaf\xe4\xb9\xf3e\xf6\x14O\xe3\xf8(Y\xec\xd89\xfdv\xfe\\\xf7n\x86DϨ\xda\x13\xe5\x92W\xe9\x92L\xc9\xc6s\x02\r\fփC\x84\x8d\x9b\xac[\f\x10\xa6(\x90,ʕ2\x91d\x91\bZ\t\x82~\xad\x8cu\xeb\x90=\x7f\x7ft\xa1R\x85\xc5I\xc67\x1643V\xe9\x90NJ\x8a?e)\xbe[n\xb7`\xc0\xefC\xf9EO\a\x18\xa3\xd8\xf3V78\xabr\xee\xf6¨#\x9e\x91\xf7Dm+\xad20Ѽ\x88\xb6$ڦ\x91\xac\xa5.\x1d\x9au]\ue8bfM\x92\xd6NY\x94\x0ee\x9e#\x8f\xa4;\"2\xfa\xf0\xad\xb3D\x8d\xda\x05\xffN\x91\xd6cpdt\x00\xa6,\xf90\x87:\x19\xdd+\xd7:\xcc1\x0f̅[\xfa\xbe&\x9d3\xc7\xebhD\xf9\x1f͵)\x85\\QG\xec\xed\v\xbaC^\x8b\xc7ң\xc6\xca\xf1N\xfaU\xe8\xac\xe5^\xf3\xc1'\"*\xda\xf8\xd1\xd0c\xee\xfe\x9e\by\xd7R\xd9\xce2\xceL'\xbaR\xf9o\f\xdb\bml\x17\rs \xb1j\x14\xd4\x11\xa1\xa7\xfc\xa0\xf5ё\xe7\x17\xd7z\x90:\xe9\xb2\xcd\xe7\xc4ہ\xa4[\xfe\b>\xdd\x17d\xa6jIKa\xa8\a\xb0\x9b\x19\x10\x1dk\x9c\x15H\xb4w\x9d\xc6\xd1\f̱\xb2 I\x12rrݬ\xdb\xe4#\x17i\xebV\xec8\xb6\xdaC9\x9cc\xe5\xf8y\x14\x12<\xbbg\x10J\xfeM\x94u\xc9x\x89<$\xb7C\x94\xd0\x1cCp\xecn\xd2>\xb1\x05\x19-\xabp\x96U\x05X\xf0i\x9b3\xf0Ȕ4\"\x87\xc6\xf4{\x11P\x92q\xb6ᢨ\xf5\f\xad:\x9b\xe4s\x830\xafMN\x1fY\xa5#\xb2 \x12%\xae\xb3\xcf\xf0\x82\xa75~\xa5\xe7\xf9\xb1)\x0e\xa3\x86\xf9\xfeb\xa5\x85r'(N\xef2\xfa\xb4c.w?|\xc6\x1f>\xe3\x0f\x9fqNG?|Ɖ\xf2\xc3g\xfc\xe13\x1e.?|Ɣ\xf2\xc3g\x9c\x89\xc8\xf7\xf2\x19S0\\\xd0\x1a\xe7\x81\nIX%\xa6BL\xa1=їO\xfa\xf1g5N\x92˼\x1a\a9r\x88'r\xfc\"\xe6u\xb4ƫIn\xc6\x19\x18\xe6\x8e;z\x9a\xe00\x9f\xe0\xf4L@\xe0\xf4\xa7gV\a!\x9f\xf0\xf4\x8c\x1fBZ\x84q\xd4ٙ@\xa4\xf9\xa7'.|\x12Q\t\xaaA\xfe\x83mU\x1d9\xb51Aڄ,\xda4\x82\xf4\x92j}b\x04X\xfe\xf8v\xd9\xff\xc5*\x9fbK76D\x80\xd1%\x1e<\xa7\x9b\x1b:\az\xbc\x1e\b\xf7K\r\x852\x02Li&E\xe1$6@\xe8\xc9+\xfbR\xb9\xd5\xc1\xa3\xfd\xa6\xe95\xac\xf4Dܹ\xe9\xb7M\xb6\xe4\xb4\xfb\xfe\x8c\xa4ۓ\x1e\x8d\xfani\xb5\xc7%Ӧ\xaeP&$Φ\xa7˦\xb0Օ\xf4$\xd9\xe4\b95!v\xee\nċ&\xbf\xbeL\xcak2\xcd\xd2\xd2[\xe7R\xecURY_9\x81\xf5\xf5\xd2Vg$\xab\x9e\xfe\xd4K\xfaZ\xfa\xd1ٕi\xcb2\x87\x13N\x93\xd2L\x93\x96nR\x06|\xd4P\x93\xd2G\xe7&\x8d&q2}\xba\xbejZ\xe8\xab&\x83\xbe~\n褴MV\x98\x9b\xe49~3d(\xd3\x0e@\xf1=\x84\xf3\xb9dR\xba\xe7\x9a?+\xee\xfc2\x80\x85\xc2\x12\xdc\xd4W\x8c\x03ʺ\xb0\xa2*\xdaK\xecb\x01\xe7\x16v\xcdeE?+:\"\xefo\xea\xfa\xf2\xb5\x91\xf8\xe5 \xaa\xe1\x86=AQ0\x1e\x9b\x9b{T\xc8\xdc婙Z\x00\xdaF\x9c\xe5\xfe2&\x7f\xe3ꅛ.t\x1b\x00Y\xd82\xb6\xd4\xc7\xe5\u16fe\x0e\x1a\xb0T=\xb6登x\x83\xbe\xfdR\x83\xde1\xbaw\xac\xf1\xcd\xdaC\xa5~\xa2\x1b\fL\x83\xfa\xf1\xea\xf0О\xc9^\x80Ӫ\a\xf6N:\x8f`\x88\x13\xb5A\xbd\xd3\x06t\xa8Te\xecr>\x16&\xe8>\b\xa9\x1a\b\x91\xa6)\xce\xff\x9cS\x96/\x11ޝ\"\xc0K\xf2\x80\xe6y\xaf\xdf\xf1\xf4䱧&ӓQ\x92NI\xbeD\xb87'\xe0\x9b實\x9f\x82\x9c\xbf\xf1\xfc§\x1e_\xea\xb4\xe3\f\ua95en\x9cO\xbbW:\xcd\xf8\xea\xa7\x18_\xf3\xf4\xe2\xacS\x8b\xc9\xe9Y\xb32\x0e\xe6\xa4V=\xe3\xb8]Z.\xc1\xf4)\xc4\xc4Ӈ\x89\x99\x06i\x83?r؉\xa7\v\xe7\x9f*L\xe4\xef\x9c)\xfdʧ\a_\xf9\xd4\xe0\xf78-\x98 \x81\tU\xe6\x9f\n|\xf6\x96\x94\xd29\xe8\xc9m\xbf9R;)\xaf\xa9\xb1\\\x1f\xb1\xc1\xbeV\xb8M\x16k\xf5b\x002K\xfe\xf5\x03z\xe9\xe2\xd068Jf\xc7#\xea\xedK\xb6\xeeZ\xdf!\xf6O`\xb8\xadK\x03\x15G\x03@\x81\x1b\xa5fE]\x85\x0f<\xdb\x0ez\xd8r\xc36J\x97ܲ\xf3f\xb3\xf8\x8d\xeb\x00\xff>_2\xf6Q5\xb9:\xdd\xfbҌ(\xabb\x87\x91\x18;\xef6x\x9e\x94D\xa53\xf4|\xad\n\x91E|\xce\xd1{\xf5\\\x83\xbdˆ\xe8濬\x93-\x12\v|\xb0\xb9\b\xb7.\xf6\xafdv\x97\xe0\x1f\xb9V\xc2+\xf1'z\xa3\xea\x04\xabn\xef\xaeW\x04+\x88\x11=~\xd5$(6,_\x03\xba\f\xed\xd8\x0f\xe9\x93զ\a\xb5\x9f#\xdc}\xe1\x03r\xf7\x9cKp[\xbcj\xce\x14j\xad\xeb\x95\xc3\xe5PO(_\\\xee\x98\xf2\xefu\b\x9d/*\xae\xed\xce%\x13]\xf4\xf0\bv}j\xd5젵\xda\x7f\xae\xa6[zd\x0f/\xd5\xd0N\xf6\xae\xea'\x0f\f\xe9\xf9\x1c\x9c\x0e\x9f\xaa\x9els*2Z\xa5\xf9=|R\xeeA\xa2\x141\xe9\xb7\xe8=W\xe5=\xb7\x90\xaf\xed'aL\xd1\xfb\xb1\r\x01\xb6\xe73\xf6.\xfaGl\x8f|\xca\xc0\xda\xe292r{\xfbɍ\x94ށy\xef\x9ftA}l\x00Y\x10(࠭\xf1\xbf[\xf5D\x17\xe0\xc7טë+\x9d\x87߀\x0e\x8aP\n\xefQì\xabB\xf1\x1c\xf4\x15\xbd<\x930\xe2\x9fz\r\x06\xee@\xff\xfd\x1ao7#\xe3\t=\xbf`\x96\fztE\x01\xc5GQ\x80q\x88'\x9a\x86\xeb\xfd\x96\x8d\xa5\xa8˵\xf3T7\xf8c\xd3\xc9\x01\xcb\xec\x86J\x1b\f\x15h\xf4\x13\xddVDm\x82\xe4\x1f&\x06k\xf8(\xa4\x85{\x18\x8f\xa1'l\x82{\xa3\x81\x1c\x80\xa0\xc0(\xe2\xfbsl\xe5\xb1G\x90\xbbx\xeb\x81\f4\x8b\x9119Vޭ\xba\xbe\xbb2\xac\x969m\x00\xdc\xfd\xe9\xe6(\xf9}\xec\xbd/\x13tB\x8az\xbf\x1bo\xd9\t\x11:ډ|\xfa\xb8\x12\x8f\xc1\xe2ƨLPTA\x0f\n\xd1I\xa4\x97\xbbC\xfcP\x80x@:j\x03_\x9e$\xe8\xaf\xc1\x02\x99\x95\x8c\xbd\xdb2\xad\xfd~ڃ\x16}\xaf\xc5*\xec{\x04\xc6\x00\x00Sa\x9f˸\x97\x80\xc2\xf6\x9a0͋p\xfb\xf4\x9cP!qK7\xee\xb0-\xc6\x1f\xb0Z4\x0fm\x9d%\x90۽\x7f\xd4\a<\xfe\x0e\xa0{()㕭uЮ\xb5\xa6[\xd6\x11\b\xb8Kȏ{\t\xb0} \xee\x18\x06\xb7/\xb4\xb5\xfb\x0f\x93oȎ\xc0i\xde\xf2\x8b>\f\xe6\"j\xf7\xc6\xeb\x02\xe1\x1f\xc7\xe3\xd1\x19\x838߸\a\xdf&\x88\xf0\xa9\xad96\xe0f\x188d\xff\x84ܫ\x8e\x84.ݟ\x18\xc35\xd6iN\xb9z9\xa2\x86\xe1\xb2\xfe\x9b\x18\x13ƏB.\xd8g؏\xd8\x17\xec\x83\xc4A\xec\x13\xc0\x9dw\x84\x9c\xb6VH;\xce\x19\xe2cӊ\x0e\x9b\x8eh\xc8i\xb1\xbd\x1b\xc0\x18d\xb2ӣOM\x15w\xda\u0530ߊ1o\x94v\xcc2\x1c\xe8\xef\xf6~\x8dj\xf0\x83\xda;\xa6\xb9G\xd5\xc8\xdeGz=0\xefH\x8e\xf7һ_\xeau\xfb\xa0\x02\xfb\xdb\xdf\xcf\xfe?\x00\x00\xff\xff0\xe5e\x05\x8f|\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcV\xcfo+5\x10\xbe\xe7\xaf\x18\x89+\xbb\xa1B \x94\x1b*\x1c*\xe0\xa9j\x9ezw\xbc\x93d\xa8\xd7^f\xc6)A\xfc\xf1\xc8\xf6n\x9b\xee:\xb4\x8f\x03\xbe\xad\xed\xf9\xe6\x9bo~x\x9b\xa6Y\x99\x81\x1e\x91\x85\x82߀\x19\b\xffT\xf4\xe9Kڧ\x1f\xa4\xa5\xb0>ݬ\x9e\xc8w\x1b\xb8\x8d\xa2\xa1\x7f@\t\x91-\xfe\x84{\xf2\xa4\x14\xfc\xaaG5\x9dQ\xb3Y\x01\x18\uf0da\xb4-\xe9\x13\xc0\x06\xaf\x1c\x9cCn\x0e\xe8ۧ\xb8\xc3]$\xd7!g\xf0\xc9\xf5\xe9\x9b\xf6\xe6\xfb\xf6\xbb\x15\x807=n@\x90ә\x1a\x8d\xc2\xf8GDQiO\xe8\x90CKa%\x03ڄ\x7f\xe0\x10\x87\r\xbc\x1e\x14\xfb\xd1w\xe1\xbd\xcdP\xdb\f\xf5P\xa0\xf2\xa9#\xd1_\xae\xdd\xf8\x95\xc6[\x83\x8bl\\\x9dP\xbe \xc7\xc0\xfa\xe9\xd5i\x03\"\\N\xc8\x1f\xa23\\5^\x01\x88\r\x03n \xdb\x0e\xc6b\xb7\x02\x18\x05\xc9Xͨ\xc5\xe9\xa6\xc0\xd9#\xf6\xa68\x01\b\x03\xfa\x1f\xef\xef\x1e\xbfݾ\xd9\x06\xe8P,ӠYֿ\x9b\x97}\xa8\x85\t$``\xa4\x04\x1a\xc0X\x8b\"`#3z\x85B\x19\xc8\xef\x03\xf79\xad`v!\xea\x05\xaa\x1e\x11\x1e\xb3\xfec\x98\xed\xcb\xe1\xc0a@V\x9a\xa4)\xeb\xa2\xe2.v\xff\x8dxZ)\xd6b\x05]*=\x94\xecy\xd4\v\xbbQ\x1e\b{\xd0#\t0\x0e\x8c\x82\xbe\x14c\xda6\x1e\xc2\xeew\xb4\xdaΠ\x8b.\x922\x19]\x97*\xf6\x84\xac\xc0h\xc3\xc1\xd3_/ؒ\x04JN\x9dѬ\x9dWdo\x1c\x9c\x8c\x8b\xf85\x18\xdf͐{s\x06\xc6\xe4\x13\xa2\xbf\xc0\xcb\x062\xe7\xf1[`\xccRo\xe0\xa8:\xc8f\xbd>\x90N}hC\xdfGOz^疢]\xd4\xc0\xb2\xee\xf0\x84n-th\f\xdb#)Z\x8d\x8ck3P\x93\x03\xf1\xb9\x17۾\xfb\x8a\xc7Ε7n\xf5\x9cjP\x94\xc9\x1f.\x0er\xeb|AzR#\x95b*P%\xc4\xd7,\xa4\xad$\xdd\xc3\xcf\xdb\xcf01)\x99*Iy\xbd\xba\xd0e\xcaOR\x93\xfc\x1e\xb9\xd8\xed9\xf4\x19\x13}7\x04\xf2\x9a?\xac\xa3\\\xb8qד\xcaT\xda)us\xd8\xdb<\xab`\x87\x10\x87\xce(v\xf3\vw\x1enM\x8f\xee\xd6\b\xfeϹJY\x91&%\xe1Cٺ\x9c\xc0\xf3\xcbEދ\x83iv^ImeJl\a\xb4)\xb9I\xdfdM{\xb2\xa5\xad\xf6\x81\xc1\xd4L\xda\x0f1\xc9\x16_\xc8e\x9cH\x85\xcdlN\xa5.\x7f\x9fM},哣\x11\x9co\xce8ݧ;s\xff\x8e\xf6h\xcf\xd6a\x81(S\bߧ\x92\x16\xfa\xd8/}6\xf0\t\x9f+\xbb\xf7\x1c҄\xc6\xf9\xa8\xb9Z\x1bP\x1e\xb1\x03\xf9E\xb8\xf3\xc8ʭ\xfc0.G~\x0eh\x04\x02\x8eާ\x96\x0e~\x01Yy\x11\x16wH\xb1\xaf\xb0\xa9\xf2\xb9\xf3\xfb\x90\xff\"Lrl\xb4\xb4\x13\x8e\xc9\x1e\xfd\x14^\x15\xc0\xeb\xb9.k9\xe7>$hY\xf9y\xfeo\xc6i.\x11c\xd5w\x93YU\x0f\x92ǚ\xe2\xf5\xfe\x1aYF\xe7\xcc\xce\xe1\x06\x94\xe3Һ\xd8\x1afs\x9eW\xcdTj\x9f\xa9GQ\xd3\x0f\xef\x14\xd0\xe2UH\xeb~\x81\x92\x9a\xe7\xf9\x88\xfeZ\x8b\xc0\xb3\x91W\xe7\x15\xc8\xdd\xf9\x9a\xe9\xed\xcb\xdf\xe6\xb2\xcfJ=o \xcd\xfaF\xa9\"䇔\xaa\xa6\xb4\xd4y\xf5\xb7f\xa1\xd2\xf6\xf2\xee4H\xde\xf4\xcb\xf4W\xb3\x8c\xe1*\x85j\x05,63|w\x11\x9eh`s\x98\x02\xfe'\x00\x00\xff\xff\xef\xf8\xa6>\x10\f\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcVM\x8f\xdb6\x10\xbd\xfbW\f\x92kd7(Z\x14\xbe\x05\xdb\x1e\x82&\xc5\"N\xf7N\x93#{j\x8ad\x87C9.\xfa\xe3\v\x92Ү-\xcb\xc9nQT\x17\xc3\xe4\xf0q>\u07bca\xd34\v\x15\xe8\x019\x92wkP\x81\xf0\x8b\xa0\xcb\xff\xe2\xf2\xf0S\\\x92_\xf5o\x17\arf\rw)\x8a\xef>a\xf4\x895\xfe\x8c-9\x12\xf2nѡ(\xa3D\xad\x17\x00\xca9/*/\xc7\xfc\x17@{'\xec\xadEnv薇\xb4\xc5m\"k\x90\v\xf8xu\xff\xdd\xf2\xed\x8f\xcb\x1f\x16\x00Nu\xb8\x86\xde\xdb\xd4at*Ľ\x17\xebu\xc5\\\xf6h\x91\xfd\x92\xfc\"\x06\xd4\xf9\x8a\x1d\xfb\x14\xd6\xf0\xb4Q!\x86\xeb\xab\xeb\x0f\x05m3\xa0}\x18Њ\x81\xa5(\xbf~\xc5\xe8\x03E)\x86\xc1&V\xf6\xa6g\xc5&\xee=\xcboO\xb77\xd0G[w\xc8\xed\x92U|\xeb\xfc\x02 j\x1fp\r\xe5xP\x1a\xcd\x02`\xc8O\x81k\xc6Լ\xad\x88z\x8f\x9d\xaa\xf7\x00\xf8\x80\xee\xdd\xfd\xfb\x87\xef7\x17\xcb\x00\x06\xa3f\nR\xb2<\x1f\"P\x04\x05\xa3'p\xdc##<\x94|B\x14\xcf\x18\a\xa7\x1fA\x01F\xff\xe3\xf2q1\xb0\x0f\xc8Bc\xf0\xf5;\xe3\xd7\xd9\xeaį\xbf\x9b\x8b=\x80\x1cJ=\x05&\x13\r#\xc8\x1e\xc7t\xa0\x19\xa2\a߂\xec)\x02c`\x8c\xe8*\xf5\xf2\xb2r\xe0\xb7\x7f\xa0\x96\xe5\x04z\x83\x9car\xad\x925\x99\x9f=\xb2\x00\xa3\xf6;G\x7f=bG\x10_.\xb5J0\n\x90\x13d\xa7,\xf4\xca&|\x03ʙ\tr\xa7N\xc0\x98\xef\x84\xe4\xce\xf0ʁ8\xf5\xe3\xa3g\x04r\xad_\xc3^$\xc4\xf5j\xb5#\x19\xbbN\xfb\xaeK\x8e\xe4\xb4*\rD\xdb$\x9e\xe3\xca`\x8fv\x15i\xd7(\xd6{\x12Ԓ\x18W*PS\x02q\xb5K:\xf3\x9a\x87>\x8d\x17\xd7\xca)S,\n\x93\u06ddm\x94.yAyr\xc3T\xd6T\xa8\x1a\xe2S\x15\xf2RNݧ_6\x9fa\xf4\xa4V\xaa\x16\xe5\xc9\xf4*/c}r6ɵ\xc8\xf5\\˾+\x98\xe8L\xf0\xe4\xa4\xfcі\xd0\tĴ\xedH2\r\xfeL\x18%\x97n\n{W\x94\t\xb6\b)\x18%h\xa6\x06\xef\x1dܩ\x0e흊\xf8?\xd7*W%6\xb9\bϪֹ\xdeN\x8dkz\xcf\x1bu\x90\xc9\x1b\xa5\x9dW\x84M@}\xd1x\x19\x85Z\x1a\x14\xa2\xf5i\x8b\x15\x10|;ý\x17\xb9\x9c?t\xa9\x9b#\xe2\xbb^\x91U[{-\t\r\xfc\xee\xd4\xcdݛş\xad\xe7\xd5b̏=\xb3\x06\xe1T\xb1\a\x96\r+\xff\x04\x00\x00\xff\xffNy\xc1Q\xa1\x0e\x00\x00"), diff --git a/config/crd/v2alpha1/bases/velero.io_datadownloads.yaml b/config/crd/v2alpha1/bases/velero.io_datadownloads.yaml index 36ab864f9..3b5ccf91a 100644 --- a/config/crd/v2alpha1/bases/velero.io_datadownloads.yaml +++ b/config/crd/v2alpha1/bases/velero.io_datadownloads.yaml @@ -83,6 +83,30 @@ spec: Cancel indicates request to cancel the ongoing DataDownload. It can be set when the DataDownload is in InProgress phase type: boolean + csiSnapshot: + description: CSISnapshot provides the information of the CSI snapshot + used to do the incremental restore. + nullable: true + properties: + driver: + description: Driver is the driver used by the VolumeSnapshotContent + type: string + snapshotClass: + description: SnapshotClass is the name of the snapshot class that + the volume snapshot is created with + type: string + storageClass: + description: StorageClass is the name of the storage class of + the PVC that the volume snapshot is created from + type: string + volumeSnapshot: + description: VolumeSnapshot is the name of the volume snapshot + to be backed up + type: string + required: + - storageClass + - volumeSnapshot + type: object dataMoverConfig: additionalProperties: type: string @@ -106,6 +130,9 @@ spec: OperationTimeout specifies the time used to wait internal operations, before returning error as timeout. type: string + restoreType: + description: RestoreType indicates the type of the restore. + type: string snapshotID: description: SnapshotID is the ID of the Velero backup snapshot to be restored from. @@ -145,6 +172,7 @@ spec: required: - backupStorageLocation - operationTimeout + - restoreType - snapshotID - sourceNamespace - targetVolume diff --git a/config/crd/v2alpha1/crds/crds.go b/config/crd/v2alpha1/crds/crds.go index 59af9e6f0..d3537c1ec 100644 --- a/config/crd/v2alpha1/crds/crds.go +++ b/config/crd/v2alpha1/crds/crds.go @@ -29,7 +29,7 @@ import ( ) var rawCRDs = [][]byte{ - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcYK\x93\xe3\xb6\x11\xbeϯ\xe8\xda\x1c\xf6\xb2\xd2d\xf3p\xa5t\xdb\xd1\xc4US\xf1Ϊ\xac\xc9\xdcA\xb2E\xc1\v\x02\b\x1e\x92\xe5$\xff\xdd\xd5\x00I\x81$4z\xd8^\xdd\x044>|\xe8n\xf4\x03\x9c\xcdfwL\xf3W4\x96+\xb9\x00\xa69\xfe\xecP\xd2?;\xff\xfa\x0f;\xe7\xea~\xf7\xf1\xee+\x97\xd5\x02\x96\xde:\xd5\xfc\x88VyS\xe2#n\xb8\xe4\x8e+yנc\x15slq\a\xc0\xa4T\x8eѰ\xa5\xbf\x00\xa5\x92\xce(!\xd0\xccj\x94\xf3\xaf\xbe\xc0\xc2sQ\xa1\t\xe0\xddֻ?\xcf?~7\xff\xfb\x1d\x80d\r.\x80\xf0*\xb5\x97B\xb1\xca\xcew(Ш9WwVcI\xc0\xb5Q^/\xe08\x11\x17\xb6\x9bF\u008f̱\xc7\x16#\f\vnݿ&S?p\xeb´\x16\xde01\xda;\xccح2\xee\xf9\x88?\x83*\"Z.k/\x98\x19.\xba\x03\xb0\xa5Ҹ\x80\xb0F\xb3\x12i\xac=l\xc0\x98\x01\xab\xaa\xa0>&V\x86K\x87f\xa9\x84o\xe4q\a\xb4\xa5\xe1\xda\x05\xf5\xa4|\xc1:\xe6\xbc\x05\xeb\xcb-0\vϸ\xbf\x7f\x92+\xa3j\x836\xf2\x05\xf8\xc9*\xb9bn\xbb\x80y\x14\x9f\xeb-\xb3\xd8\xceF\x1d\xaf\xc3D;\xe4\x0e\xc4\xd7:\xc3e\x9dc\xf0\xc2\x1b\x84ʛ`[:w\x89\xe0\xb6\xdc\x0e\xa9\xed\x99%z\xc6au\x92H\x98'8\xebX\xa3nj\x92\xa5\x91R\xc5\x1c\xe6\b-U\xa3\x05:\xac\xa088쎱Q\xa6an\x01\\\xba\xef\xfevZ\x17\xad\xb2\xe6a飒C\xc5<\xd0($Ñ\tY\xa9F\x93ՎrL\xfc\x16\"\x8e\x00\x1e\x92\xf5\x91I\xc4M\xc7\xcfR!\x97\x03\xb5\x01\xb7Ex`\xe5W\xafa\xed\x94a5\xc2\x0f\xaa\x8c\xe6\xdbo\xd1`\x90(\xa2\x04y/p\xb2\x9d2Y\xd3i,\xe7Q\xb6\x05\xeb\xb0F\xf6\x1bn\xf4\xbb\xfbVi\x90e}\xab\x8bA\xf3 \xc1\x95\xcc;ا\x1a/r\xaeT\x89RU\x98hl\xc0\x89[\xd0F\x95h\xed\x1b\x0eO\x00\x03\x16\xcfǁ\x89j\xa2\xc4\xee/L\xe8-\xfb\x18\x83L\xb9ņ-\xda\x15J\xa3\xfc\xb4zz\xfd\xebz0\fo\x04\fV:K\x91\x82\xe8k\xa3\x9c*\x95\x80\x02\xdd\x1eQF\xd37j\x87\x86\x02`ͥ\xed\x11)\x9cW\xa9\xc01\x98\x93\x7f\a<\x9a\x8d\x93\x06\x83\xf7\x10A\x93Z\x1fhO\x8d\xc6\xf1.|\xb6\xd8\xc7̓\x8c\x8e\xce\xf1\xbf\xd9`\x0e\x80\x8e\x1eWAE)\b\xe3\xb1\xda؊U\xab\xadhn\xa1\x94@6\xd6\"y\xe1gJ\vK%7\xbc\x9e\x1e<-\x7fO\xb9\xc8\x19\x9df\x1c6ْNA\xdeILf!C\xcd:ץо\xe1\xb57\xa7\xec\xbf\xe1(\xaaI\xfc9y\x93\xba\x03\x87]n\xb1qO\xbd\xbb]mVKR\xafS!B\xd9P\xef&\xae9%\t\xf0\xb4I\x10\xb9\x85w\xef@\x19x\x17\x9b\xa5w\x1f\xe2jυ\x9b\xf1A\xfe\xdfs!\xba]\xae\xf2n\xaap\xbe\xacϜ\xfc9\b\x11\x9f/\xebkk\xab)\x1b\x94\xbe\x99n8\x03\xe6\x9d\xca\f\v.\xfdϙ\xf1=\x97\x95\xda\xdbk\x0e\xdb\xd77Tb*\xefn1\xf8\x97\x11\xc6\xc8\xee\x8e\n\xe2`k\xa7`\xcfxRc\xf4\xbb\xdb\x0f\x19\xdc\x027\x94\x90\f:o$\x85\x034\x86\"\xb4\r\x90\xcaOj\x9e7Oj%\xd3v\xab\xdc\xd3\xe3\x993\xae{\xc1.\xee>=v&~\r^\xd7\a\xdfV\x122V\"\xfa]\x15Y\x85\xb4~\x13\xdb5\xff\x05/\xe4K\xa2\x1dc\xa1j^2\x016\x8cɶ\tl\x0f\xd1aO\t\xe5\xfa\xbc1ݴ[K\xf8\x86ڧ\x7f!\xb8ō\xd6C\x88\xee(\xca\U0001a4f3\xc8~\xe6x\xc7vJ\xf8&\x88\x92I\xb0\x02\xafO\xe8\x1a(}P\xb1U T|\xb3AC\x15U(\xb7\xe2ƫ\xd7\xe5{\x9bl\xc27\xe9\x1f\xcaT\r\xd3\x1a+\xea\xed\xc8\x19[\xdb^eU\xc7L\x8d\xee5\x90>\xa3\xa2\x97D\xb4S\x05\x95fd\xa0\xb6\xf6\x0f\x97+\x88\xc1\xeau\x99\xa9\xd4\xe9\xb7z\x9d2<]\xc7\xd0oc_\xe8\x04\x99\x99\x11\xc5\xef\xd7$ؑ\xdbp\x81`\x0f\xd6a\x13T0b\x18-\x95\xb3˙\xb4\bG3\\\xc0i\xe2>\xed\xf6=\xc6-\x04\xf4\ue09dW\xaf\xb92\xad\xb7\x0f\xb8-s$\xd1v\xfdP\x1c\xb2\x98\xd0Řֿn\xe3[^Dx\xf9&\xe3\xe5\x98\xf2\t\xbe\xc5\xe17S\xa6*\x90\x1b\xacr9\xf0\xb4\xe5f\xa0w\xd9\xc1\xf2\xf2Z'\xbf\xf3,_Џdƹs4}L8\xe3\x89a\xa0\x1bͦ1\xe2\xa2\xce'\xbc\xcb\\\xda\xfb\xc4\xd7\xd6\xd6\xec\xa57!\n\xb6o\xb0jsc\xf7\xc3\xca\x12\xb5\xc3\xea\xe1@e\xd1\x05\x95\x13\x11\x90o\xbfJ\xfd[\x1f\xeb&\xd4\xec\xda\x16\xa5\xa3Կ\x9cݒ\x91>\x8dA\xc2\U000c9a52\xbafJ7ֶ\xa7I\x03\xbcP\x0e\x0e\xed\xff\xfbX\xcaвP Q\x89?\xd9\xf4d\x96\xa6\xfe~F\xeb'\x12\xd2\v\xc1\n\x81\vpƟ\xeau\xf2\xad]|\x88N\xdf\x1co\xea\xf3\xa60Sݱ\xfe\x95-\xbc\x86vO\xe09\x95\x1d\xf1z\x85E8\xac\x00w(\x81\xbaw\xc6\x05V\x1df\xa6\xe19\xa7\xf9\f\xe9i-\xfdG*\xbfAkY}\xee\x02}\x8eR\xf1a\xaa]\x02\xac\xa0\xc2{\xdcv\xbc\xb7\xedݾ\xba\x01\xfa}.\xf1\x85\xed\xcf\x1b\\B\xb3~\x86̊dr1\xad\xa7v:\xa8\xc1\x1b\xdd\xd73\xee3\xa3\xdd\xfd\xccL\xad\xdaK\x9f\x99\x9a|\xd3J'\xe3\xabH.1vsY\xcc\xfe\xa3Qf\xee\xfbp\x19\xae\xd2t\xcb\xef\x96\xeb\u07bf\xadl\x95\xe8nx\xf8\xd8#}S\xa0!3\x14\xb9\x0e$<\xc9'V\xcb\x15\x7f=B\xdfL\x05\xa89\xbcl\xa94\x89\x0fB]{Yq\xab\x05;\xf4\x87IK\xe6\f\xf8\xf1\xd6L\xde\xfb\xaf\xad\x9a\xfb\x8fo\xf9\xca\xeb\xed\xce\n\xcetWa\xbe\xff\xa8\xf6\xc7\xec\xf0\xc6s\xd0\xf0#\xe7M\xbd\xdd\x00\xe1\\*h?\xba^\x1f\xc1\x87\xdb|\xcb\xe0\x9d\xd5\xded00\xaf\x12\xec\xf6\xf96\x1d\xf1E\xffMc\x01\xff\xfd\xffݯ\x01\x00\x00\xff\xff];\x85{\xd8 \x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcZK\x93۸\x11\xbeϯ\xe8r\x0e\xbeX\x9a8\x8f\xad\x94n\xb6&[5\x95\xb5\xad\xb2&s\a\x89\xa6\x845\b0\x00(\xad6\xc9\x7f\xdfj\x00\xa4@\x12z\xee\x837\x01\x8d\xc6\xd7\x0ft7\x1a\x9a\xcdf\x0f\xac\x11\xafh\xac\xd0j\x01\xac\x11\xf8\x93CE\xbf\xec\xfc\xdb?\xec\\\xe8\xc7\xdd\xfb\x87oB\xf1\x05,[\xebt\xfd\x15\xadnM\x89OX\t%\x9c\xd0\xea\xa1F\xc78sl\xf1\x00\xc0\x94ҎѰ\xa5\x9f\x00\xa5V\xceh)\xd1\xcc6\xa8\xe6\xdf\xda\x02\x8bVH\x8e\xc63\xef\xb6\xde\xfdy\xfe\xfe\xbb\xf9\xdf\x1f\x00\x14\xabq\x01ď뽒\x9aq;ߡD\xa3\xe7B?\xd8\x06Kb\xbc1\xbam\x16p\x9c\b\v\xe3\xa6\x01\xf0\x13s\xec)\xf2\xf0\xc3RX\xf7\xaf\xc9\xd4\x0f\xc2:?\xdd\xc8\xd609\xda\xdb\xcfح6\xee\xf3\x91\xff\fx\xe0h\x85ڴ\x92\x99\xe1\xa2\a\x00[\xea\x06\x17\xe0\xd74\xacD\x1a\x8b\xc2z\x1e3`\x9c{\xf51\xb92B94K-\xdbZ\x1dw@[\x1a\xd18\xaf\x9e\x14/X\xc7\\k\xc1\xb6\xe5\x16\x98\x85ϸ\x7f|V+\xa37\x06m\xc0\v\xf0\xa3\xd5j\xc5\xdcv\x01\xf3@>o\xb6\xccb\x9c\r:^\xfb\x898\xe4\x0e\x84\xd7:#\xd4&\x87\xe0E\xd4\b\xbc5\u07b6$w\x89\xe0\xb6\xc2\x0e\xa1\xed\x99%x\xc6!?\t\xc4\xcf\x13;\xebX\u074c\x11%K\x03$\xce\x1c\xe6\x00-u\xddHtȡ88\xecĨ\xb4\xa9\x99[\x80P\ueeff\x9d\xd6ET\xd6\xdc/}\xd2j\xa8\x98\x8f4\n\xc9p@BVڠ\xc9jG;&\x7f\r\x10G\f>&\xeb\x03\x92\xc07\x1d\xbf\b\x85\\\x0et\x05n\x8b\xf0\x91\x95\xdf\xda\x06\xd6N\x1b\xb6A\xf8A\x97\xc1|\xfb-\x1a\xf4\x14E\xa0 \xef\x05A\xb6\xd3&k\xba\x06\xcby\xa0\x8d\xcc:^#\xfb\r7\xfa\xcd}\xab4Ȳ\xbe\xd5Š\xb9\xa7\x10Z\xe5\x1d\xec\xc3\x06\xafr\xaeT\x89JsL46\xc0$,4F\x97h\xed\x19\x87'\x06\x03\x14\x9f\x8f\x03\x13\xd5\x04\x8a\xdd_\x98l\xb6\xec}\b2\xe5\x16k\xb6\x88+t\x83\xea\xc3\xea\xf9\xf5\xaf\xeb\xc10\x9c\t\x18\xact\x96\"\x05\xc1o\x8cv\xba\xd4\x12\nt{D\x15L_\xeb\x1d\x1a\n\x80\x1b\xa1lϑ\xc29O\t\x8e\xc1\x9c\xfc\xdb\xf3\xa3\xd90i\xd0{\x0f\x014\xa9\xf5\x81\xf6l\xd08х\xcf\xc8\xfb\x98y\x92ё\x1c\xff\x9b\r\xe6\x00H\xf4\xb0\n8\xa5 \fb\xc5؊\x99\xd8\xcf`\xe8\xa2\xe3\xf3\xd3\x05\b랰\x8b\xb5\xcfO\xddƯ\xde\xf3\xfb\xa2\xb2\x8b\xc9\x19O!\x15v8C\xb2\xb8\v\xedZ\xfc|Ie넴C,\xf5F\x94L\x82\xf5c*6\xb7F\xc9}\n(\u05ff\x1a\xc3M\xbbP\t^\x7f\xa7\xeb;\x9f\xf7\xb8\xf2zȢ\x13E\x1b\xb1\x11䰪\x9f9\x9e\xf3\x98\xf9\x84=\xe6\xb5\x13\xba\x06*\x8b\xe9\x12Y pQUh\xe8\xa6译a\xe3\xd5\xeb\xf2\xadM6\x11U\xfa\x83*\xf0\x9a5\rr\u0b7f\xe3\xdeノ\x99\r\xba\x90\xd0/\xa8\xe8%!\xedT\x91)\x8e\x03G_\xb4L;\x10\xf4\xad^\xa7\b\xcf\u05f7\x95͟\xd3\t\xc4\xef\xd7\xe1\x98\x06p\x95\x90\b\xf6`\x1dփ\xb3\x1a\x11\x06K\xe5\xecr\xb1bR\xa7\xbdj\x82i\xe2>q\xfb\x9e\xc7=\x00\x9a\xdd\x15;\xaf^s\xa5Yo\x9fPS&\xf5cq8Q\xa7\xc5\x18\x13\xfd\xeb>\xbc\xe5U\x80\x97g\x11/ǐO\xe0-\x0e\xbf\x1a\xf2\xb9\xca\xf2\xb4\xe5f\xd0첃\xe5\xf5\xf5V~\xe7Y\xbeQ1\xa2\x19\xe7\xef\xd1t\x92\xf4F3\xc7T4\x9e\x18\x86\xc0\xd1l\x1a=\xae\xea\xf5\xf8N\xf4\xb5ݞ\xf0\xbe\x14\x1d\xa2l\x8d\x8f\x8f\xf1\xd5IWw\xf6{XYb\xe3\x90\x7f\xfc\xbf\x9bcU\x87\r\xbb\xb5)\xd3A\xea\xdf\n\xee\xc9U\x1f\xc6L|\xc3\xd8\xf0\xa4\xea\x9a\xc2\r\x95\xf7i\xd0\x00/\x94\x9d}\xc3\xf3m(\xb4h\x99/\xdf\xe8\x022\xd9\xf4d\xfe\xe6\xcc\xe1\x8c\xd6\xdf\xda\xf98\xd7\xcc\nOo\xe9+\xcb]\x9d\xad)\x9b\xa9\xeeX\xff\xae\xe0\xdf\x7f\xbaG\xbf\x9cʎ\xfcz\x85\x05v\xc8\x01w\xa8@+\xa8\x98\x90\xc8;\x9e\x99\xeb\xd8%\xcdg@O+\xfd\xdfS\xf95Z\xcb6\x97\x0eЧ@\x15Z\xf1q\t\xb0\x82\xae\x05\xe3K\xd1[\x1b\xcf\xf6\xcd׳\xdf\xe6\x10_y9;\x83ŷ'/\x80Y\x11M.\xa6\xf5\xd0N\a58s7\xfc\x8c\xfb\xcchw>3S\xabx\xe83S\x93W\xfct2\xf4\x81s)\xb3\x9b\xcb\xf2\xec\x9f\xc93s\xdf\xfb\xc3p\x93\xa6#\xbe{\x8e{\xdfM\xdejٝp\xff\xbc\xadں@Cf(rw\x13\xff\b\x99X-W\x16\xf6\x1c\xfak\x96g5\x87\x97-\x15-\xa1\x05\u07b7\x87\x85m$;\xf4¤\xc5t\x86\xf9\xf1\xd4L^8o\xad\xa7\xfb\xbf\x1b\xe4k\xb2\xf3w.\xb8p\xef\xf2\xf3\xfd\xdf\b~\x9f\x1d\xce4\xab\x86\x7f\xeb\xb8\xeb\xd67\xe0p)\x15Ŀ\x99\xdc\x1e\xc1\x87\xdb\xfc\x91\xc1;\xab\xbdɠG\xce\x13ޱ\xa1\x9a\x8e\xb4E\xff\x8a\xbb\x80\xff\xfe\xff\xe1\x97\x00\x00\x00\xff\xff\xe4;\xbaG\xca%\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcZIs\xe36\x16\xbe\xfbW\xbc\xea9\xe4b\xc9\xe9YRS\xba\xb5\xe5I\x95j\xd2nW\xcb\xe3;D>\x89\x88A\x80\x83E\x8af\xf9\xef\xa9\ap\x01IH\x94\x94Nx\xe8jcyx\x1b\xbe\xb7@\xb3\xd9\xec\x8eU\xfc\r\xb5\xe1J.\x80U\x1c\x7f\xb1(\xe9/3\x7f\xff\xbb\x99s\xf5\xb0\xffx\xf7\xcee\xbe\x80\xa53V\x95_\xd1(\xa73|\xc2-\x97\xdcr%\xefJ\xb4,g\x96-\xee\x00\x98\x94\xca2\x1a6\xf4'@\xa6\xa4\xd5J\bԳ\x1d\xca\xf9\xbb\xdb\xe0\xc6q\x91\xa3\xf6ě\xa3\xf7\xdf\xcf?\xfe0\xff\xdb\x1d\x80d%.\x80\xe8\xb9J(\x96\x9b\xf9\x1e\x05j5\xe7\xea\xceT\x98\x11ٝV\xaeZ@7\x11\xb6\xd5G\x06v\x9f\x98e\xff\xf2\x14\xfc\xa0\xe0\xc6\xfes0\xf1\x137\xd6OV\xc2i&z\xa7\xfaqS(m\x9f;\xca3\xc8]\x98\xe0r\xe7\x04\xd3\xf1\x96;\x00\x93\xa9\n\x17\xe0wT,C\x1a\xabE\xf4\x14f\xc0\xf2\xdc+\x8d\x89\x17ͥE\xbdT\u0095\xb2\xa3\x8f&Ӽ\xb2^)\x1d\xa7`,\xb3\u0380qY\x01\xcc\xc03\x1e\x1eV\xf2E\xab\x9dF\x13x\x05\xf8\xd9(\xf9\xc2l\xb1\x80yX>\xaf\nf\xb0\x9e\rz]\xfb\x89z\xc8\x1e\x89[c5\x97\xbb\xd4\xf9\xaf\xbcDȝ\xf6\xf6$\x993\x04[p\x133v`\x86\x98\xd3\x16\xf3\x93l\xf8y\"f,+\xab!?\xd1\xd6\xc0P\xce,\xa6\xd8Y\xaa\xb2\x12h1\x87\xcd\xd1b#\xc4V\xe9\x92\xd9\x05pi\x7f\xf8\xebiMԪ\x9a\xfb\xadOJ\xf6\xd5\xf2H\xa3\x10\r\aN\xc8B;\xd4I\xdd(\xcb\xc4oa\xc4\x12\x81\xc7h\x7f\xe0$Ѝ\xc7'YY\xc9Lc\x89\xf26\x86x\xb7{\xccML:\x9e\xad4W\x9a\xdb\xe3\x02>~\x7f)\x9bt+@m\xc1\x16\b\x8f,{w\x15\xac\xad\xd2l\x87\xf0\x93ʂ\x8f\x1d\nԵ\x8fm\xc2\x12S('r\xd84\x86\x010V餳U\x98\xcdî\x9anCv\xe0q\xfd3\xbf\xf1]\xc84\xb2\xe4]hPr\xeeWp%\xd3\x17\xe2\xd3\x0e/\xba\f\xb16\xa5ʱU\x1d\xc6\x1cq\x03\x95V\x19\x1as\xe6z\xd2\xf6\x1e\x0f\xcf\xdd\xc0H-a\xc5\xfe\xcfLT\x05\xfb\x18\xc00+\xb0d\x8bz\x87\xaaP~zY\xbd\xfde\xdd\x1b\x86\x93\xd0\xc62k\bӈ\xf5J+\xab2%`\x83\xf6\x80(=\xbcB\xa9\xf6\xa8\t\xa4w\\\x1a`2oiB\xbc\xa0\v5\xe4\xfa\x9e\x1e͆\xc9ڝT\x85:6;\xb92\x8dY\xde`|\xf8\xa2\xb0\x18\x8d\x0e\x84\xf8߬7\a@r\x87]\x90S|\xc4 U\x1d\x020\xafU\x15\xec\xc6\rh\xac4\x1a\xba^ޫ\xd4\x16\x98\x04\xb5\xf9\x193;\x1f\x90^\xa3&2\xcd}Ȕܣ\xb6\xa01S;\xc9\xff\xd3\xd26`\x95?T0\x8b\xc6\xfa\v\xa9%\x13\xb0g\xc2\xe1\xfd@{\xf4\x95\xec\b\x1a\xe9Lp2\xa2\xe77\x98!\x1f\x9f\x95F\xe0r\xab\x16PX[\x99\xc5\xc3Î\xdb&Y\xc8TY:\xc9\xed\xf1\xc1\x1b\x83o\x9cU\xda<\xe4\xb8G\xf1`\xf8n\xc6tVp\x8b\x99u\x1a\x1fX\xc5g^\x10\xe9\x13\x86y\x99\xffI\xd7\xe9\x85\xe9\x1d;\xf2\xc2\xf0\xf9@\x7f\x85y(\xfeӕ`5\xa9 bg\x05\x1a\"\xd5}\xfd\xc7\xfa\x15\x1aN\x82\xa5\x82Q\xba\xa5#\xbd4\xf6!mr\xb9E\x1d\xf6m\xb5*=M\x94y\xa5\xb8\xb4\xfe\x8fLp\x94\x16\x8c۔ܒ\x1b\xfcۡ\xb1d\xba!٥O\xa8`\x83\xe0*\x82\x82|\xb8`%a\xc9J\x14Kf\xf0\x0f\xb6\x15Y\xc5\xcc\xc8\b\x17Y+N\x13\x87\x8b\x83z\xa3\x89&\xd3;a\xda\x0e>\xd6\x15fdSR+m\xe2[^\xc7\x12\xc2\x00\x16\xad\xeck'}\xed\xe9K\x86\x90\xe1\xa2)W\xa3\xef1E\xa8\xe1UF\xf8݄\xba:2\x89~d\x8a\xbf\x0e\xe4\xeb=\x1a+e\xb8U\xfaH\x84Ch\x1c\xba\xc1I\x8bЗ1\x99\xa1\xb8E\xbc\xa5\xdf\t\\\xe6\xa4qlݘ\x00(P\xf5\x8c*\xb9St\xb1\"C\xc0\xca\xd2\n\xf2j\x836-\xa6L\x842.\xa1Kz!Nn\x87\xa2n\x94\x12Ȇ\x1a\xcc\f_KV\x99B\xd9\t\x81W[hV\xbe\x1e+\xa4×\xeb\xd5=\xfdӌ\x93\a\xedy^C<\xdd2ʶ\xd2f\xab\xed\xbc\\\xaf\xc0\xd4\xdb\xc7F\x92N\b\xb6\x11\xb8\x00\xab\xddX\xb0\xd3\x0e\xeb\xb9\xd7|\x8f:53\xbc9~a\xe3\x85a\x1b8\xe3\x93j?\xf4F\x05\t6R.\x95\xb4(S6:\xebU\xf45\x92.\x053I\x9e\a\x9c\xad\xe3\xf5\xa9k\xd2\x10\x84̯\xb0\x05K\xf3\x05!\xe8z9\xbaM\xbc\xcd\xcd\xe0\xc0mq\x93D\xe1\x82^,P\xb4<)O}߃8j{F\x98\x97\xb7\xa5\x97wJ2\n7\xb7H\xb6\xef\x19\xfd\x02\xd9\xfa^\x92\x92n\xc0\xe5)\xe1\x14\xa1\x00\x81\x19\xe6\xe0\xaa\xeby'\xd0\xe1\x1a\xf31ϳ\x9e\xbd\x12\xd3}\xa1O \xc9(2A\x9dt~\xa6\xb4r\xa9\xe4\x96\xef\xc6g\xc7e\xfe\xb9k{V\xb4Qċ\x8e$\x8dS\x80#Nf>Ý5яr\xc3-\xdf9}\n\x8d\xb6\x1cE>J`&\x01hB\x1f\x9e\x89[\xe2H+Y\x13\xbfkH\x8d2\xfb\xe0%1J\x85\xf07\x96\x01\b\xba;\x8a\xdc\xc0\x87\x0f\xa04|\b\xbd\xa2\x0f\xf7a\xb7\xe3\xc2\xcex\xaf\xbc8p!\x9aS\xae\x8a\xa0mIA\x05\x9drS\xa1%\xa9\x83/\x03\x1a\x03UX*>\xbd\xf8V\xc1\x81\xf1(\xadoO7\xf7\t\xba\x1b\xdcR\x0e\xa8\xd1:-)\n\xa3֔\x16\x19OR\xb9D\x18:#\xa9\x89B℔\xc3\xe8饠\xff\x0f\xb1<\x06\x80\x84\x00)\x1b\x9f\xe3Ч\xec?\xae/\xe10Z\xdap\xb8\xe5\x02\xc1\x1c\x8dŲ\xcfm\xa8\x04\x02`\xdc\xc0P\xdb\x10\xbc\xc57\xd6}\x12\r\xafJ\xf3\x1d'\x0f\x90\xedL\x97\x1d\xd6\xe0[\xb7Q<\xb4\xfaؐ\xbc0-|\x1b\x82\xef\x8e\x1c\xe1K8\x9c\xc2\x0f\x93\xb9O`\xda\xf9\xbcƂ\x04\x92L*\xe4\xe5my\x91y\xe8\xe0Dl\xa1\xe1C\xc1\xb3\xa2\xefK|\x8c\xf2\x00\x96\xbd\xa3/\x06\xae`3\x1dTf\xe9\xd2`\xb0f\b\a\x83\xe9\xf8\x0e\r\xa7\xfa\x86Nξ\xbc-/*\x9f|g\xe7\xb2\x02*t\x96k-gNk_\x9a\x86Q\xb5\xbd\xa9\x84bY\x86\x95\xc5\xfc\xf1\xf8\xac\xf2)\xa7\xff\xd4[L\x8c\xc8Kz[\tS\xfbn\x17V\xec\xda\x1a\xa8a\xb7\xed\xc8\xddrM?\r\x89\xf8ތ\xce#\x04\x1fW4\x01\xfdN3\r\xf0J\x0e\xee{\v\xdf\x05Цm>\x14\xd0\xf5\x1c\x1d:\xa2\xd04\x81sfqF\xfbo\v\xfb\xe9\xda14\xe4\xe3^\xe6M\x85\xe4\x98\xccXw\xac\xa9x}\x93\xb5y\tHi\xac#\xd7\xea+P\xc3\x1cp\x8f\x12\x94\x84-を\tO2\x01`\xe7\xa9\xd4Q5<\xfb4M\xa3\xa6\xc1\x98\xec\xdeM[2\xa1\x841\x9a\xfd\x9e\xc6lsگh\x9cHd1\xbfcN\x1b\x8e\f\xed\v\x93\xcci\xcf\xd7\xd7\xcc\x00\x03\x1d\x88Ըq\n\xb4.VR2\xd1\x1d>\x96L\xb5\x11\x06ˡP\xa2vj\xe9\xca\rj\xe2\xd6?ـ\xc4\x03\xe5\xa9Y\xc1\xe4.\x99\t5O\x0e\b\x82\x19[\xbb\xdbI\x0f\x89\xdf|\x86\x92\xc5o4\xddW\xa21l7\x05֟ê\xd0E\xad\xb7\x00\xdbP\xca\xda\xd7\xfaw\xa6\x8e!W!\xb1\x9c\x0e\x17W\x05\x89\xde\x03\xc8՜|Y_\xc0˗5\x1d\xf2e\xfd[yA\xe9\xcaT\x11˜U\x89a\xc1\xa5\xfb%1~\xe02W\x871t\x9c\x11\xb5b\xb6\x98\x10\xf4\x85٢M\x92\x9d\x10~\xcf(\x97\xaf\xb3\xce\r\x12&~\xab\x94\u07b7\xf9\xa6أ5\xa9\x14\x06/\x81\x83S\x9a\x7f\xc6Cb\xb4\t\xb9\x89\xa9\x97:\x8e'\xa6F\x8f\xf5\xf1d褦ಙK\xd2l\xdf\xc3\x13s?\xfa\x00w\x95\x9ek\xfen\x89\xe0mO\xb6\xc37\xff\xbc=B\xb9~o\x88J\x8a\xc8b\t\xc2\xd1\xfe\xb6\x8e\xf1\x94\xe6\xf0Zp\xd3t\x91\x9b\xd28\xe7\xa6\x12\xec\xd8\xca2\x156Z\xdc\x1a\xbe\x0e\x8e\x9d\xe4|\xfb\xb5\xfdUA\xbauv\x1e\x95a\x02\x99\xfd\xbc:\x1dr\xbe\xc5\tgb^s\xbdWO\x17\xd6\xfc\xab\xa7\xe6*\xf2\x1c\xa5\xe5[\x1e\xbd\xc8vŚ\xef\xf0\xa7t9|ٸ\xae\xbe\xec\xfd\xd6\xe4\xa6z\xbbGa\"\x13\xad\x7f\xfa\x92\xca\xf7\xd6\x04\x06\x04A\xfe\rp9|\xf5\xbfo#:\xb3\xf5Cd\b\xfe\xa9\"VIJo|zt}j\xd9\x17\xe8\x8f\xcc*\x93^5\x1a\xf4\x9c\xe7\x11\xed\xbao\x1b\x8f\xb8M\xfb2\xbc\x80\xff\xfe\xff\xee\xd7\x00\x00\x00\xff\xffʖ\x89F\xbb&\x00\x00"), } diff --git a/pkg/apis/velero/v1/pod_volume_restore_type.go b/pkg/apis/velero/v1/pod_volume_restore_type.go index 96c1a1e4b..5ded78175 100644 --- a/pkg/apis/velero/v1/pod_volume_restore_type.go +++ b/pkg/apis/velero/v1/pod_volume_restore_type.go @@ -46,6 +46,9 @@ type PodVolumeRestoreSpec struct { // SnapshotID is the ID of the volume snapshot to be restored. SnapshotID string `json:"snapshotID"` + // RestoreType indicates the type of the restore. + RestoreType string `json:"restoreType"` + // SourceNamespace is the original namespace for namaspace mapping. SourceNamespace string `json:"sourceNamespace"` diff --git a/pkg/apis/velero/v1/restore_types.go b/pkg/apis/velero/v1/restore_types.go index c01686241..c2e47b8f8 100644 --- a/pkg/apis/velero/v1/restore_types.go +++ b/pkg/apis/velero/v1/restore_types.go @@ -113,7 +113,12 @@ type RestoreSpec struct { // ExistingResourcePolicy specifies the restore behavior for the Kubernetes resource to be restored // +optional // +nullable - ExistingResourcePolicy PolicyType `json:"existingResourcePolicy,omitempty"` + ExistingResourcePolicy ResourcePolicyType `json:"existingResourcePolicy,omitempty"` + + // ExistingVolumeDataPolicy specifies the restore behavior for the volume data to be restored + // +optional + // +nullable + ExistingVolumeDataPolicy VolumeDataPolicyType `json:"existingVolumeDataPolicy,omitempty"` // ItemOperationTimeout specifies the time used to wait for RestoreItemAction operations // The default value is 4 hour. @@ -141,6 +146,10 @@ type RestoreSpec struct { UploaderConfig *UploaderConfigForRestore `json:"uploaderConfig,omitempty"` } +func (r *RestoreSpec) IsVolumeDataInplaceRestore() bool { + return r.ExistingVolumeDataPolicy == VolumeDataPolicyTypeFull || r.ExistingVolumeDataPolicy == VolumeDataPolicyTypeIncremental +} + // UploaderConfigForRestore defines the configuration for the restore. type UploaderConfigForRestore struct { // WriteSparseFiles is a flag to indicate whether write files sparsely or not. @@ -150,6 +159,11 @@ type UploaderConfigForRestore struct { // ParallelFilesDownload is the concurrency number setting for restore. // +optional ParallelFilesDownload int `json:"parallelFilesDownload,omitempty"` + // DeleteExtraFiles specifies whether to delete the extra files in the target volume that do not exist in the backup. + // This setting is only applicable to File System restores (PodVolumeBackup or CSI File System Data Move) and has no effect on Block Data Move restores. + // +optional + // +nullable + DeleteExtraFiles *bool `json:"deleteExtraFiles,omitempty"` } // RestoreHooks contains custom behaviors that should be executed during or post restore. @@ -316,13 +330,22 @@ const ( // The failing error is recorded in status.FailureReason. RestorePhaseFailed RestorePhase = "Failed" - // PolicyTypeNone means velero will not overwrite the resource + // ResourcePolicyTypeNone means velero will not overwrite the resource // in cluster with the one in backup whether changed/unchanged. - PolicyTypeNone PolicyType = "none" + ResourcePolicyTypeNone ResourcePolicyType = "none" - // PolicyTypeUpdate means velero will try to attempt a patch on + // ResourcePolicyTypeUpdate means velero will try to attempt a patch on // the changed resources. - PolicyTypeUpdate PolicyType = "update" + ResourcePolicyTypeUpdate ResourcePolicyType = "update" + + // VolumeDataPolicyTypeNone means velero will skip and not overwrite the volume data if the volume already exists + VolumeDataPolicyTypeNone VolumeDataPolicyType = "none" + + // VolumeDataPolicyTypeFull means velero will try to restore the volume data fully if the volume already exists. + VolumeDataPolicyTypeFull VolumeDataPolicyType = "full" + + // VolumeDataPolicyTypeIncremental means velero will try to restore the volume data incrementally if the volume already exists. + VolumeDataPolicyTypeIncremental VolumeDataPolicyType = "incremental" ) // RestoreStatus captures the current status of a Velero restore @@ -440,5 +463,8 @@ type RestoreList struct { Items []Restore `json:"items"` } -// PolicyType helps specify the ExistingResourcePolicy -type PolicyType string +// ResourcePolicyType helps specify the ExistingResourcePolicy +type ResourcePolicyType string + +// VolumeDataPolicyType helps specify the ExistingVolumeDataPolicy +type VolumeDataPolicyType string diff --git a/pkg/apis/velero/v1/zz_generated.deepcopy.go b/pkg/apis/velero/v1/zz_generated.deepcopy.go index c40fbb806..dd4be9374 100644 --- a/pkg/apis/velero/v1/zz_generated.deepcopy.go +++ b/pkg/apis/velero/v1/zz_generated.deepcopy.go @@ -1754,6 +1754,11 @@ func (in *UploaderConfigForRestore) DeepCopyInto(out *UploaderConfigForRestore) *out = new(bool) **out = **in } + if in.DeleteExtraFiles != nil { + in, out := &in.DeleteExtraFiles, &out.DeleteExtraFiles + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UploaderConfigForRestore. diff --git a/pkg/apis/velero/v2alpha1/data_download_types.go b/pkg/apis/velero/v2alpha1/data_download_types.go index 220bd382b..71152731c 100644 --- a/pkg/apis/velero/v2alpha1/data_download_types.go +++ b/pkg/apis/velero/v2alpha1/data_download_types.go @@ -39,6 +39,14 @@ type DataDownloadSpec struct { // SnapshotID is the ID of the Velero backup snapshot to be restored from. SnapshotID string `json:"snapshotID"` + // RestoreType indicates the type of the restore. + RestoreType string `json:"restoreType"` + + // CSISnapshot provides the information of the CSI snapshot used to do the incremental restore. + // +optional + // +nullable + CSISnapshot *CSISnapshotSpec `json:"csiSnapshot"` + // SourceNamespace is the original namespace where the volume is backed up from. // It may be different from SourcePVC's namespace if namespace is remapped during restore. SourceNamespace string `json:"sourceNamespace"` diff --git a/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go index b86c573d3..8e06c2f79 100644 --- a/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go @@ -86,6 +86,11 @@ func (in *DataDownloadList) DeepCopyObject() runtime.Object { func (in *DataDownloadSpec) DeepCopyInto(out *DataDownloadSpec) { *out = *in out.TargetVolume = in.TargetVolume + if in.CSISnapshot != nil { + in, out := &in.CSISnapshot, &out.CSISnapshot + *out = new(CSISnapshotSpec) + **out = **in + } if in.DataMoverConfig != nil { in, out := &in.DataMoverConfig, &out.DataMoverConfig *out = make(map[string]string, len(*in)) diff --git a/pkg/builder/restore_builder.go b/pkg/builder/restore_builder.go index 22e880a98..f8382e0ed 100644 --- a/pkg/builder/restore_builder.go +++ b/pkg/builder/restore_builder.go @@ -98,7 +98,13 @@ func (b *RestoreBuilder) ExcludedResources(resources ...string) *RestoreBuilder // ExistingResourcePolicy sets the Restore's resource policy. func (b *RestoreBuilder) ExistingResourcePolicy(policy string) *RestoreBuilder { - b.object.Spec.ExistingResourcePolicy = velerov1api.PolicyType(policy) + b.object.Spec.ExistingResourcePolicy = velerov1api.ResourcePolicyType(policy) + return b +} + +// ExistingVolumeDataPolicy sets the Restore's volume data policy. +func (b *RestoreBuilder) ExistingVolumeDataPolicy(policy string) *RestoreBuilder { + b.object.Spec.ExistingVolumeDataPolicy = velerov1api.VolumeDataPolicyType(policy) return b } diff --git a/pkg/cmd/cli/restore/create.go b/pkg/cmd/cli/restore/create.go index 3f59b6a6b..f612cc185 100644 --- a/pkg/cmd/cli/restore/create.go +++ b/pkg/cmd/cli/restore/create.go @@ -95,6 +95,7 @@ type CreateOptions struct { IncludeNamespaces flag.StringArray ExcludeNamespaces flag.StringArray ExistingResourcePolicy string + ExistingVolumeDataPolicy string IncludeResources flag.StringArray ExcludeResources flag.StringArray StatusIncludeResources flag.StringArray @@ -110,6 +111,7 @@ type CreateOptions struct { ResourcePoliciesConfigMap string WriteSparseFiles flag.OptionalBool ParallelFilesDownload int + DeleteExtraFiles flag.OptionalBool client kbclient.WithWatch } @@ -123,6 +125,7 @@ func NewCreateOptions() *CreateOptions { PreserveNodePorts: flag.NewOptionalBool(nil), IncludeClusterResources: flag.NewOptionalBool(nil), WriteSparseFiles: flag.NewOptionalBool(nil), + DeleteExtraFiles: flag.NewOptionalBool(nil), } } @@ -136,7 +139,8 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) { flags.Var(&o.Annotations, "annotations", "Annotations to apply to the restore.") flags.Var(&o.IncludeResources, "include-resources", "Resources to include in the restore, formatted as resource.group, such as storageclasses.storage.k8s.io (use '*' for all resources).") flags.Var(&o.ExcludeResources, "exclude-resources", "Resources to exclude from the restore, formatted as resource.group, such as storageclasses.storage.k8s.io.") - flags.StringVar(&o.ExistingResourcePolicy, "existing-resource-policy", "", "Restore Policy to be used during the restore workflow, can be - none or update") + flags.StringVar(&o.ExistingResourcePolicy, "existing-resource-policy", "", "Restore Policy to be used during the restore workflow for Kubernetes resources, can be - none or update") + flags.StringVar(&o.ExistingVolumeDataPolicy, "existing-volume-data-policy", "", "Restore Policy to be used during the restore workflow for volume data, can be - none, full or incremental") flags.Var(&o.StatusIncludeResources, "status-include-resources", "Resources to include in the restore status, formatted as resource.group, such as storageclasses.storage.k8s.io.") flags.Var(&o.StatusExcludeResources, "status-exclude-resources", "Resources to exclude from the restore status, formatted as resource.group, such as storageclasses.storage.k8s.io.") flags.VarP(&o.Selector, "selector", "l", "Only restore resources matching this label selector.") @@ -168,6 +172,9 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) { f.NoOptDefVal = cmd.TRUE flags.IntVar(&o.ParallelFilesDownload, "parallel-files-download", 0, "The number of restore operations to run in parallel. If set to 0, the default parallelism will be the number of CPUs for the node that node agent pod is running.") + + f = flags.VarPF(&o.DeleteExtraFiles, "delete-extra-files", "", "Whether to delete extra files in the target volume that do not exist in the backup during file system restore. This setting is only applicable to File System restores (PodVolumeBackup or CSI File System Data Move) and has no effect on Block Data Move restores.") + f.NoOptDefVal = cmd.TRUE } func (o *CreateOptions) Complete(args []string, f client.Factory) error { @@ -217,6 +224,10 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto return errors.New("existing-resource-policy has invalid value, it accepts only none, update as value") } + if len(o.ExistingVolumeDataPolicy) > 0 && !restore.IsVolumeDataPolicyValid(o.ExistingVolumeDataPolicy) { + return errors.New("existing-volume-data-policy has invalid value, it accepts only none, full, incremental as value") + } + if o.ParallelFilesDownload < 0 { return errors.New("parallel-files-download cannot be negative") } @@ -337,27 +348,29 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error { Annotations: o.Annotations.Data(), }, Spec: api.RestoreSpec{ - BackupName: o.BackupName, - ScheduleName: o.ScheduleName, - IncludedNamespaces: o.IncludeNamespaces, - ExcludedNamespaces: o.ExcludeNamespaces, - IncludedResources: o.IncludeResources, - ExcludedResources: o.ExcludeResources, - ExistingResourcePolicy: api.PolicyType(o.ExistingResourcePolicy), - NamespaceMapping: o.NamespaceMappings.Data(), - LabelSelector: o.Selector.LabelSelector, - OrLabelSelectors: o.OrSelector.OrLabelSelectors, - RestorePVs: o.RestoreVolumes.Value, - PreserveNodePorts: o.PreserveNodePorts.Value, - IncludeClusterResources: o.IncludeClusterResources.Value, - ResourceModifier: resModifiers, - ResourcePolicy: resPolicies, + BackupName: o.BackupName, + ScheduleName: o.ScheduleName, + IncludedNamespaces: o.IncludeNamespaces, + ExcludedNamespaces: o.ExcludeNamespaces, + IncludedResources: o.IncludeResources, + ExcludedResources: o.ExcludeResources, + ExistingResourcePolicy: api.ResourcePolicyType(o.ExistingResourcePolicy), + ExistingVolumeDataPolicy: api.VolumeDataPolicyType(o.ExistingVolumeDataPolicy), + NamespaceMapping: o.NamespaceMappings.Data(), + LabelSelector: o.Selector.LabelSelector, + OrLabelSelectors: o.OrSelector.OrLabelSelectors, + RestorePVs: o.RestoreVolumes.Value, + PreserveNodePorts: o.PreserveNodePorts.Value, + IncludeClusterResources: o.IncludeClusterResources.Value, + ResourceModifier: resModifiers, + ResourcePolicy: resPolicies, ItemOperationTimeout: metav1.Duration{ Duration: o.ItemOperationTimeout, }, UploaderConfig: &api.UploaderConfigForRestore{ WriteSparseFiles: o.WriteSparseFiles.Value, ParallelFilesDownload: o.ParallelFilesDownload, + DeleteExtraFiles: o.DeleteExtraFiles.Value, }, }, } diff --git a/pkg/cmd/cli/restore/create_test.go b/pkg/cmd/cli/restore/create_test.go index 9a6a92608..7d6398f8c 100644 --- a/pkg/cmd/cli/restore/create_test.go +++ b/pkg/cmd/cli/restore/create_test.go @@ -68,6 +68,7 @@ func TestCreateCommand(t *testing.T) { includeNamespaces := "app1,app2" excludeNamespaces := "pod1,pod2,pod3" existingResourcePolicy := "none" + existingVolumeDataPolicy := "none" includeResources := "sc,sts" excludeResources := "job" statusIncludeResources := "sc,sts" @@ -80,6 +81,7 @@ func TestCreateCommand(t *testing.T) { resourceModifierConfigMap := "modifier-cm" ResourcePoliciesConfigMap := "policies-cm" writeSparseFiles := "true" + deleteExtraFiles := "true" parallel := 2 flags := new(pflag.FlagSet) o := NewCreateOptions() @@ -92,6 +94,7 @@ func TestCreateCommand(t *testing.T) { flags.Parse([]string{"--labels", labels}) flags.Parse([]string{"--annotations", annotations}) flags.Parse([]string{"--existing-resource-policy", existingResourcePolicy}) + flags.Parse([]string{"--existing-volume-data-policy", existingVolumeDataPolicy}) flags.Parse([]string{"--include-namespaces", includeNamespaces}) flags.Parse([]string{"--exclude-namespaces", excludeNamespaces}) flags.Parse([]string{"--include-resources", includeResources}) @@ -106,6 +109,7 @@ func TestCreateCommand(t *testing.T) { flags.Parse([]string{"--resource-modifier-configmap", resourceModifierConfigMap}) flags.Parse([]string{"--resource-policies-configmap", ResourcePoliciesConfigMap}) flags.Parse([]string{"--write-sparse-files", writeSparseFiles}) + flags.Parse([]string{"--delete-extra-files", deleteExtraFiles}) flags.Parse([]string{"--parallel-files-download", "2"}) client := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch) @@ -133,6 +137,7 @@ func TestCreateCommand(t *testing.T) { require.Equal(t, includeNamespaces, o.IncludeNamespaces.String()) require.Equal(t, excludeNamespaces, o.ExcludeNamespaces.String()) require.Equal(t, existingResourcePolicy, o.ExistingResourcePolicy) + require.Equal(t, existingVolumeDataPolicy, o.ExistingVolumeDataPolicy) require.Equal(t, includeResources, o.IncludeResources.String()) require.Equal(t, excludeResources, o.ExcludeResources.String()) @@ -147,6 +152,7 @@ func TestCreateCommand(t *testing.T) { require.Equal(t, ResourcePoliciesConfigMap, o.ResourcePoliciesConfigMap) require.Equal(t, writeSparseFiles, o.WriteSparseFiles.String()) require.Equal(t, parallel, o.ParallelFilesDownload) + require.Equal(t, deleteExtraFiles, o.DeleteExtraFiles.String()) }) t.Run("create a restore from schedule", func(t *testing.T) { diff --git a/pkg/controller/restore_controller.go b/pkg/controller/restore_controller.go index 5b055bc6c..e923e0c39 100644 --- a/pkg/controller/restore_controller.go +++ b/pkg/controller/restore_controller.go @@ -361,10 +361,15 @@ func (r *restoreReconciler) validateAndComplete(ctx context.Context, restore *ap } // validate ExistingResourcePolicy - if restore.Spec.ExistingResourcePolicy != "" && !pkgrestoreUtil.IsResourcePolicyValid(string(restore.Spec.ExistingResourcePolicy)) { + if !pkgrestoreUtil.IsResourcePolicyValid(string(restore.Spec.ExistingResourcePolicy)) { restore.Status.ValidationErrors = append(restore.Status.ValidationErrors, fmt.Sprintf("Invalid ExistingResourcePolicy: %s", restore.Spec.ExistingResourcePolicy)) } + // validate ExistingVolumeDataPolicy + if !pkgrestoreUtil.IsVolumeDataPolicyValid(string(restore.Spec.ExistingVolumeDataPolicy)) { + restore.Status.ValidationErrors = append(restore.Status.ValidationErrors, fmt.Sprintf("Invalid ExistingVolumeDataPolicy: %s", restore.Spec.ExistingVolumeDataPolicy)) + } + // if ScheduleName is specified, fill in BackupName with the most recent successful backup from // the schedule if restore.Spec.ScheduleName != "" { diff --git a/pkg/controller/restore_controller_test.go b/pkg/controller/restore_controller_test.go index 6a2f4d8d1..d25e6a460 100644 --- a/pkg/controller/restore_controller_test.go +++ b/pkg/controller/restore_controller_test.go @@ -348,6 +348,39 @@ func TestRestoreReconcile(t *testing.T) { expectedCompletedTime: ×tamp, expectedRestorerCall: nil, // this restore should fail validation and not be passed to the restorer }, + { + name: "valid restore with update existingvolumedatapolicy(full) gets executed", + location: defaultStorageLocation, + restore: NewRestore("foo", "bar", "backup-1", "ns-1", "", velerov1api.RestorePhaseNew).ExistingVolumeDataPolicy("full").Result(), + backup: defaultBackup().StorageLocation("default").Phase(velerov1api.BackupPhaseCompleted).Result(), + expectedErr: false, + expectedPhase: string(velerov1api.RestorePhaseInProgress), + expectedStartTime: ×tamp, + expectedCompletedTime: ×tamp, + expectedRestorerCall: NewRestore("foo", "bar", "backup-1", "ns-1", "", velerov1api.RestorePhaseInProgress).ExistingVolumeDataPolicy("full").Result(), + }, + { + name: "valid restore with update existingvolumedatapolicy(incremental) gets executed", + location: defaultStorageLocation, + restore: NewRestore("foo", "bar", "backup-1", "ns-1", "", velerov1api.RestorePhaseNew).ExistingVolumeDataPolicy("incremental").Result(), + backup: defaultBackup().StorageLocation("default").Phase(velerov1api.BackupPhaseCompleted).Result(), + expectedErr: false, + expectedPhase: string(velerov1api.RestorePhaseInProgress), + expectedStartTime: ×tamp, + expectedCompletedTime: ×tamp, + expectedRestorerCall: NewRestore("foo", "bar", "backup-1", "ns-1", "", velerov1api.RestorePhaseInProgress).ExistingVolumeDataPolicy("incremental").Result(), + }, + { + name: "invalid restore with invalid existingvolumedatapolicy errors", + location: defaultStorageLocation, + restore: NewRestore("foo", "invalidexistingvolumedatapolicy", "backup-1", "ns-1", "", velerov1api.RestorePhaseNew).ExistingVolumeDataPolicy("invalid").Result(), + backup: defaultBackup().StorageLocation("default").Result(), + expectedErr: false, + expectedPhase: string(velerov1api.RestorePhaseFailedValidation), + expectedStartTime: ×tamp, + expectedCompletedTime: ×tamp, + expectedRestorerCall: nil, // this restore should fail validation and not be passed to the restorer + }, { name: "valid restore gets executed", location: defaultStorageLocation, diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 8205accb9..7a83b8b34 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -1890,7 +1890,7 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso if err != nil { warnings.Add(namespace, err) // check if there is existingResourcePolicy and if it is set to update policy - if len(ctx.restore.Spec.ExistingResourcePolicy) > 0 && ctx.restore.Spec.ExistingResourcePolicy == velerov1api.PolicyTypeUpdate { + if len(ctx.restore.Spec.ExistingResourcePolicy) > 0 && ctx.restore.Spec.ExistingResourcePolicy == velerov1api.ResourcePolicyTypeUpdate { // remove restore labels so that we apply the latest backup/restore names on the object via patch removeRestoreLabels(fromCluster) //try patching just the backup/restore labels @@ -1910,12 +1910,12 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso restoreLogger.Infof("restore API has resource policy defined %s, executing restore workflow accordingly for changed resource %s %s", resourcePolicy, fromCluster.GroupVersionKind().Kind, kube.NamespaceAndName(fromCluster)) // existingResourcePolicy is set as none, add warning - if resourcePolicy == velerov1api.PolicyTypeNone { + if resourcePolicy == velerov1api.ResourcePolicyTypeNone { e := errors.Errorf("could not restore, %s %q already exists. Warning: the in-cluster version is different than the backed-up version", obj.GetKind(), obj.GetName()) warnings.Add(namespace, e) // existingResourcePolicy is set as update, attempt patch on the resource and add warning if it fails - } else if resourcePolicy == velerov1api.PolicyTypeUpdate { + } else if resourcePolicy == velerov1api.ResourcePolicyTypeUpdate { // processing update as existingResourcePolicy warningsFromUpdateRP, errsFromUpdateRP := ctx.processUpdateResourcePolicy(fromCluster, fromClusterWithLabels, obj, namespace, resourceClient) if warningsFromUpdateRP.IsEmpty() && errsFromUpdateRP.IsEmpty() { @@ -1936,7 +1936,7 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso } //update backup/restore labels on the unchanged resources if existingResourcePolicy is set as update - if ctx.restore.Spec.ExistingResourcePolicy == velerov1api.PolicyTypeUpdate { + if ctx.restore.Spec.ExistingResourcePolicy == velerov1api.ResourcePolicyTypeUpdate { resourcePolicy := ctx.restore.Spec.ExistingResourcePolicy restoreLogger.Infof("restore API has resource policy defined %s, executing restore workflow accordingly for unchanged resource %s %s ", resourcePolicy, obj.GroupVersionKind().Kind, kube.NamespaceAndName(fromCluster)) // remove restore labels so that we apply the latest backup/restore names on the object via patch diff --git a/pkg/util/velero/restore/util.go b/pkg/util/velero/restore/util.go index e0812884b..96a368e50 100644 --- a/pkg/util/velero/restore/util.go +++ b/pkg/util/velero/restore/util.go @@ -5,8 +5,14 @@ import ( ) func IsResourcePolicyValid(resourcePolicy string) bool { - if resourcePolicy == string(api.PolicyTypeNone) || resourcePolicy == string(api.PolicyTypeUpdate) { - return true - } - return false + return resourcePolicy == "" || + resourcePolicy == string(api.ResourcePolicyTypeNone) || + resourcePolicy == string(api.ResourcePolicyTypeUpdate) +} + +func IsVolumeDataPolicyValid(volumeDataPolicy string) bool { + return volumeDataPolicy == "" || + volumeDataPolicy == string(api.VolumeDataPolicyTypeNone) || + volumeDataPolicy == string(api.VolumeDataPolicyTypeFull) || + volumeDataPolicy == string(api.VolumeDataPolicyTypeIncremental) } diff --git a/pkg/util/velero/restore/util_test.go b/pkg/util/velero/restore/util_test.go index be72ff8ba..bcd447d4b 100644 --- a/pkg/util/velero/restore/util_test.go +++ b/pkg/util/velero/restore/util_test.go @@ -9,7 +9,16 @@ import ( ) func TestIsResourcePolicyValid(t *testing.T) { - require.True(t, IsResourcePolicyValid(string(velerov1api.PolicyTypeNone))) - require.True(t, IsResourcePolicyValid(string(velerov1api.PolicyTypeUpdate))) - require.False(t, IsResourcePolicyValid("")) + require.True(t, IsResourcePolicyValid(string(velerov1api.ResourcePolicyTypeNone))) + require.True(t, IsResourcePolicyValid(string(velerov1api.ResourcePolicyTypeUpdate))) + require.True(t, IsResourcePolicyValid("")) + require.False(t, IsResourcePolicyValid("invalid")) +} + +func TestIsVolumeDataPolicyValid(t *testing.T) { + require.True(t, IsVolumeDataPolicyValid(string(velerov1api.VolumeDataPolicyTypeNone))) + require.True(t, IsVolumeDataPolicyValid(string(velerov1api.VolumeDataPolicyTypeFull))) + require.True(t, IsVolumeDataPolicyValid(string(velerov1api.VolumeDataPolicyTypeIncremental))) + require.True(t, IsVolumeDataPolicyValid("")) + require.False(t, IsVolumeDataPolicyValid("invalid")) }