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 e12ea9b4f..b58666cca 100644 --- a/config/crd/v1/bases/velero.io_restores.yaml +++ b/config/crd/v1/bases/velero.io_restores.yaml @@ -89,6 +89,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. @@ -499,6 +504,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 a2ce01c2d..488066eaf 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\xbcWMs\xdb6\x13\xbe\xebW\xec\xcc{y;\x13\xca\xc94\xedttk\x95\x1c\x06\x8d\x1f\xb02ΰ\xf1n\xd1\"\xabR\xb1Z-\x00\x94s\x9e\x95\x88I\xfe\x05\xd0\xdeq\xf0\xd6b(jtˇ\xb8\xc5m4\xb6Đ\x9c\x0f\xa1wo\x97\xef~^\xfe\xb4\x00p\xaa\xc5\x15\x94\xfe\xd1Y\xafʀ\x7fE$\xa6\xe5\x0e-\x06\xbf4~A\x1dj\xf1]\a\x1f\xbb\x15\x1c\x0f\xb2m\x1f7\xe7\xfc\xa1w\xb3\xc9n҉5ğ\xe6N\xefL\xaf\xd1\xd9\x18\x94=M\"\x1dR\xe3\x03\x7f>\x06*@\xce\xf3\x91qu\xb4*\x9cX.\x00H\xfb\x0eW\x90\f;\xa5\xb1\\\x00\xf4\xd5'GE_\xf8\xee]v\xa5\x1blU\x8e\x00\xe0;t\xbf~\xb9\xfd\xfe\xe3\xfd31@\x89\xa4\x83\xe98\xf5\xf0\x9f\xe2 \x87im`\b\x14\xf4\xe9\x00\xfbC\x86\xa0\x1c\xa8\xc0\xa6R\x9a\xa1\n\xbe\x85\xad\xd2\x0f\xb1\x03\xbf\xfd\x135\x03\xb1\x0f\xaa\xc67@Q7\xa0\xc4KV\x18Ų\xbe\x86\xcaX\\\x1ed]\xf0\x1d\x066C\x93\xf2o\x84\xb5\x91\xf4R\x15\xf2\x93³\x15\x94\x02:$\xe0\x06\x87\xe6a\xd9\xf7\n|\x05\xdc\x18\x82\x80]@B\x97a(b\xe5\xfaj\x96\x13\xd7\xf7\x18č\xcc4\xdaR\xb0\xba\xc3\xc0\x10P\xfbڙ\xbf\x0f\xbeI:&A\xad\xe2\xd4L\xc7\x18\x9c\xb2\xb0S6\xe2\x1bP\xae\x9cxn\xd5\x1e\x02\xa6\x0eF7\xf2\x97\fh\x9a\xc7\xef> \x18W\xf9\x154\xcc\x1d\xadnnj\xc3\xc3\rԾm\xa33\xbc\xbfI\x97\xc9l#\xfb@7%\xee\xd0ސ\xa9\v\x15tc\x185ǀ7\xaa3E*ĥ[\xb8l\xcb\xff\x85\xfe\xceҳ\xb0\xbc\x17@\x12\a\xe3\xea\xd1A\xba8\xaf\x18\x8f\\\xa5\x8c\xae\xec*\x97x\x9c\x82\x88\xa4u\x9b\x8f\xf7_a\xc8$O\xaa\x87\xd8A\xf5\xa4/\xc3|\xa4\x9b\xc6U\x18\xb2]\x82\xa9\xf8DWv\xde8N\xffhk\xd01Pܶ\x86i\xc0\xba\x8cn\xeav\x9dX\n\xb6\b\xb1+\x15c9U\xb8u\xb0V-ڵ\"\xfc\x8fg%S\xa1B\x86pմ\xc6\xdc;U\xce\xed\x1d\x1d\f\xccyf\xb4\x13ʸ\xefP\xcb`\xa5\xb7bi*\xa3\xf3\x95\xaa|\x00ud\x90\xbe\xd3\xcf\x1b5\xcf\x00)9\x15j\xe4\xa9t\x92\xcbפ$\xe1\x1f\x1b\xf5\x9c\xb0\xfe\x8f\xcbz)\x9cC}\"\x99\x8f~\x98\x0e\xeaR\x0e0\v\xf4\xd9L\x06|K\x1b\xa4\xafB(Bv\xe3\x9cNC\xcb\x0f]l\xe7\x03\x14\xf0[\xca\xf9\xce\xd7\x17\xcf\xd7ޱ܋\x8bJ߽\x8d-\xde;\xd5Q\xe3_нel\xff\xe80\xe4\x17\xfa\xa2\xea\xf0\xd0\x1f^\xc5\v\x8aў\x8d\xbbAyA\xf0|\xa5\xbd\xc2U^\xaeȩ\u05fc\xaa\xd0\xf5\xfd\xedkZxF\xfd\x15C\xbau\x95\x7f\xa1ģ\xe2\xac\xde\x19\x1a\x18~i\x87x\x19Ӳ\x85\f\x98\x16\x93\xfcv\"|\x8a[\f\x0e\x19\xe9\xc8ԏ\x86\x9bY\x8f\x00\x8f\x8d\xd1M2L\x17B\x1e\x01\"\xaf\xcd\x1c\xa5^\x91\xbe\xf0\x88\t8s)\x8btYgĒ\xfc\x89\xf8\f\xfb\x9d\vP\xf4\x8ct\x15\x83\xb2\xe2H\xaf\xe0Ф?\xb4Z\xc7\x10\xd2\x13\x95\xa5\xb2\x99L\r\xae%сy\xbem\xee^`ғ\a\x1bF\xdb\xe1\xb7\xcd]\xdaЕq9\xc5.`A\xa6\x96\xb5J΄`\x13\xf1e:NK\x1e\xdc&^\xee\xb52\x05W\xe6\tO\xe7#\xbbv\x85lZ\x94\r\t\xf0\xa93\x01\t\x14\xc3G\xf93\xdd\xcd7@\x1e\f\x0f+\x98\xbcɄ\xa5T\xdevl\xf7\xc9P\x1ek\xadt3\x87\xaa\v\x88\xc2C\x90\x17Zt\xcc&?8\xe8\xf2\x9e1ݡ\x0f\x05\xb8\x12\xb4r3\xf5n\x11J\xb4\xc8X\xc2v\x9f_\xce=1\xb6\xa7yW>\xb4\x8aW \xfbG!-:\xd1p\xd1Z\xb5\xb5\xb8\x02\x0e\xf1\x1c\xcag\v\xef\x1aE34\xf02,\xbe\x88\xe1\x1cZ\x0f\f1\x85+|\t^#\xc9\xc8ZTN\xd6@\xc1M\xa3\b\xb6\x88s-\xeaqc\x1c\xfb1\f\x13\xacJ\x8f\x94\xa6-\xbe\xc6\xc0\xeb7E|2\xb2\xd1\x197\xfd:\x99\x8b\xe3G\x1f<\x8f\x8d\xa7\x833\x87;\f\x82\xb02j,\x13z-\x02\xb1\xb1\x16\x02\n\xcehT\x96\f[2\xf9\xb6\xb9\x9b\x89\x12\x90cp\x04\xef߾_\xc2Z\xc9w\xee\xf1s\xa2A\xfd\x00\x9c\xf6\x97\x06\x0f\xdfUA\xb8\x95\xd3\x16\x99JQy^Iq&B\x9f'\x8d۱\xc5J\xec\x03ڽ\xac\xd7>\xf7\xea\xfc62\xbf\x89\x14\xf0\x19\x1fg\xa4\x87گ\xc7\xdc,]\x9e\bI\xd6\xf9r\x84\xe7~|\xbd\xe4\xdf\x00\x00\x00\xff\xff\xba\x18f-\x8f\x10\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=]\x93\xdc(\x92\xef\xfe\x15\x84\xefa\xee\"\xba\xca7q\x1fq\xd1o\u07b6}\xee\u06ddv\x87\xdbg?SRV\x89i\x04\x1a@]\xae\xdd\xdb\xff~A\x02\x12R!\x89\xaa\xfe\x98\x99\x8d\xd1KG\xab \x81\xfc\xce$A\xab\xd5\xea\x15m\xd8WP\x9aIqIh\xc3\xe0\xbb\x01a\xff\xd3\xeb\xfb\xff\xd2k&\xdf<\xfc\xf8꞉\xf2\x92\\\xb5\xda\xc8\xfa3h٪\x02\xde\xc1\x96\tf\x98\x14\xafj0\xb4\xa4\x86^\xbe\"\x84\n!\r\xb5\xaf\xb5\xfd\x97\x90B\n\xa3$\xe7\xa0V;\x10\xeb\xfbv\x03\x9b\x96\xf1\x12\x14\x02\x0fC?\xfc\xeb\xfa\xc7\xff\\\xff\xc7+B\x04\xad\xe1\x92(\xd0F*\xd0\xeb\a\xe0\xa0\xe4\x9a\xc9W\xba\x81\xc2\xc2\xdc)\xd96\x97\xa4\xff\xc1\xf5\xf1㹹~v\xdd\xf1\rg\xda\xfc9~\xfb\x17\xa6\r\xfe\xd2\xf0VQ\xde\x0f\x86/u%\x95\xb9\xe9\x01\xae\x88\xf2\xcd5\x13\xbb\x96S\xd5uxE\x88.d\x03\x97\x04\xdb7\xb4\x80\xf2\x15!~Q\xd8\x7fEhY\"\x9a(\xbfUL\x18PW\x92\xb7\xb5蠗\xa0\v\xc5\x1a\x83h\xf8R\x01.\x86\xc8-1\x15\x90\r-\xeeۆ\x98\x8a\xe90(a\x9al\x95\xac\xb1;!?k)n\xa9\xa9.\xc9\xda\"h\xedz\xd8\xf9\xf8\x06\x0e\x9f\x7f\xc2\xd7\xfe\x959\xd89k\xa3\x98إf\xe1\xf1D\xb4\xa1\xa6\xd5D\xb7EE\xa8&7\xb0\x7fs-n\x95\xdc)\xd0:1>6_7\x15\xd5\xc3\xc1\xef\xf0\x87\xcc\xc1\xbfHC9\x11m\xbd\x01e\xd1\x00JI\xa5\t\x97\xbb\x1d\x94\xa4lm?č\x8ah\x9c\x9a\x87\xeb8\x98\xc8\xfb\xf8\x95\x9b\x88%\xc9\x0eT\xceL\xf6T\t&v\xe7\xcc%t\x1d\xcc\xe6\xdb\xf0ej>\x11\xa4 e\xebB\x01\n\xd8\x17V\x836\xb4n\x06@\xdf\xee`\x00\xaf\xa4ƽp??\xfc\xe8X\xb9\xa8\xa0\xa6\x97\xbe\xa5l@\xbc\xbd\xbd\xfe\xfaow\x83\xd7d\x88\x8e\xff[u\xefI\xc7\"L\x13J\xbe\xa2(Z$\xa0j \xa6\xa2\x86(h\x14h\x10F#\x86h\xd3pV\xe0ĉ\xdcF\x90B/\xc7\xd5=\xb4\xc0\xfa\x92Pb\xa8ځ!\x7fn7\xa0\x04\x18Ф\xe0\xad6\xa0\xd6\x1d\xa0F\xc9\x06\x94aAl\xdd\x13i\xb7\xe8\xed\xdc\xc2\xeccq\xe1z\x91Ҫ9pK\xf0r\r\xa5G\x9f\x13R\x94L\xbf\u0530\xd9)H\xab\x97\xdd\xe0\xa6n\xa0\xa2\x0fL\xaa\x94\x18H\x85M#{ޫii\xb5\xa4\a2\xb6q\x99\vN\"\xab\x92\xf2~\x89!>\xda6\xbdu \x05\x86<\xddR<\xb5\xbd\xed\xde\x00\x81\xefP\xb4&1M\x12\x9cC\xa9H#\xb5\x99\xa6\xfb\xb4\xea\"\xb1s\x94\xfaq\x86i\x8eV\x96du\xf7x%\x1c\x88jq0P\xc8R\x80]Fm\x89ڷU\xb2um'\x91B6TCI\xa4\x98\x1c\x19٥\xe5\xa0\xfdX%rF\xaf\x87.\xfa\xf5\xa3\xc7C8\xdd\x00'\x1a8\x14F\xaacd\xe6\xa0\xd4=9\x8au\x02\x95\tm:\x94\x80~\x013 \x89\xe5\xf4}Ŋ\xcay\x18\x96=\x11\x0e)%h\xabM\xd0e>L-\x92,\x91\xdf\x0f2\xa7=\xfagA\xac\xc6\xf0R\x1a\xa5\x7f2\xd4p\xff$Q\xdb\xeb\xde#\xdd\xe2\xdf\x1b9\xbb\xec\x7fL\xc4\x06cr\x06\xd3\xce\xc8?A\xf73\x9b\xa7'\xf9\x16#<\xd0kr\xbd%P7\xe6pA\x98\to\x97$\x81r\x1e\x8d\xf1;\xa6\xcd\xe9L\x9fI\x9a\x1c\x99x&\xc2tC\xfc\x0e\xe9\x82&\xe3\xce[\x8cl\x9a\xfc%\xeeuAضCzyA\xb6\x8c\x1bP#쟥\xea\x03e\x9e\x02\x199V\x8f`\x9e\xc0\x14\xd5\xfb\xef\xd6\xc5\xd1}\x9a6\x13/\xe3\xce\xce7\x0e\x11\xc4\xd0y\xd6;~\xbe\xaf\xee\xbb|\xc1ʚ\x9c\x95\x87`d\x9d\x81\x03\xaf\xbb\xcb\xe5\xf5\xac\xac\xccf\xb4\n\x9c\xb0\xd8t\"9:\xdd4\a)\x8f@\aZqtq\x16\xa9\x1b\xef^\xe6[\x94\x13x\xe1T\xd5\x10\xcdݙ\xe0\x9a6V-\xfc\xcdZZ\x94\xa6\xbf\x93\x862\xa5\xd7\xe4-\xee\xd8r\x18\xfc\xe6\xf3p\x11\x98\x8c!\x1b;\x94\xe5\x9f\aʭ\xed\xb7\n\\\x10\xe0\xce\x13\x90\xdb#\xbf\xe8\x82\xec+\xa9\x9d\xd9\xde2\xe0\xb8_\xf1\xfa\x1e\x0e\xaf/\xec\xf0\x8bC\xc6J\xe6\xf5\xb5x\xed|\x88#\x85\xd19\x1cR\xf0\x03y\x8d\xbf\xbd~\x8c+\x95ɩ\x99\xcd\x06,Z\xd3&\x8fCE2Y\xdf?\x03\x8e\x89s\xf3}R\xde;\xd9s\xab\xcdb\xd1Fj\xf31\x9d7\x9c\x98\xcfm\xe81\xf4\x8c\x139\xb6ň\xc1\xe7\xd1:}o\x9dȭ\x01\xe5s\x89\xce\x06\x84\xf8㑑YjW&\x9el\x97\f\xa4]~\xd7\"x\x81\x9b\xdc\xc6M\xce\x14OqX-^N\xf4\xf6\xdf\x7f\x8f\xf2\x99Vr\xed\xff\xf1B\x9eڡ.d]\xd3\xf1\xaef\xd6T\xaf\\\xcf\xc0\xd3\x1e\x90\xa3\xbeڵ(Ϲ\x16\xb9\xe7!ܿ\xdc3S1AhP\x1b\xa0\x83\xebѡ\xeb9\x9dݫ\x8e&\x1d\xe5\xbb\x17\xced5\xb2$\xfb\n\x14\f\x18\xe38\uf39e\xaa\x90&JY\x9c\xe0\x906\xb2\xfcA\x93-S\xda\xc4SФչ\xb4>\x91|v\xde_X\r\xb25ω\xe0\xf7\xfd0\x83\xbd\xe6\x9a~gu[\x13Z\xcb\xd6\x19s\xc3\xeanWףwO\x99鶭0\x7fc\xa4%A\xc3\xc1\x00\xd9\xc06\xbdߛz\n)4+\xa1+\x1drdc\xd2\n\xe6\x962ަv\x89Rϩ\x11\xb0\xc0\xea\xa73P\xfc\xc9\xf5\x8c\xf2\x8e\x95\xdc\x0f\x11\x94\xb9v\xdcH\x03¶\x84\x19\x02\xa2\xb0\x18\a\xe5T2\x0eᑁ\xa8a\xb9z.O\x81\xdb\aD[\xe7!`\x85\x02\xc9\xc4l\xca-n\xfe\x812\xfe\x1cd\xb3\x9c\xf7A\xaa\xcf@\xcbsr4ߢ\xee\x04\x84n\x15n\xfe;ݱg}\xeedq=\nb\xa8&{\xe0\x9c\xd0\x14w\x1c-\xbfp'\x93\v\xb9\xc2#\x81\x96\xbc\x81I\xfcy\xe6\v'\xc5x\f\f\xa9W'\xe0\x16T\xe0\xe9f\x9dXȤ9\xccѢG~\xb9\x8b.\xf0\xdd/-\xa8\x03\x91\x0fX\xc2ཷ\xfe\xac\x82W7\xdaƘA\x01ze<\xb5\xa9p\x14\xca\xf4\n\x8a\xbc\x15Η\x18\xcf\a\xfbX\xcdׇjV\x9d\xdb(,9\xc6Dw!\xbbމnKn\x7fnQ\xff\xf3\x06n\xa7\x87n\x8b\xbeR\xbe?\xfb+\x15\xeb\x9fS\xa4\x9f\xb7\x1d\xb4X\x94\xff\\\x81\xdcR(\x97\xed\xbd\xe6\x15ݟ\xb6\x89\xfa\x8cE\xf6\xcfQ\\\x9f\x89\xa9\x9cb\xfa\xd3\xf0\xf4\x02\xc5\xf3/Z4\xffR\xc5\xf2\xd9E\xf2Y\xfb\x98ٛV\xb9یgV}/\xef\xba\xcf\x17\xbdg\x14\xbbg\xec\xa4-/\xf2\x8c\xe5e\x14\xb3\x9fVĞA\xb3\\Q|\xc1b\xf5\x17,R\x7f\xe9\xe2\xf4\x05\xceZ\xf8\xf9\xb4\"\xf4\xb3w`\xc2V\xff\x8d,\xe1V*\xb3\x14\x9c\u070e\xdb'vR\xa3\x80M\xf2\x92\x88\xd04\xb1J\f1|xqޢқ\x9e\xc1\x9d\xfeI\x96vnK{,\x9fG͏\xce*oA\x81p\xd7|\xfc\xcfݧ\x9b\x0e~\xca\xe7\xf5\x9e\xf1\xe8z\t\xe7\xc1\x94\x1e9~k\xce\x1739l\xa1\x0f\xf0\xc4\xfb\"\xb4a\xff\x8d\xf7\x0e>\"\x1d\xf4\xf6\xf6\x1aa\x04?\r/2\xec\xaa(\xba\x1d\xcb\rX\x8bաjR,\xae\xb7\x03\x88Ê\xdf\xf8\x1a%(ݕY\xc1b\xb2P\xe3e\x05\xef\xf6\xda\xcdcj\x94\x0f\xd6i\x14\a\"\x1dGVL\x95\xab\x86*s@\xb6\xd1\x17\x839\x0433\x97ΙT\xac\xc7׀%\xd1\x1bn\xff½\xc8C3\xdc\xed\x1d\xe3\xee\x9cyL\x9f?YfX6Jk|sq\xfc`\xbc\xe4j\x11\x19\xbf\x88\xb2\xb7/S\xa6\x93y\xc5\xd6ٗk9\xf4L\xa8\x1fܑ\xb0\xaa\xed\x18Sg\x14\xe8,\x86\xdb\x19\a?\xe6\x13\v\x99W3\xe5\x19\x8c3\xaecB|\xe5\xe2\x8a$oiʼ\x89\xe9WE\xf4\x8cV\xd3E\x05e\xcb\xe1\xdc{X\xef\xa2\xfe\xcb7\xb1\x86\xd12\xeeb\xb5Ȏ\f\xb4\xf5\xb0\x86w\xbezJx\xc81%\xa7\x82pLظ+\x1f\vw;pQ\x80\xd6ۖ\x87\xcaQ\xbc\xc0\x1b\xcaМ\xe9n\xc6'\xd5>\xea{ּs5\x94\xe3\xb0\xfb,\x1cO\x83\v\x97\xf8G\xd6\x01\xf7\x14\xd4\x03\xa8U\x81\x1ea\xab\xa0\f\x15\x9d3^$\xa9\x03H\xa6\xe3H~\xe0\xaa'\xfa\x7f\xab@ W:'*\x94\x8e\xc6\xd0,:\x1a(\t<\x80 lK\xa2yI\x11M8\x05\xfe#\xc5\r8\xd8n\xa10nC\x97\xa2\xc3\x1c\xa4\xf6\b#\xac\x97\xfb\x84g\xf5\b\x83\xd76\\\xd2\x12\x94s\xb4\x17\b\xf9\xbf\x83\xc6#M\x14\x10\xd0_\xa2<{\x01\xed\xa3\xecQC\x15\xe5\x1c\xf8\a\xc6A\xbf\x93{a畡foS\xfd\xa2\x13\xd0E\xab\xac\xb3v\b\xb7\xf0k0f:-\xbb\x95j\xfe,\xd2\xf1\x15\xfb\xc3g\xaf\x98\x81\xbb\x86*\r8\xa3\x8c\x15|\x1buqy\xde-\xa7;Wt^\xb2\x82\x1a\xe8\x04\aG\x98\x9a>\xf6\xd7\b\x8b\x1f\xb0\x06XNl/e\xab\xea\xa9Ï\x93\xcaz\xea\"\xef\x84\x03\x96\xbc\xca\xdb\xf9Y\x05m\f\x1e5E:\"\x11M\xf8\x9c\x84\xdc\x1e\xdd\xe6=\x00;\xcdi\xfe\xc0P\xfc\xed\x83s4\xdd\xd51\x18\xbc\x80_\x95Q\x85{|\x95qW\xcaN\xf6Twǖ\x92\x11U\x0fہA\xb5fA\a\xcddE\x912\x0e\xe5\x1c\xa7~\xe9\xb4\xd5\x0f\xba\x83\x835\xf7\x96\xc5\xef\fU\xa6\x9b\xfa\xb1w\xea\"s\xf7釕\xed}\x9e~J_H\x8e_\xd08\xeb^m\xf7\x1d\x0f\x14\x8f\"\x1cp\xb5>\x8d;\xf9]\x83\xd6t\x17ҽ{P@v ,\u07bb]\xbc\xa4\x1f\x1c\x0e\xcf{\x17`\x90\ue845i)\x0f_\x10\xa1\xf8E\x13_\xa7\x14\xbe\x04\x80\xf9\xe2ݤ\xe1M\xab\n\x7fL\xff3P=\xfe\xb0\xc4\x11.>\xc4m\xfdv\xac[\xb1\xabB\xa0\xee(\x05~Z\xc005\xfe\x94\xc8`J\x12G>\xc9I\xa8\xa4\xbc\xcf\n\x9e>v\r\xfb\x8d\x1b&\x1c+\xe1\xe5\x04\x1bٚ\xc8{\xf5\bOL\x13/\xda~b\xfb\x820ߺ\xa3\xcaS\xbb\x98y\xfe\xfb\xc7\x01\xa4.i1\xfa\xd4\v\xed\x1aT3W\xf5܅\xcf\x14p~\xb8\x18C\x1e}\xff\xa4\x87]\xf5\x97f{M\xd0_\xd421P\xd8_K\x02\xe9\xee\xdb\xee=ͩۍ\x97\xec\x1fB\xfd\x80\x93\xca\xc0\xf1Ǿ\xf5\x14\x1e\xdd4]\x18\x04\"\x9d? \x18R\x9a\xaa\x93\x8c3\xa6>\x13{\xe0爖6\xe3l\x9b\xce\xed\x88\xccU\x17Z|\x9e\x90\xca\xf4\x8d\x12+r\x03\xfb\xc4[\x87,\xac3A\xa9J49\xfa\xc0R\xfc\xe37ʬ\xfb\xf3A\xaa[\xde\xee\x98\xf84}\xc6j\xae\xf1-U\x86Y\xa6u\xf3I\xf4\xbd\n6.\xf1\xdbr\xef\xe9\x1f\x98\xa0\x9c\xfd5\xa5\xcb\xe3\x1f\x97F\x98\xd1w\x8dG\xde9\x16* ~I\x01z\r\xfd\x83\x8e\xccO\x18wMndR\x8c})\x16\x1b\x02e\x9al@\x9b\x15l\xb7R\x19\xb7S\xbeZ\xd9\xf0\xc5;HVC`\xf4\xef\xbe\x1bCX*\xba\xea\x8a\\\x82ò\xf5\tb\x85V\a\x13\t5=\xb8<3-\n\x1b\x13\xc0\x1bmh*\xe2|\x94\x9e\xc6\x04\x84\x97\x95\x1c\x15r\x1d\xb7\xef2\xb7\x9d\xfa@p\x0euxq\x8c3\xe8|\xaazdp/\x15\xd1\x16{\xe7(\x13\xe2\xd4\xd8\xf5t2%\xcf\xd4|\xe9\xa0L\xa9G\xbf\xbe\xc1'/|)\x93od\xc9VTT\xec&\x8f\x8eWJ\xb6\xbb*\xf0\xe6\x94CD\xca\x16\xf3!\r\xaa\x02\x1d>\xd1eZ%\xa2\xf2\x18_\xcd8\xa5\xa5\xbb\xe9N\xfb(\x8fPԪ?Bګ\xaa\x19\x9b\x9f\x9d\xfb\x9d\x80\xb8h\xfb\x13\x10\xa9>\x88b\xf6\xb0\xeb\xf1\xce\xe3I\xaee\x12\t\x9d6~2$t\x10\xa7\x90\x10\xfb\x12}\xc4\xf3\x9b\xc1Ȕ\x8fr&:\xe6\x9d\x18\\\xe2<\xa8\xe5E\xc7N\xd0\xd0\xdd9\r\x1dz\x10\xfc\x9d\x95\xe8\x1b@8%\xf2ű\xd3q\xefo7b}輭\xf7gǮ_G0F\x97\r\xd8(\xb6\x1f&ě\xff̶)yq\xdfA\xdcp\xf8\x97\xa3__\xf8Ҁ\xf0Q\xcas0\x12\xbe]\x99\x88\xe7=\xd8\xe7\x8c\xe8\xbb/q>UL\x9f4KG/\x91\xc1\xcb\b\xcf~\xa4\xf8M\xbb\xe9\xbf\xd9D\xfe\xf6\xf7W\xff\x1f\x00\x00\xff\xff\x95Pn\x17dw\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\x16\x9bL\xacA\xb9vH\x9a\x16&\x88\xb2\x91L\x18\xfc\xa7\xe0\f\x84!\xba]\xd5\xccX2\xf8\xa5\x05m\xe9]\x8e\xc1^\xa3\\$+ mcwd9\xaep#\xc85\xad\x81_S\r/\xbcVvU\xf4\xc2.B\xd6j\xc5\xd2~\\١7\xfa!\xc8쉥\xf5\\侁b\xb0\xd3l3\xb6\x0e\xecb-Հ\xc9\xd8&C\x1c\xa57\xbf-\xbd8\x1c\xff2Ge\xb6\xfcԵ\xb6\xf4fG\xd6\n\xf6K;\x94\xd1{\xfcj(\f\xe2b\xc9h\xbc\xba\x93\x88\xb6\x05\xbe\x17\xbc-\xa1\xec\xf4\x8b\xbd\t\xe6L\xe3\xdd\x1e\x14T\xcb(\x13v\x13Y\xfd\xc8\xceE\xf4\xbf\"\x03\xa7\n\x88\x90&\x01\x8f\t\a\x8f0\x11K\xbf\xfd\x991\x03ub\xc4\a\xa7L\x88h9\xa7+\x0e\x97Ĩv\x1f\x8d\xae-U\x8a\xee&\xb0\x15tԳ\x90\xd5\x01\U0006c1b3\x02\x97\xbcc(\x88\xaf\xdf/\xaa\x98\xb6\x8c2\xcc\xf2NrV\xecf\xf0\xf5.\xd9(\xecV\xbfw\x83\x9a\xba\x82\x8a>2\xa9R\xdb@*\xac\x1a\xc9\xf3\x9eMK\xcb%=\x90\xb1\x8c˜\xf0\xc4Vr\x83\xffj\xd5oxK\r=j\xce\xe3f\xa7\xcf\xfa\x11!YŌ>\xdfl+)\x1f\xe6\xc8\xff\x83\xad\xd3\xcbBR\xa0\x81\xd7M\xc1Ӷ\xd7TV@\xe0;\x14\xadI\f\x93\x04UX*\xd2Hm\xa6\xa9|\x9aQ\x93X\x15L\xfdx`\x8b\xec\xcd,\xb9\xb1]\xf1\"'\x90\xb0\xc5\xc1@\xfcH\x01v\x1a\xb5]̾\xae\x92\xad\xab;\x89\x14\xb2\xa2\x1aJ\"\xc5d\xcfH&-\a\xed\xfb*\x91\"z\xae{\xd1\xcf\x1f\xf5;\xc2\xe9\n8\xd1\xc0\xa10R\xed#3\a\xa5\xae䈑\tT&dǐ\xf2\xfb\t\x1c\x00I,\xa5o+VTN\x9f\xb2\xe4\x89pH)A[މ\x06\xc2nj\x92dn\xf9}'\x87xe_f\xb6\xd5\x18^\x8a\x7f\xf6%C\xe8\xf4%\x89\xda^\xd2\xec\xf1\x14\xff\xddȃ\xd3\xfe\xe7Dl\x10\x9d'\x10\xed\x81\xfdOP\xd9Φ\xe9I\xbaE{\x16\xf4\x92ܬ\tԍ\xd9]\x10f\xc2\u05f9\x9d@9\x8f\xfa\xf8\x1d\xaf\xcd\xf1D\x9f\xb949{\xe2\x99\x16\xa6\xeb\xe2w\xb8.(2\xee\xbd\xc4\xc8^\x93\xbfƭ.\b[wH//Țq\x03j\x84\xfd\x93X}X\x99\xa7@F\x8e\xd4#\xe8\x151E\xf5\xee\xbbUqt\xef\x94\xce\xc4˸\xb1\xb3\x04\x82\xbd4\x14\xcf3p\tz\a\x98\x82\x1a\xbd\x0e\xe8荿\xa0\tqu\xfbv\xdf30.\x19\x94\xb77\x91\x99M\xe7\xca\xd5hF\xf1\xf8\xbc\r\x14~A\x1d\xa83!\x9d\x87\xe9\x82P\xf2\x00;\xa7\xbaPA\xec\xfa\xd0P9\xa3{\x05\xe8\xeaB:{\x80\x1d\x82I\xfb\xae\xf6K.5\xb8\xf2\x00\t\xa5?U\x068\xb4c\xf2N\x00\x87'\xfb\x01\x11\x81\x1e\x8b\\2p\xc5o\x85\x84\xa7(]2yI(\x01\xf7'L3\x8bT\xe2>bG/R\xc0\x0fڭ\xa5\xdd1\x15\xf3\x1e\\\r\xb8gr\x17ԕ\xaf\x94\xb3\xb2\xeb\xc8\xed\x91\x1bqAn\xa5\xb1\x7f\xd04\xd3H(o%\xe8[i\xf0˳`\xd4\r\xfc9\xf1\xe9z\xc0\x8d&\x1c\x97\xb7\b\x8b=\x9cN\xa6Yj\xebp\xcf4\xb9\x11\xd6^q(\xc9\xec\n\xadPם\xeb\xa8n5:'\x85\x14\v\x94\x99ɞ<\xbe\xa5\x1a\xa0\xfb\xecN}\x87_\xac\xb0p\xbf8\x97:\xa7E\x1fdA_/5\xb0aEf\x7f5\xa8\r\x90Ʋ\xf0<\x8a\xc8d\xac~6ǑO\x9e\xf4\x8e\xcb\xf7\xc5C\xe7\x1dYX\x91\xb3\xf0\x10\x8c\xac3p\xe0yw9?\x9f\x85ݳ\x19\xb5\x02%\xccV\x9dp\x05OW\xcdA\xca\x19\xe8@)\x8e*\xce\xec\xeaƱ\xda|\x89r\x04-\x1c\xcb\x1a\xa2\xb1;\x11\\\xd3Ʋ\x85\xbf[I\x8b\xbb\xe9\x1f\xa4\xa1L\xe9%\xb9\xc2\xf84\x87\xc1o\xde\xeb\x18\x81\xc9貱]Y\xfay\xa4\xdc\xca~\xcb\xc0\x05\x01\xee4\x01\xb9\xdeӋ.ȶ\x92ډ\xed5\x03\x8eљ\xd7\x0f\xb0{}a\xbb\x9f\xed2f2\xafo\xc4k\xa7C\xec1\x8cNᐂ\xef\xc8k\xfc\xed\xf59\xaaT&\xa5fV\x1b\x90hM\x9b<\n\x15\xc9\xd0D_\x06\x14\x13G\"\xfa\x10\x84W\xb2\x0f\xcd6\x8bD\x1b\xa9͇\xb4\xdfpb\xbf\xc2\xd7\xf3iͿ-\x9c\x1a\xa8?5~\xc7L\xaa\xb0\x19hM\xc0\x19因4h\xb5S\x05:9\xe0}\x86\xb6\xfdU\xe1\xce|\x040)z\xfdRAؾ\xfe\xac\x02\xd3\xe4\xdfI%\xdbDV\xdf\x01\x94\xcddw\xccOx\x90\xe8\xe1\x03\n`\xe8\xe3\x8f\xcb\xe1/F\xfa\xb4\x0f\xf4\xa2%\x00\xa1Q\xd4{f\x99(\xd9#+[\xcaî\xedOL8\x02\xea\xe9,\x01M*\"\x18w\x04\x18\xda\x0f\b\x8e|j\\X\xe6h\x16wX\x17\xcd\xcb\x0e99'd\x98\xf31!\r\x8f\r_\ni\xf6\x8e\xed\xd9am\x19\xe7\xf1i-\x04{\x18\x94?!\xaai\xedF5\xa5\xed'\xd7U\xaa\x81R~\x92\xe1\xf8i\x04#\xf6\x8e\xbe\xa4\xe6_\xb7ܰ\x86\x83\xd5\xe8\x1eY\x99&\x9a\vٵN4\x9bS\xfbs\x93\xfa\x9f\xd7p;\xdet\x9bՕ\xf2\xf5\xd9_)Y\xff\x94$\xfd\xbcp\xd0lR\xfes\x19rs\xa6\\\xb6\xf6\x9a\x97t\x7f\\\x10\xf5\x19\x93\xec\x9f#\xb9>\x13S9\xc9\xf4\xc7\xe1\xe9\x05\x92\xe7_4i\xfe\xa5\x92峓\xe4\xb3\xe2\x98\xd9A\xab\xdc0\xe3\x89Y\xdf\xf3Q\xf7\xc3I\xef\x19\xc9\xee\x19\x91\xb4\xf9I\x9e0\xbd\x8cd\xf6\xe3\x92\xd83\xd6,w+\xbe`\xb2\xfa\v&\xa9\xbftr\xfa\fe\xcd\xfc|\\\x12\xfa\xc9\x11\x98\x10꿕%\xdcIe挓\xbbq\xfdD$52\xd8$/\x89\bU\x13\xb3D\x13Û\x17\xa7M*\x1d\xf4\f\xea\xf4GYڱ\xcd\xc5X>\x8f\xaa\xef\x9dU^\x83\x02\xe1.5\xf9\x9f\xfbO\xb7\x1d\xfc\x94\xce\xeb5\xe3\xd1\xf5\x12N\x83)=r|h\xce'39l\xa1\x0e\xf0\xc4q\x11ڰ\xff\xc6[\x16\xcfp\a]\xdd\xdd \x8c\xa0\xa7ᵍ]\x16E\x17\xb1\\\x81\x95X\x1d\xaa&\xb7\xc5\xcdz\x00q\x98\xf1\x1b_\x1a\x05\xa5\xbb ,HL\x16r\xbc\xecƻ\xbbq\xe3\x98\xea\xe5\xbdU\x1aŎHG\x91\x15S墡\xca\xec\x90l\xf4\xc5`\fA\xcc\x1cr\xe7L2\xd6\xfdKϒ\xe8\rw\x9da,r\xd7\f\xa3\xbdcܝ2\x8e\xe9\xf3'\xb3'O\x9ep\x1c\xd3\x12{\x81\x98J|N&\x98<\x99\x9bL\x1ds/Rr\x0f\xcc\\\x92\x14\xb1\x06J\xae\xa5X\xb3\xcdG\xda\x041\xe2\xf09\xc9,\xbc\x8b\xa6\xb1\xa0-H\xb7\xab\xfa;B\x9d܉\xa0\xd2.\x85\x95\xd0C.\xab\xf2=B\xbe\v\x805\xb8\xf0\xb6\xe3J\xdd\x14\x1aP\x8b\xde\xdf\xd6\xdfݴk\xa6G\xab/F&\xab\xbf\xe5f\x90\xbb`٠\x01%\xfco\xa9\xb1\xfa\x84\x9b{̷\x89\x86\xbb\xeb\x06k\xb1aGh\t\xc7w\x8e\x97\x13\xadG\xc9:\t\xe0#\x7fJ\x8f\xc1\xb5T55a\a\xa0C\x8f:\xbc\xbb;\xe2\xee\x1b(\x96\xc3%\xff\x83'\xff\xc1\x93\xff\xe0\xc9O˓-s\xbb\xfbz\x92+\xfcs\xd7\xfa\xb0\xeeI9\xef\xdc\xff\t0\xb6=\xaa\x9fZ\xd0FW\x89K\xff\xce\xd3?\xf1>L\xbc4\xf8\x8cI\xde\xfb\x8b\x9b\xa3y\xb2\xa2\x8a4\xc8-\x04\x1d3L\x1bwk|Os\\\xd0^r\xb9\x88\x8c_D\xdeۗI\xd3ɼb\xeb\xe4˵\x1cz&\xd8\x0fF$,k\xdb\xc7\xd4\t\t:\xb3\xe6v\xc6\xc1\x8fÎ\x85̫\x99\xf2\x04\xc6\t\xd71!\xberqE\x92\xb74e\xde\xc4\xf4\xab\"\xfa\x00W\xd3E\x05e\xcb\xe1\xd4[g\xef\xa3\xf6\xf3\xf7Ά\xde2n\x9e\xb5Ȏ\x04\xb4հ\x867\xdc\xfa\x95\xf0\x90㕜2\xc2\xd1a\xe3\xae|,\xdc]\xc8E\x01Z\xaf[\x1e2G\xf1\xbar(Cu\xa6\xbb\x11\x1f\x95\xfb\xa8\x1fX\xf3\xd6\xe5P\x8e\xcd\xee\x93p<\r.\u009f\x91\xe9T\x03\x02\x94\x82\xfc\xc4e\xf1\xd0\xd7\xea_\xff8\x8fsO\x9f\x85l\xa8\xa2\x9c\x03G\x94\xbf\x95[a)+c\x19\xefR\xed\xa23\xecE\xab\xac\xba\xbd\v\xafFx|N\xa0|-\xd5\xe1\xd3d\xfbOB\f\xcbV1\x03\xf7\rU\x1ar\t\xf1ۨ\x89\xf3ԯ9ݸc\x03%+\xa8\x81\x8e\xf6\xb0\x87\xa9\xe1{z\xb5\xb0\xf8\x0e\xb3\xb8\xe5D\x80\xf0\xec%\x9b\x14\xb7S\x17\xcf'T\xe8\xe4\xd5\xf3NS.hc\xf0\xb00\xae#.\xa2\tϟ\xc8\xf5\xde\xed\xf3\x03\xb0Ӽ\xc2\x1f\xf9\x8a\xdf\xea8EV]\xef\x83\xc1\a#T\x19\x9dQ\x88/\xa1\xee\x0e#\x90-\xd5\xdd\xc1\xb3\xa4M\xdc\xc3v`P0Y\xd0A\xb6XfJ\x19\x87\xf2\x10\xa5~\xe9\xe4\xcd\x0f\xba\x83\x83\xa7&,\x89\xdf\x1b\xaaL7\xf4}\xfb\xc2\xf9V\xdcS%\v\xdb\xfa4\t\x93\xbe\xf5\x1b_|9\xe9\x1ex\xf7\xee\fn\x8f\"\x1cQ\xb6Z\xa9;\xbb_\x83\xd6t\x13\x1c\xf6[P@6 ,\u07bb8lҒ\t\xd7\x1fx%nణ\x85i)\x0f/\xdeP|\x81\xc7g\x9a\x85\x97+\xd0㿙T\x9dҬ\xc2_\xb4\xf0\x19\xa8\x1e?\x84\xb2\x87\x8b\xf7q]\x1fPw3vy$\xd4\x1d\x86\xc1\xa70\fS\xe3\xa7o\x06C\x92\xd8\xf3Qj^%\xe5C\x96\xf9\xfb\xa1\xab؇ޘp\xa4\x84\xd7K\xacdk\"\xfb\xc3#<1L\xbc*\xfd\x895\x04\x84y\xe5\x0e\x9bOš\xf3\xf4\x83\x0f\x03H\x9d\xdbi\xf44\x11\xed*T\a.[\xba\x0f\xcfjp\xbe\xbb\x18C\x1e\xbd\xd7\xd3î\xfak\xcf='\xe8\xafڙ\xe8(DH\x93@\xba\x1b\xd3{[a\xea~\xea9\xf9\x87P\xdf\xe3\xa02p\xfc\xa1\xaf=\x85G7LgȂH{\x80\b:\x05L\xd5\xed\x8c\x13\x86~\xc0z\xc4\xe7\xb3\xe6©\xb6N\xa7vD\xe2\xaa3\x0e?O\xec\xca\xf4\x9d \vr\v\xdb\xc4W\x87,\xcc\x14\xc2]\x95\xa8\xb2\xf7 X\xfc\xe37ʬ\xfa\xf3^\xaa;\xden\x98\xf84}J\xeeP\xe5;\xaa\f\xb3D\xebƓh{\x1dd\\\xe2\xb7\xf9\xd6\xd3?0A9\xfb[\x8a\x97\xc7?\xce\xf5p\x80\xdf5\x1ey\xa7H\xa8\x80\xf89\x06\xe89\xf4\x0f:\x12?\xa1\xdf%\xb9\x95\xc9m\xec\x93\xe9\xd8\x10(\xd3d\x05\xda,`\xbd\x96\xca8\x1ba\xb1\xb0\x06\xa8W\x90,\x87@\xff\x8d{爰\x94}ܥ)\x05\x85e\xed]\xfc\n\xa5\x0e\xba\x82j\xbas\x91\x02Z\x14֪\x837\xdaД\xcf\xe0,>\x8d.$\xbfWrX\xc8M\\\xbf\xf3\xbdw\xec\x03\xc19\xd4\xe1\xd5?N\xa0\xf3\xa9\xfc\x9f\xc1\xcdbD[\xec\x9d\xc2L\x88cc7\xd3\xee\xb0B\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?\xbf\bS\x9aH\xb1\xaeEa\x17Bv\xfb\vz\x1d{<\x8e0\x0e\xb8c\xbe\xb9U\x1f\x8d\x9b\x98ϢS\x04\xe6\x88\x11\xadT\x1e&\xfcF\x14\xc0\xcc\xceX(\x83\xcaoæN,8,\xe4h\x15\x85\ac\x90\xee~P\xe3\x04\x91uQ\xf0u\x01\x97d!\x0f\xd0l\\Y\x8f\x11\xed+\x18+\xb2S\x92\xccA\x1c!\x98\xf6?\xf4(Cq\x17\x7f\x00\xc6#\xe0==1\xc8+\x8a\x0e\xd1\xfbԊ\xe2Vi\xc80\x00\xb8\U00101140\x82\x82\x19\xa9X\xa1\xe4=h\x87Ec\xe8\xd1\xd0\x00\nh\xce\xd0g\xd7h\x9e\x85d\x9b\x1a\xdd\xf9%Cm\x11\x95\x11!\x8d\x05\x1e\x11\xe6\x13\xf0\x0e\xbe\xa1e\x80\xfc\xaa\xa8\x8d\x05}\x93\xa9\n\xf2\xb0z7j\xd6Ry\xf8\xe1 d\x1f\xfc\x15\"\x03\xe4C\xe6*-h\x85,&\xdam\x1c\x88f\x92\x16\xf3\x90\xd5~\bm\x807\xa9c\fXlx\xfe\xfb\xf3\v\x92\x80~\xef\xfd~\f\xe3\x1a\x1a2\xcd\xd2\xd1\xe4.\x8d\xb7\x10\x16\xca\bu'u\xd4\f\xbes\xad\xf9\xee\x00כ\x95\xc8\x17\xe0{\f\xf6\x80\xf32T\xfbN\xbc\x1f\xf6\xff\xaf\xc8\xfd\xd3\xf2\xdb\xd0j>\x17\x12\xf9\\\bc{l6n\t\x10\xc9:\x16\x7f{\x02I\a\x13\xd5\xe4\x14W\xffA\x88yҹ\x13\x9b,\x8dl\xfa\t\xf0OEɭR\x0f)\xd4\xfb\x1f\xac\u05ee\xff\xb1\x8cv\x9c\xd8\x1a\xb6\xfcQ(m\x86k\xcc\xf0\r\xb2\xdaF5\v\xb7,\x17\x9b\rh\x84E{$͖\xca!b\x1d\x8e\xfdXGeE+\f\xc6\xd52\x1dYJԈ\r\x85\xa2\xfb(T\xe7\xe0`\x88A\x0eD.\x1eE^\xf3\x82|\t.37>\xde\xe0\x17\xd3j\x13\x02\xb1\x87\x7fT\xaa]q\x0eM\x18$2\xb1\xb7d\xa8$\xa0\xaf_b\x8c\xb4_5N\x89\xb0\x0es\xb0od\xa6\xae\v0\xbe\xbb\x9c\xdc\xe4V']\xb4\xccr\v4\x05_C\xc1\f\x14\x90Y\xa5\xe3\x14J\x91\x03WR\x95n\x84\xb8#Z\xb6\x1fu\xb5\x83\x99\x00\xcb(\xd4݊l\xeb\xdcW\x144\x82\xc5r\x05\x86\x96\x94xU\x15\x11\xd3ՖI\xe1\xf0\x9dM鍶$h\x90!ܘ.iK\xa2~n\xcb(\xd9۹٧\xfa\xf8&\xc9(\xbe\xffJD\x0fV\xe7Ha\x9f\xd0$\x8c6[\x92\xe7C\x94\xf4Hq\x01f\xd9Y\xda\x146|Mah\xcf\x7f\xdcۇ\xda#ʯ\x8bw\xc7M\x98\x19\xac\x9b\x9cS/˸\xa6\x9b\x7f\x12\xbe\x91ɺ\xf1\x16k\x16\xcf>u[^Ж\x8agH~\xc16\xa2\xb0@N\xd5\x14\xa2l\x06\xe7NI\xa0T\v\xcch\x87\xddf\xdb\x0f\xcd\xc6[B\x8b\x01\xad\x86\x00\x9c\x83\x1e\xa2\x1c\xe2A\x02Hָ\x16\xb4\xe3,܊\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\x0fq\xc18{\x80\x9ds\xb1\xb8d\xc87\x1e*'\xa2\xa0\x81\xd2)HS<\xc0\x8e@\x8d\xe7G\x8c\x979\xd2\xe2\xca\x03\x8cl\x99\xc6J\x8f\xae\x88\x9f߈rt\xc3\x0fD\x98\x94\xd9Ԗ\x86\xa8~\xfa\x8cd'\xc4\xcb\f\xbd\x14J\xe0ˑ\xc3N\x16\xa7n_\xfd\x8c\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\v\x88\x03t\x96\x04\x89\xd8ͼq\xb6\x14\x05\xb5\xe1\x870l%1$s$\x9a\xd1\x1d%Z\xb9.]gemh\x9fZ*\xb9p\xcbbc\xbdy\x1e(\xddc\xc1I:\xf6\x9dޢ1r\xbf\xb8\x94\xaf\x82g\x90\x87\xad:\xcaE\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\xc2\xceXY\xe0\\O\xac\x19\xa4%\xa9z$\x9d\xe9p\xf5Tb=\x93L\xe4E\x90ە$\x05ݬ\xe0y\xd6k\xa6\xdc\x1c\xa3b:cq.@\xc9ik\xedoh\xe9i6\xfe\x9dU\\h\xb3d\xef(-\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\xb3\x9c\xd4mWa\x9d\xaf\xe4\xb9\xf3e\xf6\x14O\xe3\xf8(Y\xec\xd89\xfdv\xfe\\\xf7n\x86DϨ\xda\x13\xe5\x92W\xe9\x92LI\xc7s\x02\r\fփC\x84\x8d\x9b\xec[\f\x10\xa6(\x90,ʕ2\x91\xa4\x91\bZ\t\x82~\xad\x8cu\xeb\x90=\x7f\x7ft\xa1R\x85\xc5I\xc67\x1643V\xe9\x90ϊ\x8a?e)\xbe[n\xb7`\xc0\xefC\xf9EO\a\x18\xa3\xd8\xf3V78\xabr\xee\xf6¨#\x9e\x91\xf7Dm+\xad20Ѽ\x88\xb6$ڦ\x91\xec\xa5.\x1d\x9au]\ue8bfM\x92\xd6NY\x94\x0ee\x9e#\x8f\xa4;\"2\xfa\xf0\xad\xb3D\x8d\xda\x05\xffN\x91\xd6cpdt\x10\xa6,\xf90\x97:\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\x90B\xe9\xb2\xce\xe7\xc4ہ\xa4[\xfe\b>\xed\x17d\xa6jIKa\xa8\a\xb0\x9b\x19\x10\x1dk\x9c\x15H\xb4w\x9d\xc6\xd1Ḻ\xb2 I\x12rrݬ\xdb\xe4#\x17i\xebV\xec8\xb6\xdaC\xb9\x9cc\xe5\xf8y\x14\x12=\xbbg\x11J\xfeM\x94u\xc9x\x89<$\xb7C\x94\xd0\x1cGp\xecn\xd2?\xb1\x05\x19-\xabp\x96U\x05X\xf0\xe9\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\xf4c.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;\x82\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*\x9fbK77D\x80\xd1e\x1e<\xa7\x1b\x1c:\az\xbc\x1e\b\xf7L\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~Cd(\xd3\x0e\xc0\xde\x05ϣ\x95^BBg\xad\x97\x1e\x9c\xc0\xc5\xf7\x98`\xcfe\xb5ҽ\xf0\xe2Y\xb1\xf3\x97\x01,\x14\xf8\xe0j\xbfb,Sօ\x15U\xd1^\xc8\x17\v\x9a\xb7\xb0k.\\\xfaY\xd11\x7f\x7f\xebؗ\xafͬ]\x0e\"3n\xd8\x13\x14\x05\xe31\xfd\xb2G\x85\xcc]\x04\x9b\xa9\x05\xa0}GM\xe5/\x94\xf2\xb7\xc7^\xb8)O7\x1a\x90\x97PƖ+\xb9<|[\xd9A#\x9c\xaa\x8b\xf7\xa2\v\x173ѷ_j\xd0;Fw\xa75\xfee{0\xd6++\x83\xc1uP\xa1^\xa5\x1f\xda\xf7\xd9\v\xd2Z\x15\xc7\xdeI\xe7\xd5\fq\xa26\xa8;۠\x14\r\x83\x8c]4\xc8\xc2\x04\xdd\a!U\x03!\xd24%\x80\x99sR\xf4%B\xd4S\x04\xa9I^\xdc<\x0f\xfc;\x9e\x00=\xf6\xe4gzBM\xd2Iϗ\bY\xe7\x04\xad\xb3|\xee\xf4\x93\x9c\xf37\xcf_\xf8\xe4\xe6K\x9d\u061cA\xbd\xd4\x13\x9a\xf3i\xf7J'2_\xfd$\xe6k\x9e\xc0\x9cu\xf229\xc5lV\xd6Ĝ\xf4\xb0g\x1c\x19Lˇ\x98>I\x99x\x8221[\"m\xf0G\x0e;\xf1\x84\xe4\xfc\x93\x91\x89\xfc\x9d3\xa5_\xf9\x04\xe4+\x9f|\xfc\x1e'\x1e\x13$0\xa1\xca\xfc\x93\x8d\xcf\xdeVS:\a=\xb9u9Gj'\xe555\x96\xeb#6؛\v7\xe2b\xad^\f@fɿ\xe4@\xafv\x1c\xda\xcaG\xc9\xecxD\xbd\xbd\xd5\xd6]\xeb;\xc4\xfe9\x0f\xb7\xfdj\xa0\xe2h\x00(p\xa3\xf4\xb2\xa8\xab\xf0\x81g\xdbA\x0f[n\xd8F\xe9\x92[v\xdelx\xbfq\x1d\xe0\xdf\xe7K\xc6>\xaa&ߨ{\xe7\x9b\x11eU\xec0\x12c\xe7\xdd\x06ϓ\x92\xa8t\x86\x9e\xafU!\xb2\x88\xcf9z7\xa0k\xb0wa\x12\xdd^\x98u2^b\x81\x0f6\x17\xe1\xe6\xc8\xfe\xb5\xd2\xeeB\xffc\xd7{*\xf1'zo\xeb\x04+\x87\xef\xaeW\x04+\x88\x11=\xe4\xd5$Y6,_\x03\xba\f\xed\xd8\x0f\xe9\x93զ\a\xb5\x9f\xe7\xdc}\xad\x04r\xf74Mp[\xbcj\xce\x14j\xad\xeb\x95\xc3\xe5PO(_\\\xee\x98\xf2o\x8f\b\x9d/*\xae\xed\xce%D]\xf4\xf0\bv}j\xe5\uf835\xda\x7fz\xa7[zd\x0f\xaf\xee\xd0n\xfc\xae\xea'@\f\xe9\xf9\x1c\x9c\x0e\x9f\f\x9f<\x13\xfe\x028\x1dv\xa1\x16D\xc5\xc8O\xd1,Γ\xaf\xba\x1a\xff\xda\xc0_\xd4#\xbc\x8f\xae\xbe\xf6\x9f\xdf\x194\x19I\xaf\fP\xe9\xa2\xfc\b\x05ۜJ\xba\xa7\xfcyj/\x9e/\x19P\xf1\xf7\x9c?gq\xf2\xa6\x0fj\xfcE\x1a\xba\x05>t\x1a\xf3\xaa譯\x1d\xbb\xbe\xa3\xb8\xb5Q\xa5~\xea\xfb\xb85,O\x86$\x89\b,!\x0f>\xd2s*2Z\xa5\xf9=|R\xeeq\xa5\x141\xe9\xb7\xe8=\xbd\xe5=\xb7\x90s\xee'aL\xd1\xfb\xb1\r\x01\xb6gL\xf6\x1e+@l\x8f|\x8e\xc1\xda\xe292r{\xfbɍ\x94\u07b4y\uf7e7A}l\x00Y\x10(࠭\xf1\xbf[\xf5D\x97\xf8\xc7ט\xc3\v2\x9dG\xec\x80\x0e\xbbP\x1a\xf2Qì\xabB\xf1\x1c\xf4\x15\xbd\xa2\x930\xe2\x9fz\r\x06\xee@\xff-\x1eo7#\xe3\t=\xbf`\xa6\x0fztE\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{g\x82\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}콕\x13tB\x8az\xbf\x1bo\xd9\t\x11:ډ|\xfa\xb8\x12\x8f\xc1\xe2ƨLPTA\x8f#\xd1i\xaa\x97\xbb\a\xfdP\x80x@:j\x03_\x9e$\xe8\xaf\xc1\x02\x99\x95\x8c\xbd=3\xad\xfd~ڃ\x16}s\xc6*\xec{\x04\xc6\x00\x00Sa\x9f˸W\x8d\xc2\xf6\x9a0\xcd\xebv\xfb\xf4\x9cP!qK7\xee\xb0-\xc6\x1f\xe3Z4\x8f\x86\x9d%\x90۽\xe5\xd4\a<\xfe\xa6\xa1{\xf4)㕭uЮ\xb5\xa6\x9b\xe2\x11\b\xb8\x8bԏ{հ}\xec\xee\x18\x06\xb7\xaf͵\xfb\x0f\x93\xef\xe1\x8e\xc0i\xde%\x8c>r\xe6\"j\xf7^\xed\x02\xe1\x1f\xc7\xe3\xd1\x19\x838߸\xc7\xeb&\x88\xf0\xa9\xad96\xe0f\x188d\xff\x1cޫ\x8e\x84\x1e\x0e\x98\x18\xc35\xd6iN\xeaz9\xa2\x86\xe1\xc1\x81\x9b\x18\x13Əs.\xd8g؏\xd8\x17\xec\x83\xc4A\xec\x13\xc0\x9dل\x9c\xb6VH;\xce\x19\xe2cӊ\x0e̎h\xc8i\xb1\xbd\x1b\xc0\x18d\xe3\xd3\xc3UM\x15wbְߊ1o\x94v\xcc2\x1c\xe8\xef\xf6~\x8dj\xf0\x83\xda;\xa6\xb9G\xd5\xc8\xdeGz\t1\xefH\x8e\xf7һ_\xeau\xfb(\x04\xfb\xdb\xdf\xcf\xfe?\x00\x00\xff\xff\xeaC\x1a-[}\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\xbcWM\x8f\xdb8\x12\xbd\xfbW\x14\x92k$o\xb0\xd8\xc5·F\xef\x1c\x82I\x06\x8d\xb8\xa7\xef4Y\xb2\x19S\xa4\xa6\xaa(\xc7\xf3\xf1\xdf\a$%\xb7-\xcb\xe9\xf4`0\xbat\x8b\"\x1f\xeb\xe3իrUU\v\xd5\xd9'$\xb6\xc1\xaf@u\x16\xbf\n\xfa\xf4\xc6\xf5\xfe\x7f\\۰\xec\xdf/\xf6֛\x15\xdcG\x96\xd0~F\x0e\x914\xfe\x1f\x1b\xeb\xad\xd8\xe0\x17-\x8a2J\xd4j\x01\xa0\xbc\x0f\xa2\xd22\xa7W\x00\x1d\xbcPp\x0e\xa9ڢ\xaf\xf7q\x83\x9bh\x9dA\xca\xe0\xe3\xd5\xfd\xbf\xea\xf7\xff\xad\xff\xb3\x00\xf0\xaa\xc5\x15\xf4\xc1\xc5\x16٫\x8ewA\\\xd0\x05\xb3\xee\xd1!\x85چ\x05w\xa8\xd3\x15[\n\xb1[\xc1\xf3\x87\x021\\_L\x7f\xcah\xeb\x01\xed〖78\xcb\xf2\xe376}\xb4,yc\xe7\")wӲ\xbc\x87w\x81\xe4\xa7\xe7\xdb+\xe8ٕ/\xd6o\xa3St\xeb\xfc\x02\x80u\xe8p\x05\xf9x\xa74\x9a\x05\xc0\x10\x9f\fW\x812&G\\\xb9\a\xb2^\x90\xee\x13\x96?]f\x905\xd9NrD\x1f(\xf4\xd6 \x81e\x90\x1dB7\xbe\x87&\xbf\x17;\x80%\x90\xdabF\x00\xf8\xc2\xc1?(٭\xa0N\xf1\xad\xc7C\xc3璛\x87\xcbE9&\xb3Y\xc8\xfa\xed\x9c!%\xae0\x06\x16\xc6\xc8\x02\x8b\x92\xc8\xc0Q\xef@1\xdc\xf5\xca:\xb5q\xb8\xfc٫\xf1\xff\x19\xbb\xf2\xa9\xba\xdb)\xc6K\xb3\xceVfl:\x83\x18\t[k\xc2lʣm\x91E\xb5\xdd\x05\xe0\xdd\xf6\x12\xce()\v\x03Eߗ\xcc\xea\x1d\xb6j5\xec\f\x1d\xfa\xbb\x87\x0fO\xff^_,\xc3\\H\xa6TK\x99R02\x02\x0e;$\x84\xa7\xcc\xeb\x9c&\xe4!i'P\x80\x91G\\\x9f\x16;\n\x1d\x92ؑ\x84\xe59\xab\xf3\xb3Չ]\xbfW\x17\xdf\x00\x92+\xe5\x14\x98T\xf0X\xb84\xd0\x12\xcd\xe0}\xe1\x94e \xec\b\x19}\x91\x80\xb4\xac<\x84\xcd\x17\xd4RO\xa0\xd7H\t&\xd5Lt&\xe9D\x8f$@\xa8\xc3\xd6\xdb_O\xd8\f\x12\xf2\xa5N\t\xb2@&\xbeW\x0ez\xe5\"\xbe\x03\xe5\xcd\x04\xb9UG LwB\xf4gx\xf9\x00O\xed\xf8\x14\b\xc1\xfa&\xac`'\xd2\xf1j\xb9\xdcZ\x19\xd5O\x87\xb6\x8d\xde\xcaq\x99\x85\xccn\xa2\x04\xe2\xa5\xc1\x1eݒ\xed\xb6R\xa4wVPK$\\\xaa\xceV\xd9\x11_Ԫ5oi\xd0K\xbe\xb8\xf6\x8a\x9f\xe5\xc9j\xf5\x8a\xf4$\xe1*\xac)P\xc5\xc5\xe7,\xa4\xa5\x14\xba\xcf?\xac\x1fa\xb4\xa4d\xaa$\xe5y\xebU\\\xc6\xfc\xa4hZ\xdf \x95s\r\x856c\xa27]\xb0^\xf2\x8bv\x16\xbd\x00\xc7Mk%\xd1\xe0\x97\x88,)uS\xd8\xfb\xdc!`\x83\x10\xbbTPf\xbaჇ{բ\xbbW\x8c\xffp\xaeRV\xb8JI\xf8\xael\x9d\xf7\xbd\xe9\xe6\x12\xde\xf3B\x1d\xdaՍ\xd4\xce+ºC}Qx\t\xc56vP\x88&\xd0$@jԋy\xbc\xcbx\xce\v\x05\x94\xa6\xdd\xd8\xedt\x15.\x1aЭ\xb3\xdf\b،\xdf\xf7\xf9\xa6\xc4\xe1&ЩGU\xa3\x9f\x83%\x91\x06\x87-:s\xc5ԛ1Ϯ\x10\x9a\x94b\xe5\xae\r\xbd\xb4\xe4\xb41\xcf,\xca\xfa\x12\xf2g\x80\xcc\x7fC\xfe%1\xa6\xc1\xd9\x06\xf5Q;,\x80\x10\x9a\x19\xee\xbd\xca\xe4\xf4\xa0\x8f\xed\x1c\x11\xef&?|ο]\xff,\x9a\xa6m&\xf9\xb3\xf9\xbcZ\xe44\xec\x99\x15\bł=\xb0\xec|%nN\xb3\xec\n~\xfbc\xf1g\x00\x00\x00\xff\xff+\xf2\xd32>\x10\x00\x00"), diff --git a/config/crd/v2alpha1/bases/velero.io_datadownloads.yaml b/config/crd/v2alpha1/bases/velero.io_datadownloads.yaml index fa3757a9d..d3313eedc 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 96990c557..ab7629830 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\xb2I\xc1\v\x02\b\x1e\x92\xe5$\xff\xdd\xd5\x00IA$4z\xd8^\xdd\x044\xba\xbf~\xa0\x1f\xe0l6\xbbc\x9a\xbf\xa2\xb1\\\xc9\x050\xcd\xf1g\x87\x92\xfe\xd9\xf9\xd7\x7f\xd89W\xf7ۏw_\xb9\xac\x16\xb0\xf4֩\xf6G\xb4ʛ\x12\x1f\xb1\xe6\x92;\xae\xe4]\x8b\x8eU̱\xc5\x1d\x00\x93R9F˖\xfe\x02\x94J:\xa3\x84@3kPο\xfa\x02\v\xcfE\x85&0\xefEo\xff<\xff\xf8\xdd\xfc\xefw\x00\x92\xb5\xb8\x00\xe2W\xa9\x9d\x14\x8aUv\xbeE\x81F\u0379\xba\xb3\x1aKb\xdc\x18\xe5\xf5\x02\x0e\x1b\xf1`'4\x02~d\x8e=v<²\xe0\xd6\xfdk\xb2\xf5\x03\xb7.lk\xe1\r\x13#\xd9a\xc7n\x94q\xcf\a\xfe3\xa8\"G\xcbe\xe3\x053LJ\xee\x00l\xa94. \x9cѬDZ\xeb\x94\r*yl\x98\aZ\x85d9\"!/5h\xb2\xd6Q\x8e\x89\xdf\x02\xc4\x11\x83\x87\xe4|D\x12\xf9\xa6\xebg\xa1Pȁ\xaa\xc1m\x10\x1eX\xf9\xd5kX;eX\x83\xf0\x83*\xa3\xfbv\x1b4\x18(\x8aHA\xd1\v\x9c|\xa7L\xd6u\x1a\xcby\xa4\xed\x98\xf5\xbcF\xfe;\x16\xf4\xbb\xc7Vi\x90ec\xab\xcfA\xf3@\xc1\x95\xcc\aا\x06/\n\xaeԈRU\x98X\xec\b\x13\xb7\xa0\x8d*\xd1\xda7\x02\x9e\x18\x1c\xa1x>,LL\x13)\xb6\x7faBo\xd8ǘd\xca\r\xb6lѝP\x1a\xe5\xa7\xd5\xd3\xeb_\xd7G\xcb\xf0F\xc2`\xa5\xb3\x94)\b\xbe6ʩR\t(\xd0\xed\x10et}\xab\xb6h(\x016\\ځ#\xa5\xf3*%8$s\x8a\xef\xc0\x8fv\xe3\xa6\xc1\x10=\x04Ф\xde\a\x92\xa9\xd18ާώ\xf7\xa1\xf2$\xab#=\xfe7;\xda\x03 \xd5\xe3)\xa8\xa8\x04aT\xab˭Xu֊\xce\xe3\x16\fj\x83\x16e,J\xb4\xcc$\xa8\xe2',\xdd|\xc4z\x8d\x86\xd8P\xb6\xf7\xa2\"e\xb7h\x1c\x18,U#\xf9/\x03o\vN\x05\xa1\x829\xb4.\\F#\x99\x80-\x13\x1e?\x90\xd1F\x9c[\xb6\a\x83$\x13\xbcL\xf8\x85\x03v\x8c\xe33Y\x91\xcbZ-`㜶\x8b\xfb\xfb\x86\xbb\xbe\x1e\x97\xaam\xbd\xe4n\x7f\x1f\xbc\xc1\v\uf531\xf7\x15nQ\xdc[\xde̘)7\xdca\xe9\xbc\xc1{\xa6\xf9,(\"CM\x9e\xb7՟LW\xc1\xed\x91\xd8I \xc6_\xa8\xa4W\xb8\x87\xca+\xdd\nֱ\x8a*\x1e\xbc@Kd\xba\x1f\xff\xb9~\x81\x1eI\xf4Ttʁtb\x97\xde?dM.k4\xf1\\mT\x1bx\xa2\xac\xb4\xe2҅?\xa5\xe0(\x1dX_\xb4\xdcQ\x18\xfcǣu\xe4\xba1\xdbe\xe8Y\xa0@\xf0\x9a\xf2A5&x\x92\xb0d-\x8a%\xb3\xf8\x8d}E^\xb13r\xc2E\xdeJ;\xb11q4o\xb2ѷR'\\\x9bf\x90\xb5ƒ\xbcJ\x86\xa5c\xbc\xe6]%\xa14\xc0\x8eh\x8f-\x94\xbf\xfa\xf4\xcbV\x931ѹp\xa3\xdfC\x8eQ\x8fV&\x89\xbc\xabu\xb6+R\xe2\xb8H\xa5\xbfI}4\xa8\x95\xe5N\x99\xfd\xa1J\x8eC\xe1\xa4W\xe8W2Y\xa2\xb8E\xbde8\t\\Vds\x1cB\x99\x92P\xe4\x1a\x80*\xd9(\xba\\G\xae\x80'G4\x14\xdb\x16]^Q\x99\xadj\\¡\xa7\x84\xb4w\x1c\xab[(%\x90\x8d\xadHQ\xf8\x99\xca\xc2Rɚ7S\xc5\xd3\xf6\xf7T\x88\x9c\xb1i&`\x13\x91\xa4\x05E'!\x99\x85\n5\xebC\x97R{\xcd\x1boN\xf9\xbf\xe6(\xaaI\xfe9y\x93z\x85\x83\x94[|<@\xefoWWՒ\xd2\xebT\xc8P6\xf4\xbbIhNA\x02<\xd5\tGn\xe1\xdd;P\x06\xde\xc5a\xe9݇x\xdas\xe1f\\BmS1;.D/\xe8\xaa\x00\xa7&\xe7\xcb\xfa\x8c\xf2ρ\x88 }Y_\xdb^MѠ\xf4\xedT\xe0\f\x98w*\xb3,\xb8\xf4?g\xd6w\\Vjg\xafQvhq\xa8\xcbT\xde\xdd\xe2\xf3/#\x1e#\xd7;ꉃ\xbb\x9d\x82\x1d\xe3I\x9b1H\xb7\x1f2|\v\xac\xa9&\x19t\xdeH\xca\bh\f%i\x1bX*?i{\xde\xd4\xd4J\xa6\xedF\xb9\xa7\xc73:\xae\a\xc2>\xf5>=\xf6.~\r\x817\xe4ߎ\x122^\"\xf8}#Y\x85\xca~\x13\xda5\xff\x05/\xc4K\xa4=b\xa1\x1a^2\x016\xac\xc9n\x0e\xec\x94\xe8yO\x01\xe5F\xbd1\xdct`K\xf0\x86\xf6gx$\xb8%\x8c\xd6\xc7,zU\x94\xe1\r\xa7`\x91\xc3\xce\xe1\x8em\x95\xf0m %\x97`\x05^\x9f\xb05P\x05\xa1~\xab@\xa8x]\xa3\xa1\xa6*t\\Q\xf0\xeau\xf9\xde&Bx\x9d\xfe\xa1b\xd52\xad\xb1\xa2\U0004e0b1\xf3\xedU^u\xcc4\xe8^\x03\xe83&zIH{SPwF\x0e\xea\xda\xffp\xb9\x02\x19\xac^\x97\x99f\x9d~\xab\xd7)\xc2ӭ\f\xfdj\xfbB\x1advF\x10\xbf_\x13a\x0f\xae\xe6\x02\xc1\xee\xad\xc36\x98`\x840z*\xe7\x973\x95\x11\x0en\xb8\x00\xd3$|:\xf1\x03\x8f[\x00\xe8\xed\x05\x92W\xaf\xb9Nm\xf0\x0f\xb8\rsD\xd1\r\xfeP\xec\xb3<\xa1\xcf1]|݆\xb7\xbc\b\xf0\xf2M\xc4\xcb1\xe4\x13x\x8b\xfdo\x86L\x8d 7X\xe5j\xe0i\xcf\xcd@o\xb3\x8b\xe5\xe5\xedN^\xf2,\xdfӏhƵs\xb4}(8\xe3\x8d\xe3D7\xdaMs\xc4E\xc3Ox\x9a\xb9t\xfc\x89\x0f\xae\x9d\xdbKoB\x16\xec\x9eaU}\xe3\x00\xc4\xca\x12\xb5\xc3\xeaaOm\xd1\x05\x9d\x13\x01\x90o?L\xfd[\x1f\xfa&\xd4\xec\xda)\xa5\x874<\x9e\xddR\x91>\x8d\x99\x84\x17\x14S%}\xcd\x14nloO\x83\x06x\xa1\x1a\x1c^\x00\xde\xc7V\x86\x8e\x85\x06\x89\xba\xfc\x89ГU\x9aF\xfc\x19\x9d\x9fPH/\x04+\x04.\xc0\x19\x7fj\xdc\xc9Ow\xf1-:}v\xbciԛ\xb2\x99ڎ\r\x0fm\xe1A\xb4\x7f\x05ϙ\xec\xc0o0Xd\x87\x15\xe0\x16%\xd0\x00ϸ\xc0\xaa癙y\xceY>\x03z\xdaK\xff\x91\xc6o\xd1Z֜\xbb@\x9f#U|\x9b\xea\x8e\x00+\xa8\xf1\x1e\x8f\x1d\xefmw\xb7\xaf\x1e\x80~\x9fK|\xe1\xf8\xf3\x06\x960\xaf\x9f\x01\xb3\"\x9a\\N\x1b\xa0\x9dNj\xf0\xc6\xf4\xf5\x8c\xbb\xccj\x7f?3[\xab\xee\xd2g\xb6&\x9f\xb5\xd2\xcd\xf80\x92+\x8c\xfd^\x96\xe7\xf0\xdd(\xb3\xf7}\xb8\fWY\xba\xc3w\xcbu\x1f\x9eW6J\xf47<|\uf47e-А\x1b\x8a\xdc\x04\x12^\xe5\x13\xaf嚿\x81\xc30L\x05Vsx\xd9Pk\x12߄\xfa\xf1\xb2\xe2V\v\xb6\x1f\x94I[\xe6\f\xf3í\x99<\xf9_\xdb5\x0f\xdf\xdf\xf2\x9d\xd7ۓ\x15\x9c\x99\xae\xc2\xfe\xf0]폑\xf0Ƌ\xd0\xf1wΛf\xbb#\x0e\xe7JA\xf7\xdd\xf5\xfa\f~,\xe6[&\xef\xac\xf5&\x8b\x01y\x95\xf0\xee^p\xd3\x15_\f\x9f5\x16\xf0\xdf\xff\xdf\xfd\x1a\x00\x00\xff\xff_zG\xb9\xdb \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؊3ڝ\xcf\xcc\xd4*\x1e\xfa\xcc\xd4\xe4!?\x9d\f\xad\xe0\\\xca\xec\xe6\xb2<\xfb\x97\xf2\xcc\xdc\xf7\xfe0ܤ\xe9\x88\xef\x9e\xe3\xde7\x94\xb7Zv'ܿp\xab\xb6.А\x19\x8a\xdc\xddĿC&V˕\x85=\x87\xfe\x9a\xe5Y\xcd\xe1eKEK\xe8\x82\xf7\x1dba\x1b\xc9\x0e\xbd0i1\x9da~<5\x93G\xce[\xeb\xe9\xfe\x1f\a\xf9\x9a\xec\xfc\x9d\v.ܻ\xfc|\xffO\x82\xdfg\x873\xfd\xaa\xe1?;\xee\xba\xf5\r8\\J\x05\xf1\x9f&\xb7G\xf0\xe16\x7fd\xf0\xcejo2\xe8\x91\xf3\x84w쩦#m\xd1?\xe4.\xe0\xbf\xff\x7f\xf8%\x00\x00\xff\xff\xbb\\\xe6\x8f\xcd%\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcZI\xb3\xdb6\x12\xbe\xbf_\xd1\xe59\xe4b\xe9ų\xa4\xa6t\xb3\xe5Iի\x89\xedW\x96\xe7\xdd!\xb2)\"&\x01\x0e\x16)\x9a忧\x1a\v\t\x92\xd0\x1a'<\xb8\xfc\xb04zC\xf7\xd7\r-\x16\x8b\a\xd6\xf1\x17T\x9aK\xb1\x02\xd6q\xfcŠ\xa0\xbf\xf4\xf2\xeb\xdf\xf5\x92\xcb\xc7\xfd\x9b\x87\xaf\\\x94+X[md\xfb\x19\xb5\xb4\xaa\xc0\xf7Xq\xc1\r\x97\xe2\xa1E\xc3Jf\xd8\xea\x01\x80\t!\r\xa3aM\x7f\x02\x14R\x18%\x9b\x06\xd5b\x87b\xf9\xd5nqkyS\xa2r\xc4\xe3\xd1\xfb\xef\x97o~X\xfe\xed\x01@\xb0\x16W@\xf4l\xd7HV\xea\xe5\x1e\x1bTr\xc9\xe5\x83\xee\xb0 \xb2;%m\xb7\x82a\xc2o\vGzv\xdf3\xc3\xfe\xe5(\xb8\xc1\x86k\xf3\xcf\xc9\xc4O\\\x1b7\xd95V\xb1ft\xaa\x1b\u05f5T\xe6\xe3@y\x01\xa5\xf5\x13\\\xecl\xc3T\xba\xe5\x01@\x17\xb2\xc3\x15\xb8\x1d\x1d+\x90Ƃ\x88\x8e\xc2\x02XY:\xa5\xb1\xe6YqaP\xadec[1\xd0G](\xde\x19\xa7\x94\x81SІ\x19\xabAۢ\x06\xa6\xe1#\x1e\x1e\x9fij\x92;\x85\xda\xf3\n\xf0\xb3\x96♙z\x05K\xbf|\xd9\xd5Lc\x98\xf5zݸ\x890d\x8eĭ6\x8a\x8b]\xee\xfc/\xbcE(\xadr\xf6$\x99\v\x04Ss\x9d2v`\x9a\x98S\x06˓l\xb8y\"\xa6\rk\xbb)?\xc9V\xcfP\xc9\f\xe6\xd8Y˶k\xd0`\tۣ\xc1(D%U\xcb\xcc\n\xb80?\xfc\xf5\xb4&\x82\xaa\x96n\xeb{)\xc6jyG\xa3\x90\f{N\xc8B;TY\xddHÚ\xdf\u0088!\x02\xef\x92\xfd\x9e\x13O7\x1d\xbf\xc8ʓ(\x14\xb6(\xeec\x88\x0f\xbb\xe7ܤ\xa4\xd3\xd9Nq\xa9\xb89\xae\xe0\xcd\xf7ײI\xb7\x02d\x05\xa6FxNJ\xaf\xb6\x83\x8d\x91\x8a\xed\x10~\x92\x85\xf7\xb1C\x8d*\xf8\xd8\xd6/ѵ\xb4M\t\xdbh\x18\x00m\xa4\xca:[\x87\xc5\xd2\xef\nt#ىǍ\xcf\xfc\xc6w\xa1PȲw!Fɥ[\xc1\xa5\xc8_\x88\xb7;\xbc\xea2\xa4\xda\x14\xb2\xc4^u\x98r\xc45tJ\x16\xa8\xf5\x99\xebI\xdbG<|\x1c\x06fj\xf1+\xf6\x7ffMW\xb37>\x18\x165\xb6l\x15v\xc8\x0e\xc5\xdb秗\xbflF\xc3p2\xb4\xb1\xc2h\x8ai\xc4z\xa7\xa4\x91\x85l`\x8b\xe6\x80(\\x\x85V\xeeQQ\x90\xdeq\xa1\x81\x89\xb2\xa7\t\xe9\x82!Ր\xeb;z4\xeb'\x83;\xc9\x0eUjvre\x1a3<\xc6x\xff%i1\x19\x9d\b\xf1\xbf\xc5h\x0e\x80\xe4\xf6\xbb\xa0\xa4\xfc\x88^\xaa\x90\x02\xb0\f\xaa\xf2v\xe3\x1a\x14v\n5]/\xe7U\xb2\x02&@n\x7f\xc6\xc2,'\xa47\xa8\x88L\xbc\x0f\x85\x14{T\x06\x14\x16r'\xf8\x7fz\xda\x1a\x8ct\x876̠6\xeeB*\xc1\x1aس\xc6\xe2\xeb\x89\xf6\xe8k\xd9\x11\x14ҙ`EB\xcfm\xd0S>>H\x85\xc0E%WP\x1b\xd3\xe9\xd5\xe3㎛\b\x16\nٶVps|t\xc6\xe0[k\xa4ҏ%\xee\xb1y\xd4|\xb7`\xaa\xa8\xb9\xc1\xc2X\x85\x8f\xac\xe3\v'\x88p\x80aٖ\x7fR\x01^\xe8ѱ3/\xf4\x9fK\xf47\x98\x87\xf2?]\t\x16Hy\x11\a+\xd0\x10\xa9\xee\xf3?6_ r\xe2-\xe5\x8d2,\x9d\xe9%ڇ\xb4\xc9E\x85\xca䀹l\x1dM\x14e'\xb90\ue3e2\xe1(\fh\xbbm\xb9!7\xf8\xb7Em\xc8tS\xb2k\a\xa8`\x8b`;\n\x05\xe5t\xc1\x93\x805k\xb1Y3\x8d\x7f\xb0\xad\xc8*zAF\xb8\xcaZ)L\x9c.\xf6\xeaM&\"\xd2;a\xda!|l:,Ȧ\xa4V\xda\xc4+\x1er\t\xc5\x00\x96\xac\x1ck'\x7f\xed\xe9˦\x90\xe9\xa2K\xaeF\u07fb\x1c\xa1ȫH\xe2wLu!35\xe3̔~C\x90\x0f{\x14vRs#Ց\b\xfb\xd48u\x83\x93\x16\xa1\xaf`\xa2\xc0\xe6\x1e\xf1\xd6n'pQ\x92Ʊwc\n@\x9e\xaacT\x8a\x9d\xa4\x8b\x95\x18\x02\x9e\f\xad \xaf\xd6h\xf2b\x8aL*\xe3\x02\x06\xd0\v)\xb8\x9d\x8a\xba\x95\xb2A6\xd5`\xa1\xf9F\xb0N\xd7\xd2\\\x10\xf8\xa9\x82\xb8\xf2˱C:|\xbdyzM\xff\xc4q\xf2\xa0=/C\x88\xa7[Fh+o\xb6`\xe7\xf5\xe6\tt\xd8>7\x92\xb0Mö\r\xae\xc0(;\x17\xec\xb4\xc3:\xee\x15ߣ\xca\xcdLo\x8e[\x18\xbd\xd0o\x03\xab\x1d\xa8vC/T\x90`\x94r-\x85A\x91\xb3\xd1Y\xaf\xa2/J\xban\x98\xce\xf2<\xe1l\x93\xae\xcf]\x93H\x10\n\xb7\xc2\xd4,\xcf\x17\xf8\xa4\xeb\xe4\x186\xf1\x1e\x9b\xc1\x81\x9b\xfa.\x89\xfc\x05\xbdZ\xa0dyV\x9ep߽8\xb2:#\xcc\xf3\xcb\xda\xc9{I2J7\xf7H\xb6\x1f\x19\xfd\n\xd9\xc6^\x92\x93n\xc2\xe5)\xe1$E\x01\nfX\x82\xedn睂\x0eWX\xcey^\x8c앙\x1e\v}\"\x92\xcc2\x13\x04\xd0\xf9\x81`\xe5Z\x8a\x8a\xef\xe6g\xa7e\xfe\xb9k{V\xb4Y\xc6K\x8e$\x8dS\x82#N\x16\x0e\xe1.b\xf6#lX\xf1\x9dU\xa7\xa2Qű)g\x00\xe6b\x00\xba\xa0\x0f\xc7\xc4=y\xa4\x97,\xe6\xef\x10R\x13d\xef\xbd$\x8dR>\xfd\xcde\x00\n\xdd\x03E\xae\xe1\xd5+\x90\n^\xf9^ѫ\xd7~\xb7\xe5\x8dYp\x01\x95N\x8f9\xf0\xa6\x89\aݔD\xfb\xaa\x82j:i/e\x97\xac\x1a>MhL\xb4a\xa8\xfet\x1a0\x12\x0e\x8c'Ⱦ?]\xbf\xce\xd0\xddbE0P\xa1\xb1JP\"F\xa5\b\x19iGR\xdaL&:#i\xc7\x14\nse\x16\xcd\xca\xf9<\xa20\x91ғ\x1fB\x9b\x8by\x85Un4@\x1e\xd7\x1b EHq\xc2\xfe\x84\xa9=\xb4\x1f\xecϬ\x89\xd6O,^\x11xu\x83\n\x8b\xe4\x8c\x18\xa1)\x9e\x85@\xc6t\xe0\xee\xaaC\x85\x148?\xce9X)\x81Ae\xc9\xd5\xdcaW\x90c=\xb4\xedU\xf3\xf4\xfe\x8c0\xb3\xd5\xe7\xb8?cm\x9d`\xa0\v\xb6\x9e\xc2%\xe7\xb3\xf4\xffi\xf2N#~F\xf4ܥ>ǡ\xab\xd1~\xdc\\\xc3a\xb24rX\xf1\x06A\x1f\xb5\xc1v̭/\xfd\xbc\xe9\xef`\xa8\xef\x00\xdfsC6c\x12\x91W\xa9\xf8\x8e\xd3}\x17\xfd\xccP\x0e\x04'\r}3\x97K\x1d\x18\xc8:k\x9f\xaf\x9d\x7f\x0f\xe4(\xa1\xf8\xc3\to0Q:\xc4\xdaϗ!\xf8gR\xc7E\x85<\xbf\xac\xaf2\x0f\x1d\x9c\x01\x134|\xa8yQ\x8f}\x89\xcf\xd3:\x80a_\xd1U\x7f7\xb0\x99G\x11\x8b|-8Y3\r\xfe\x93\xe9\xf4\x0eM\xa7Ɔ\xce\xce>\xbf\xac\xaf\xaa\x97]+ﺊ\xd9?%\x04-\xc7\xe0\x1a\x1e\x18duW\xcd̊\x02;\x83\xe5\xbb\xe3GY^r\xfa\xb7\xa3\xc5Ĉ\xb8\xa6\x99\x991\xb5ko\"\x05\xb6\xdb\xf2ud\xb7o\xc1\xdesM\xdfN\x89\xb8f\x9c*\x93|=/a}\xf4;\xcd4\xc0\x17rp\xd7L\xfaΧh\xda\xe6\x12?]\xcf١3\n\xb1\xeb_2\x83\v\xda\x7f\x1f\xce\xcb7\v\xfc\vLڼ\xbe\xabs0'3\xd7\x1d\x8b\xb9\xd8u\xd5\xe3\xd3ONc\x03\xb9^_\x9e\x1a\x96\x80{\x14 \x05T\x8c7\x84\x1e\x1d\xc9L\x00;O%`(\xff\xce\x17\xbb\x84\x11*d۵\x97-\x99Q\xc2<\x9a\xfd\x9e\xc6싘Ϩm\x93\xc1r\xbfc\x11\xe3\x8f\xf4\xfd*\x9d-b\xce7T\x18a\"剄\xb8q*h]\xad\xa4le3}\x1d\xbb\xd47\x9a,\x87Z6\xc1\xa9\x85m\xb7\xa8\x88[\xf7F\a\x02\x0f\x04L\x8b\x9a\x89]\x16\t\xc57&\x84\x86is\n,\xe6\x1e\xf9\xa6\x92\xa5\x8fr\xc3ע\xd6lw)X\x7f\xf0\xab<\n\r[\x80m\xa9@\x19k\xfd;\x1dr\xc8M\x91X\\N\x177%\x89ы\xd7͜|\xda\\\xc1˧\r\x1d\xf2i\xf3[yAa\xdb\\ׂ*\x95\xccpÅ\xfd%3~\u0894\x87y\xe88[ę\xfa\x82\xa0\xcf\xcc\xd4=H\xa6Z\x85\xf6̰|@\x9d[\xa4\x98\xf8\xad \xbd\xeb\xeb^b\x8f\xd6\xe4 \f^\x13\x0eNi\xfe#\x1e2\xa31\xe5f\xa6\x9eC\x1e\xcfL\xcd~\x9d\x91N\xfa\xd6y.\\ƹ,\xcd\xfe\a\x10\x99\xb9\x1f]\x82\xbbIρ\xbf\xbb\x8a\xf8\u0604\x1f\xe2\x9b\xfb=\xc3,ʍ\x9b\x81TR$\x16\xcb\x10N\xf6\xf7u\x8c\xa3\xb4\x84/5\xd7\xf1\xd9 6BJ\xae\xbb\x86\x1d{Y.\xa5\x8d>nM\x9f\x83\xe7Nr\xbe\xdf\xde\xff\x8c$\xdf+=\x1f\x95\xe1Bdv\xf3\xf2t\xca\xf9\x16'\x9c\xc9yC\x8b\xe1ʚ\xff\xe9}\xbc\x8a\xbcDaxœ'\xf8\xa1XsO:9]N\x9f\xb2n\xab/G?.\xba\xab\xde\x1eQ\xb8\x80D\xc3o\x9drxoC\xc1\x80B\x90{\xf4]O\x7f\xe6\xf1\xba\xcf\xe8̄֎O\xfe\xb9\"V\n\x827\x0e\x1e\xdd\x0e-\xc7\x02\xfd\x91\xa82\xebU\xb3A\xc7y\x99\xd0\x0e\x8d\xfat\xc4n\xfb\x9f\x02\xac\xe0\xbf\xff\x7f\xf85\x00\x00\xff\xff \xad\x88\xba\xac(\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 416a2b8ca..c74dacd31 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. @@ -149,6 +154,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. @@ -158,6 +167,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. @@ -324,13 +338,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 @@ -453,5 +476,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 ffbbf0cf8..fd592009a 100644 --- a/pkg/apis/velero/v1/zz_generated.deepcopy.go +++ b/pkg/apis/velero/v1/zz_generated.deepcopy.go @@ -1766,6 +1766,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 297a064b8..57827b97d 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 472e51a21..5ef993617 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 ac4284229..7b65407de 100644 --- a/pkg/cmd/cli/restore/create.go +++ b/pkg/cmd/cli/restore/create.go @@ -99,6 +99,7 @@ type CreateOptions struct { IncludeNamespaces flag.StringArray ExcludeNamespaces flag.StringArray ExistingResourcePolicy string + ExistingVolumeDataPolicy string IncludeResources flag.StringArray ExcludeResources flag.StringArray StatusIncludeResources flag.StringArray @@ -115,6 +116,7 @@ type CreateOptions struct { SkipDefaultResourceModifier bool WriteSparseFiles flag.OptionalBool ParallelFilesDownload int + DeleteExtraFiles flag.OptionalBool client kbclient.WithWatch } @@ -128,6 +130,7 @@ func NewCreateOptions() *CreateOptions { PreserveNodePorts: flag.NewOptionalBool(nil), IncludeClusterResources: flag.NewOptionalBool(nil), WriteSparseFiles: flag.NewOptionalBool(nil), + DeleteExtraFiles: flag.NewOptionalBool(nil), } } @@ -141,7 +144,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.") @@ -175,6 +179,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 { @@ -224,6 +231,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") } @@ -344,27 +355,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 643340e22..50d4aebde 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}) @@ -107,6 +110,7 @@ func TestCreateCommand(t *testing.T) { flags.Parse([]string{"--resource-policies-configmap", ResourcePoliciesConfigMap}) flags.Parse([]string{"--skip-default-resource-modifier"}) 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) @@ -134,6 +138,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()) @@ -149,6 +154,7 @@ func TestCreateCommand(t *testing.T) { require.True(t, o.SkipDefaultResourceModifier) 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 e4eb68144..69f8636b7 100644 --- a/pkg/controller/restore_controller.go +++ b/pkg/controller/restore_controller.go @@ -365,10 +365,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 738ad43db..4fb77c8fd 100644 --- a/pkg/controller/restore_controller_test.go +++ b/pkg/controller/restore_controller_test.go @@ -350,6 +350,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 a6d97d1ec..3537337e4 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -1930,7 +1930,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 @@ -1950,14 +1950,14 @@ 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) itemStatus.action = ItemRestoreResultSkipped ctx.restoredItems[itemKey] = itemStatus // 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() { @@ -1980,7 +1980,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")) }