From 1a237d3e4c942403009ea29225bcb4c87cd09526 Mon Sep 17 00:00:00 2001 From: Ming Qiu Date: Tue, 5 Dec 2023 04:20:23 +0000 Subject: [PATCH] Update API Signed-off-by: Ming Qiu --- config/crd/v1/bases/velero.io_backups.yaml | 1 + .../v1/bases/velero.io_podvolumebackups.yaml | 1 + .../v1/bases/velero.io_podvolumerestores.yaml | 1 + config/crd/v1/bases/velero.io_restores.yaml | 2 + config/crd/v1/bases/velero.io_schedules.yaml | 1 + config/crd/v1/crds/crds.go | 10 +- pkg/apis/velero/v1/backup_types.go | 5 +- pkg/apis/velero/v1/pod_volume_backup_types.go | 3 +- pkg/apis/velero/v1/pod_volume_restore_type.go | 3 +- pkg/apis/velero/v1/restore_types.go | 6 +- pkg/apis/velero/v1/zz_generated.deepcopy.go | 35 ++-- pkg/apis/velero/v2alpha1/data_upload_types.go | 2 +- .../velero/v2alpha1/zz_generated.deepcopy.go | 10 +- pkg/builder/backup_builder.go | 6 +- pkg/builder/data_upload_builder.go | 2 +- pkg/builder/restore_builder.go | 2 +- pkg/cmd/cli/restore/create.go | 8 +- pkg/cmd/cli/restore/create_test.go | 2 +- pkg/cmd/const.go | 1 - pkg/cmd/util/output/backup_describer.go | 10 +- pkg/cmd/util/output/backup_describer_test.go | 2 +- pkg/cmd/util/output/restore_describer.go | 11 +- pkg/cmd/util/output/schedule_describer.go | 4 +- pkg/controller/data_download_controller.go | 2 +- pkg/controller/data_upload_controller_test.go | 4 +- .../pod_volume_backup_controller_test.go | 4 +- pkg/datapath/file_system.go | 4 +- pkg/datapath/file_system_test.go | 4 +- pkg/datapath/mocks/types.go | 8 +- pkg/datapath/types.go | 4 +- pkg/podvolume/backupper.go | 6 +- pkg/podvolume/restorer.go | 6 +- pkg/uploader/kopia/snapshot.go | 28 ++-- pkg/uploader/kopia/snapshot_test.go | 10 +- pkg/uploader/provider/kopia.go | 4 +- pkg/uploader/provider/kopia_test.go | 22 +-- pkg/uploader/provider/mocks/Provider.go | 14 +- pkg/uploader/provider/provider.go | 4 +- pkg/uploader/provider/restic.go | 38 ++--- pkg/uploader/provider/restic_test.go | 14 +- pkg/uploader/util/uploader_config.go | 70 ++++++++ pkg/uploader/util/uploader_config_test.go | 149 ++++++++++++++++++ pkg/util/uploaderconfig/uploaderconfig.go | 50 ------ .../uploaderconfig/uploaderconfig_test.go | 95 ----------- 44 files changed, 378 insertions(+), 290 deletions(-) create mode 100644 pkg/uploader/util/uploader_config.go create mode 100644 pkg/uploader/util/uploader_config_test.go delete mode 100644 pkg/util/uploaderconfig/uploaderconfig.go delete mode 100644 pkg/util/uploaderconfig/uploaderconfig_test.go diff --git a/config/crd/v1/bases/velero.io_backups.yaml b/config/crd/v1/bases/velero.io_backups.yaml index 41ce2ada8..3c46f833f 100644 --- a/config/crd/v1/bases/velero.io_backups.yaml +++ b/config/crd/v1/bases/velero.io_backups.yaml @@ -479,6 +479,7 @@ spec: type: string uploaderConfig: description: UploaderConfig specifies the configuration for the uploader. + nullable: true properties: parallelFilesUpload: description: ParallelFilesUpload is the number of files parallel diff --git a/config/crd/v1/bases/velero.io_podvolumebackups.yaml b/config/crd/v1/bases/velero.io_podvolumebackups.yaml index 6279a0c17..8d4b8032e 100644 --- a/config/crd/v1/bases/velero.io_podvolumebackups.yaml +++ b/config/crd/v1/bases/velero.io_podvolumebackups.yaml @@ -126,6 +126,7 @@ spec: type: string description: UploaderSettings are a map of key-value pairs that should be applied to the uploader configuration. + nullable: true type: object uploaderType: description: UploaderType is the type of the uploader to handle the diff --git a/config/crd/v1/bases/velero.io_podvolumerestores.yaml b/config/crd/v1/bases/velero.io_podvolumerestores.yaml index afb9d1025..385d8999e 100644 --- a/config/crd/v1/bases/velero.io_podvolumerestores.yaml +++ b/config/crd/v1/bases/velero.io_podvolumerestores.yaml @@ -124,6 +124,7 @@ spec: type: string description: UploaderSettings are a map of key-value pairs that should be applied to the uploader configuration. + nullable: true type: object uploaderType: description: UploaderType is the type of the uploader to handle the diff --git a/config/crd/v1/bases/velero.io_restores.yaml b/config/crd/v1/bases/velero.io_restores.yaml index 76344e27f..74cf7e619 100644 --- a/config/crd/v1/bases/velero.io_restores.yaml +++ b/config/crd/v1/bases/velero.io_restores.yaml @@ -420,10 +420,12 @@ spec: type: string uploaderConfig: description: UploaderConfig specifies the configuration for the restore. + nullable: true properties: writeSparseFiles: description: WriteSparseFiles is a flag to indicate whether write files sparsely or not. + nullable: true type: boolean type: object required: diff --git a/config/crd/v1/bases/velero.io_schedules.yaml b/config/crd/v1/bases/velero.io_schedules.yaml index 76d8c2884..0cf3cbe52 100644 --- a/config/crd/v1/bases/velero.io_schedules.yaml +++ b/config/crd/v1/bases/velero.io_schedules.yaml @@ -517,6 +517,7 @@ spec: uploaderConfig: description: UploaderConfig specifies the configuration for the uploader. + nullable: true properties: parallelFilesUpload: description: ParallelFilesUpload is the number of files parallel diff --git a/config/crd/v1/crds/crds.go b/config/crd/v1/crds/crds.go index 3acbadc8e..82b59b27f 100644 --- a/config/crd/v1/crds/crds.go +++ b/config/crd/v1/crds/crds.go @@ -30,14 +30,14 @@ import ( var rawCRDs = [][]byte{ []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4VAo\xe46\x0f\xbdϯ \xf6;\xec\xe5\xb3g\xb7\xbd\x14\xbem\xd3\x16\b\x9a\x04A\x12\xe4Nۜ\x19mdI\x95\xa8I\xa7E\xff{A\xc9\xcexl'\xb3Y\xa0\xbaY\xa2\x1e\xc9G>ZEQ\xacЩG\xf2AYS\x01:E\x7f2\x19\xf9\n\xe5\xd3O\xa1Tv\xbd\xff\xbczR\xa6\xad\xe0\"\x06\xb6\xdd\x1d\x05\x1b}C\xbf\xd0F\x19\xc5ʚUG\x8c-2V+\x004\xc62\xcav\x90O\x80\xc6\x1a\xf6Vk\xf2ŖL\xf9\x14k\xaa\xa3\xd2-\xf9\x04>\xb8\xde\x7f*?\xffP~Z\x01\x18쨂\x1a\x9b\xa7\xe8<9\x1b\x14[\xaf(\x94{\xd2\xe4m\xa9\xec*8j\x04}\xebmt\x15\x1c\x0f\xf2\xed\xdes\x8e\xfa\xe7\x04t7\x00\x1dґV\x81\x7f_<\xbeR\x81\x93\x89\xd3ѣ^\n$\x1d\ae\xb6Q\xa3\x9f\x19\x88\x83\xd0XG\x15\xdcH,\x0e\x1bjW\x00}\xa6)\xb6\x02\xb0m\x13w\xa8o\xbd2L\xfe\xc2\xea\xd8\r\x9c\x15\xf05Xs\x8b\xbc\xab\xa0\x1c\xd8-\x1bO\x89\xd8\a\xd5Q`\xec\\\xb2\x1d\b\xfb\xb2\xa5\xfe\x9b\x0f\xe2\xbcE\xa69\x980W\x1ec}88:A9\x12\x01\xa3\xb3\x8c\x18\xd8+\xb3]\x1d\x8d\xf7\x9f3\x15͎:\xacz[\xeb\xc8|\xb9\xbd|\xfc\xf1\xfed\x1b\xc0y\xebȳ\x1aʓר\xfdF\xbb\x00-\x85\xc6+ǩ9>\n`\xb6\x82V\xfa\x8e\x02\xf0\x8e\x06N\xa9\xedc\x00\xbb\x01ީ\x00\x9e\x9c\xa7@&w\xe2\t0\x88\x11\x1a\xb0\xf5Wj\xb8\x84{\xf2\x02\x03ag\xa3n\xa5]\xf7\xe4\x19<5vk\xd4_/\xd8\x01\xd8&\xa7\x1a\x99\xfa\x1e9\xaeTC\x83\x1a\xf6\xa8#\xfd\x1fд\xd0\xe1\x01<\x89\x17\x88f\x84\x97LB\t\xd7\xd6\x13(\xb3\xb1\x15\xec\x98]\xa8\xd6\xeb\xad\xe2Av\x8d\xed\xbah\x14\x1f\xd6IA\xaa\x8el}X\xb7\xb4'\xbd\x0ej[\xa0ov\x8a\xa9\xe1\xe8i\x8dN\x15)t\x93\xa4Wv\xed\xff|/\xd4\xf0\xf1$\xd6Y-\xf3Jby\xa3\x02\xa2\x16P\x01\xb0\xbf\x9a\xb38\x12-[\xc2\xceݯ\xf7\x0f0\xb8NŘ\xb2\x9fx?^\f\xc7\x12\ba\xcal\xc8\xe7\"n\xbc\xed\x12&\x99\xd6Ye8}4Z\x91\x99\xd2\x1fb\xdd)\x96\xba\xff\x11)\xb0Ԫ\x84\x8b4\x8b\xa0&\x88N\xd4Жpi\xe0\x02;\xd2\x17\x18\xe8?/\x800\x1d\n!\xf6\xdbJ0\x1e\xa3S\xe3\xcc\xda\xe8`\x18\x81\xaf\xd4k:\xd6\xee\x1d5R>aP\xae\xaa\x8dj\x926`c=\xe0̾<\x81^\x96\xae\xac<\xfc\xee\xd9z\xdcҕ͘S\xa3\xc5\xd8&w\x86\xe0d\xb2d\x19Ӳ\xe1\f\x1b\x80w\xc8#\xfd2*\xf32\x06\x16\xf3y\xa3\b\xa9\x10(r6h\x1a\xfa-u\x94i\x0egr\xba^\xb8\")\xed\xec3\xd8\r\x93\x19\x83\xf6\xb1.dR\x13\xf8h\xde\x15\xec\xe90?\x13\xe6݉1(\xd3J\x1b\xf4\xd3T\x9c\f\xd4K]ɴ\xe0O\xff\x9b\xe3E&vsw\x05\x13\x92\x83\xce\x14+\r\x8e\xdd!F\x98&\x94|\xc1a\x11\xe5\xa9L̑\x1a\xa2\xa0T\xa0A\x18M\xcc\x11HFKS) rO~\xaev\xa0\x04\x18\xd05hB2^i\x03\x8ahC\r\x10j\b%\xa5d\xc2\x10&\x88a\x05\x90?\xbd\xbd\xdb\x12\xb9\xfb\x1d2\xa3\t\x159\xa1ZˌQ\x0399I^\x15\xe0\xda\xfeySC-\x95,A\x19\x16\xe8\xecJKxZ_{\xc3{i)\xe0j\x91\xdcJ\r\xb8ax*B\xee\x89f\xc7c\x8eL7\xc3E9\xea\x00&\xb6\x12\x15\x1e\xf9\r\xb9\ae\xc1\x10}\x94\x15ϭ\xb0\x9d@Y\x82e\xf2 \xd8?kؚ\x18\x89\x9drj\xc0\v@S\x980\xa0\x04\xe5\xe4Dy\x057H\x92\x82\x9e\x89\x02\xdb\v\xa9D\v\x1eV\xd1\x1b\xf2\xabT@\x98\xd8\xcb7\xe4hL\xa9\u07fczu`&L\x9aL\x16E%\x989\xbfB\xf9g\xbb\xcaH\xa5_\xe5p\x02\xfeJ\xb3Ú\xaa\xec\xc8\fd\x96\x91\xafh\xc9ֈ\xba\xc0\x89\xb3)\xf2\xff\x17\x04@\xbf\xec\xe0j\xceV\x18\xb5QL\x1cZ?\xa0\xd4Op\xc0N\x00'_\xae\xa9\x1bECh\xfb\xc9R\xe7\xf3\xfb\xfb\x87\xb6\xec1ݧ>ҽ%\x90\r\v,\xc1\x98\u0603rL\xdc+Y L\x10\xb9\x93>\x14]\xce@\xf4ɯ\xab]\xc1\x8c\xe5\xfb?*\xd0V\xc8\xe5\x86ܢ&!; U\x99[\xc9ܐ\xad \xb7\xb4\x00~K5<;\x03,\xa5\xf5\xda\x126\x8d\x05m%د\xec\xa8\xd6\xfa!\xe8\xb2\x11~9\x85p_B֙0\xb6\x15۳\f\xa7\x05\xd9K\xd5\xe8\v\xa7\xae6\x1d\x90\xf1)kK\xa6ٽ\xa0\xa5>J\xf3\xc0\n\x90\x95\xe9\xd7\xe8!t{\xbf\xed5\b\xc8x\xd4P\xadT\x1ar;Ϟ(3\x16\xbd\x01Lb\x01\x91/\xa8a\x02<\xd44\x95&\xa6R\x02g\xe9g\xa0\xf9\xf9A\xfe\xa6\x81\xe4\x15\nk\xa6\x00\x87|Cv\xb0\x97\n\"p\x15\xd8\xf6\xb62(e\t\xa3\x11%Y\x99\ry8\x82%#\xad\xb8\xf1r\xcf4y\xfd\x13)\x98\xa8\fl\x06\xd0F\x18\x8cD\xa1\x86\x16\xf2\x04j\x86^﨡\xbf\xdaz=2\xd9\xf6\x04\x01ؑ\xee<\xc9vg\xfbcdT\x9e\xabd\xbboAd\x9a\xacVD*\xb2rK\xe0\xea\x06A\xdbEլ\x99h\xf5\x11\x81\xf8\xc48\x0f\xfd.\x1b\xb9#\xa0\xe3\x9d~\x90\x1f\xb4\x13\xd29B\x8c4k\xd1\xe5\xe9\b\xe6\b\x8a\x942,>\x11\xbc\xf7\x8c\x03\xd1gm\xa0\xf0T\t*?\x10\x11\xa7\x03\xe7\x1e\x84\xb6D\xf58\x0f\xc7)*\xce\xe9\x8e\xc3\x1bbT5\xecΑa'%\a\xda_~\xfat\xf8\fڰl\x86\n\xab>\x19\\\xab\b\x11\x94\xff\x01\xc7\x16\x93\x88f\x96\x19\xfa\b\x84\x06j\xd8e\x91\xf3\x16\x11;\x14 \xff)\xc8;\xab\xb33\xabI\x87\xd8\x12\xaf\xb3\x19p\\'\x84$\\\x8a\x03(כ]\x0f\x83\xe4(\xb0\xb2\x95\x13\xab*\x15p\xab\xf3ɾ\xb2ZtHgB\xec,\x1e\x95\x01&\xb4\x01\x9aoV\xd7d\x10|\xcdx\x95C~댠{k\xbe\xe5\xc1h\x1dh\xc2\x1e\xa3\xdeO6\xf6+(g\x19\xda^\xde\xccZ\xa3\x85\x18cV\xb3\x90\x9eKpF\xaae\x9cǰY![\xd3\\\x83\xb1UV\x7fY\xddX~F\x80v{\xed\xf6\xa1\tUPS \xae\xf9\" \xa1(\xcdy\xc8=f\xa0\x88\x10lRM$\xb2\x8e*E\xcf#\x8c\xab-\xed\xcbX7ּ\xc7<\x11\xaa\xfd\xc1\xec\xeb\xf7\xbb\x90\x81\x11\x88L\x7f\xaf\f\\\xcc2\x8d\xde\"e²\xca:n\x1dNit\x86\"ñ4\xb3\xb6\"\x13\x0e\x1e\xfa9\rc\xbe\x17\xba,\x95\xe41ѭ%Ƌ\xa4\xf5\x10i\xd4*\xfa\x8e\x89r\x94\xf2q\x8e\x10\x7f\xb3u\x1a_\x83d\x18\x80 ;8\xd2\x13\x93\xca\x0f\xbd\xb1\x03\xe0+d\x95\x89\xceejH\xce\xf6{P\x16Ny\xa4\x1a\xb4s7\xc7\t2n>\x93\x96r\x88\xfe\xd8\x1bG\xc3H+\xa98\xf21ԭ!\xd0_\xd1B\xb1\x88Z\v\x17WΜ\x9dX^Q\x8e\x8b(\x15\x99\x1b\x0f\xad\xf1\x8a-\xc6\x13L\x1e\xe0\xec\x96耹\xe5D\xc7\x1d\x91\x02\xac\tZX\x1flX5\xb6ȸ26\xec\x1d\xb5v\x86t\"\xaa*\x0e\xdaw\xe5\f\xbbF\a܌\x82\xae9\xe2\xfcwNw\xc0\x89\x06\x0e\x99\x91*N\x8e9&\xbb\x92\xa2\xd7F\xa8\x18\xd1p]\x87\xa0\x19\xd8\x04H\x82NՑeGg\xa6Y\tB8$\x97\xa0q\x96Ӳ\xe4\x91\x15\xa0)\x93\x9c\xf7\x9dLM\xf4\xa6\xccL\xf9>\xbc\xd8\xe4oJ\x82nlʌ\x96\xecR\xb6\x16\ab\xe4\xe4\xb0\xffo\x126\xa8\xfd\v\x84v;hz]\xa1\xb5$e\xa0\xd1`B\xcb\xe5\x860\x13\xbe\xceA\xb4NN\xd3\xff\xbf0c\x96K\xfc\xb6\xdf\xf2\xaa\x12?ɕ9\x88\x96+u\xf7\xff\x82L\xc1\xc5\xe2ޯ\x15\xc9\f\xf9\xa5\xddꆰ}͐\xfc\x86\xec\x197\xa0z\x9c\xf9\xa6\xf9r\rb\xa4\xacw\xb6\x14\xd4d\xc7\xf7_\xad奛\xbd\x9cD\xba\xf4\x1b;\xfb5\xd8\xf3݅y\x06.\xc1\xa00SP\xb8`\xf3\x03R\xb3\xf9\x82\x16\xd5ۏ\xefbѬnI\x90\xbc\xc1@\xde\xf6\x90mw\xed\x8d\xf2\xd4axӧ\xf6o\xdc6\xc2\r\xa1\xe4\x11\xce\xceb\xa1\x82X\xe6P\xdbш\xa73$\x0e\xeeg\xa0\x90=\xc2\x19\xc1\xf8\r\x8a\xd9֩\xa2\xe0\xca#\x9cS\xaa\xf5\bhqb\xdao\xbcXJ\xda\x0fH\b\x8cg\xa7\x13\x8f\xe0fS\xd0E\xf3\x83#\xe9\x8a$\x94@\xfb\v\x86Y\xb3\xad\xb5Q\x87\x8c}\xa9\x1d\x8b\xec,8\xb22q\xa0v\x99\xc3P\x82\xdc\xd7\xdbM_(gyݑ\x93\xfb\xad\x18\xb7\x86\xbb\xe5\xa34[qC\xde\x7fe\xda\xef\xf8\xbd\x93\xa0?J\x83_\x9e\x85\x9c\x0e\xf1\v\x88\xe9\x1a\xe2\xf4\x12Nm[:\xb4\xf7\xad\x12\x84ە\xad\xf3\xf0j\xf60M\xb6\xc2\xfa-\x9e\x1e\xb8\v麛^\x1f\xba\xa5\xa84nL\t)\xd6.\xf4\x12\xeb\xc9\x11;\x11\xa4T\x1d\x8e\fQ\xab;\x1d\x89\xf5\xc4˃]I\\{\xb7\xaf\xcai\x06y\xd8W\xc1\xdd@j\xe0\xc02R\x80:L-\x1c\xedRZ\xfd\x9e\x86B\xa2\xd6ue\xa1\x84\xa5-\xed\xa1x\xd5\x1d\r~w\xcb\xda\xce܄Z\x81ٳUG6\x01ǫΏ\b\x97X\xb4?f\xa9K\xf3\x1c\xd34(\xbf[\xa0\xf1\x17\xf0b\xb8\xf6;\xc4\xdc\nYPܜ\xf8/\xbb̡@\xff7))S\ts\xf8-\xa6cp\xe8\xb4\xf5Q\xacv7\xb6\a\xa6\x89\xe5\xef\x89\xf2\xe1\xf6rdp\xd2\xea\x16\xe0n!\x97\xfb\x81\xc5rC\x9e\x8eR\xbb5\x157EfA2MV\x8fp\xf6\x9bqm=\xb0ڊ\x95[\xe0\x17\xab\x9b\xdaZ\x90\x82\x9f\xc9\nۮ\xbe\xc5\bJ\x94\xc4\xc4j_\u05cfu\xfaɺ\xa0\xe5\xdaK\xaf\x91\x05\xcbF\xdba\xbaL\xaa\x89m}\xd0`A؆u\x8e\x885\x8f\xa7F\x9b$\xbf\xa5ԑ\x9d\xef\x11T\xee\xa46.\"\xd91g\x97D\xbf\x88\x93=\x1f\xf5\"t\xef\xb2t\xa4\n\xf9\x17V]\xf6\x02\xb5\x96\xdbzZ3\xbb=\x03\x1fIs@\xadC\xb6jf\xbe\xd3\xc3+\xb7g\x81\x9d\xd0\f\x8d\x92Y\xb8\xa5\x92\x19\xe8\xe8nqS\x12\xb4\xfcLp\xb1\x0e,R\xe7\xf8\xb8\xe4\x86\xe9`f(醬%\xd2B\x17\xe0\xfd\xd7V\xd4\xd3*\r\xfb\xf7\x9c\xf0-ŋ\xe0\\/\n\xda\xcf\xe2IB\xf1ֵ\f\xd3\xc4\x03r.\x85:T\xa8\"\xd2-O/H\xdf\xc3\xf2^0\xb1\xc5\x0e\xc8뫛\x03\xb5r\x8d\xe5r\xc4J\x8f\xe4\xbemC\xf4\xfa\x83\x18I戕Rb\xc4_A\x87s\xc3\xf8\xb850\x13A\ni\xdaa\b\v\xb7\x94\xf9KM\xf6Li\xd3F4U(\xe2\xb9\"\xb1\xb2\xd4\xe3\x12\uf57a\xc8\xe1\xfa\xe4Z\xb6\x02`G\xf9\x14r\xa1F\x93'b\x057\x93\x80\xb0=a\x86\x80\xc8d%0lc\xa7:v\xe1X\xe0\x14t2\xc9\xd2\x14\x84- \xaa\"\x8d\x00k\x94:&&\xe3;\xed\xea\x1f(\x8b\xed@\x0f\xcbB\xb6\x99\xb1\x94\xb1X\xe9\xb0-䎵\x93\xda\n\xfa\x95\x15UAhaI\x9f\xea.\xed]\xc6Y\x87\xe3u\xde\x19\xc2\xc5e\xc4H;\xa9J\x0e&uF\xba\f3;M4ˡ^\x98\xbd\x14HA(\xd9S\xc6G\xd2]\x86e\x11m\x97\xf8(^Y\\\xcf\xf9H\xeb|\x8d\xa4H\b\xe0&\x1a\x99\xd3ںT\xe9\xa6❂4\xf3l.\x98\x1d̳R1\x89yzW\xb6м\x88Qq\xfea\xa2\r\xca\x0f\x13m\xa6\xfc0\xd1F\xcb\x0f\x13m\xbe\xfc0\xd1|\xf9a\xa2\x85\xf2\xc3D\xfba\xa2MU\x9b\xd2\xd6s\x18\xb9\xd3q#?\xceb\x91\xb0\xad=\x85\xe2\x04|\x9f\x85\xe1\xf3\xbcS33\xb7\xf1V\x91<\xfe\xe4\xdcp\xddZJ\xeaTM;A\x82x\xbb\xc3>3ɛߐ/\x1f:\xbd(_~;\xd9\xf8J\xf9\xf2\x1eþ\xd5}\xa5l\xf90\xfee\xd9\xf27>U\xa3\x00\x1a\xc2\xf3n/>\x1f\xeb\xb2\xd7\xdb\x00\xf0\x1f\x9c\x7f;\xc8\x0f\xbb\x8c\xf1Ϟm?\xc2\xfc\xc4\xc4\xf8\xd5_V\xdf\x1f\xa5\x17\xd3v\x94\x9a\x032E\x06\x15\x8e\xf9Z\xbf\xb2\x9d\xdc\xd5M\xa4\xfb>\x85s\xa94\xa6f\xccO\xd1k\xa8eZ\x04\xfb^'\xb3\x81\xe2S\xe9\u05ca\xb4\x13\x9d\xdbH\x93\xb93\x9d\x91\xf1`\x10@\x9fEvTR\xc8J\xfb\xb8\x81\x85\xfe\x16\xc3\x17~+\x14\xd3\xc0\x12\x15\xeckr\x94U$c{\x82v3\xf9{\xe3Y{~\x8f\x1a\f=\xbd\xdet\x7f1\xd2\xe7\xf0\x91'f\x8e\x11<\x9f\x8e pw]\x1c\xda\t\xf9a\xc2\xf9\x03\xe7}A\"R\x11\xc1\xf8\u0602U\x9f\xca\xef,M\x9fJ\x17$Z\xbc\xf2O\a8Ҳ\xfc.\xce\xed\xeb\xe6\xee\x8d\x18\x81K7\xb3ӏ0\xa4g\xefM\xa7\xdb-\xc9\xd9\xebg\xe4\x8d\x02\x9d\xcf\xd4K\x89M\xcdd\xe5]\x90\x8b\x97\x98\x87\xfd\xcd[\xef)\xd9v\x17\xe5\xd8ͦ*'f\xd6us\xe6\xa6A.ȧK\"\xce|\xee\xdc\xe2\x8c9\x9f\xa169\x8e\xe4<\xb9H\x06\xdc$\xe0\xd1츩\xbc\xb7\x99\xb8\xf70'.=\xdbm\x124f\xc2\xcd\xe7\xb8]/\x93\xfd\x1a^\xf6\xb8\xaa\x99\xcdS\x9b\xf5§\xf1\x9b\xcdD[\x92\x7f6K\xb1\vs\xcd\xea\\\xb2\x91~\x97f\x98u3\xc8F\x80\xa6䕍䍍@\x9c\xcc&K\xcd\x16\x1b\x81=\xb3\xecNJ\xc9\xe4\x8fK\xb2\xc4◨\x90\xd9Ր\xffQ\xf2w)\x19\xa4\xea\x18\x97s\x0eͧ^u\xcb\xf9`cM\x1b\xab1;\x95\x99\xe3rc\xb5\xa8\xb8a%\xc7\xed\xc5\x13ˣ>\xbb9¹\xbe\x18\xe2w\x89\xc75\xdde&\xe4\xd3\xe7Z\x987=\x93\x9bj\xf2\x04\x9c\x13\x1a\x13\xc5\xc1\xc83w\x0fP&\xd7`W\b;=\xfd\x95\x17\xfe\xba\xa0\x1b'\xefx\"5\xb6\x03c\x8ePX(\xe3מ\x8c\xaa\xf2is\xd2Y\xbe\xf8\xed\x1f\x15\xa83\xc1\xebYj\xfbb\xe6<\x94\x9b\x96\xda\xfaBAQxm\xe3n\x9f\xea\x99\xd9\xcd\xf4$o\x85[\xf0\xa2`{8\"\x1c\xab!x\xcdk\xab\f\xad\xd70R5\x1e\x88\x95u\xeb\xc8\xefs\x96j\xeaa\xa2\xe7u4\x96\xbb\x1a\xb3\x8b\xfc\xb3\xb8\x1b\x97;\x1c\x13 S\x0f\a\xa5m\x88\xcf\x1e\x06z.\xc7c\xce\xf5H\xb6\xb9\xd2\x0e\xfb<\xc7!\x9f\x05\x87{\x16\xb8 ˜\x90d2\xa5\x1c\xe2y\x16W\xe4\x19\x9d\x91\xe7pG.sHf@\xf6\x0e\xe7\xa4\x1c\xbbIJ\xf6H\xde\xefLI֘ߒ\x9c>N\x93p\x8c&a\xb3r\x0eӄ\xe32ˎ\xc9$\xd0\xf0\x99\\\x95grV\x9e\xc3]y^\x87e\xd6e\x99\x95\x9c\x99\x9f\x97\x1do\xb98x/U\x0ejr\xaf#U4'\x85\xb2\xe7_t\xfb\xecE\xfeÝr\xb6Vǔ\x8d\x05\xac\xebS\xef\x19\xf9\x99\t\xbf\x8fj\x85\xb0\xb5\xeew6`\x1aC$\x1e\xffo\xac<\x7fۨ۵\xd1PR\x85;\xac\xbb\xb3K\xad\xd0\x1b\xf2\x9ef\xc7\x1e\xf4cԯ\xd8KUPCV\xf5\x96\xd7+\a\xdc\xfe\xbd\xda\x10\xf2A֛\xf6\xed\x9bd4+J~\xb6~C\x04\xe6\xaa\r\xe22\x81\x88\n_\xe8\xffNr\x96E,\xad\xe8\xe5B\xae\xf2\xe0J\b\xbc\xf2(ko}\x97\xb6b\xdc\xd0B\xa3\xac{\xbd\xe2^r.\x9f\x16\xba\xe3\xb4d\xff\x81\xb74\xcf\xc7p\xde\xdem\xb1j\x90\x14\xbcݹ\xce\x10\xaa\x91ށ]1\x9b\xe1\x8c\xcd\xf8\xed\xbe\x031\x92iW\xff\x89\xd2Z\xaf\xd8l\xec\xd6%\x97\xf5g5\xcd\xdd\xd6a\xb7Aa\xa1\xe2L$\xe6z\x98#S\xf9\xba\xa4ʜ]^\xc1M\x8d\xc3x\x1c'\xac\x9bSі\xd1\xe5ex\xddo\x94\xb6\xe1\xd6_\xdc\xcc;\x97ݭ\xd0>E/\xc1c\xfc(\xdf\xec!\xbe+\xe21n\x82\xac\x91R\x91\xcfѤ\xa4\xabE\xb1\xb4\xbf\xda\xf6Wy\x82w\xd1hV\x87<\xf7\xbd\xea\x91t\xa2\x00\xd1]\xee:u;(^\xcey\x99.\x8a\xe7\a\x85\xae\xfd\xf5\x9d\x89c\xf1\xb5#C\t7\x97\x06\xb8:\x1e\xb5\xb1\xd3\xeb\xee\v\xbaV\xb5\n\xf3Ǝw\x9eB\xe8\xaa\x7f\xc1\xdd_\xaf\x9f#\xa5\x8dT\xf4\x00\xbfHw\xf5\xf2\x1c\r\xba\xb5;\xf7n{\x93'\xe4,\x86\xd9\x10s\x05\xfc%\xd0=`M*\xf2\xe0\x1a\\\x8b\xe5\xc2[}\x8d\xe13\x83yx\xf8\xc5\r\xc0\xb0\x026\xef*\xb7\x97o\xb5\x9d\x06K\xcd00\xd7hg\xff{\x8c\xac\x17\x04\xef\x93m\U00067177\x02Lwƴ\xb7E\xd8W%\x974\au+Ş\x1df\x06\xf2[\xa7ro\x9d\xcc\xf0\xa3\x1f\\\xbd\xfa\x04\xf8K\xef\x06\xb4v\n\xe7\xc0?0\x0e\xda\xf5\x9b\xa0%\uf1adj\xa5Y\x15;g\x89\xed\xed\x8fu\a#ˋ\xc3\x1b\x83\xba%(k\xf9\xb8\xf0o\xa5\x83܍\x8f\xac!9\x13\x06\x0e\x91\x80\xf2\x84\x9aP\xc6/\xa2\x83k8B\x047\xb6х-\x89\xcd>\xcb\x16D\x1e&\xef`m\xb6\x05\x8f\x81,\xa3\x83g\x81O~ӆ\x16sW\xd9\xdf\x0e[\xe0;#*o\xa5\xcb\xd5\xf7\xb1?Qݰ9\xa6f\x1bp\xae%\xfa\x04\x16\x1a\xe4\x04N \x88]\x88\x1c}\xc3[8\xfd6\x11\xa8m(\xfe\x9c\x84\xd3\xf5A\xf3\a\xd7\u07bf\x9f\xf2\x80\xf6\x94:\x81z\xa9'`\xd67\xecG\x880\x94L\xe7k\xbf\xb1\xc6*\xac\xa3@\x93l\xb1\xa8\xae\xcd4\xeb\xea\xf9d\xa5u{\xbf\x1dk9*\xc1\xa1B\x8c\x7f\x83\x97,\xbeQI\rG\x96\xaa\xa2\x86#\x9bSP\x1du\x14\x19\\\xa3\xa0\xae>L\x9c\xab\xb3W`c%g\x01\xe0y\xaf\xf0\xbe\x81;\xf0U\x80\xd6\xf4\x10\xee\xbe~\xb2\x16\xf1\x01\x04`t(2\x1a\x1foo\x0e\buo~v\x1b\x8343\x15\xf5\x1d\x84\xf4\xcbV\xad\x971\x05\xcc\xe5\xc1\xbdL\xc1\u008bD\xc1UXH\x93\xaf%S)\xae\xc5\xfb\xba\xa2\xa5\r\x1auȈ\xe6\x05)\xe0\xec\xc0\xac]n\x99t\xa0jG\x0f\xb0\xce$瀺v\x88\xd7sNV\x7f\f\xeb3P=;\xb4\x0f\xed\xba~\x03\xc9q\xdb]\x9cH]&2>(d\x98\x82慮\x01B\x12;^\xe4J8*D߲\x1abڮ\x1b&\x98\u05eb>\xcc蟶\xba\xf1\xcei\xbfڠK\xb3\xc7QL}jLx\x84\xf5\x95\x7f\xc8a\xbdW\xb2X{^`\xb6\u05cd\xdf\xeeULZk\xc2\x1c\xa3$'\xee\x8d7\x7fc:\x8aAY\x82 T{|\x12.\xba\xb9x\xf5І*\x93\x1a\x06\xb8\xefT\x9e\x89\x00 \xe48\xbe\xf7~;\xdb]\xf8s\xeb\x9f8\xac\x01\xdf\x10\xcdDx\xff\xd5m\x96;Q\xd0D\n|&N\xaax\"\xdf\xc0\xa5\xef8\xf0]\xf4\xffX\xdf\xfdT\xaf\x89\xefS\x9c\xc0/\xbd\xea\xbdC\x9d\xf8\xd8_]\xc5;n\x11z\xfc\x89\xed]naf\xb1\xfe\xf3\xff\xfaa\xcdS\x92\x93\xf1rҿ@סv\x14f\x9e\xf6\xbb\xe3`-\x1f\r\xd0u]^.\xf2QO\x97E]\xae\x19r\tO\x13_'\x10q\xba,\xd8\xf2l\x91\x96\xeb\x8e\xee\x89\xe2s\xa8ss\xec\xef\xbeZ$\xd4\xe2!D\x82-\x91a\xd4\xe1\x97\xd9`K+\xd6\x12p\x1cy\xbd\xac\x17\x7f\xb9R\xb4%\xba\x0e\f>\xa2\x02\xcd[s\xdb\xf7\xe4\xbf\xfcO\x00\x00\x00\xff\xff8\xa76\x179}\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec}O\x93\x1b+\x92\xf8ݟ\x82\xd0\xef\xe0\x99\x89\x96\xfc\xfc\xdbˆo\x9e\xb6\xbd\xa3x\xef\xd9\x1d\xee~\x9e\xcb^PUJ\xe25\x055@\xa9\xad\xd9\xd8\xef\xbeA\x02\xf5\x97\xaa\xa2d\xf5[φ\xb9\xd8]\x82$\xc9L\x92\xcc$\x81\xf5z\xfd\x82\x96\xec\v(ͤxCh\xc9\xe0\xab\x01a\xffқ\xc7\x7f\xd7\x1b&_\x9d^\xbfxd\"\x7fCn+md\xf1\x19\xb4\xacT\x06\xef`\xcf\x043L\x8a\x17\x05\x18\x9aSC\u07fc \x84\n!\r\xb5\x9f\xb5\xfd\x93\x90L\n\xa3$\xe7\xa0\xd6\a\x10\x9b\xc7j\a\xbb\x8a\xf1\x1c\x14\x02\x0f]\x9f~ڼ\xfe\xff\x9b\x9f^\x10\"h\x01oȎf\x8fU\xa97'\xe0\xa0\xe4\x86\xc9\x17\xba\x84̂<(Y\x95oH\xf3\x83k\xe2\xbbs\xa8\xfe\x15[\xe3\aδ\xf9\xb9\xf5\xf1\x17\xa6\r\xfeP\xf2JQ^\xf7\x84\xdf4\x13\x87\x8aS\x15\xbe\xbe Dg\xb2\x847\xe4\xa3\xed\xa2\xa4\x19\xe4/\b\xf1Xc\x97k\x8f\xf0鵃\x90\x1d\xa1\xa0\x0e\x17Bd\t\xe2\xed\xdd\xf6˿\xddw>\x13\x92\x83\xce\x14+\r\x8e\xdd!F\x98&\x94|\xc1a\x11\xe5\xa9L̑\x1a\xa2\xa0T\xa0A\x18M\xcc\x11HFKS) rO~\xaev\xa0\x04\x18\xd05hB2^i\x03\x8ahC\r\x10j\b%\xa5d\xc2\x10&\x88a\x05\x90?\xbd\xbd\xdb\x12\xb9\xfb\x1d2\xa3\t\x159\xa1ZˌQ\x0399I^\x15\xe0\xda\xfeySC-\x95,A\x19\x16\xe8\xecJKxZ_{\xc3{i)\xe0j\x91\xdcJ\r\xb8ax*B\xee\x89f\xc7c\x8eL7\xc3E9\xea\x00&\xb6\x12\x15\x1e\xf9\r\xb9\ae\xc1\x10}\x94\x15ϭ\xb0\x9d@Y\x82e\xf2 \xd8?kؚ\x18\x89\x9drj\xc0\v@S\x980\xa0\x04\xe5\xe4Dy\x057H\x92\x82\x9e\x89\x02\xdb\v\xa9D\v\x1eV\xd1\x1b\xf2\xabT@\x98\xd8\xcb7\xe4hL\xa9\u07fczu`&L\x9aL\x16E%\x989\xbfB\xf9g\xbb\xcaH\xa5_\xe5p\x02\xfeJ\xb3Ú\xaa\xec\xc8\fd\x96\x91\xafh\xc9ֈ\xba\xc0\x89\xb3)\xf2\xff\x17\x04@\xbf\xec\xe0j\xceV\x18\xb5QL\x1cZ?\xa0\xd4Op\xc0N\x00'_\xae\xa9\x1bECh\xfb\xc9R\xe7\xf3\xfb\xfb\x87\xb6\xec1ݧ>ҽ%\x90\r\v,\xc1\x98\u0603rL\xdc+Y L\x10\xb9\x93>\x14]\xce@\xf4ɯ\xab]\xc1\x8c\xe5\xfb?*\xd0V\xc8\xe5\x86ܢ&!; U\x99[\xc9ܐ\xad \xb7\xb4\x00~K5<;\x03,\xa5\xf5\xda\x126\x8d\x05m%د\xec\xa8\xd6\xfa!\xe8\xb2\x11~9\x85p_B֙0\xb6\x15۳\f\xa7\x05\xd9K\xd5\xe8\v\xa7\xae6\x1d\x90\xf1)kK\xa6ٽ\xa0\xa5>J\xf3\xc0\n\x90\x95\xe9\xd7\xe8!t{\xbf\xed5\b\xc8x\xd4P\xadT\x1ar;Ϟ(3\x16\xbd\x01Lb\x01\x91/\xa8a\x02<\xd44\x95&\xa6R\x02g\xe9g\xa0\xf9\xf9A\xfe\xa6\x81\xe4\x15\nk\xa6\x00\x87|Cv\xb0\x97\n\"p\x15\xd8\xf6\xb62(e\t\xa3\x11%Y\x99\ry8\x82%#\xad\xb8\xf1r\xcf4y\xfd\x13)\x98\xa8\fl\x06\xd0F\x18\x8cD\xa1\x86\x16\xf2\x04j\x86^﨡\xbf\xdaz=2\xd9\xf6\x04\x01ؑ\xee<\xc9vg\xfbcdT\x9e\xabd\xbboAd\x9a\xacVD*\xb2rK\xe0\xea\x06A\xdbEլ\x99h\xf5\x11\x81\xf8\xc48\x0f\xfd.\x1b\xb9#\xa0\xe3\x9d~\x90\x1f\xb4\x13\xd29B\x8c4k\xd1\xe5\xe9\b\xe6\b\x8a\x942,>\x11\xbc\xf7\x8c\x03\xd1gm\xa0\xf0T\t*?\x10\x11\xa7\x03\xe7\x1e\x84\xb6D\xf58\x0f\xc7)*\xce\xe9\x8e\xc3\x1bbT5\xecΑa'%\a\xda_~\xfat\xf8\fڰl\x86\n\xab>\x19\\\xab\b\x11\x94\xff\x01\xc7\x16\x93\x88f\x96\x19\xfa\b\x84\x06j\xd8e\x91\xf3\x16\x11;\x14 \xff)\xc8;\xab\xb33\xabI\x87\xd8\x12\xaf\xb3\x19p\\'\x84$\\\x8a\x03(כ]\x0f\x83\xe4(\xb0\xb2\x95\x13\xab*\x15p\xab\xf3ɾ\xb2ZtHgB\xec,\x1e\x95\x01&\xb4\x01\x9aoV\xd7d\x10|\xcdx\x95C~댠{k\xbe\xe5\xc1h\x1dh\xc2\x1e\xa3\xdeO6\xf6+(g\x19\xda^\xde\xccZ\xa3\x85\x18cV\xb3\x90\x9eKpF\xaae\x9cǰY![\xd3\\\x83\xb1UV\x7fY\xddX~F\x80v{\xed\xf6\xa1\tUPS \xae\xf9\" \xa1(\xcdy\xc8=f\xa0\x88\x10lRM$\xb2\x8e*E\xcf#\x8c\xab-\xed\xcbX7ּ\xc7<\x11\xaa\xfd\xc1\xec\xeb\xf7\xbb\x90\x81\x11\x88L\x7f\xaf\f\\\xcc2\x8d\xde\"e²\xca:n\x1dNit\x86\"ñ4\xb3\xb6\"\x13\x0e\x1e\xfa9\rc\xbe\x17\xba,\x95\xe41ѭ%Ƌ\xa4\xf5\x10i\xd4*\xfa\x8e\x89r\x94\xf2q\x8e\x10\x7f\xb3u\x1a_\x83d\x18\x80 ;8\xd2\x13\x93\xca\x0f\xbd\xb1\x03\xe0+d\x95\x89\xceejH\xce\xf6{P\x16Ny\xa4\x1a\xb4s7\xc7\t2n>\x93\x96r\x88\xfe\xd8\x1bG\xc3H+\xa98\xf21ԭ!\xd0_\xd1B\xb1\x88Z\v\x17WΜ\x9dX^Q\x8e\x8b(\x15\x99\x1b\x0f\xad\xf1\x8a-\xc6\x13L\x1e\xe0\xec\x96耹\xe5D\xc7\x1d\x91\x02\xac\tZX\x1flX5\xb6ȸ26\xec\x1d\xb5v\x86t\"\xaa*\x0e\xdaw\xe5\f\xbbF\a܌\x82\xae9\xe2\xfcwNw\xc0\x89\x06\x0e\x99\x91*N\x8e9&\xbb\x92\xa2\xd7F\xa8\x18\xd1p]\x87\xa0\x19\xd8\x04H\x82NՑeGg\xa6Y\tB8$\x97\xa0q\x96Ӳ\xe4\x91\x15\xa0)\x93\x9c\xf7\x9dLM\xf4\xa6\xccL\xf9>\xbc\xd8\xe4oJ\x82nlʌ\x96\xecR\xb6\x16\ab\xe4\xe4\xb0\xffo\x126\xa8\xfd\v\x84v;hz]\xa1\xb5$e\xa0\xd1`B\xcb\xe5\x860\x13\xbe\xceA\xb4NN\xd3\xff\xbf0c\x96K\xfc\xb6\xdf\xf2\xaa\x12?ɕ9\x88\x96+u\xf7\xff\x82L\xc1\xc5\xe2ޯ\x15\xc9\f\xf9\xa5\xddꆰ}͐\xfc\x86\xec\x197\xa0z\x9c\xf9\xa6\xf9r\rb\xa4\xacw\xb6\x14\xd4d\xc7\xf7_\xad奛\xbd\x9cD\xba\xf4\x1b;\xfb5\xd8\xf3݅y\x06.\xc1\xa00SP\xb8`\xf3\x03R\xb3\xf9\x82\x16\xd5ۏ\xefbѬnI\x90\xbc\xc1@\xde\xf6\x90mw\xed\x8d\xf2\xd4axӧ\xf6o\xdc6\xc2\r\xa1\xe4\x11\xce\xceb\xa1\x82X\xe6P\xdbш\xa73$\x0e\xeeg\xa0\x90=\xc2\x19\xc1\xf8\r\x8a\xd9֩\xa2\xe0\xca#\x9cS\xaa\xf5\bhqb\xdao\xbcXJ\xda\x0fH\b\x8cg\xa7\x13\x8f\xe0fS\xd0E\xf3\x83#\xe9\x8a$\x94@\xfb\v\x86Y\xb3\xad\xb5Q\x87\x8c}\xa9\x1d\x8b\xec,8\xb22q\xa0v\x99\xc3P\x82\xdc\xd7\xdbM_(gyݑ\x93\xfb\xad\x18\xb7\x86\xbb\xe5\xa34[qC\xde\x7fe\xda\xef\xf8\xbd\x93\xa0?J\x83_\x9e\x85\x9c\x0e\xf1\v\x88\xe9\x1a\xe2\xf4\x12Nm[:\xb4\xf7\xad\x12\x84ە\xad\xf3\xf0j\xf60M\xb6\xc2\xfa-\x9e\x1e\xb8\v麛^\x1f\xba\xa5\xa84nL\t)\xd6.\xf4\x12\xeb\xc9\x11;\x11\xa4T\x1d\x8e\fQ\xab;\x1d\x89\xf5\xc4˃]I\\{\xb7\xaf\xcai\x06y\xd8W\xc1\xdd@j\xe0\xc02R\x80:L-\x1c\xedRZ\xfd\x9e\x86B\xa2\xd6ue\xa1\x84\xa5-\xed\xa1x\xd5\x1d\r~w\xcb\xda\xce܄Z\x81ٳUG6\x01ǫΏ\b\x97X\xb4?f\xa9K\xf3\x1c\xd34(\xbf[\xa0\xf1\x17\xf0b\xb8\xf6;\xc4\xdc\nYPܜ\xf8/\xbb̡@\xff7))S\ts\xf8-\xa6cp\xe8\xb4\xf5Q\xacv7\xb6\a\xa6\x89\xe5\xef\x89\xf2\xe1\xf6rdp\xd2\xea\x16\xe0n!\x97\xfb\x81\xc5rC\x9e\x8eR\xbb5\x157EfA2MV\x8fp\xf6\x9bqm=\xb0ڊ\x95[\xe0\x17\xab\x9b\xdaZ\x90\x82\x9f\xc9\nۮ\xbe\xc5\bJ\x94\xc4\xc4j_\u05cfu\xfaɺ\xa0\xe5\xdaK\xaf\x91\x05\xcbF\xdba\xbaL\xaa\x89m}\xd0`A؆u\x8e\x885\x8f\xa7F\x9b$\xbf\xa5ԑ\x9d\xef\x11T\xee\xa46.\"\xd91g\x97D\xbf\x88\x93=\x1f\xf5\"t\xef\xb2t\xa4\n\xf9\x17V]\xf6\x02\xb5\x96\xdbzZ3\xbb=\x03\x1fIs@\xadC\xb6jf\xbe\xd3\xc3+\xb7g\x81\x9d\xd0\f\x8d\x92Y\xb8\xa5\x92\x19\xe8\xe8nqS\x12\xb4\xfcLp\xb1\x0e,R\xe7\xf8\xb8\xe4\x86\xe9`f(醬%\xd2B\x17\xe0\xfd\xd7V\xd4\xd3*\r\xfb\xf7\x9c\xf0-ŋ\xe0\\/\n\xda\xcf\xe2IB\xf1ֵ\f\xd3\xc4\x03r.\x85:T\xa8\"\xd2-O/H\xdf\xc3\xf2^0\xb1\xc5\x0e\xc8뫛\x03\xb5r\x8d\xe5r\xc4J\x8f\xe4\xbemC\xf4\xfa\x83\x18I戕Rb\xc4_A\x87s\xc3\xf8\xb850\x13A\ni\xdaa\b\v\xb7\x94\xf9KM\xf6Li\xd3F4U(\xe2\xb9\"\xb1\xb2\xd4\xe3\x12\uf57a\xc8\xe1\xfa\xe4Z\xb6\x02`G\xf9\x14r\xa1F\x93'b\x057\x93\x80\xb0=a\x86\x80\xc8d%0lc\xa7:v\xe1X\xe0\x14t2\xc9\xd2\x14\x84- \xaa\"\x8d\x00k\x94:&&\xe3;\xed\xea\x1f(\x8b\xed@\x0f\xcbB\xb6\x99\xb1\x94\xb1X\xe9\xb0-䎵\x93\xda\n\xfa\x95\x15UAhaI\x9f\xea.\xed]\xc6Y\x87\xe3u\xde\x19\xc2\xc5e\xc4H;\xa9J\x0e&uF\xba\f3;M4ˡ^\x98\xbd\x14HA(\xd9S\xc6G\xd2]\x86e\x11m\x97\xf8(^Y\\\xcf\xf9H\xeb|\x8d\xa4H\b\xe0&\x1a\x99\xd3ںT\xe9\xa6❂4\xf3l.\x98\x1d̳R1\x89yzW\xb6м\x88Qq\xfea\xa2\r\xca\x0f\x13m\xa6\xfc0\xd1F\xcb\x0f\x13m\xbe\xfc0\xd1|\xf9a\xa2\x85\xf2\xc3D\xfba\xa2MU\x9b\xd2\xd6s\x18\xb9\xd3q#?\xceb\x91\xb0\xad=\x85\xe2\x04|\x9f\x85\xe1\xf3\xbcS33\xb7\xf1V\x91<\xfe\xe4\xdcp\xddZJ\xeaTM;A\x82x\xbb\xc3>3ɛߐ/\x1f:\xbd(_~;\xd9\xf8J\xf9\xf2\x1eþ\xd5}\xa5l\xf90\xfee\xd9\xf27>U\xa3\x00\x1a\xc2\xf3n/>\x1f\xeb\xb2\xd7\xdb\x00\xf0\x1f\x9c\x7f;\xc8\x0f\xbb\x8c\xf1Ϟm?\xc2\xfc\xc4\xc4\xf8\xd5_V\xdf\x1f\xa5\x17\xd3v\x94\x9a\x032E\x06\x15\x8e\xf9Z\xbf\xb2\x9d\xdc\xd5M\xa4\xfb>\x85s\xa94\xa6f\xccO\xd1k\xa8eZ\x04\xfb^'\xb3\x81\xe2S\xe9\u05ca\xb4\x13\x9d\xdbH\x93\xb93\x9d\x91\xf1`\x10@\x9fEvTR\xc8J\xfb\xb8\x81\x85\xfe\x16\xc3\x17~+\x14\xd3\xc0\x12\x15\xeckr\x94U$c{\x82v3\xf9{\xe3Y{~\x8f\x1a\f=\xbd\xdet\x7f1\xd2\xe7\xf0\x91'f\x8e\x11<\x9f\x8e pw]\x1c\xda\t\xf9a\xc2\xf9\x03\xe7}A\"R\x11\xc1\xf8\u0602U\x9f\xca\xef,M\x9fJ\x17$Z\xbc\xf2O\a8Ҳ\xfc.\xce\xed\xeb\xe6\xee\x8d\x18\x81K7\xb3ӏ0\xa4g\xefM\xa7\xdb-\xc9\xd9\xebg\xe4\x8d\x02\x9d\xcf\xd4K\x89M\xcdd\xe5]\x90\x8b\x97\x98\x87\xfd\xcd[\xef)\xd9v\x17\xe5\xd8ͦ*'f\xd6us\xe6\xa6A.ȧK\"\xce|\xee\xdc\xe2\x8c9\x9f\xa169\x8e\xe4<\xb9H\x06\xdc$\xe0\xd1츩\xbc\xb7\x99\xb8\xf70'.=\xdbm\x124f\xc2\xcd\xe7\xb8]/\x93\xfd\x1a^\xf6\xb8\xaa\x99\xcdS\x9b\xf5§\xf1\x9b\xcdD[\x92\x7f6K\xb1\vs\xcd\xea\\\xb2\x91~\x97f\x98u3\xc8F\x80\xa6䕍䍍@\x9c\xcc&K\xcd\x16\x1b\x81=\xb3\xecNJ\xc9\xe4\x8fK\xb2\xc4◨\x90\xd9Ր\xffQ\xf2w)\x19\xa4\xea\x18\x97s\x0eͧ^u\xcb\xf9`cM\x1b\xab1;\x95\x99\xe3rc\xb5\xa8\xb8a%\xc7\xed\xc5\x13ˣ>\xbb9¹\xbe\x18\xe2w\x89\xc75\xdde&\xe4\xd3\xe7Z\x987=\x93\x9bj\xf2\x04\x9c\x13\x1a\x13\xc5\xc1\xc83w\x0fP&\xd7`W\b;=\xfd\x95\x17\xfe\xba\xa0\x1b'\xefx\"5\xb6\x03c\x8ePX(\xe3מ\x8c\xaa\xf2is\xd2Y\xbe\xf8\xed\x1f\x15\xa83\xc1\xebYj\xfbb\xe6<\x94\x9b\x96\xda\xfaBAQxm\xe3n\x9f\xea\x99\xd9\xcd\xf4$o\x85[\xf0\xa2`{8\"\x1c\xab!x\xcdk\xab\f\xad\xd70R5\x1e\x88\x95u\xeb\xc8\xefs\x96j\xeaa\xa2\xe7u4\x96\xbb\x1a\xb3\x8b\xfc\xb3\xb8\x1b\x97;\x1c\x13 S\x0f\a\xa5m\x88\xcf\x1e\x06z.\xc7c\xce\xf5H\xb6\xb9\xd2\x0e\xfb<\xc7!\x9f\x05\x87{\x16\xb8 ˜\x90d2\xa5\x1c\xe2y\x16W\xe4\x19\x9d\x91\xe7pG.sHf@\xf6\x0e\xe7\xa4\x1c\xbbIJ\xf6H\xde\xefLI֘ߒ\x9c>N\x93p\x8c&a\xb3r\x0eӄ\xe32ˎ\xc9$\xd0\xf0\x99\\\x95grV\x9e\xc3]y^\x87e\xd6e\x99\x95\x9c\x99\x9f\x97\x1do\xb98x/U\x0ejr\xaf#U4'\x85\xb2\xe7_t\xfb\xecE\xfeÝr\xb6Vǔ\x8d\x05\xac\xebS\xef\x19\xf9\x99\t\xbf\x8fj\x85\xb0\xb5\xeew6`\x1aC$\x1e\xffo\xac<\x7fۨ۵\xd1PR\x85;\xac\xbb\xb3K\xad\xd0\x1b\xf2\x9ef\xc7\x1e\xf4cԯ\xd8KUPCV\xf5\x96\xd7+\a\xdc\xfe\xbd\xda\x10\xf2A֛\xf6\xed\x9bd4+J~\xb6~C\x04\xe6\xaa\r\xe22\x81\x88\n_\xe8\xffNr\x96E,\xad\xe8\xe5B\xae\xf2\xe0J\b\xbc\xf2(ko}\x97\xb6b\xdc\xd0B\xa3\xac{\xbd\xe2^r.\x9f\x16\xba\xe3\xb4d\xff\x81\xb74\xcf\xc7p\xde\xdem\xb1j\x90\x14\xbcݹ\xce\x10\xaa\x91ށ]1\x9b\xe1\x8c\xcd\xf8\xed\xbe\x031\x92iW\xff\x89\xd2Z\xaf\xd8l\xec\xd6%\x97\xf5g5\xcd\xdd\xd6a\xb7Aa\xa1\xe2L$\xe6z\x98#S\xf9\xba\xa4ʜ]^\xc1M\x8d\xc3x\x1c'\xac\x9bSі\xd1\xe5ex\xddo\x94\xb6\xe1\xd6_\xdc\xcc;\x97ݭ\xd0>E/\xc1c\xfc(\xdf\xec!\xbe+\xe21n\x82\xac\x91R\x91\xcfѤ\xa4\xabE\xb1\xb4\xbf\xda\xf6Wy\x82w\xd1hV\x87<\xf7\xbd\xea\x91t\xa2\x00\xd1]\xee:u;(^\xcey\x99.\x8a\xe7\a\x85\xae\xfd\xf5\x9d\x89c\xf1\xb5#C\t7\x97\x06\xb8:\x1e\xb5\xb1\xd3\xeb\xee\v\xbaV\xb5\n\xf3Ǝw\x9eB\xe8\xaa\x7f\xc1\xdd_\xaf\x9f#\xa5\x8dT\xf4\x00\xbfHw\xf5\xf2\x1c\r\xba\xb5;\xf7n{\x93'\xe4,\x86\xd9\x10s\x05\xfc%\xd0=`M*\xf2\xe0\x1a\\\x8b\xe5\xc2[}\x8d\xe13\x83yx\xf8\xc5\r\xc0\xb0\x026\xef*\xb7\x97o\xb5\x9d\x06K\xcd00\xd7hg\xff{\x8c\xac\x17\x04\xef\x93m\U00067177\x02Lwƴ\xb7E\xd8W%\x974\au+Ş\x1df\x06\xf2[\xa7ro\x9d\xcc\xf0\xa3\x1f\\\xbd\xfa\x04\xf8W\xdeu\xb7f\f\xe7\xc0?0\x0eڡ\x95\xa0D\uf1adj\x9dZ\x15;g\xa8\xed\xed\x8fu\a#\xab\x8f\x1b\x16\xc6|KP\xd60r\xd1\xe1J\a\xb1\x1c\x1fx\xc3\x11&\f\x1c\"\xf1\xe6\t-z\xea\\\xfc\x1dDzN\xa5|\x89\xb7j\xc5\x03[\x93ʙ\x8aQ\x8d2\x06\xa7\xf5\xf6\x01F\xca\xf1x\xf9uo\xc9\x1c3\xfe\xc7n\x87\xc7\x1b\xd1\xe7\xef\x87w\x17\xa7\xfb\xd7 \xbc W\n\xaf\xb8\xf4\x97\xaa㕐\x17]\x11\xbf\xab\xf3x\xea,!\xfd\xd6\x18(\xca\xe8\x05\xd2\x11\xf4F\xda\xd6\x06\x894\x947\xa2\x1b[\x02\xea&\x98a4\x99Z\xe4\xa6\xec\x04㦄66\xd6[\x9f\x93~\xc9X\xeb\xb6\xe9c\xd5U\x96\x81\xd6\xfb\x8a\xf3s\x9d\x0f\xbfd\xe01k\xe0J\xa4\xf8@\x19\xbf\x88\x0e\xae\xe1\b\x11\xdc\xd8F\u05fd$6\xfb$\\\x10y\x98\xbc\x83\xa5\xdb\x16<%\xb2\x8c\x0e\x9e\x05>7N\x1bZ\xcc\xddt\x7f;l\x81ϐ\xa8\xbc\x95MW_\xd7\xfeDu\xc3昚m\xc0\xb9\x96\xe82Xh\x90\x138\x81 v\x9dr\xf4\rO\xe5\xf4\xdbD\xa0\xb6\xa1\xf8c\x14N\xd7\a\xcd\x1f<\x7f\xff\xbc\xca\x03\x9a[\xea\x04\ua95e\x80Y_\xc0\x1f!\xc2P2\x9d+\xfe\xc6ڲ\xb0\x8e\x02M2բ\xba6Ӭ\xab瓕\xd6\xed\xfdv\xac\xe5\xa8\x04\x87\n1\xfe\r\x1e\xba\xf8F%5\x1cY\xaa\x8a\x1a\x8elNAu\xd4Qdp\x8d\x82\xba\xfa0q\xae\xceސ\x8d\x95\x9c\x05\x80\xc7\xc1\xc2\xf3\a\xee\xb4\xeb\xfa\xfd%\xc7mw\xaf\"u\x89\xca\xf8ސa\n\x9a\a\xbc\x06\bI\xecx\x91\xa7\xe1\xa8\x10}\xeaj\x88i\xbbn\x98`^\xaf\xfa(\xa4\x7f\xf9\xea\xc6\xfb\xae\xf1\xe0JA\x7f\x97\xea\x86\x14L\xd8\x7f\xa8\xc8\xdd\x06Ph\xbc\b\xff\xa3\x94\x8f\xf7\x11\xabr\x80\xfc\xdf\xea\x8aMt\x9e\t\x876\x1e\xad\xdb\xc9\xca\xef\xdb\xd6\x16f|/\x0f\xaf9\xbf\xb2\xe7\x840'\x14zt8\v\xf4\xb8\xeb`\xc4m\xba\x0f\xaf/q~\xbe\xe9C\xee\xbd\xd0\xd6\xc0\x9e\x82\x88\x92\xeb\x17\xf1\xf6\xb5P~\xaf\xa4\a\xc4U\x9f\xb8\xe3\x9e\xf4\xec\xc8K\xbc7O\xe31\x93/N\xe0i;\xcf!߲\xd4FP\xf7\xf6\x9b\x9b\xd5\xd7u<\xf1\xc2\xff\x19ɿ\xb3u\xea\xb3\xe2-7\n\xc2z0\x16X\x8a\x9f\x0f^\x93\x8f0\x8c\x83\xb8#\xbf\x90\xe3\x8e\x7f\xecy;[e+\xee\x94<(\xd0C\xc1Y\x93\xbfSf\x988|\x90\xea\x8eW\a&\x1as{Q\xe5;\xaa\f\xb3\xa2\xec\xf0\x89!\xca\x04\xe5\xec\x9f1\xe5\xd4\xfeq\x1ePmmD~K@c\xec\x87w`-\xcdQo;\xaa\aKO\xd79Y\xf0\xd5\xe6t`X\xfb\x1b\xdb!\x16\xee\xf1\xc06\xe4\xa34\x10\x12_X\x17\xa6\xb5\x96@\x9b5\xec\xf7R\x19\xb7!\xba^\x13\xb6\xf7\xde{\x04\xaeU\x1c\x18\xc4q\xef\xe3\x11f\x9aL\xe7f\xb9\xc1@\xaa\xc2U\x13/\xf4.\xe8\xd9mw\xd0,\xab\xacE\xf4J\x1b\xca#\x06\xc97)j\f\x93\xd8\xf9\x02\xf9o)\xbb@\xdbv\xfdaX\v\xc19\xca\xe1U\x00\xce\x18\x8b\x9a\xa6\x04\xc3\xe0 ȓb\xc6X\x03\xa8\x9d\xd9H\x8c5y8'\xda\x1a\x01\x17ŷ\x88Sp\xdb\xf1L\x8bn\xfc\xb4\xae<\xa6\x1f\xfd\xe0\xf09\xb8\x1d\x92`4n\xe73J|[\xcb\xca\xecH\xc5\xc1\n\x95\x92\xd5\xe1\x18\xe4rĔ\x1d\x81\x9bW\x80\xb1@\xd4\x10:d\x95\x99J\x89\xd6\xces}\xbc\xb5A\x97f\x8f\xa3\x98\xfa̙\xf0F\xeb+\xff\xce\xc3z\xafd\xb1\xf6\xbc\xc0d\xb0\x1b\xbf\x1b\xac\x98\xb4ք9FIN\xdc\x13p\xfeBu\x14\x83\xb2\x04A\xa8\xf6\xf8$܃s\xf1\xea\xa1\rU&5\fpߩ<\x13\x01@\xc8q|\xef\xfdn\xb7\xbb\x0f\xe8ֿ\x80X\x03\xbe!\x9a\x89\xf0<\xac\xdbKw\xa2\xa0\x89\x14\xf8\x8a\x9cT\xf1<\xbf\x81K\xdfq\xe0\xbb\xe8\xff\xb1\xbe\xfb\xa9^\x13ߧ8\x81_z\xd5{g>\xf1-\xc0\xba\x8aw\xdc\"\xf4\xf8\x13ۻ\xd4\xc3\xccb\xfd\xe7\xff\xf5\xb3\x9c\xa7$'\xe3\xe5\xa4\x7f\x81\xaeC\xed(̼\xfcw\xc7\xc1Z>\x1a\xa0뺼\\䣞.\x8b\xba\\3\xe4\x12^.\xbeN \xe2tY\xb0\xe5\xd9\"-\xd7\x1d\xdd\x13\xc5\xd7R\xe7\xe6\xd8\xdf}\xb5H\xa8\xc5C\x88\x04[\"è\xc3/\xb3\xc1\x96V\xac%\xe08\xf2\xb8Y/\xfer\xa5hKt\x1d\x18|D\x05\x9a\xb7\xe6\xb6\xef\xc9\x7f\xf9\x9f\x00\x00\x00\xff\xffqN\x18=X}\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs\xe3\xb8\x11\xbe\xebWt\xed\x1e|YQ3\x9bKJ\x97\x94FN\xaa\xa6\xe2\x89]#ǹ\xe4\xb0\x10Д\xb0\x06\x01\x06\x0fi\x94T\xfe{\xaa\x01\xf0!\x92\xb2\xe4\xa9$\x8b\x8bM\xb2\xd1\xe8\xfe\xfa\r\xcd\xe7\xf3\x19\xab\xe5\vZ'\x8d^\x02\xab%~\xf3\xa8\xe9\xc9\x15\xaf\xbfw\x854\x8b\xc3\xc7٫\xd4b\t\xeb༩\xbe\xa23\xc1r\xbc\xc7Rj\xe9\xa5ѳ\n=\x13̳\xe5\f\x80im<\xa3\u05ce\x1e\x01\xb8\xd1\xde\x1a\xa5\xd0\xcew\xa8\x8bװ\xc5m\x90J\xa0\x8d̛\xa3\x0f\x1f\x8a\x8f?\x17\x1ff\x00\x9aU\xb8\x84-㯡v\xdeX\xb6CexbY\x1cP\xa15\x8543W#\xa7\x13vքz\t݇\xc4!\x9f\x9e$\xff\x14\x99m\x12\xb3\x87\xcc,~W\xd2\xf9?_\xa6y\x90\xceG\xbaZ\x05\xcb\xd4%\xb1\"\x89\xdb\x1b\xeb\xff\xd2\x1d=\x87\xadS\xe9\x8bԻ\xa0\x98\xbd\xb0}\x06ษq\tqw\xcd8\x8a\x19@\x86&r\x9b\x03\x13\"\x82\xcdԓ\x95ڣ]\x1b\x15*ݞ%\xd0q+k\x1f\xc1L\xba@V\x06\x1am\xc0y\xe6\x83\x03\x17\xf8\x1e\x98\x83ՁIŶ\n\x17\x7fլ\xf9?\xf2\x03\xf8\xd5\x19\xfd\xc4\xfc~\tE\xdaU\xd4{暯\xc9FO\xbd7\xfeD\n8o\xa5\xdeM\x89\xf4\xc0\x9c\x7faJ\x8a(ɳ\xac\x10\xa4\x03\xbfGP\xccy\xf0\xf4\x82\x9e\x12B@\x10!4\b\xc1\x91\xb9|\x0e\xc0!q\x89\x18MK\xaaFg\x9d\x89M\xa2\xc0ˀK\x92\x9f\xded\xe9{l\x1b\xff.\xb8Ŗ\xa5\xf3\xac\xaa\xcf\xf8\xaevx\x89\xd9\x19\x14\xf7X\xb2\xa0|_U\xb2\x92\xea\xfb\xe5\xb9Z5\xf2B\xa4]g'ޟ\xbdK\xa7n\x8dQ\xc8\x12\x97Du\xf8\x98\xbc\x90\xef\xb1b\xcbLljԫ\xa7\xcf/\xbfۜ\xbd\x86)G\x1a\x04\x05\x19\x8e\xf5l\xb3G\x8b\xf0\x12\xe3/\xd9\xcde\xd5Z\x9e\x00f\xfb+r\xdf\x19\xb1\xb6\xa6F\xebe\x13,i\xf5rQ\xef\xed@\xa6;\x12;Q\x81\xa0$\x84ɏr\xbc\xa0Ț\x82)\xc1\xef\xa5\x03\x8b\xb5E\x87\xda\xf7\xe1m\x05+\x81\xe9,^\x01\x1b\xb4Ćb9(A\xb9\xeb\x80փEnvZ\xfe\xb3\xe5\xed\xc0\x9b\xec\xbc\x1e\x9d\x1f\xf0\x8c\xf1\xa9\x99\"W\r\xf8\x130-\xa0b'\xb0H\xa7@\xd0=~\x91\xc4\x15\xf0\x85\xfc]\xea\xd2,a\xef}햋\xc5N\xfa&\asSUAK\x7fZ\xc4t*\xb7\xc1\x1b\xeb\x16\x02\x0f\xa8\x16N\xee\xe6\xcc\xf2\xbd\xf4\xc8}\xb0\xb8`\xb5\x9cG\xd1uJ\x9a\x95\xf8\xd1\xe6\xac\xed\xee\xced\x1dEmZ1k\xbea\x01ʘ\xc9\v\xd2֤E\a4\xbd\"t\xbe\xfeq\xf3\f\xcd\xd1\xd1\x18C\xf4#\xee\xddFי\x80\x00\x93\xbaD\x9b\x8cXZSE\x9e\xa8Em\xa4\xf6\xf1\x81+\x89z\b\xbf\v\xdbJz\xb2\xfb?\x02:O\xb6*`\x1d\v\x13l\x11B\x1d㾀\xcf\x1a֬B\xb5f\x0e\xff\xe7\x06 \xa4ݜ\x80\xbd\xcd\x04\xfd\x9a:$N\xa8\xf5>4\xb5\xf0\x82\xbd&\xa3xS#?\x8b\x1f\x81NZ\xf2p\xcf<Ƹ\x18\xe0\x9aC\xfcr1m\xd6tp\xd3b\x9c\xa3s_\x8c\xc0ᗁȫ\x96\xf0L\xc6\x1am%],\x8bP\x1a;\xac\x18\xac\xcd\xc0\xfd\xd5d\xaab\xf4\ru\xa8Ƃ\xcc\xe1+2\xf1\xa8\xd5\xe9§\xbfY\xe9\xc7\a]0$\xad$\xe2\xe6\xa4\xf9\x13Zi\xc4\x15\xe5?\r\xc8[\b\xf6\xe6\betk\xedՉr\x90;i>ζ\xcdZ=}n2o\n\xa0\x1co\x19\xab\x02V9rM\t\x1f@HG\r\x80\x8bL\xc7`\xe9\xa0b\x83\xb0\x04oû\xd4\xe7F\x97r7V\xba\xdf\xd3\\\xf2\x98+\xac\aȭ\xe3I\x94\x9a\xc8;jk\x0eR\xa0\x9dS|\xc8R\xf2,I\xb0\xa9r\x95\x12\x95pcM/DYTŢ\xa0\xa8f\xea\x8a\r\xd7-a쀙\xd4Ƀ;\x061\xd9\xd8*\x97T\xedQ\x8b\xb6\x1b9\x93\xc6Ĭ\xe5P\xc0Q\xfa}J\x87j*\xee\xe0\xcdأ\xf5\x8a\xa7\xa9\xd7\x03ٟ\xf7H\x94\xa9\x80\"8\xe4\x16}\xf46T\xe4>\xe4J\x05\xc0\x97\xe0bB\x1d\xe6\x89f\xc5F\xad\xd9\xfd\x8a\xa71\xd0p\u0378\xb9\x85\xb9.\xf2\x1d\xb5\u038d\xc0\x16K\xb4\xa8\xfddR\xa7\x01\xc4j\xf4\x18\xf3\xba0\xdcQJ\xe7X{\xb70\a\xb4\a\x89\xc7\xc5\xd1\xd8W\xa9ws\x02|\x9e#h\x11NJŏ\xf1\xcf\x05\x95\x9f\x1f\xef\x1f\x97\xb0\x12\x02\x8cߣ%\xab\x95A5\x8e\xd6\xebo~\x8a5\xf6'\bR\xfc\xe1\xee{p1u\x8a\x9c\x1b\xb0\xd9D\xef?Q\xa3\x16\x85\"\x886\xc9*\xc6\x02UJ2v\x95\xad\x99r͔#Nu\x98\xfdE\x89\x89*\xc8TF}\xc5q2}#\xcc\x00\xbe\xcd;C\xcd+V\xcf\x135\xf3\xa6\x92|6\xd46\xb6\xc1W\"\xb2i\xbb\xa5\x16\x92S\xdbv\x1eI\xcd8\"κ\xf3\t\x18\x86\xfd\xfa\xa5\xfc1\rSR7W\xcf+\x12?\xf6i\xbb!.%\xb3\\\x11\x1dzj\xb7\x1ch\xa4\x8a\xc9\xec\x18\xe7\x98B\xb8њb\xd7\x1b`mb\xbcsÊ\xf0\xce|\xb2\r\xfc\x15'\x80\x1f\xa9\xf2)\x126\x18\xa7m$Kp\x18S\xf551\xe0zDp\xb6F{\x8b,\xeb\x15\x11\xb6E\x95\xc1z\x05۠\x85\xc2F\xa2\xe3\x1e5\xcd\x13\xb2\x14?\xfcf3\x93b\xce\xd3\b\x84\xe2+\x1e\xe4\xf8Nh\x8c\xee\xc3hG\x13\xf8m8\xd0\xc3/\xcdh\xbd\xb0\x99\xec\x97\t0J\xa9\xa8s\x9c\xc8\x13]\xc70\xbe\xbd\xfc\xb4y\xb8s\xb1\xe1G\xed\xa7\x9a\xc4#Z\x8c\xf3\x15\n\xea\xf9M\xbe\xc5\bΣ\x9dp\x80\xd6z\xd1栌\xde\r\x02'\xad|\xa7A\xfd\\r(cA\xa0\xa7Ҥw\xc0\xf7Lﰻ\xb3\xca\xf2\xbf-)\xb9\xcf\xc0g:\x0f\x91\xfa\x92{\xdcd\xd1g9\xd5ԏ\xee\x8b;\xe2\xe9\xbb\xe2F\xfaƲ\x17\x87\xa2+\xb8\x8f\xe8\x9b*M\xa0\xce}w\x7fܭ\xef\x1f\x86Ǘ\xd37 \xf1ޛ\xf37nA\xe0\xc8\\w\x87\xfe\xdb\xe1PQ\xb7z\xb5\x05\xfe\x92\xa8\xd2ec\xde\x02lk\x82\x7f+2\xef\xa6\x1c:\xff8\xf0\x1e\x19\xe3O\x1eך\f\xa2i,\u0083\xa5\xc1\xb3\xbbC\x8bIa\xaa\xb6\xdc~\x19\xb5\x1a\xfc2\xd3\xff6\xfe\xdd\xe6\x06\xbd&k\xed\xe8e\xaa\x97=\xbbf\x90\xfbo¶\xbdW^¿\xfe=\xfbO\x00\x00\x00\xff\xff\x80.\x12\xd3P\x1c\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4\x96M\x93\xdb6\x0f\xc7\xef\xfe\x14\x98y\x0e\xb9<\x92\xb3\xed\xa5\xa3[\xb3\xc9a\xa7mƳ\x9bɝ&a\x8bY\x8ad\x01\xd0[\xb7\xd3\xef\xde!)\xf9E\xb67\xdbCy\x13\t\x02\x7f\xfe@\x80j\x9af\xa1\xa2\xfd\x8a\xc46\xf8\x0eT\xb4\xf8\x87\xa0\xcf_\xdc>\xffĭ\r\xcb\xdd\xdd\xe2\xd9z\xd3\xc1}b\t\xc3#rH\xa4\xf1#n\xac\xb7b\x83_\f(\xca(Q\xdd\x02@y\x1fD\xe5iΟ\x00:x\xa1\xe0\x1cR\xb3E\xdf>\xa75\xae\x93u\x06\xa98\x9fB\xef\u07b7w?\xb4\xef\x17\x00^\r\u0601A\x87\x82k\xa5\x9fS$\xfc=!\v\xb7;tH\xa1\xb5a\xc1\x11u\xf6\xbf\xa5\x90b\aDž\xba\x7f\x8c]u\x7f,\xae>\x14W\x8f\xd5UYu\x96\xe5\x97[\x16\xbf\xda\xd1*\xbaD\xca]\x17T\f\xd8\xfamr\x8a\xae\x9a,\x00X\x87\x88\x1d|β\xa2\xd2h\x16\x00㱋\xcc\x06\x941\x05\xa4r+\xb2^\x90\xee\x83K\xc3\x04\xb0\x01\x83\xac\xc9F)\xa0\xbe\xf4X\x8e\ba\x03\xd2#\xd4p \x01\xd68*0e\x1f\xc07\x0e~\xa5\xa4\xef\xa0ͼ\xdaj\x9a\x85\x8c\x06\x15\xf5\x87\xf9\xb4\xec\xb3`\x16\xb2~{K\x02\x8b\x92ē\x88\x12\xd7\x06\x0ft\xc2\xf7\\@\xb1oc\xaf\xf8<\xfaSY\xb8\x15\xb9\xda\xec\xee*i\xdd㠺\xd16D\xf4?\xaf\x1e\xbe\xfe\xf8t6\r\xe7Z\xaf\xa4\x16,\x83\x9a\x94fp\x95\x1a\x04\x8f\x10\b\x86@\x13Un\x0fN#\x85\x88$v\xbaZu\x9c\x14\xcf\xc9\xecL»\xac\xb2Z\x81\xc9U\x83\\\xa0\x8d\x97\x00\xcdx\xb0\n\xd32\x10FBF_\xeb\xe8\xcc1d#\xe5!\xac\xbf\xa1\x96\x16\x9e\x90\xb2\x1b\xe0>$gr\xb1\xed\x90\x04\bu\xd8z\xfb\xe7\xc17\xe7s\xe6\xa0N\xc91?\xd3(\x97\xce+\a;\xe5\x12\xfe\x1f\x9470\xa8=\x10\xe6(\x90\xfc\x89\xbfb\xc2-\xfc\x961Y\xbf\t\x1d\xf4\"\x91\xbb\xe5rkej\x1a:\fC\xf2V\xf6\xcbR\xffv\x9d$\x10/\r\xee\xd0-\xd9n\x1bE\xba\xb7\x82Z\x12\xe1RE\xdb\x14\xe9\xbe4\x8ev0\xff\xa3\xb1\xcd\xf0\xbb3\xad\x17\x17\xa4\x8eR\xe8\xafd \x97yM{\xddZOq\x04\x9d\xa72\x9d\xc7OO_`\n]\x921\xa7_\xb8\x1f7\xf21\x05\x19\x98\xf5\x1b\xa4\x9a\xc4\r\x85\xa1\xf8Dob\xb0^ʇv\x16\xfd\x1c?\xa7\xf5`\x85\xa7+\x99s\xd5\xc2}餹\xa8S4Jд\xf0\xe0\xe1^\r\xe8\xee\x15\xe3\x7f\x9e\x80L\x9a\x9b\f\xf6m)8}\x04\xe6ƕ\xda\xc9\xc2Ծo\xe4\xebJ\xd1>E\xd49\x83\x19b\xdem7V\x97\xf2\x80M x\xe9\xad\ue9e2\x9d\xd1=\x14x{\xb6p\xbd\xa0\xf38\xb6\xc9\xf9\xca\xcd\xc3Cɝ%\x9c\xdd\xc2\x06.z\xee\xeb\\J3\xfc\x97dj'\x1e\xd9\xe8D\x84^N\xfa\xb3\xba\xb6\xe9\xad,\x90(\xd0\xc5\xecLԧbT^ze=\x83\xf2\xfbq#H\xaf\x04^\x90r\x19\xe8\x90r\x9fA\x03&]\xf0\x1b\xb1\x9c\xbe%\x91\x82F\xe6\xf6\xc2\xce\n\x0eW4\xbd\x92\x9d<|rN\xad\x1dv \x94\xf0Ff\x15\x91\xda\xcf\xd6ʛ\xf5\x1d\x04\xabls-\a\x87w\xfa\xbbI(\xb8}\x1a.#5\xf0\x19_\xae\xcc>\xf8\x15\x85-!ϯ|^\\Uz\x87\x9f\x817P\xbaz)/&9\xf7;sB\x91%\x90ڞr\xe5\xb4>\xf4\xef\x0e\xfe\xfa{\xf1O\x00\x00\x00\xff\xff\x045\f\xc6i\n\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4VM\x93\xdb6\f\xbd\xfbW`\xa6\x87\xb43\x91\x9c\xb4\x97\x8eo\xad\x93\xc3N\xd24\xb3N\xf7NS\xb0\xc4.E\xb2\x04\xe8\xcd\xf6\xd7w@J\xfe\x94\xbd\xdeCu\x13\t\x82\x8f\x0f\x0f\x8f\xac\xaaj\xa6\x82y\xc0Hƻ\x05\xa8`\xf0;\xa3\x93?\xaa\x1f\x7f\xa5\xda\xf8\xf9\xf6\xfd\xecѸf\x01\xcbD\xec\xfb{$\x9f\xa2\xc6\x0f\xb81ΰ\xf1n\xd6#\xabF\xb1Z\xcc\x00\x94s\x9e\x95\f\x93\xfc\x02h\xef8zk1V-\xba\xfa1\xadq\x9d\x8cm0\xe6\xe4\xe3\xd6\xdbw\xf5\xfb\x9f\xebw3\x00\xa7z\\@㟜\xf5\xaa\x89\xf8OBb\xaa\xb7h1\xfa\xda\xf8\x19\x05Ԓ\xbb\x8d>\x85\x05\xec'\xca\xdaa߂\xf9Ð澤\xc93\xd6\x10\x7f\x9a\x9a\xfdl\x86\x88`ST\xf6\x1cD\x9e$\xe3\xdadU<\x9b\x9e\x01\x90\xf6\x01\x17\xf0E`\x04\xa5\xb1\x99\x01\fG̰\xaa\xe1t\xdb\xf7%\x95\xee\xb0W\x05/\x80\x0f\xe8~\xfbz\xf7\xf0\xcb\xeah\x18\xa0A\xd2\xd1\x04\xceD\x9d`\x06C\xa0`@\x00\xecw\xa0@9P\x91\xcdFi\x86M\xf4=\xac\x95~La\x97\x15\xc0\xaf\xffF\xcd@\xec\xa3j\xf1-P\xd2\x1d(\xc9WB\xc1\xfa\x166\xc6b\xbd[\x14\xa2\x0f\x18ٌ,\x97\xef@C\a\xa3'\xc0\xdf\xc8\xd9J\x144\"\x1e$\xe0\x0eG~\xb0\x19\xe8\x00\xbf\x01\xee\fA\xc4\x10\x91\xd0\x159\x1d%\x06\tRn8A\r+\x8c\x92\x06\xa8\xf3\xc96\xa2\xb9-F\x86\x88ڷ\xce\xfc\xbb\xcbM\u0090lj\x15\x8fr\xd8\x7f\xc61F\xa7,l\x95M\xf8\x16\x94k\xa0W\xcf\x101\xf3\x94\xdcA\xbe\x1cB5\xfc\xe1#\x82q\x1b\xbf\x80\x8e9\xd0b>o\r\x8f\xbd\xa3}\xdf'g\xf8y\x9e\xdb\xc0\xac\x13\xfbH\xf3\x06\xb7h\xe7d\xdaJE\xdd\x19F\xcd)\xe2\\\x05Se\xe8.\xf7O\xdd7?ġ\xdb\xe8\xcd\x11V~\x16\x99\x11G\xe3ڃ\x89\xac\xf9+\x15\x10\xd5\x17\xc1\x94\xa5\xe5\x14{\xa2eHع\xff\xb8\xfa\x06\xe3ֹ\x18\xa7\xec\x17\xe5\xec\x16Ҿ\x04B\x98q\x1b\x8c\xa5\x88Yy\x92\x13]\x13\xbcq\x9c\x7f\xb45\xe8N駴\xee\r\xd3(f\xa9U\r\xcbl(\xb0FH\xa1Q\x8cM\rw\x0e\x96\xaaG\xbbT\x84\xff{\x01\x84i\xaa\x84\xd8\xdbJp腧\xc1\x85\xb5\x83\x89\xd1\xc9.\xd4\xeb\xa4\xd5W\x01\xb5TO\b\x94\x95fctn\r\xd8\xf8\bj\xdf\xf9\x03\x81\xf5Q\xe6\xe9\xce\xcd\xe0Tl\x91OGO\xb0|\xcbA\xb2\xfdS\xa7\x8e\x8d\xe6G\xac\xdbZ\xbc\x82\x06 \xc5=~\xaa\xcf2^\xc6\x00\x93\xea\x9dD2\x8aXh\x10^\xc5\nĤ\x0e1\x9do-\x1f\xba\xd4OoP\xc1\xef\x19\xf3g\xdf^\x9d_z\xc7\"\xf7\xabA\x0fަ\x1eWN\x05\xea\xfc\v\xb1w\x8c\xfd\x9f\x01c\xb91\xaf\x86\x8e\x17\xef\ue5ba\x12\x98\xec\xc5}\xefQ\xfc\x1e/\x9ft\b\xb8)\xcb\r\x98\x86ț\x0e\xba\\ݽ\x86\xc2\v\xe1\xaf(ҝ\xdb\xf8\xe9\xb8\v\xed=~\xf9\x1a\x7fY\xab\xf2\x10\x18\xb5*K\xca݆\xf0)\xad1:d\xa4\xbd\xcd>\x19\xee&3\x02}S\xe6\x84H\xf9\x01\xa4\xd5\xe9\xd3K\xbe5B\x83\x16\x19\x1bX?\x97\x1b\xe9\x99\x18\xfbs\xdc\x1b\x1f{\xc5\v\x90˻b3!#\x97\xacUk\x8b\v\xe0\x98.\xa9l\xf2\xe0\xa1S4цGg\xfe*1S\xc2\xd85\xe3Ue\xc0\xc5{\xa3\x82/\xf841\xfa5z\x8dDx\xdeF\x17O2\xd9\x04g\x83$/\xac急\xe1\xe1>\x8c\xfc\x17\x00\x00\xff\xff\t\x15i;\xcd\r\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs\x1b7\xf2\xbf\xebSt9\a\xfdSe\x0ec\xff\xb7\xb6\xb6x\xb3\xe5͖v\x13Yeʾ\xa4r\x00\a=3\x88f\x00\x04\xc0P\xe2\xa6\xf2ݷ\x1a\x0fr\x1e )\xa9\xd6\u07b9H\x04\x1a\x8d\x1f\x1a\xfd\xc6b\xb1\xb8`Z|Ac\x85\x92+`Z\xe0\xa3CI\xbflq\xff7[\b\xb5ܾ\xb9\xb8\x17\x92\xafષNu\x9fЪޔ\xf8\x01+!\x85\x13J^t\xe8\x18g\x8e\xad.\x00\x98\x94\xca1\x1a\xb6\xf4\x13\xa0T\xd2\x19նh\x165\xca\xe2\xbe\xdf\xe0\xa6\x17-G㙧\xad\xb7?\x14o\xde\x16?\\\x00H\xd6\xe1\n\xb4\xe2[\xd5\xf6\x1dnXy\xdfk[l\xb1E\xa3\n\xa1.\xacƒx\xd7F\xf5z\x05\x87\x89\xb06\xee\x1b0\xdf*\xfeųy\xef\xd9\xf8\x99VX\xf7\xaf\xdc\xecO\xc2:O\xa1\xdbްv\x0e\xc2OZ!\xeb\xbeef6}\x01`K\xa5q\x057\x04C\xb3\x12\xf9\x05@<\xa2\x87\xb5\x00ƹ\x17\x1ako\x8d\x90\x0e\xcd\x15qH\xc2Z\x00G[\x1a\xa1\x9d\x17ʭ\xe2\x10\x00B@\b\xd61\xd7[\xb0}\xd9\x00\xb3p\x83\x0f\xcbkykTm\xd0\x06x\x00\xbfY%o\x99kVP\x04\xf2B7\xccb\x9c\r\xe2]\xfb\x898\xe4v\x04\xda:#d\x9d\x83q':\x84\x87\x06%\xb8FX\b\xa7\x85\af\t\x8eq\xfe\x94\xf9\x8d\xfd<-\xb7\x8euz\x84\xe0\xca ;,\r\x108s\x98\x03\xb0\x97'\xa8\n\\\x83$y\xafXLH!k?\x14n\x02\x9c\x82\rz\x88ȡ\xd7\x19d\x1a\xcbB+^\xc8\xc4t\x04\xebf2zN6D\xff\xdfF5\x02t\xab\xf8\v\xa0\x98\x9d\xb8\x01\ng ,\xb0\xb84\x9c\xe2 \xe8\xe4\x8e>\xfd}}\aik\x7f\x19S\xe9{\xb9\x1f\x16\xda\xc3\x15\x90\xc0\x84\xacȬ\xe9\x12+\xa3:\xcf\x13%\xd7JH\xe7\x7f\x94\xad@9\x15\xbf\xed7\x9dpt\xef\xbf\xf7h\x1d\xddU\x01W>S \xf7\xd4k\xd2\\^\xc0\xb5\x84+\xd6a{\xc5,~\xf5\v I\xdb\x05\t\xf6iW0Lr\xa6\xc4Aj\x83\x89\x94\xa2\x1c\xb9\xafIޱ\xd6X\xd2\xed\x91\x00i\xa5\xa8D\xf4P\x952\xc0\xa6\xe4ňq\xdep\xe9\xcbz\xa7)\xd1\x04\xd9\xfbܚ\x84M\x0e|jr\x98\x81r\xc6\x14\xa0\x9dz\xd9\xfd\x1a\x83ZY\xe1\x94\xd9\x11\xe3\xe0`\x8b\x19\x87#\xd7@\x9fT\x1cϜ\xe3Fq\xcc\xc1\xa6\xa5\xe0\x1a\x16\xb4\x95\xf2+\xf2G\xbd\x94\xf3]\xe8S\xf2Y\xc0\xb4\xe2gp\xc5\x1d\x19\x18\xacР,19\xaeS\xc9C\x06\xd90\xac\xcf1\x1eW\n8\xe1ճ\x88\xdf\xdd^'O\x9e\x84\x18\xb1\xbb\xf9\xbeg\xe4C_%\xb0\xe5>Н\xdf\xfb\xf2\xba\n\x9by\x9f\xe6\x140\xd0\x02C\x1a\xb8\x0f\x12 \xa4u\xc88\xa8*ˑj\x12 \xc37\x18W\xbc\x0e\x1e,\xba\xcaCh!\xd9\x03#\xdf)8\xfcs\xfd\xf1f\xf9\x8f\x9c\xe8\xf7\xa7\x00V\x96h}\x16\xec\xb0C\xe9^\xef\x13s\x8eV\x18\xe4\x94fc\xd11)*\xb4\xae\x88{\xa0\xb1\xbf\xbc\xfd5/=\x80\x1f\x95\x01|d\x9dn\xf15\x88 \xf1\xbd[NJ#l\x10Ǟ#<\b\u05c8i0\xddK\x80\xd4+\x1e\xfb\xc1\x1fױ{\x04\x15\x8f\xdb#\xb4\xe2\x1eW\xf0ʧ5\a\x98\x7f\x90\xed\xfc\xf9\xea\b\xd7\xff\v\xa6\xfd\x8a\x88^\x05p\xfb8<4\xba\x03\xc8`yF\xd45\x1e\xb2\xaa\xe9\xe7\x83\n\xb9\xea\xefA\x19\x92\x80T\x03\x16\x9e1\xdd^p\x94\xc8g\xa0\x7fy\xfb\xebQ\xc4cy\x81\x90\x1c\x1f\xe1-\x88X\xdahſ/\xe0\xcek\xc7N:\xf6H;\x95\x8d\xb2xL\xb2J\xb6\xbb\x90\xe7n\x11\xac\xa2B\t\xdbv\x11\xf2 \x0e\x0flGRH\x17G\xfa\xc6@3\xe3Njk\xca~\xee>~\xf8\xb8\n\xc8H\xa1j\xef\x89)jV\x82\xb2\x19JcB,\xf6\xda8\v\xe6\xe9\xb3}P\x1f\xa7\xa0l\x98\xac1\x9c\x17\xa1\xea):\x16\x97/\xb1\xe3yJ\x92\xbeLj2u\x1c\xff\xb3\xe0\xfe\xc4\xc3\xf9\f\xfa\t\x87\x1bV\x19'\x0fw\xdfo\xd0Ht\xe8\xcf\xc7Ui\xe9h%jg\x97j\x8bf+\xf0a\xf9\xa0̽\x90\xf5\x82Ts\x11t\xc0.}\x99\xba\xfc\xce\xffy\xf1Y|E\xfb\xd4\x03\x8d*\xed\xafy*\xda\xc7._t\xa8\x94\xc3>=\x8e]\xaecf5]Kf\xf1Ј\xb2I\xc5I\xf4\xb1G\x8cIP&̃kfr\xf7\xd5U\x99\x04\xda\x1bB\xb4[\xc4^ڂIN\xff[a\x1d\x8d\xbfH\x82\xbdx\x92\xf9~\xbe\xfe\xf0m\x14\xbc\x17/\xb2\xd5#\tx\xf8\x1e\x17\aX\x8b\x8e\xe9E\xa0fNu\xa2\x9cPSVz\xcdI\xf0\x95@s&\x8d\xfb4\"N\x89f&\xbf\xdd\xd3<+\x8ft\xac\xce$n\xc3\xd6\xe1\xa9\xf4\ue93cƍ\x1bV[`\x06\x81A\xc74\xdd\xf3=\xee\x16!!\xd0LP4\xa7\x80\xbd\xef\x8a\x00Ӻ\x15\xd9\xc0\x1d\xc3~LY\xa3$\xa8,g\xb5=v\xf6쭥.\xd0\x1a\x1d\x95\xad\xdfD\x0e\x9f'{>Y&\xf9\xc4a\x89\x1dZ\xcb\xeas\xa6\xf8s\xa0\nM\x8f\xb8\x04\xd8F\xf5n\xdf\xf5\x18ŌK\x1bu\xeay\x8d\x97l?a\xacΌ\xea=\x1b랶\xf5k\x86\x8e\xe0\xf0P\xe9Qm0\x9f7\xbd\xc4'\x00\xf8\x17\xb8s\b\x89&g`{\xefu\xd2\xc2\xe0\x84S\xbe\xc1\x87\xcc\xe8\xec\xe5p8y\x95L&3\xf7\xa3\xb7\x86g\x9d?ntN\x04\x91\f\x1a\xd5&cV\x8e\xb5 \xfbn\x83\x86\xe4\xb0\xd99\xb4cw\x9ekq\xf9\xd2\xf8 \xc6\xc1\xfat\x7f\x81S\xac\xf6K&}+چ\xb0ͅ\xd5-\xdbe\x18\xa7\x83\xf8\xf4\x97\x8c\x8b\\\xc0A\x9f\x93Qk<\x16\xe5O\xb7\xe6<\xa6\x0fJ\x1e)֒=\v\xe9\xfe\xfa\x97\x13ɲ\x90\x0e\xebIp\x88\xf3$\xce\xf7\xb4\xcb\xd7\xd9\xe1D\x12c%ӶQ\xee\xfa\xc3\x19-X\xef\t\x935\x1c\xf2h\xef\xfb|\xa3<\x12EU\xc8]\xd5\u07b7<\xcbT\xc7o\xd6砎\x88\xcfD\xa1\xf8Z\x9e\x8bAk\xd4̐\xa5\xfbg\x95\xab\xe9\xbb\xdfk\xb0\xc2\xf7\x8a)\xf5\f\xb9h\xe8\xe4X\nN\x94Z)\x83\x19\x97\t\xf3\xb02\n\"c\xf8\xdf2~d\xf5d6\xe8\x91\xf3\x01\xef\xf8\xde0\x1c\xe97\xfb\xb7\xb4\x15\xfc\xf1\xe7\xc5\x7f\x02\x00\x00\xff\xff\xb6]>s\xd5\"\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs#\xb7\x11\xbe\xf3Wt\xad\x0f\x8a\xabv\x86\xdeM*\x95\xe2mW\x8aSJl\xadj\xa9\u074b\xcb\apМ\x819\x03\xc0x\x90b\\\xfe\xef\xa9\x06\x06\xe4\xbcHJ\xaaȞˮ\x80F\xe3Ç~\xa1\x99eٌi\xf1\x15\x8d\x15J.\x80i\x81\x8f\x0e%\xfde\xf3\xcd?l.\xd4|\xfbn\xb6\x11\x92/\xe0\xda[\xa7\x9a\xcfh\x957\x05\xde\xe0ZHᄒ\xb3\x06\x1d\xe3̱\xc5\f\x80I\xa9\x1c\xa3aK\x7f\x02\x14J:\xa3\xea\x1aMV\xa2\xcc7~\x85+/j\x8e&(O[o\xbf\xcb߽Ͽ\x9b\x01H\xd6\xe0\x02\xb4\xe2[U\xfb\x06\rZ\xa7\f\xda|\x8b5\x1a\x95\v5\xb3\x1a\vR^\x1a\xe5\xf5\x02\x8e\x13qq\xbbq\x04}\xaf\xf8נ\xe7s\xd4\x13\xa6ja\xdd\x7f&\xa7\x7f\x10\xd6\x05\x11]{\xc3\xea\t\x1ca\xd6\nY\xfa\x9a\x99\xf1\xfc\f\xc0\x16J\xe3\x02\xee\b\x8af\x05\xf2\x19@{\xce\x00-\x03\xc6y`\x8e\xd5\xf7FH\x87\xe6\x9aT$\xc62\xe0h\v#\xb4\v\xcc\x1c\xf4\x80Z\x83\xab\x90\xb6\f\xac2!\x85,\xc3P\x84\x00N\xc1\n\xa1E\u00832\x80_\xac\x92\xf7\xccU\vȉ\xb8\\+\x9eˤ\xb3\x95\x89\x9c\xdf\rFݞ\xcea\x9d\x11\xb2<\x85\xec\xff\f\xaa\x87\xe7^\xf1'\"y\xa80\xc8$4^\u05caq4\xb4y\xc5$\xaf\x11\xc8@\xc1\x19&\xed\x1a\xcd\t\x14i\xd9\xc3^\xf7\x91|I\xfa:3\xcfa\xe79TD\xd9\xde\xf6_\xbbC\x97\xf6\xbdW\xbc]\x00\xadQ\x83u\xccy\v\xd6\x17\x150\vw\xb8\x9b\xdf\xca{\xa3J\x83\xd6N\xc0\b\u2e6e\x98\xed\xe3X\x86\x89\xd7űV\xa6an\x01B\xba\xbf\xff\xed4\xb6vQ\xee\x94c\xf5ǽC\xdbC\xfa0\x1c\x8eh\xc9\xd9\xca\xf6\xfa\xff\x14\xb8+\x82t\xa3d\x9f\u05cf\x83\xd1)\xb0\x1d\xa5)\xde\xe6\x85\xc1\x10j\x1fD\x83ֱF\xf7\xb4~(\xfb\xfa8sq No\xdf\xc5PVTذE+\xa94\xca\x0f\xf7\xb7_\xff\xba\xec\r\x03h\xa34\x1a'Rt\x8d_'ytF\xa1\xcf\xec\x15)\x8cR\xc0)k\xa0\x8dN\x11ǐ\xb7\x18\xa2\xb3\b\v\x06\xb5A\x8b2摞b !&A\xad~\xc1\xc2\xe5\xb0DCj\xc0V\xca\xd7!\x02m\xd180X\xa8R\x8a\xff\x1et[\xf2=ڴf\x0e\xdb\x10\x7f\xfcB\f\x96\xac\x86-\xab=\xbe\x05&94l\x0f\x06i\x17\xf0\xb2\xa3/\x88\xd8\x1c~$\v\x11r\xad\x16P9\xa7\xedb>/\x85KI\xb3PM\xe3\xa5p\xfby\xc8\x7fb\xe5\x9d2v\xceq\x8b\xf5܊2c\xa6\xa8\x84\xc3\xc2y\x83s\xa6E\x16\xa0ː8\xf3\x86\x7fc\xda4k\xafzXGN\x17\xbf\x90\xeb\xce\xdc\x00%;\x10\x16X\xbb4\x9e\xe2Ht\nٟ\xff\xb9|\x80\xb4u\xb8\x8c!\xfb\x81\xf7\xe3B{\xbc\x02\"L\xc85\x05]\xbaĵQMЉ\x92k%\xa4\v\x7f\x14\xb5@9\xa4\xdf\xfaU#\x1c\xdd\xfb\xaf\x1e\xad\xa3\xbb\xca\xe1:T\x12\x14/\xbd&\xcb\xe59\xdcJ\xb8f\r\xd6\xd7\xcc\xe2\xab_\x001m3\"\xf6iW\xd0-\x82\x86\u0091\xb5\xceD\xaa`N\xdcװ*Yj,\xe8\xfa\x88AZ*֢\b\xbeA\xe1\a\xd8H>艹v]\xfaV\xac\xd8x\xbdtʰ\x12\x7fPQ\xe7Ph\x80\xed\xe3Ԛ\x04Nvr^T\x0e6J\x8e\x94\x02\xd4i\xf1\xaeB\x83\xdd5\x06\xb5\xb2\xc2)\xb3'\xc51[\xe6#\r'.\"\x1cY\xf1\vǠp\x1f\x1c\xc2\xe0\x1a\r\xca\x02S\x848W\xc9L\x9c\xa2\x93\xd0\xc7\x10OS\x0fg\xa2\xe7$\xe0\x0f\xf7\xb7)b&\x86[\xe8n\xbc\xef\x05z\xe8[\v\xacyH(\x97\xf7\xbe\xba]\xc7\xcdB\xecp\n\x18h\x81\xb1\"=\x04c\x10\xd2:d\x1c\xd4zR#\xbd\r\x80\x1c\xcc`\xbb\xe2m\x8c\x14mH:\x86p\xa2\x1e\x18\xc5(\xc1\xe1\xdf\xcbOw\xf3\x7fM1\x7f8\x05\xb0\xa2@kC\xbe\xc6\x06\xa5{{\xc8\xd9\x1c\xad0ȩp\xc1\xbcaR\xacѺ\xbc\xdd\x03\x8d\xfd\xe9\xfd\xcf\xd3\xec\x01|\xaf\f\xe0#kt\x8doAD\xc6\x0f\xe1/ٌ\xb0\x91\x8e\x83F\xd8\tW\x89a\xd2:0@\xd6\xd5\x1e{\x17\x8e\xeb\xd8\x06A\xb5\xc7\xf5\b\xb5\xd8\xe0\x02ބJ\xf0\b\xf37r\xac\xdfߜ\xd0\xfa\x97\xe8@oH\xe8M\x04w\xc8w]\x8f<\x82t\x15s\xe0\x8c(K<\x16\xa2\xc3/\x04o\n\x89߂2ĀT\x1d\x15A1\xdd^\x8cG\xc8G\xa0\x7fz\xff\xf3I\xc4}\xbe@H\x8e\x8f\xf0\x1e\x84\x8c\xdchſ\xcd\xe1!X\xc7^:\xf6H;\x15\x95\xb2x\x8aY%\xeb}\xac\xf6\xb7\bV5\b;\xac\xeb,\xd6\x1b\x1cvlO,\xa4\x8b#{c\xa0\x99qg\xad5U\x19\x0f\x9fn>-\"22\xa82\xc4;\xcaNkAU\x03\x95\v1\xe7\x05k\x1c%\xcd\xf4Y\x1f\xcd\xc7)(*&K\x8c\xe7EX{\xcaB\xf9\xd5K\xfcx\x9c\xfa\xd37Q\x02\f\x03ǟ\x96D\x9fx\xb8P\xa9>\xe1pݷ\xd6\xd9\xc3m\xfc\n\x8dD\x87\xe1|\\\x15\x96\x8eV\xa0vv\xae\xb6h\xb6\x02w\xf3\x9d2\x1b!ˌL3\x8b6`\xe7\xe1\xc9<\xff&\xfc\xf3Ⳅ\xd7\xf5S\x0f\xd4{\xf4\xbf\xe6\xa9h\x1f;\x7fѡR\xad\xf8\xf4\x8bE\x96f\x82*$*\x82b\xd59]\xd73\xadk*l\xdaR\xea\xd0T,\x94\\\x8bқ\xf0z9Eʤ+t\x1b\x8c\x17n\xefKG4]݅\x16\xa7\xab\xa6.\xaf\xd7\xf8\x1c\xa3E\xe9\x9b1\x94\f6J\v61N\x86;rZ\x9ax3.\xf6\xce\xdc\\\xf4\x8a\v\x1c\xb4\xfd\xb8\x89\xc7e\xebT\xb1\xd8\x0e#\xf4\xa0\v\xae5\x9d\xa5\x9e\xebl\x06\x7f\xf5\xf4r\xe8#̦\x9f\xcc\x03\x19\xad\xf8lHZ7N\r&\x8fQf8\xd1w\xe0\xc1l\xafO\xdc=\u0378\xdb\x10\x9a\x90\xcf\xe97\xc4\xc6g\xcb{L{.\xb5C\xe9\xcd\xf7\xe2\x8eC\xa1\xe8=\xd5\xebY^\xb0\x81\xeb\xf1\x8a\xd0\xde3\xbc\xf5\t\xd1`x\xc6Ǟ\xed\x8eٴ\xc9\xd4}CG_\\\x1aJ\rR\x87<\xbcv\xe81\xb6f\xa2F\x0e\x87\x9f\x9e\xc2\xef\v6\xf4\xb9\xae\xa6\x8a\xfb\xa4\xc8[\xe4!\x98N\x80\x1e\xafK\xadc\xce\x1cf\xa4b$!}]\xb3U\x8d\vpƏ\xa7ϸW\x83ֲ\xf2\x92\x7f\xfd\x18\xa5b#\xa4]\x02l\xa5\xbc;tBZGk\xa9\xb8\xb2\xad\x15<\xaf\x1bS1{\t\xca=\xc9LY\xdc\xc1\xe5ϛ\x1c\x9c\tew\xb8\x9b\x18\x1d\xb5\xf2\xbb\x93\xd7Ʉ&\xe6\xbe\x0f\xd6\xf1,\x02ڍ.qЊA\xa5\xead\xdd\xcaQ\xa6\xf6\xcd\n\r\x11\x11~?H\x8c\xa4\xc01\xd5Z\nO\xd2#\x93G\r)\x16FU\xed#\xbb`2tZm\xccv\\X]\xb3\xfd\x84\xdet\x92Pu\x92\xf9\x92\x1f\x1d-&y!\xb9\xff\x89\xecx\xbe%v\xf8}d\xba&\x9e\xfa\xb5e\xea\x16\xba?\x9d\f\xe6\x0f?\f\xbd\xce\x0eg\x92\xbfu̸\xa7\x86\xbdeO\xf8R\xc4\v\xaa\xa7\xe3]7t\x8d\x03U\x7f\x9b?2FM\x125\x1a\f\xc8yGw\xdbN\xee\x8e\xf8\xd5\xe1ǒ\x05\xfc\xf6\xfb\xec\x7f\x01\x00\x00\xff\xff\xb1\x168S\xd6 \x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xdc=]s\x1b9r\xef\xfe\x15(\xe7\xc1I\x95H\x9f\x93\x97\x94\xde\x14\xaf\x9de\xee\xd6VI\x8e\xf7\x19\x9ci\x928a\x80Y\x00C\x99I忧\xd0\xf8\x98\x0fbf0\x94\xb8\xb7wx\xd3\x10h\x00ݍ\xfe\x06\xb4Z\xad\xdeК}\a\xa5\x99\x14\xb7\x84\xd6\f~\x18\x10\xf6/\xbd~\xfaw\xbdf\xf2\xfd\xf1Û'&\xca[\xf2\xb1\xd1FV\x0f\xa0e\xa3\n\xf8\tvL0äxS\x81\xa1%5\xf4\xf6\r!T\bi\xa8\xfd\xacퟄ\x14R\x18%9\a\xb5ڃX?5[\xd86\x8c\x97\xa0\x10x\x98\xfa\xf8\xa7\xf5\x87\x7f]\xff\xe9\r!\x82VpK\x14h#\x15\xe8\xf5\x118(\xb9f\U0008dba1\xb00\xf7J6\xf5-i\x7fpc\xfc|n\xad\x0fn8~\xe1L\x9b?w\xbf\xfe\x85i\x83\xbfԼQ\x94\xb7\x93\xe1G\xcdľ\xe1T\xc5\xcfo\bх\xac\xe1\x96|\xb1\xd3Դ\x80\xf2\r!~\xe98\xedʯ\xfa\xf8\xc1\x81(\x0ePQ\xb7\x1eBd\r\xe2\xee~\xf3\xfd\xdf\x1e{\x9f\t)A\x17\x8a\xd5\x06\x11\xe0\xd7F\x98&\x94|ǽ\xd9\x05 \xae\x899PC\x14\xd4\n4\b\xa3\x899\x00\xa1u\xcdY\x81\xa8\x8e\x10\t\x91\xbb8J\x93\x9d\x92U\vmK\x8b\xa7\xa6&F\x12J\fU{0\xe4\xcf\xcd\x16\x94\x00\x03\x9a\x14\xbc\xd1\x06\xd4:ª\x95\xacA\x19\x16\x10\xebZ\x87]:_\a{yg\xb7\xebz\x91\xd2\xf2\t\xb8%{\x94A\xe91dWk\x0eL\xb7[\x1bn\xc7o\x89\n\"\xb7\x7f\x85¬\xc9#(\v\x86\xe8\x83lxi\xd9\xeb\b\xca\"\xa7\x90{\xc1\xfe'\xc2\xd6v\xa3vRN\rxz\xb7\x8d\t\x03JPN\x8e\x947pC\xa8(IEOD\x81\x9d\x854\xa2\x03\x0f\xbb\xe85\xf9\x05\xc9#v\xf2\x96\x1c\x8c\xa9\xf5\xed\xfb\xf7{f\xc21)dU5\x82\x99\xd3{\xe4x\xb6m\x8cT\xfa}\tG\xe0\xef5ۯ\xa8*\x0e\xcc@a\x1a\x05\xefi\xcdV\xb8t\x81Ge]\x95\xff\x14\xc9\xf6\xae\xb7Vs\xb2\x9c\xa7\x8dbb\xdf\xf9\x01\xd9|\x82\x02\x96\xe1\x1d/\xb9\xa1n\x17-\xa2\xed'\x8b\x9d\x87O\x8fߺ|\xc6\xf4\x10\xfb\x88\xf7\x0e\xf3\xb5$\xb0\bcb\a\xca\x11\x11\xb9\xcd\xc2\x04Q֒\t\x83\x7f\x14\x9c\x81\x18\xa2_7ۊ\x19K\xf7\xdf\x1aЖ\xa1\xe5\x9a|D\xd9A\xb6@\x9a\xba\xa4\x06\xca5\xd9\b\xf2\x91V\xc0?R\rW'\x80Ŵ^Y\xc4摠+\xf6\x86\x9d\x1d\xd6:?\x04\xe15B/\x7f\xfa\x1fk(z'\xc6\x0ec;\x7f\xcc\xc9N\xaa\x9ep\xb0C\xd6=\xa0\xe9Ck\x9b;\xfdV\x82\r\x7f\x19,\xe5?bG\xcb?v\x11\x8d`\xbf5\x80\"ΝX8\x13)g IX\x1f\xb2\xc5\xfa\xec\xf7\x11\x9c\xda\x06?\nޔPFi{\xb6\x97\xc1\x8a?\x9d\r@\xadC\x99\xb0\xfcoſ]\xb6h\x7f\xb5\xe24\xb1b\xaa\x80X\x0ed\xc2\xc1#L\xe0f\x93\x98\xb6\x8d\x19\xa8\x12\x8b\x9b\xdc\x1d!\xa2\xe1\x9cn9\xdc\x12\xa3\x1a\x18\xc1\fU\x8a\x9eF\x10\x13Tp.^b\x7f/\x108+\xa0\xab(\x1cj\x9c\x92\xa1\xea|E\xe4\x0f\x8e\x15\xa6\xad8\v\xbb\xbc\x97\x9c\x15\xa7YԤ\x06\x85\xe3\xe6\x0f_\xe0\xe0-\x1c\xe8\x91I\x95ؒ=\x91\xb6kG\x91\xb6\xc2TZY恔\x97m8\x89\xac\x83\x94Os\xb4\xff\xd9\xf6i\xa56)\xd0x\x8b[\xf1\xd4\xf6Jt\v\x04~@ј\xc42\t)\x1bT R\x91Zj3N\xf7q\xd9C\x9c8\x18cZ2\xc54g;\xf3\xa22P\xcen\xb4'6\xa5\x00\xbb\xd6\xcaR\xae\xed\xabd\xe3\xfa\x0e\xf5[\a\xe3i\x8c\x90-\xd5P\x12鹾\xe1\xa0\xfd\\%\x92\xbf\x95+7\xa3\xa0\xe3来\xc1\xe9\x168\xd1\xc0\xa10R\x9dc2\a\x9f\xae\xe5\xc8\xca\x11<&\xa4f\x9f\xfdۍM\x80$\x96͟\x0f\xac88#\xc0\xf2&\xc2!\xa5\x04\x8d\x82\xc3\x1a\xaa\xa7\xb1M\x929\xda\xfbI\xa6DG\xdbf\xce\xd4\x10^J\x9c\xb4-CܶmF\xf0\x9e\t\x16\xff=\xa99\xdb\xf6\x8f\x89ؠI.`\xda\xcd\xd9\xd0\xd7eZt\xaa\xac\xb1\xbf\xd9\x11\xa8js\xba!̄\xafs\x10)\xe7\x9d\xf9\xff\x8e\t\xb3\x9c\xe37Ñ\xaf\xca\xf1\x93T\x99\x83h\xa9\x12\xa7\xff;$\n*\x8bG\xaf+\xb2\t\xf2\x97\xee\xa8\x1b\xc2v\x91 \xe5\r\xd91n@\r(\xf3\xa2\xf3\xf2\x1a\xc8\xc8\xd1w\xb6U\xd4\x14\x87O?\xace\xa3\xdb8S&^\x86\x83\x9dI\x1c|\x84\xbeb\x9e\x81K\xd0}e\n*\xe7\x16\x7fCl\xb6_П\xb8\xfb\xf2\x13\x94S\xe8!y\x9cw\xb6\x91\xbb\xc1b\xbbS{;?w\x1b\xde\xf4\x89>\x93\vx\xdc\x10J\x9e\xe0\xe4,\x16*\x88%\x0e5h\xef&\xbd\xa7s\xe4`\xe4\x05\x99\xec\tN\bƇRfG粂kO\x900\xf7S\xad\x87@\xbb&\xef\xe0:L\xda\x0f\x88\bt\xbc\xf3\x91G0,\x16d\xd1\xfc\xe6H\xbe \t-\xe0\xfe\x82mF\xb2u\u0087H\xd8wڑȞ\x82\x03\xab37\x8a\xd1C\rxZB`\xec;嬌\x139\xbe߈qk\xb8߾H\xb3\x117\xce#\xd3\xc8%?I\xd0_\xa4\xc1/WA\xa7[\xf8\x05\xc8t\x03\xf1x\t'\xb6-\x1e\xba\x11\xb6\f\xe6vm\xe3\x02)\x910֝\xc6\xce\xc04\xb1\xf4=R~\x1e\bOlNZ\xd9\x02\xdc)r\xb9;\xb3Xn\xc8\xf3Aj\xa7Sw\fx*d\xd3oL\x93\xb7Opz{s&\a\xden\xc4[\xa7\xe0\x17\x8b\x9bh-H\xc1O\xe4-\x8e}\xfb\x12#(\x93\x133\xbb\xfdX=Őܪ\xa2\xf5\xcas\xaf\x91\x15+Fljdx\xbcm=v\xea\x86\xc8\xdbظ7\x8f\xa7v\x9bſ\xb5\xd4\xe6\xe7t\xa0od=\xf7aDߦM\xc4\xcbfm}\x1f\xfb\x8a\xc2\xd8Z\x80;\x03\xca\a\xff\x9c\x80\x0e\x9e\xc3\v}\xaa\xb9\xe0^\f\xec\xd1\x18\x90\xb5\b\x9e\xe1&\x97*\xc9Y\xe2\x12k\xd3\xe2e\xa1\x9d\xfe\xe9G'6iO\xb6\xfd\xbb\xbb\x91\u05f6\x86\vYUt\x98\x1c\xccZ\xeaG72\xf0\xb4\a䨯\xf6\r\x9e\xe7|31\xf0\x10\xa6\x05\x9f\x9990Ah\x10\x1b\xa0\x82\xb2Qp\xa0G lG\x98! \nK\x17PNd\xe3\x14\x1e\x19\x88\x9al\xb6\xcc\x13\xf0\xb6\x81h\xaa<\x04\xac\xf0d31\x19L\xebv\xffL\x19\xbf\x06\xd9,\xe7}\x96\xea\x01hyI\x00\xe6\xd7\xcep\x02B7\n\x13\xf7N\xbc<3\x9e\xb7fK9\xc2i#\x8a\x03\xa0\x9c\x12=\xf1A\x1cx&\xb4\x01\x9a\xcb\v\xd6jj\x84`b\x9fG\xbb\xec\x10g\xdb\x1c\xaa\xb7Rr\xa0Â\xa7T\xb3\xb8\xbe\\\f\xfdڎ\xfe]\xc4P\xa4@\xbe\xb9\xb0\x05O*/\x8b\xa81P\xd5\xee\xbcI\xa2\x1a\xd1\xd5>W\x90BK|p\xbf\x8a\xd7t\xae\x99`\x19\x84\x1d\xe4\\\x98\xe9Z\x96\x16\xc4U-K;A4*.\t\x9fmz\x00\xec\xe9\fN\n\xae=r\xcd\x02+s\v\x84\x96%\x94.0iM\x15ﳸ\xf2\xb2\x91R\x85\xe4\ue59b\x89Y\x94\r\xad\xe7\x91b(V\x1daՈ'!\x9f\xc5\n=y\xbdX\x80\xe4\x87\x06_uzs\xb1$\xfa=\xa5P\x9f_\xf3y*\x18OW\x902\xd9|\xb3(\x1a2\xc5\x05sr͕.\x8f\xfc8\xbb\x8a\xa9\xf9'\x06\xfbD\xf3GWs\x9c[϶I\x8f\xea\x18\x7f\xcf\a0\aP\xa1\x98y\x85u\xdb)9\xdd\xe6\xa3[?&\x16\xb8Y\xfe\t\xa6\xb0+\xbc\x1c\x94\xbc\xa5\x1d\x1dk\x05\xdcXƦ\r7\xae\xfcX5\t&\xca*\xfcJ[\x069\x95\x13s\xf5\x12\xfd\x1a\xc0X\xaf\x10\x8a\x00e\x98$\xb1CGKW\xe9\xdbM\xc6\xf7\v\x1f0\xe4\x17V\xfa7/\x0f̨i\x98\xa9d\x98.\x9a\x9c\xc2\xd79\xdbt1\xd6\xf2\xa0\xef\xe7\xabi\xffX\xe83P}\xad\xfd9\x185@\xfb\x18L\f\x19\x94\x83\xa0\xe4\xb6.;\x16\x16P\x96\x12.\xf6\x14\xfap\xa0\x85xW\xe0I\x94\x01\xb0\xc6P\xb3?m\xbe\xba\x9di\xf2\x81\x1cd\x93(\xa9\x9b\xc0\xceL\x81\xc5xY\x85O\"\x80\xa1\xc7\x0f\xeb\xfe/F\xfa\"\v\x8c|%v\x87\x8eJ\x1bMe\xa2dGV6\x94\xf7\x0eY\x87-Z\xee!R\x11\xc1x*\xbfj\xd9*\x8c\xef\xb1\x11\xf9Z\xbb<\xcbbq4m\"\xe6\xd5b\\\\\x81ѯ\xb0\x18QRKS\x0e\xf9\xa5\xa6\xf95\x16\xd3E\x11K*+\x86u\x13\xa3@\xe7\xeb)r\xac\xfb\x99ډ\v*&2\xab\xe5^\x9c ɩ\x89\xb8\xa8\x12b\xb6\xa0,\xb3\xfe\xa1_\xd90\rrA\xd5C\x16r\xe6+\x1c\x16\xd75\xf8:\x82\xc9}dW3$\xea\x14&\x01\x8f\xd60LU'L\xa3\xd42/*\x1bM9\xb5\xe2W\xf1\xa5\xae\xe8M]ß\xbạ\x9a\x019\xa8\x01ϩ\xee\xceJ\xe3e\xe7lr\xb2l\xf3\x99\xe3\xe9\xaa\xed\x8cj\xed\x8cl\xd0\xdcJ3\xaa\xb2\x97Ucg\xe0\xf0J\xbe֕\xbc\xadk\xf8[\xd7\xf5\xb8f}\xaeYΙ\xf9yY\x15\xf5\xc5I\x86\x90\x8e\xfe\"K\xb8\x97\xca\xcc9\b\xf7\xc3\xfe\x89\x14`\xc7i\x92\xbc$\"tMe\x1a\xac\xed\xef\xed\xfe\xcb6\x95\xce\xd6\x05\xf3\xf7\x17Yڵ\xcd\xe5\x16\x1e\x06\xddϮ\xd0\xee@\x81p\x0fK\xfc\xd7\xe3\xd7/\x11~\xca\x1e\xf5F\xef\xe0M\x03g`\x94\x1e9>\xfb\xe4\vn\x1c\xb6P\x87\xbfr\x92\x80\xd6\xec?\xf1ͮ\xf9\x80\xcc\xdd\xfd\x06\xbb\x06k\t\xdf\xfa\x8a\t\xfd\x98{ۂ\xd5\x1e\x11#\xa3ܿ\xd9\xf5 &\xcaN\xe3\x9f\x04_L\nڋ\x8d\xd5d\xb9\"${\xea\xee7nuk\xf2ٚn\xe2D\xa4c\xbc\x03S媦ʜ\x90;\xf4M\\\xc3xP&萩\xd0ɨ\xa8=\x7f\v*\x89\xdb\xf0$\x14&\xe0Nu?\x9b9\xc4\xe8%\xeb\x18\xbf=1{o\xe2\x15\xd71\xae\x8eW\x88\xa9\xc4\xe7d\x05ī\x85\xa4\xbc\x18\xba\xff>'\xd6\x1eb\xc7iyf=\xd9\x10\xd6I\xe0ǎG\x91\xa6\x05\xad\xf5!\x11\x15z\x99LÇ\xaa\f5M\xe6~\\\xdfޖXq\xe8\b\xa0g\b\"Ju\x9e\xed\x1b\xacɞU\a\b\xd50\x9aЂ\xf1\x9b\x8ec\xfe\xfb\xa4<3\x9f\x05\xb9\xf8A\x10\x87\x9e\x11Q\x81\x91&+\xc6\x02/\xb4x\xb9 \xd99k\xc2e\x14\xb6N\u06dd\x99/J\\\xfc\x96\xc4<\xb2\x12\x88\x1a{F\"穈\xbf)>'D\x92.\x0eP6\x1c2\x1ex{\xect\x9d\x7f\xe2-\x00N\x9dI\xd9\x7f\xe4\xcdⵣ^\xad\xc1\xdb\x7fL\xce#\xddC\x1e)\xf1\xee\x82t\x96\xbd{u\xaa\xb0v\xbcn\x8a\x02\xb4\xde5M\x17ˡR\x9cBu,e-\xd7\x1d\xd8\x0e\fZ\x9d\x164\x94\x04\x8e \x88\xe5M\xca8\x94Su\xd3\xdf0^\xa9\x8e\xa0\xde\xe9\b\a+\xb9,_?\x1a\xaaL\\\xfa\xf9Q\xdcIUQsKJj`eG_f\x9a\xa4\x9f\x8dTj>\xb5\x84\xb7\x85\xfc\x01\xc0+>H^\xce\xfd\x1d\x9f\n\xb4\xa6\xfb\xe07=\x83\x02\xb2\aaQ<\xf52^{Mʋ\xceX\xf0g\xb1E\v\xd3P?\x813Qb\xd2-\x01\xd2?\xb7\x8a\xae\xd8~T`1a`\x7f\x96\xee\xf2W\xb4\x1e\x80\xea\xe1\xf3\xbcg\x88\xf8\xdc\xed냕\x0e\a\xee-\x18\xea\xaa\xf3\xf05Wâ{8\xa2\x06\xec̋\x84\xebAʧ,\x1b\xf2\xe7ر\x8d\x950\xe1\xf8\b/\xa6mec\xba֡\x1c\x8b\xac⫉\xafl\v\"\xcc;wSe,\x00x\xfe,c\x1c\x10\xbd1i('\xa2\xa9\xb6\xa0\x90!c\x87\xc3\xc4m\xed\xc7\xf06,秛!\xe4\xc1c\xd1-\xec)\x88Hz/\x03:7xC\xe4j\x00\xc4u\x9fx8\x92\xe0K\xbfAa\x8f=U7\xc5\xd1\x11ǟqQ\xb9\bv\xbdǰ\xeb\x16\xef\x9c\x10\x10i\x1f\x8a\x84\xccq8\x16\x17,}\xc2Z\xab\x0fTϙi\xf7\xb6O\xbc\xba\xdb\xd1I\xd1B{\x189\x92髄+\xf2\x05\x9e\x13_\x1d\xb20\xff\x92\xd6$+\xb2\x11\xf7J\xee\x15\xe8s\xc6Y\xe1\xdd2&\xf6\x9f\xa5\xba\xe7͞\x89X\xfa\xbb\xac\xf3=U\x86YVv\xebI\x8c\xfd\x18tY\xe2\xb7\xf9\xd1#?LȨ\xda\xefy6\x18\xe9\xba\xcd\xc9'/@\xdf\xe9V_\xa4\x02w\x1eښ|\x91\x06B\x8e\x90\xf5\x812M\xb6\xa0\xcd\nv;\xa9\x8c\x8b\x1d\xafV\x84\xed\xbc\x9d\x92\x8aqR\xc6\xd1\xc7qok[\xc7'V\xb5E\x8b\xdbDZ\x14*\x05t\x8e*zr\xe10Z\x14ր\x85\xf7\xdaД!\xfd\"1\x8aN\x95\xe7\xe6\x9cC\xbe\xe9\xf6\x8f\xa1\xa4x\xc0\x11\x9cC\x1d\xde\xe9u\x1a8Y\x1fA\xf0\xfeh\xe7I\x01\xa2\xad6\xbb\xe4\xb8\x13'h6\xe3\x0eb\xff\"T\xec<&\xa7\xfc6z\xaf\b\x8f\xd7@3\x1d\x86Z\x9a\x15\a*\xf6\x96}\x94l\xf6\x87\xc0\x82c\x86\xca\bв\xc1Xs\x8d'U\x87\\\xbbi\x94褊|\xf6\xbdl\x97;\x05\xf4b\x89\xa9ڛ\x00\xad̘м)c\x7fd\xf0\b\xfeS\x81\xec8\x84\xea\x93(\xa6\xaf'8?\x8fM\xdcB\x9cBFr\xbfQ\x02^\xb2\xdf88\x7f\xbf]\xe5ݺ\x12K6?\xee߿\x02:ƌ\x82y\\L\x1b\b\xb8\xbf\xc4\xca\x17\x91\xbbk`\x04S\"\x15M\xb4\xc6\xc52\\螓5\x17\xec\xe9u~\x993\x89\x13[W\xf2\x8f\xeb\x04\x1e\xa3\x19\xf3)\xc7\x1d\xfc>\xe8>\xb8\xebe\x1d\xc3\x16\xa2w\xe1\x12\xc8\xf9g\xb6\v\xff\x8ee\xcb\xe1_\xcez\xfc\xcew\xb6\x9e\xa9\x12L\xec\xe76\xff\xab\xef\x96\xf0\x86=\x84\x84?\x9c\xd8D\xf4\x90\x17\xf9\xc3a\x91#\xffq \xfa\xc8/\xf0\x88\x93\xea\xe4\xec#2r\xd9A\xb2\x9f\xc9\x7f\xf9\xff\x00\x00\x00\xff\xff\xbb\x8aQ\x92$i\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=Mw$)rw\xfd\n\x9e|\x18\xdbOU=m_\xfctk\xab{\xecz;ӭ\xd7\xd2\xf6\xc9\x17*3J\xc5(\x13r\x81,uy\xdf\xfew\xbf\b \xbf*\xc9$K\x92gfW\\\xba\x95\x05A\x10\x11\xc4\a\x04\xb0Z\xad.x%\xbe\x816B\xc9k\xc6+\x01\xdf-H\xfcˬ\x1f\xffì\x85zwx\x7f\xf1(d~\xcdnjcU\xf9\x15\x8c\xaau\x06\x1fa'\xa4\xb0Bɋ\x12,Ϲ\xe5\xd7\x17\x8cq)\x95\xe5\xf8\xd9\xe0\x9f\x8ceJZ\xad\x8a\x02\xf4\xea\x01\xe4\xfa\xb1\xde¶\x16E\x0e\x9a\x80\x87\xae\x0f?\xae\xdf\xff\xdb\xfa\xc7\v\xc6$/ᚙl\x0fy]\x80Y\x1f\xa0\x00\xad\xd6B]\x98\n2\x04\xfa\xa0U]]\xb3\xf6\a\xd7\xc8w落\xf3\xed\xe9S!\x8c\xfdS\xef\xf3\xcf\xc2X\xfa\xa9*j͋N\x7f\xf4\xd5\b\xf9P\x17\\\xb7\xdf/\x183\x99\xaa\xe0\x9a}Ʈ*\x9eA~\xc1\x98ǟ\xba^1\x9e\xe7D\x11^\xdcj!-\xe8\x1bU\xd4e\xa0Ċ\xe5`2-*K#\xbe\xb3\xdcֆ\xa9\x1d\xb3{\xe8\xf6\x83\xe5W\xa3\xe4-\xb7\xfbk\xb66To]\xed\xb9\t\xbf:\x129\x00\xfe\x93=\"n\xc6j!\x1f\xc6z\xfb\xc0n\xb4\x92\f\xbeW\x1a\f\xa2\xccrb\xa0|`O{\x90\xcc*\xa6kI\xa8\xfc'\xcf\x1e\xebj\x04\x91\n\xb2\xf5\x00O\x8fI\xff\xe3\x1c.\xf7{`\x057\x96YQ\x02\xe3\xbeC\xf6\xc4\r\xe1\xb0S\x9aٽ0\xf34A =l\x1d:?\x0f?;\x84rn\xc1\xa3\xd3\x01\x15\x84w\x9di \xb9\xbd\x17%\x18\xcb\xcb>\xcc\x0f\x0f\x90\x00\x8cHT\xf1ڐp\xb4\xado\xbb\x9f\x1c\x80\xadR\x05py\xd1V:\xbcw\xb2\x97\xed\xa1\xe4\u05fe\xb2\xaa@~\xb8\xdd|\xfb\xf7\xbb\xdeg6\x90%O)&\f\xe3\xec\x1bM\f\xa6\xfdLev\xcf-Ӏ\x9c\ai\xb1F\xa5a\x15\xa8\x9b7 \x19S\x9aU\xa0\x85\xcaE\x16\xb8B\x8d\xcd^\xd5Eζ\x80\fZ7\r*\xad*\xd0V\x84\xa9\xe7JG\xa3t\xbe\x0e0\xfe\x01\a\xe5j9I\x04C\xc2\xe7'\x14\xe4\x9e\x0en~\b\xd3\xe2OL\xea\x01fX\x89K\xa6\xb6\xbfBf\xd7\xec\x0e4\x82\tXgJ\x1e@#\x052\xf5 \xc5\xff6\xb0\rJ\xbd%a\xb4\xe0\xf5A[h\x02K^\xb0\x03/j\xb8b\\\xe6\xac\xe4G\xa6\x01{a\xb5\xec\xc0\xa3*f\xcd~Q\x1a\x98\x90;u\xcd\xf6\xd6V\xe6\xfaݻ\aa\x83&\xcdTY\xd6R\xd8\xe3;R\x8ab[[\xa5ͻ\x1c\x0eP\xbc3\xe2a\xc5u\xb6\x17\x162[kx\xc7+\xb1\"\xd4%i\xd3u\x99\xffS\xe0\xa8\xf9\xa1\x87\xeb\xc9|s\x85\x14\xe1\x04\aP#:\x81qM\xdd(ZB\xe3'\xa4\xce\xd7Ow\xf7]a\x12fH}\xa2{G\xc2Z\x16 \xc1\x84܁\x9f\xd1;\xadJ\x82\t2\xaf\x94\x90\x96\xfe\xc8\n\x01rH~SoKa\x91\xef\x7f\xa9\xc1X\xe4՚ݐyA9\xac+\x9c\x81\xf9\x9am$\xbb\xe1%\x147\xdc\xc0\xab3\x00)mVH\xd84\x16t-㰲\xa3Z\xe7\x87`\xde\"\xfc\ns\xfc\xae\x82\xac7e\xb0\x9d؉\x8c&\x06i\xcfF\x05\f4\xa8+㳖~!55\xfc:\xc0\xc3\xe9\xb2\xd0+\x18\xb4\x1fvO\x1cn\xcd\x18ʕ\x83\x86:E\xaa!wǴ`\x87\x12\x1e\xca\f&}\xad\x97j\xdfN`2\xaf\xea\xd6\x11\x1cO\xb8J?AY\xa1ژA\xf1\xdeWC\x14\x91>y\xe35\x05\xc3\x1fԬ\xf2ڕ\x9d(7\xean\x0fȷ\x83Ƚ\xf6:\xe1*\x9b\xe4,\x96̈;\xc9+\xb3W\x16m\x9c\xaa\xedX\xad\xc1\x00n\xee6\x83F\x1d\xce#VdÉ\xd1V\xb1'.N9\xed\n\xca\xe5\xcd݆}C\x97\b\x02L\xe6,9\xb3\xb5\x96\xa4\x8e\xbf\x02Ϗ\xf7\xea\xcf\x06X^\x93V\nv\xf9*\x02x\v;\x9c\xf4\x1a\x10\x066\x00\xadq\x0e\x18BM\xd5vM\x0eG\x0e;^\x17\xd6+9a\xd8\xfb\x1fY)dm\xe1\x94\xefl\x9a\xf7D$ny\xa9\x0e\xa0\x13h\xf8\x91[\xfe\v\xd6\x1d\x90\x0ea0\x02\xe2\xd9Od\xdc\x1e#\x03\xc5&['\xa9l\xb3\xeb@\x15\x86]^\xe2<\xbbt.\xf1啫[\x8b®\x84\xa4~\"0]\xefO\xa2(B\xff\xe7Q\xc3\x11\xd7\xf1\xd6ܫ\x9f\x8c\x13\xeb\x14\xe2D\x9a\x8e(\x98J\xe5\xec@\xf5b2&\n`\xe6h,\x94\x9eR\x1dυ\x88Kڱ(<\x18öǀ\xfb\xf8\xb8e]\x14|[\xc05\xb3\xba\x1e\xefvJ\x91\x8d\xd1\xe6+\x18+\xb2\x04\xca\\\x0eI\xe3Z\x8e\x10F\xd3\x0f\x11\xa2\f(\x80.\x0f\x7fD\xb7\xdbS\b}\xa7\xa2\xe8\x10w\x9e*\x8c\xfd\x8fd\x1f\xd1\xdcgh\x84\xaf\xbdq\x17P\x90C!\x15+\x94|\x00\xedzD\xc7)H\x98\x06\x94\xb8<\x02\x15-\xad\x86\x02]\x06\xb6\xab\xd1\b\xaf\x19j\x82\xa8\x8c\bi,\xf0|}\xf9Z̃\xefYQ\xe7\x90\xdf\x14\xb5\xb1\xa0\xef0\x04\xccC\b<\xaae\aL\xfc4\t\xc0\xbb_\x85\xc8\x00\xf9\x90\xb9J+\x8a4cDj=\xb1c\x05.\xf0E\xa6zL[\x17\xab\xa3*\fX\xacr\xf9\xaf\x971%\x8a\x12\xd0\xef\xbdߏa\\CC\x8d\x9eF\x8d@l\xf4,\x94\x95=\x8eˑ\xb0PF\x888\xabr\x16\xb0\x97k\xcdǔj\x18N\x13џ\xcf\xde\x18\x88\x01\x83e\xa8\xf6\x1b\xb1x\xd8\xff?\"\x93\xcfb\xab\xa1u,.$\xb2\xb3\x10\xc6\xf6\xb89\f\x88\x1a\xcc0vF\x9ab\xd0\"\xa4\x83\x89ʭü\xdf3\xcdΙ\t1\xd1o$͋\xf3\x9eDŽ\xea\x0fH\xb0\xbdR\x8f)D\xfao\xac\xd7\x06\xca,\xa3%U\xb6\x85=?\b\xa5\xcdp\xb5\x05\xbeCVۨ\x9e\xe0\x96\xe5b\xb7\x03\x8d\xb0h\x81\xb0YO\x9c\"\xd6t\x98\xc0:\n(Za0\xae\x96\xe9\xc8<\xa2Fl(\x14\x8eE\xa12B\x1c\xbdx\xb2\xee\xb98\x88\xbc\xe6\x05\x19z.37>\xde\xe0\x17sOf\x04\xe2\x04\x7f\xe7N\x84Q \x97zQ\xb6\x92\x80\xeeu\xa9t\xcc\xf3t\xe5\x14L\x9c\f[N\xc1q,$m\x8b\xae\v0\x1e\x15\xe7\xc0\xb6z\xe7\xaa\xe5\x94[\xa0*\xf8\x16\nf\xa0\x80\xcc*\x1d'O\x8a\x10\xb8\x92\xaa?#\x94\x1dѤ\xfd hV\x89\xb6\x05\x03̽\xc8\xf6\xce\xddD)#X,W`Hc\xf0\xaa*\"V\xa8-\xb3\x92\xe1;\x9bS\x1amIP\x1fC\xb81EҖD\x1dܖ\x19mܧz#6oD\xef\xa1)\x9f%웓\xe6//\xecHn\x01\x86\x9c>\U000bab98\xb0\xe1k\nԞ\x1fh\xfe\xce\x18w\xdel\xd9\f[\xbf\xf8ly\x11\xae5h\xfc\x9d0\x8d\x8c՝\xb7U\x8b\x18\xf6s\xb7\xe5\x15\x13\xbb\x86a\xf9\x15ۉ\xc2\x02\xf9Rs\x88v\x1c\x9dYν$\x81Rm/\x96\x92\xdbl\xff\xa9Y\xd6Nh1\xa0\xd5\x10\x80\xf3\xcbC\fC\f<\x9d.\n4\xc0$\x90\x9dA\x91\x9b\xd6\xc4xn?\xef\x8aq\xf6\bG\xe7Y\x8d.\x0f\x8d\x15d-o@j\xa0\xcdER#\x8fp$P~\xb70\t\xde\x12Qq\xe5\x11\x8e\xa9U\aDE\xfc\xfc>\x85\xa3.~\xa0Q\xa4L\xa5\xb64D\xf5s\x87Y\x956X\xb6L)\x85\x12(~\xe6\xb0\x1b\x86\xf5\xb6\xc8\x1f\xe1\xf8\x83q\xec\xc3Y\xb3\x17\xd5\x02\n\xa0¦%\x19\xb5k\xf6\x86\xbf\xf1B\xe4Mg4O\x16@\xdc\xc8+\xf6YY\xfc\xe7\xd3wa\x10E\x99\xb3\x8f\n\xccge\xe9˫\x92\xd8\r\xe2L\x02\xbb\xc64-\xa53\vH\x97E\xfd\xb78\x90\tE\x11m\xd8&\f\xdbH\x8c\xcf\x1c}\x96\xb0i\x0f\x019\x87VY\x1b\xda]\x96J\xaeܒ\x96\xefm\x01\xd0.^\x9eUJ\xf78u\xb5\x10\xe2(\x8a\x1e\xbd{\xb4V\ue5d3}\xf9\xa9\xa2\xa1*x\x06y\xd8e\xa3$\x00n\xe1Ad\xac\x04\xfd\x00\xacB\xbb\x91.T\v4\xb9+gHa\xbak\x11\x8a7\v#{\xdace\x85\xb3>\xb1f`sR\xf5Ȏ\xfft\xf5\xb4Q\x92y'\x7f(\x89\xfa\xdd\x14\xb5e\x96e!\xbfN}\x10\x87\xa4s?JN\x1bO\x7fE\xf3J\xe2\xfd\xb74kȅ6k\xf6\x81\x12\xf4\n\xe8\xb6\x0f\xab\x84\x9d\xae\x92@\"&\xc20\x94\x93\x03/\xd0}@\xe5-\x19\x14ΙP\xbb\x13\x0f*M\xc5<\xed\x95q6\xbf\xd9\x18\xbb|\x84\xa3ߜ\xedj\x89ˍ\x8c\xae\xda\xf7\v\xea\xfc\x13\xa5\xd5x-J\x16GvI\xbf]\x92c\xb6d\x8a\x9c\xe1\xbc-\x90\xea\x05U\xbf\xaf\x1e\xeb-h\t\x16̪\xe4\xd5\xca\xcf\x06\xab\xca\xe8\x1e\xa7+\x94F\xb7$\x8c\xc08=x<ظI6C\xf7\x7f\x8e\x02\xc9\xf3\xa1R&\x92i\x11A\xebV\x19\xeb\x16\x0f{\xae\xfa\xc8\xeabJ\xe4\xe8W\x1c\x19\xdfY\xd0\xccX\xa5Cb\x17\xaa\xec\xc1\xe2:J\x8d\x99\x97\x1b\xb7O\xe4W2\x1d`\fP/[\xed\xe2\xec\xc1\xa5۫\xc2\xff\xcf\xc3\xcc\xc8\xd1\"ؕV\x19\x98h6B[\x12\xad\xce\xccbo\xb3\xd0\xcb]\xe0\xb7KR\xeb)\xcbС,s㑴g\x04E\x9f\xbew֬Q\x85\xe1\xdf)\xa2|\x0e\x8e\x8cr\xbb˒\x0f\x93\f\x93ѽq\xad\xc3\x04\xf4\xc0\\\xb0\xa5\x1fjRH\xcb|n/\x92\xbf7\xa7\xa5\x14rC\x1d\xb1\xf7\xaf\xe6\xe8\xb0`\x06b\x19Ice\xc0\x0e߾eH\xf3!5\xf6e!UM\xd1>\x8f\x86\x1egOwA\xd29\xc5\xd0\x11\x97\xcav\x17z|O?\x18\xb6\x13\xda\xd8\x16\xe1\x05P\x85\x99\xc8z\x1a\x1d\xde\x19\xf1\xa9\xfc\xa4\xf5\xd9\xe1\xe9\x17\u05fa\xb3$\xb9WO>\xc1sIP\x1e\x88\xbf\xe7\a`bDŽe 3UKZ,Cu\x81\xdd,\x80\xe8\x98\xe8\x8cI\xa2\xcd\xec4\x96u\x99N\x90\x15I\xa7\x90\xb3+k\xdd&?q\x91\xb6\xb2\xc5\xcec\xab\x9dJ\xa2\x1c+\xfd\xccP\x9fM\xd9\xcd\xe4-\xf9wQ\xd6%\xe3%\xb2eI̹sy\x98!\xed\xd7\xf1\xfa\x89\v\xebOS\xb8M\xd9e\xda4SeU\x80\x85\x90a\x99)iD\x0e\x8d\xfb\xe0\xf9?\x9a\xaf\x1a+\x9c\xed\xb8(j\xbd@G/\xe6\xccҘϫ\xa7\x97\x0f\xe4\xd2\x11Y\x111\x13\x17\xec\x178\xdc\xf3\xf6\xa3\xd2\xcb\\\xe6[\r/\xef\x9aVZ(ʁ\x9d\xf1Nga\x92\xf7\xda\xf7N\xbd\xf0ry\x8c\xb9\xa7\xb3P\t\x937\xf7\xb4)o\xee\xe9\x9b{\xfa\xe6\x9e\x0eʛ{\xfa枾\xb9\xa7\xe3\xe5\xcd=\xed\x947\xf74\xd9~\xa4`\xb8\xa2\x95ۉ\nIX%\xa6o̡=ӗ\xcfR\xf2gA\x96dWo\xc6[\x8e\x9c\x05Zt\x86\xc4t\x8c^\x93n\x8dS2L&w\xa64\xc1\v\x7f\x81\xb36\x01\x81\xb3\xcf\xdal&\x01\xbc\xe0Y\x1b\x8f\xe9p\xed\xfc\x05O\xda\x04Z,?\x84q\xe5ӘJ\xe0aK\xc8\xe5\xa0\xe4\xb1nc^l\x0f\x8f\xd1:\xbfq\xd6\xfdI\xb6\xe6\xf9\"\xf3\xffr~'\"6'\xa7S#P\x85A\xb9\xfacp\xe2,\xdaG\xa9\xed\xfe\x17\x1b]KX\xa7x\xdd5\x03\xddT\xcb~\xca\xeb\x1fG\xb0ϑ\xe4\xd4\xf371\xe7<\xae\xdb:\xc4Խ\xf3\x1e\xbfoZZ(\xbfTޒ\xa5\x9f{ߌ4{\xc6\xc9wn\x8e2\xdbk%Um\xfc\n\x0f\xf6\xf0!sW\x01\x84\x8e\xcc\x12e\xf0\x9e\xedU\x1d9\xe31Cׄ\xcc\xdbx\xbe\xad\xcf\xe0\x00\xcb\x0f\xef\xd7\xfd_\xac\xf2ٷ\x11\xac\x9f\x84ݻ\xfb\x18x\x9e\xa3\xa3\xde9\xe2\x13&\xaf\xbf\x93e(x\x11\x88J3)\n'\x95\x01B߀~\xa9ܒ\xdf\xd9~\xcb\xfc\xc2Sz\x8e\xee\xd2\xcc\xdc&\x97r\xdeK~F>\xee\xb2\xc3R\xb3\xb9\xb7)H\xb3\x94\x8c\xdb\xf1\\\xda\x19\xa8K\xf2lS\xd7\x14\x13rj\xd33i\xd3\xc8\xc3\xe8&\xa5\xd4\xfc\xd9\xe4(45W\xf6u2d\x13\xf3b;ٮ\xb3 \xcf̆M&XZ\xe6kr\xbek'\x8bu\x9eZ\x13Y\xae㹫\xb3 \xc7r[S2V\x93pM\xceSm\xb2O\xe7wF\x9e\x95\x9d\xfa\xf2\xe7`^r\xddb:\xd74)\xc34imc\x1e\xe7\xa4\x1cҥ\x99\xa3IT]\x9a%\xdad\x80Nt\x9c\x94\x1bz\x9a\xf795\x94ٌ\xd0x\xb6\xe7\x14ر<Є\x1c\xcf\t\x90\xdd\xec\xcf\xc5n\xc0\xac4\xcdVX\x9a\xbb9~?Z(\xf3ֹ\xf8-d\xf6\xb9dR\xba\xe74\xa7\x04w_\x06MPZ\x82\x9f8\xe6\x88\xc7Ce瞟\xe1\x88G@nv\xac\xac\v+\xaa\xa2sA\x99\xddñ\xb9\xf2\xe7WE\a\u05f7G\x82\xf6\xe5k#\xf21\x90\xfd\x90\x82\x1b\xf6\x04E\x81\xff\x9eP!s\xd7\x01fj\x05h\xa5\xe2\x1b\x81\xfe\xaa#\x7f\x97\xe0\x95[\x16\xa3S\xfdd\x01K\x844}\x01֤)\x99v\x8f\x9dWO\xdf\xfeR\x83>2\xbas+\xf8AQ1kO{\xfa\xc9l0&\f\xca\xc7k1w)e_\x19\xc5gC\xa3\x02\xd8\a\xe9\f\xf3\x10W\x82\x85Z\xa7\r\xa7\xa6\x94-FO1\x10R5\x10\"\xedS\xbc\xef%\xc7\x1f_#\xb8z\x89\xf0*\xc9\x11y\x8d\x10뵂\xac\xa5a֒䍤㋯\x11l-\t\xb7\x16\xf9\x8c\xe9\xc7\x13_\xebX\xe2+\x84]g\a^\x8bH\x97z\xecpq\xf8\x950\xbe\x99c\x86'>Z\x02\xc8\xe8\xf1\xc2\xf1\x10,\x01\xe2ɱ\xc2\xd9 ,e\x1e\fôg\x1f\x12LNdZ\xb4\x9b\x9e\x9a\x84\x94\xb6\xd1=\x7f\xf8/\xf1\xd0_\xe26x\n\xf6\x89\x87\xfb\x96\x1f\xeaK\xa4\xf3\x99\xe1\xd9d\u05c9\x87\xf7\x16\x05hg\x86h\x93\x10\xa7\x0e\xebM\ai\xd3\vp\xc3Czg\xb8\x13\t\x12\x96Pe\xf9A\xbbgo\xc6(\x9d\x83\x9e\xdd\xd7Z\"γ\x82<\x88\xa3\xfa\xfd\x0fvt\u008d\xa8X\xab\xbbg\x16\xe3\xa8j\xee\x1d\xc9؟\x84\xf4\xbb\xf5(\xb8\x1d\x9f\xa4\xb7\xf1\xd6:L\xf1}\x9d\xd6K\xf5\x17\xab\xbb\x1d;\x03\x15״\x8f\xbf=\xba\xa4 \xb3f\x9fx\xb6oz\x88\x80\xa4~\xf7ܰ\x9d\xd2%\xb7\xec\xb2\xd9\n}\xe7:\xc0\xbf/\u05cc\xfd\xa4\x9a\xf4\x91νb\x11\xa8F\x94UqĈ\x89]v\xc1ti^\xd6ɂ\x88\xc5(\xd8\\\xf8\v\v\a\x97\n\xefTQ\xa8\xa73\x97.x%\xfe\x8b\xde1I[\x1b\xfbp\xbb\xa1\xeaA\xaa\xe8\r\x94&{\xae\x91\xb1-L+\xf4v\xe0\xe4zt\xa1\x8ed\xaf6\x7fN@\xa4W\x04\x82\x9f\xe1\xd5x\xa6P\x8b\xddn\x1c\x96k\x12,.\x8fL\xf9{\xe2\x85\xceW\x15\xd7\xd1M=\xe6\xe5\xc1\\\xf50\fv|n\x05kҬ\x9d\xbe\x8a\xd0-=\x9a\x87\a\x12h\xb3\xf7X\xf5\xb7щ\xd2\x1dz>\a\xa7\xe9\x83˳G\x96_\x01\xa7i\x97iET\x8c\xfc\x14M\xc7{\xf1\xd5C\xe3/\x91\xffE\x1d\xe0ct\x15\xb1\xffd\xc0\xa0\xc9H\x02]\x80:umz\x9b5\x17\xbf\xce\xfa\x052\xe2\x02*\xfe\xe2\xeb\x05\xe3\xf3-\xc6^i\xf0\xf7\x7f\a\xd8\x13\xb6\r\xa7\xec\xed7\n7\x1bu\xe9g\xb8\x0f&\xc3R\xe1\xe0\xaa\xd6\b\xc8\xd83\v/E-\xab4\x7f\x80\x9f\x95{\t#\x85Z\xfd\x16\xbd\xc7P\xbc3\x17\xb2\x89\xfd\\\x8b)s?\xb6!\xc0\xf6\x90\xc1\xc9u\xf4\x88홷\xed[[$\f\xee\xfe\xfeg7 +JX\x7f\xac]\x86\t\xea]\x03H\xe90P\xd7h\x1b\xd7N{\xf5D\xf7\xb9w\x9f\xab\xe8<\b\x04t\xa8\x81\xd2F\xcf\x1aM]\x15\x8a\xe7\xa0o\x94܉\x87\x84\x81\xfd\xb9\xd7``\xd93\xfa\xe8\a\x1b\xeccd`\xa1\xe7so\xc9E\x7f\xac(\xa0\xf8I\x14`\x1cV\x89Z\xfc\xf6\xb4e\xa3\xd4\xebr\xeb\xbc\xcf\x1d\xfe\xd8t2a*\xdd8h\xc1\xbe\x02\x8d^\x9e[گM\x90\xde鑲\x86IBZx\x88d\xef̨\xefC\xef]\x8f0\x03Rtַ\xf1\x96\x1dW\xb83\x17\xa72\x01\xd5.\n\x8b\x1b\xa32A\xde3m}Б\x90\u05fbPz*\n\x9a\xa0cm\xe0˓\x04\xfd5\xe8[\xb3\x91\xb1\x874\xfaS\xe2\xa4a\xf4\x11\r\xab\xc8g\x1fT\x1f\x8bդ'\x90qO\xb0\x84=\x1ca\x9a\x87wNI7\xa3\xc6\xe3*|\xdc\xe1X\x8d\xbfu\xb3j\x9e߹H\xa0\xac{b\xa6\x0fx\xfce%\xf7\x16M\xc6+[\xeb\xa0OjM\xb7k#\x10p\x97O\x9f\xf7\xb6R\xfbV\xdd\f/\xdb\xd7\xeb\xdaU\xedٷ\xf2F\xf8\u05fc\x8e\x14}.\xc8Ń\xee-\xbb\x15\xc2?\x8f\x9d\xa3\xf3\x80n#\x9f\x19\xe9-\xd6i\x8e\xf3yBS\xc3p\x8b\xf9]\f\xf5\xf1\xf3Y+\xf6\x19N\xe3\xb1\x15\xfb$q\x10\xa7n\x9a;\x84\x059\xad\x85\x8f\xbd+79\xc4CӊN\xc0\x8dh\x8b\xbe\x9a\x1bT\x1f\xe4\xe7ҫ4M\x15w\xdam\x8c\xad\xff,vn\xa3\"\xc31\xfd\xcbI\x8d\xa8\xe2\x9aTZ1\x855:\xa5N>\x1a\xd0\az\x06&\b\x89wź_\xeam{\xa9<\xfb\xeb\xdf.\xfe/\x00\x00\xff\xffs@N\x8d|t\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs\x1b7\xf2\xbf\xebSt9\a\xfdSe\x0ec\xff\xb7\xb6\xb6x\xb3\xe5͖v\x13Yeʾ\xa4r\x00\a=3\x88f\x00\x04\xc0P\xe2\xa6\xf2ݷ\x1a\x0fr\x1e )\xa9\xd6\u07b9H\x04\x1a\x8d\x1f\x1a\xfd\xc6b\xb1\xb8`Z|Ac\x85\x92+`Z\xe0\xa3CI\xbflq\xff7[\b\xb5ܾ\xb9\xb8\x17\x92\xafષNu\x9fЪޔ\xf8\x01+!\x85\x13J^t\xe8\x18g\x8e\xad.\x00\x98\x94\xca1\x1a\xb6\xf4\x13\xa0T\xd2\x19նh\x165\xca\xe2\xbe\xdf\xe0\xa6\x17-G㙧\xad\xb7?\x14o\xde\x16?\\\x00H\xd6\xe1\n\xb4\xe2[\xd5\xf6\x1dnXy\xdfk[l\xb1E\xa3\n\xa1.\xacƒx\xd7F\xf5z\x05\x87\x89\xb06\xee\x1b0\xdf*\xfeųy\xef\xd9\xf8\x99VX\xf7\xaf\xdc\xecO\xc2:O\xa1\xdbްv\x0e\xc2OZ!\xeb\xbeef6}\x01`K\xa5q\x057\x04C\xb3\x12\xf9\x05@<\xa2\x87\xb5\x00ƹ\x17\x1ako\x8d\x90\x0e\xcd\x15qH\xc2Z\x00G[\x1a\xa1\x9d\x17ʭ\xe2\x10\x00B@\b\xd61\xd7[\xb0}\xd9\x00\xb3p\x83\x0f\xcbkykTm\xd0\x06x\x00\xbfY%o\x99kVP\x04\xf2B7\xccb\x9c\r\xe2]\xfb\x898\xe4v\x04\xda:#d\x9d\x83q':\x84\x87\x06%\xb8FX\b\xa7\x85\af\t\x8eq\xfe\x94\xf9\x8d\xfd<-\xb7\x8euz\x84\xe0\xca ;,\r\x108s\x98\x03\xb0\x97'\xa8\n\\\x83$y\xafXLH!k?\x14n\x02\x9c\x82\rz\x88ȡ\xd7\x19d\x1a\xcbB+^\xc8\xc4t\x04\xebf2zN6D\xff\xdfF5\x02t\xab\xf8\v\xa0\x98\x9d\xb8\x01\ng ,\xb0\xb84\x9c\xe2 \xe8\xe4\x8e>\xfd}}\aik\x7f\x19S\xe9{\xb9\x1f\x16\xda\xc3\x15\x90\xc0\x84\xacȬ\xe9\x12+\xa3:\xcf\x13%\xd7JH\xe7\x7f\x94\xad@9\x15\xbf\xed7\x9dpt\xef\xbf\xf7h\x1d\xddU\x01W>S \xf7\xd4k\xd2\\^\xc0\xb5\x84+\xd6a{\xc5,~\xf5\v I\xdb\x05\t\xf6iW0Lr\xa6\xc4Aj\x83\x89\x94\xa2\x1c\xb9\xafIޱ\xd6X\xd2\xed\x91\x00i\xa5\xa8D\xf4P\x952\xc0\xa6\xe4ňq\xdep\xe9\xcbz\xa7)\xd1\x04\xd9\xfbܚ\x84M\x0e|jr\x98\x81r\xc6\x14\xa0\x9dz\xd9\xfd\x1a\x83ZY\xe1\x94\xd9\x11\xe3\xe0`\x8b\x19\x87#\xd7@\x9fT\x1cϜ\xe3Fq\xcc\xc1\xa6\xa5\xe0\x1a\x16\xb4\x95\xf2+\xf2G\xbd\x94\xf3]\xe8S\xf2Y\xc0\xb4\xe2gp\xc5\x1d\x19\x18\xacР,19\xaeS\xc9C\x06\xd90\xac\xcf1\x1eW\n8\xe1ճ\x88\xdf\xdd^'O\x9e\x84\x18\xb1\xbb\xf9\xbeg\xe4C_%\xb0\xe5>Н\xdf\xfb\xf2\xba\n\x9by\x9f\xe6\x140\xd0\x02C\x1a\xb8\x0f\x12 \xa4u\xc88\xa8*ˑj\x12 \xc37\x18W\xbc\x0e\x1e,\xba\xcaCh!\xd9\x03#\xdf)8\xfcs\xfd\xf1f\xf9\x8f\x9c\xe8\xf7\xa7\x00V\x96h}\x16\xec\xb0C\xe9^\xef\x13s\x8eV\x18\xe4\x94fc\xd11)*\xb4\xae\x88{\xa0\xb1\xbf\xbc\xfd5/=\x80\x1f\x95\x01|d\x9dn\xf15\x88 \xf1\xbd[NJ#l\x10Ǟ#<\b\u05c8i0\xddK\x80\xd4+\x1e\xfb\xc1\x1fױ{\x04\x15\x8f\xdb#\xb4\xe2\x1eW\xf0ʧ5\a\x98\x7f\x90\xed\xfc\xf9\xea\b\xd7\xff\v\xa6\xfd\x8a\x88^\x05p\xfb8<4\xba\x03\xc8`yF\xd45\x1e\xb2\xaa\xe9\xe7\x83\n\xb9\xea\xefA\x19\x92\x80T\x03\x16\x9e1\xdd^p\x94\xc8g\xa0\x7fy\xfb\xebQ\xc4cy\x81\x90\x1c\x1f\xe1-\x88X\xdahſ/\xe0\xcek\xc7N:\xf6H;\x95\x8d\xb2xL\xb2J\xb6\xbb\x90\xe7n\x11\xac\xa2B\t\xdbv\x11\xf2 \x0e\x0flGRH\x17G\xfa\xc6@3\xe3Njk\xca~\xee>~\xf8\xb8\n\xc8H\xa1j\xef\x89)jV\x82\xb2\x19JcB,\xf6\xda8\v\xe6\xe9\xb3}P\x1f\xa7\xa0l\x98\xac1\x9c\x17\xa1\xea):\x16\x97/\xb1\xe3yJ\x92\xbeLj2u\x1c\xff\xb3\xe0\xfe\xc4\xc3\xf9\f\xfa\t\x87\x1bV\x19'\x0fw\xdfo\xd0Ht\xe8\xcf\xc7Ui\xe9h%jg\x97j\x8bf+\xf0a\xf9\xa0̽\x90\xf5\x82Ts\x11t\xc0.}\x99\xba\xfc\xce\xffy\xf1Y|E\xfb\xd4\x03\x8d*\xed\xafy*\xda\xc7._t\xa8\x94\xc3>=\x8e]\xaecf5]Kf\xf1Ј\xb2I\xc5I\xf4\xb1G\x8cIP&̃kfr\xf7\xd5U\x99\x04\xda\x1bB\xb4[\xc4^ڂIN\xff[a\x1d\x8d\xbfH\x82\xbdx\x92\xf9~\xbe\xfe\xf0m\x14\xbc\x17/\xb2\xd5#\tx\xf8\x1e\x17\aX\x8b\x8e\xe9E\xa0fNu\xa2\x9cPSVz\xcdI\xf0\x95@s&\x8d\xfb4\"N\x89f&\xbf\xdd\xd3<+\x8ft\xac\xce$n\xc3\xd6\xe1\xa9\xf4\ue93cƍ\x1bV[`\x06\x81A\xc74\xdd\xf3=\xee\x16!!\xd0LP4\xa7\x80\xbd\xef\x8a\x00Ӻ\x15\xd9\xc0\x1d\xc3~LY\xa3$\xa8,g\xb5=v\xf6쭥.\xd0\x1a\x1d\x95\xad\xdfD\x0e\x9f'{>Y&\xf9\xc4z$\x8a\xaa\x90\xbb\xaa\xbdoy\x96\xa9\x8e\x9f\xb4\xcfA\x1d\x11\x9f\x89B\xf11=\x17\x83֨\x99!K\xf7\xaf.W\xd3g\xc1\xd7`\x85o%Sf\x1aR\xd5\xd0\xe8\xb1\x14\x9c(\xb5R\x063.\x13\xe6ae\x14D\xc6\xf0\xbfe\xfc\xc8\xea\xc9l\xd0#\xe7\x03\xde\xf19b8\xd2o\xf6Om+\xf8\xe3ϋ\xff\x04\x00\x00\xff\xff{ŋW\xf4\"\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs#\xb7\x11\xbe\xf3Wt\xad\x0f\x8a\xabv\x86\xdeM*\x95\xe2mW\x8aSJl\xadj\xa9\u074b\xcb\apМ\x819\x03\xc0x\x90b\\\xfe\xef\xa9\x06\x06\xe4\xbcHJ\xaaȞˮ\x80F\xe3Ç~\xa1\x99eٌi\xf1\x15\x8d\x15J.\x80i\x81\x8f\x0e%\xfde\xf3\xcd?l.\xd4|\xfbn\xb6\x11\x92/\xe0\xda[\xa7\x9a\xcfh\x957\x05\xde\xe0ZHᄒ\xb3\x06\x1d\xe3̱\xc5\f\x80I\xa9\x1c\xa3aK\x7f\x02\x14J:\xa3\xea\x1aMV\xa2\xcc7~\x85+/j\x8e&(O[o\xbf\xcb߽Ͽ\x9b\x01H\xd6\xe0\x02\xb4\xe2[U\xfb\x06\rZ\xa7\f\xda|\x8b5\x1a\x95\v5\xb3\x1a\vR^\x1a\xe5\xf5\x02\x8e\x13qq\xbbq\x04}\xaf\xf8נ\xe7s\xd4\x13\xa6ja\xdd\x7f&\xa7\x7f\x10\xd6\x05\x11]{\xc3\xea\t\x1ca\xd6\nY\xfa\x9a\x99\xf1\xfc\f\xc0\x16J\xe3\x02\xee\b\x8af\x05\xf2\x19@{\xce\x00-\x03\xc6y`\x8e\xd5\xf7FH\x87\xe6\x9aT$\xc62\xe0h\v#\xb4\v\xcc\x1c\xf4\x80Z\x83\xab\x90\xb6\f\xac2!\x85,\xc3P\x84\x00N\xc1\n\xa1E\u00832\x80_\xac\x92\xf7\xccU\vȉ\xb8\\+\x9eˤ\xb3\x95\x89\x9c\xdf\rFݞ\xcea\x9d\x11\xb2<\x85\xec\xff\f\xaa\x87\xe7^\xf1'\"y\xa80\xc8$4^\u05caq4\xb4y\xc5$\xaf\x11\xc8@\xc1\x19&\xed\x1a\xcd\t\x14i\xd9\xc3^\xf7\x91|I\xfa:3\xcfa\xe79TD\xd9\xde\xf6_\xbbC\x97\xf6\xbdW\xbc]\x00\xadQ\x83u\xccy\v\xd6\x17\x150\vw\xb8\x9b\xdf\xca{\xa3J\x83\xd6N\xc0\b\u2e6e\x98\xed\xe3X\x86\x89\xd7űV\xa6an\x01B\xba\xbf\xff\xed4\xb6vQ\xee\x94c\xf5ǽC\xdbC\xfa0\x1c\x8eh\xc9\xd9\xca\xf6\xfa\xff\x14\xb8+\x82t\xa3d\x9f\u05cf\x83\xd1)\xb0\x1d\xa5)\xde\xe6\x85\xc1\x10j\x1fD\x83ֱF\xf7\xb4~(\xfb\xfa8sq No\xdf\xc5PVTذE+\xa94\xca\x0f\xf7\xb7_\xff\xba\xec\r\x03h\xa34\x1a'Rt\x8d_'ytF\xa1\xcf\xec\x15)\x8cR\xc0)k\xa0\x8dN\x11ǐ\xb7\x18\xa2\xb3\b\v\x06\xb5A\x8b2摞b !&A\xad~\xc1\xc2\xe5\xb0DCj\xc0V\xca\xd7!\x02m\xd180X\xa8R\x8a\xff\x1et[\xf2=ڴf\x0e\xdb\x10\x7f\xfcB\f\x96\xac\x86-\xab=\xbe\x05&94l\x0f\x06i\x17\xf0\xb2\xa3/\x88\xd8\x1c~$\v\x11r\xad\x16P9\xa7\xedb>/\x85KI\xb3PM\xe3\xa5p\xfby\xc8\x7fb\xe5\x9d2v\xceq\x8b\xf5܊2c\xa6\xa8\x84\xc3\xc2y\x83s\xa6E\x16\xa0ː8\xf3\x86\x7fc\xda4k\xafzXGN\x17\xbf\x90\xeb\xce\xdc\x00%;\x10\x16X\xbb4\x9e\xe2Ht\nٟ\xff\xb9|\x80\xb4u\xb8\x8c!\xfb\x81\xf7\xe3B{\xbc\x02\"L\xc85\x05]\xbaĵQMЉ\x92k%\xa4\v\x7f\x14\xb5@9\xa4\xdf\xfaU#\x1c\xdd\xfb\xaf\x1e\xad\xa3\xbb\xca\xe1:T\x12\x14/\xbd&\xcb\xe59\xdcJ\xb8f\r\xd6\xd7\xcc\xe2\xab_\x001m3\"\xf6iW\xd0-\x82\x86\u0091\xb5\xceD\xaa`N\xdcװ*Yj,\xe8\xfa\x88AZ*֢\b\xbeA\xe1\a\xd8H>艹v]\xfaV\xac\xd8x\xbdtʰ\x12\x7fPQ\xe7Ph\x80\xed\xe3Ԛ\x04Nvr^T\x0e6J\x8e\x94\x02\xd4i\xf1\xaeB\x83\xdd5\x06\xb5\xb2\xc2)\xb3'\xc51[\xe6#\r'.\"\x1cY\xf1\vǠp\x1f\x1c\xc2\xe0\x1a\r\xca\x02S\x848W\xc9L\x9c\xa2\x93\xd0\xc7\x10OS\x0fg\xa2\xe7$\xe0\x0f\xf7\xb7)b&\x86[\xe8n\xbc\xef\x05z\xe8[\v\xacyH(\x97\xf7\xbe\xba]\xc7\xcdB\xecp\n\x18h\x81\xb1\"=\x04c\x10\xd2:d\x1c\xd4zR#\xbd\r\x80\x1c\xcc`\xbb\xe2m\x8c\x14mH:\x86p\xa2\x1e\x18\xc5(\xc1\xe1\xdf\xcbOw\xf3\x7fM1\x7f8\x05\xb0\xa2@kC\xbe\xc6\x06\xa5{{\xc8\xd9\x1c\xad0ȩp\xc1\xbcaR\xacѺ\xbc\xdd\x03\x8d\xfd\xe9\xfd\xcf\xd3\xec\x01|\xaf\f\xe0#kt\x8doAD\xc6\x0f\xe1/ٌ\xb0\x91\x8e\x83F\xd8\tW\x89a\xd2:0@\xd6\xd5\x1e{\x17\x8e\xeb\xd8\x06A\xb5\xc7\xf5\b\xb5\xd8\xe0\x02ބJ\xf0\b\xf37r\xac\xdfߜ\xd0\xfa\x97\xe8@oH\xe8M\x04w\xc8w]\x8f<\x82t\x15s\xe0\x8c(K<\x16\xa2\xc3/\x04o\n\x89߂2ĀT\x1d\x15A1\xdd^\x8cG\xc8G\xa0\x7fz\xff\xf3I\xc4}\xbe@H\x8e\x8f\xf0\x1e\x84\x8c\xdchſ\xcd\xe1!X\xc7^:\xf6H;\x15\x95\xb2x\x8aY%\xeb}\xac\xf6\xb7\bV5\b;\xac\xeb,\xd6\x1b\x1cvlO,\xa4\x8b#{c\xa0\x99qg\xad5U\x19\x0f\x9fn>-\"22\xa82\xc4;\xcaNkAU\x03\x95\v1\xe7\x05k\x1c%\xcd\xf4Y\x1f\xcd\xc7)(*&K\x8c\xe7EX{\xcaB\xf9\xd5K\xfcx\x9c\xfa\xd37Q\x02\f\x03ǟ\x96D\x9fx\xb8P\xa9>\xe1pݷ\xd6\xd9\xc3m\xfc\n\x8dD\x87\xe1|\\\x15\x96\x8eV\xa0vv\xae\xb6h\xb6\x02w\xf3\x9d2\x1b!ˌL3\x8b6`\xe7\xe1\xc9<\xff&\xfc\xf3Ⳅ\xd7\xf5S\x0f\xd4{\xf4\xbf\xe6\xa9h\x1f;\x7fѡR\xad\xf8\xf4\x8bE\x96f\x82*$*\x82b\xd59]\xd73\xadk*l\xdaR\xea\xd0T,\x94\\\x8bқ\xf0z\x19\x93\"}]\xb3U\x8d\vpƏ\xe9<\xe3)\xdd\xfe\xe3\x85\xcb\xfd\xd2\x11M7{\xa1\x03ꪩ\xbb\xed\xf5ELJA\xe9\x9b1\x94\f6J\v61Nv=\xf2i\x9ax3\xae\x05\xcf\\lt\x9a\v\x1c\xb4\xed\xba\x89\xb7g\xebs\xb1\x16\x0f#\xf4\xde\v\x9e7\x9dĞ\xeb\x8b\x06\x7f\xf5\xf4\xb0\xe8#̦_\xd4\x03\x19\xad\xf8lHZ7\x8c\r&\x8fAh8\xd1\xf7\xef\xc1l\xaf\x8d\xdc=\u0378\x19\x11z\x94\xcfiGľh\xcb{̊.uK\xe9I\xf8\xe2\x86D\xa1\xe8\xb9\xd5ki^\xb0\x81\xeb\xf1\x8a\xd0\xfd3\xbc\xf5\t\xd1`x\xe5ǖ\xee\x8eٴ\xc9\xd4}CG_\\\x1a*\x11R\x87<<\x86譶f\xa2F\x0e\x87_\xa6\xc2\xcf\x0f6\xb4\xc1\xae\xa6j\xff\xa4\xc8[\xe4!\xd6N\x80\x1e\xafK\x9de\xce\x1cf\xa4\xe2e\x81fҽ\x1a\xb4\x96\x95\x97\xfc\xeb\xc7(\x15\xfb$\xed\x12`+\xe5ݡQ\xd2:ZKŕm\xad\xe0y͚\x8a\xd9KP\xeeIf\xca\xe2\x0e.\x7f\xde\xe4\xe0L(\xbb\xc3\xdd\xc4\xe8\xa8\xd3ߝ\xbcN&41\xf7}\xb0\x8eg\x11\xd0nt\x89\x83V\f*U'\xebV\x8e\x12\xb9oVh\x88\x88\xf0\xf3Bb$\x05\x8e\xa9\xceSx\xb1\x1e\x99\x93\vx\xdc\x10J\x9e\xe0\xe4,\x16*\x88%\x0e5h\xef&\xbd\xa7s\xe4`\xe4\x05\x99\xec\tN\bƇRfG粂kO\x900\xf7S\xad\x87@\xbb&\xef\xe0:L\xda\x0f\x88\bt\xbc\xf3\x91G0,\x16d\xd1\xfc\xe6H\xbe \t-\xe0\xfe\x82mF\xb2u\u0087H\xd8wڑȞ\x82\x03\xab37\x8a\xd1C\rxZB`\xec;嬌\x139\xbe߈qk\xb8߾H\xb3\x117\xce#\xd3\xc8%?I\xd0_\xa4\xc1/WA\xa7[\xf8\x05\xc8t\x03\xf1x\t'\xb6-\x1e\xba\x11\xb6\f\xe6vm\xe3\x02)\x910֝\xc6\xce\xc04\xb1\xf4=R~\x1e\bOlNZ\xd9\x02\xdc)r\xb9;\xb3Xn\xc8\xf3Aj\xa7Sw\fx*d\xd3oL\x93\xb7Opz{s&\a\xden\xc4[\xa7\xe0\x17\x8b\x9bh-H\xc1O\xe4-\x8e}\xfb\x12#(\x93\x133\xbb\xfdX=Őܪ\xa2\xf5\xcas\xaf\x91\x15+Fljdx\xbcm=v\xea\x86\xc8\xdbظ7\x8f\xa7v\x9bſ\xb5\xd4\xe6\xe7t\xa0od=\xf7aDߦM\xc4\xcbfm}\x1f\xfb\x8a\xc2\xd8Z\x80;\x03\xca\a\xff\x9c\x80\x0e\x9e\xc3\v}\xaa\xb9\xe0^\f\xec\xd1\x18\x90\xb5\b\x9e\xe1&\x97*\xc9Y\xe2\x12k\xd3\xe2e\xa1\x9d\xfe\xe9G'6iO\xb6\xfd\xbb\xbb\x91\u05f6\x86\vYUt\x98\x1c\xccZ\xeaG72\xf0\xb4\a䨯\xf6\r\x9e\xe7|31\xf0\x10\xa6\x05\x9f\x9990Ah\x10\x1b\xa0\x82\xb2Qp\xa0G lG\x98! \nK\x17PNd\xe3\x14\x1e\x19\x88\x9al\xb6\xcc\x13\xf0\xb6\x81h\xaa<\x04\xac\xf0d31\x19L\xebv\xffL\x19\xbf\x06\xd9,\xe7}\x96\xea\x01hyI\x00\xe6\xd7\xcep\x02B7\n\x13\xf7N\xbc<3\x9e\xb7fK9\xc2i#\x8a\x03\xa0\x9c\x12=\xf1A\x1cx&\xb4\x01\x9a\xcb\v\xd6jj\x84`b\x9fG\xbb\xec\x10g\xdb\x1c\xaa\xb7Rr\xa0Â\xa7T\xb3\xb8\xbe\\\f\xfdڎ\xfe]\xc4P\xa4@\xbe\xb9\xb0\x05O*/\x8b\xa81P\xd5\xee\xbcI\xa2\x1a\xd1\xd5>W\x90BK|p\xbf\x8a\xd7t\xae\x99`\x19\x84\x1d\xe4\\\x98\xe9Z\x96\x16\xc4U-K;A4*.\t\x9fmz\x00\xec\xe9\fN\n\xae=r\xcd\x02+s\v\x84\x96%\x94.0iM\x15ﳸ\xf2\xb2\x91R\x85\xe4\ue59b\x89Y\x94\r\xad\xe7\x91b(V\x1daՈ'!\x9f\xc5\n=y\xbdX\x80\xe4\x87\x06_uzs\xb1$\xfa=\xa5P\x9f_\xf3y*\x18OW\x902\xd9|\xb3(\x1a2\xc5\x05sr͕.\x8f\xfc8\xbb\x8a\xa9\xf9'\x06\xfbD\xf3GWs\x9c[϶I\x8f\xea\x18\x7f\xcf\a0\aP\xa1\x98y\x85u\xdb)9\xdd\xe6\xa3[?&\x16\xb8Y\xfe\t\xa6\xb0+\xbc\x1c\x94\xbc\xa5\x1d\x1dk\x05\xdcXƦ\r7\xae\xfcX5\t&\xca*\xfcJ[\x069\x95\x13s\xf5\x12\xfd\x1a\xc0X\xaf\x10\x8a\x00e\x98$\xb1CGKW\xe9\xdbM\xc6\xf7\v\x1f0\xe4\x17V\xfa7/\x0f̨i\x98\xa9d\x98.\x9a\x9c\xc2\xd79\xdbt1\xd6\xf2\xa0\xef\xe7\xabi\xffX\xe83P}\xad\xfd9\x185@\xfb\x18L\f\x19\x94\x83\xa0\xe4\xb6.;\x16\x16P\x96\x12.\xf6\x14\xfap\xa0\x85xW\xe0I\x94\x01\xb0\xc6P\xb3?m\xbe\xba\x9di\xf2\x81\x1cd\x93(\xa9\x9b\xc0\xceL\x81\xc5xY\x85O\"\x80\xa1\xc7\x0f\xeb\xfe/F\xfa\"\v\x8c|%v\x87\x8eJ\x1bMe\xa2dGV6\x94\xf7\x0eY\x87-Z\xee!R\x11\xc1x*\xbfj\xd9*\x8c\xef\xb1\x11\xf9Z\xbb<\xcbbq4m\"\xe6\xd5b\\\\\x81ѯ\xb0\x18QRKS\x0e\xf9\xa5\xa6\xf95\x16\xd3E\x11K*+\x86u\x13\xa3@\xe7\xeb)r\xac\xfb\x99ډ\v*&2\xab\xe5^\x9c ɩ\x89\xb8\xa8\x12b\xb6\xa0,\xb3\xfe\xa1_\xd90\rrA\xd5C\x16r\xe6+\x1c\x16\xd75\xf8:\x82\xc9}dW3$\xea\x14&\x01\x8f\xd60LU'L\xa3\xd42/*\x1bM9\xb5\xe2W\xf1\xa5\xae\xe8M]ß\xbạ\x9a\x019\xa8\x01ϩ\xee\xceJ\xe3e\xe7lr\xb2l\xf3\x99\xe3\xe9\xaa\xed\x8cj\xed\x8cl\xd0\xdcJ3\xaa\xb2\x97Ucg\xe0\xf0J\xbe֕\xbc\xadk\xf8[\xd7\xf5\xb8f}\xaeYΙ\xf9yY\x15\xf5\xc5I\x86\x90\x8e\xfe\"K\xb8\x97\xca\xcc9\b\xf7\xc3\xfe\x89\x14`\xc7i\x92\xbc$\"tMe\x1a\xac\xed\xef\xed\xfe\xcb6\x95\xce\xd6\x05\xf3\xf7\x17Yڵ\xcd\xe5\x16\x1e\x06\xddϮ\xd0\xee@\x81p\x0fK\xfc\xd7\xe3\xd7/\x11~\xca\x1e\xf5F\xef\xe0M\x03g`\x94\x1e9>\xfb\xe4\vn\x1c\xb6P\x87\xbfr\x92\x80\xd6\xec?\xf1ͮ\xf9\x80\xcc\xdd\xfd\x06\xbb\x06k\t\xdf\xfa\x8a\t\xfd\x98{ۂ\xd5\x1e\x11#\xa3ܿ\xd9\xf5 &\xcaN\xe3\x9f\x04_L\nڋ\x8d\xd5d\xb9\"${\xea\xee7nuk\xf2ٚn\xe2D\xa4c\xbc\x03S媦ʜ\x90;\xf4M\\\xc3xP&萩\xd0ɨ\xa8=\x7f\v*\x89\xdb\xf0$\x14&\xe0Nu?\x9b9\xc4\xe8%\xeb\x18\xbf=1{o\xe2\x15\xd71\xae\x8eW\x88\xa9\xc4\xe7d\x05ī\x85\xa4\xbc\x18\xba\xff>'\xd6\x1eb\xc7iyf=\xd9\x10\xd6I\xe0ǎG\x91\xa6\x05\xad\xf5!\x11\x15z\x99LÇ\xaa\f5M\xe6~\\\xdfޖXq\xe8\b\xa0g\b\"Ju\x9e\xed\x1b\xacɞU\a\b\xd50\x9aЂ\xf1\x9b\x8ec\xfe\xfb\xa4<3\x9f\x05\xb9\xf8A\x10\x87\x9e\x11Q\x81\x91&+\xc6\x02/\xb4x\xb9 \xd99k\xc2e\x14\xb6N\u06dd\x99/J\\\xfc\x96\xc4<\xb2\x12\x88\x1a{F\"穈\xbf)>'D\x92.\x0eP6\x1c2\x1ex{\xect\x9d\x7f\xe2-\x00N\x9dI\xd9\x7f\xe4\xcdⵣ^\xad\xc1\xdb\x7fL\xce#\xddC\x1e)\xf1\xee\x82t\x96\xbd{u\xaa\xb0v\xbcn\x8a\x02\xb4\xde5\xf0{\x86\x88\xcfݾ>\xdc\xe9p\xe0^\x93\xa1\xae\xbe\x0f߃5,:\x98#\x8a\xc4μH<\x1f\xa4|ʲB\x7f\x8e\x1d\xdbh\v\x13\x8e\x8f\xf0j\xdbV6\xa6k_ʱ\xd8,\xbe\xbb\xf8\xca\xf2\x1aa\u07b9\xbb.c!\xc4\xf3\x87\x1d\xe3\x80\xe8\xcfIC9\x11M\xb5\x05\x85\f\x19;\x1c&\xee{?\x86\xd7e9?\xdd\f!\x0f\x9e\x9bnaOAD\xd2{\x19й\x03\x1cb_\x03 \xae\xfb\xc4ӓ\x04\xdf\n\x0e*\x7f챻)\x8e\x8e8\xfe\x8c\x8b\xcaE\xb0\xeb=\x86]\xb7x\xe7ƀH{a$\xe4\x9eñ\xb8`\xe9\x13\xf6^}\xa0z\xceл\xb7}\xe2\xe5ߎN\x8a6\xde\xc3ȑL_F\\\x91/\xf0\x9c\xf8ꐅ\x19\x9c\xb4&Y\x91\x8d\xb8Wr\xaf@\x9f3\xce\no\xa71\xb1\xff,\xd5=o\xf6L\xc4\xe2\xe1e\x9d\xef\xa92̲\xb2[Ob\xecǠ\xcb\x12\xbf͏\x1e\xf9aBF\xd5~ϳ\xe1L\xd7mN>y\x01\xfaN\xb7\xfa\"\x15\xfa\xf3\xd0\xd6\xe4\x8b4\x10\xb2\x8c\xac\x0f\x94i\xb2\x05mV\xb0\xdbIe\\\xf4y\xb5\"l\xe7\xed\x94T\x94\x942\x8e^\x92{\x9dۺN\xb1..\xda\xec>\x12\xa6P)\xa0{Uѓ\v\xa8Ѣ\xb0&0\xbc׆\xa6L\xf1\x17\x89Qt\xcb<7\xe7\x1c\xf2M\xb7\x7f\fF\xc5\x03\x8e\xe0\x1c\xea\xf0V\xb0\xd3\xc0\xc9\n\v\x827P;\x8f\x12\x10m\xb5\xd9%ǝ8A\xb3\x19w1\xfbW\xa9b\xe719\xe5\xb7\xd1{\x87x\xbc\x8a\x9a\xe90\xd4Ҭ8P\xb1\xb7\xec\xa3d\xb3?\x04\x16\x1c3TF\x80\x96\rF\xabk<\xa9:d\xebM\xa3D'\xd9\xe4\xf3\xf7e\xbb\xdc)\xa0\x17KL\xd5\xde%heƄ\xe6M\x19\xfb#\x83G\xf0\x9f\n\x85\xc7!T\x9fD1}\xc1\xc1y\x8al\xe2\x1e\xe3\x142\x92\xfb\x8d\x12\xf0\x92\xfd\xc6\xc1\xf9\xfb\xed*\xef֕X\xb2\xf9\xf1\b\xc1+\xa0c\xcc(\x98\xc7Ŵ\x81\x80\xfbK\xac|\x11\xb9\xbb\x06F0%R\xf1Hk\\,Å\xee9Ys\xe1\xa2^\xe7\x979\x938\xb1u%\xff\xb8N\xe01\x9a1\x9fr\xdc\xc1\xef\x83\xee\x83\xdbb\xd61l!z\x17.\x81\x9c\x7ff\xbb\xf0\x0f]\xb6\x1c\xfe\xe5\xac\xc7\xef|\xeb\xeb\x99*\xc1\xc4~n\xf3\xbf\xfan\to\xd8CH\xf8ÉMD\x0fy\x91?\x1c\x169\xf2?\v\xa2\x8f\xfc\x02\x8f8\xa9N\xce>\"#\x97\x1d$\xfb\x99\xfc\x97\xff\x0f\x00\x00\xff\xff\xf4\xd4_Pfi\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=Mw$)rw\xfd\n\x9e|\x18\xdbOU=m_\xfctk\xab{\xecz;ӭ\xd7\xd2\xf6\xc9\x17*3J\xc5(\x13r\x81,uy\xdf\xfew\xbf\b \xbf*\xc9$K\x92gfW\\\xba\x95\x05A\x10\x11\xc4\a\x04\xb0Z\xad.x%\xbe\x816B\xc9k\xc6+\x01\xdf-H\xfcˬ\x1f\xffì\x85zwx\x7f\xf1(d~\xcdnjcU\xf9\x15\x8c\xaau\x06\x1fa'\xa4\xb0Bɋ\x12,Ϲ\xe5\xd7\x17\x8cq)\x95\xe5\xf8\xd9\xe0\x9f\x8ceJZ\xad\x8a\x02\xf4\xea\x01\xe4\xfa\xb1\xde¶\x16E\x0e\x9a\x80\x87\xae\x0f?\xae\xdf\xff\xdb\xfa\xc7\v\xc6$/ᚙl\x0fy]\x80Y\x1f\xa0\x00\xad\xd6B]\x98\n2\x04\xfa\xa0U]]\xb3\xf6\a\xd7\xc8w落\xf3\xed\xe9S!\x8c\xfdS\xef\xf3\xcf\xc2X\xfa\xa9*j͋N\x7f\xf4\xd5\b\xf9P\x17\\\xb7\xdf/\x183\x99\xaa\xe0\x9a}Ʈ*\x9eA~\xc1\x98ǟ\xba^1\x9e\xe7D\x11^\xdcj!-\xe8\x1bU\xd4e\xa0Ċ\xe5`2-*K#\xbe\xb3\xdcֆ\xa9\x1d\xb3{\xe8\xf6\x83\xe5W\xa3\xe4-\xb7\xfbk\xb66To]\xed\xb9\t\xbf:\x129\x00\xfe\x93=\"n\xc6j!\x1f\xc6z\xfb\xc0n\xb4\x92\f\xbeW\x1a\f\xa2\xccrb\xa0|`O{\x90\xcc*\xa6kI\xa8\xfc'\xcf\x1e\xebj\x04\x91\n\xb2\xf5\x00O\x8fI\xff\xe3\x1c.\xf7{`\x057\x96YQ\x02\xe3\xbeC\xf6\xc4\r\xe1\xb0S\x9aٽ0\xf34A =l\x1d:?\x0f?;\x84rn\xc1\xa3\xd3\x01\x15\x84w\x9di \xb9\xbd\x17%\x18\xcb\xcb>\xcc\x0f\x0f\x90\x00\x8cHT\xf1ڐp\xb4\xado\xbb\x9f\x1c\x80\xadR\x05py\xd1V:\xbcw\xb2\x97\xed\xa1\xe4\u05fe\xb2\xaa@~\xb8\xdd|\xfb\xf7\xbb\xdeg6\x90%O)&\f\xe3\xec\x1bM\f\xa6\xfdLev\xcf-Ӏ\x9c\ai\xb1F\xa5a\x15\xa8\x9b7 \x19S\x9aU\xa0\x85\xcaE\x16\xb8B\x8d\xcd^\xd5Eζ\x80\fZ7\r*\xad*\xd0V\x84\xa9\xe7JG\xa3t\xbe\x0e0\xfe\x01\a\xe5j9I\x04C\xc2\xe7'\x14\xe4\x9e\x0en~\b\xd3\xe2OL\xea\x01fX\x89K\xa6\xb6\xbfBf\xd7\xec\x0e4\x82\tXgJ\x1e@#\x052\xf5 \xc5\xff6\xb0\rJ\xbd%a\xb4\xe0\xf5A[h\x02K^\xb0\x03/j\xb8b\\\xe6\xac\xe4G\xa6\x01{a\xb5\xec\xc0\xa3*f\xcd~Q\x1a\x98\x90;u\xcd\xf6\xd6V\xe6\xfaݻ\aa\x83&\xcdTY\xd6R\xd8\xe3;R\x8ab[[\xa5ͻ\x1c\x0eP\xbc3\xe2a\xc5u\xb6\x17\x162[kx\xc7+\xb1\"\xd4%i\xd3u\x99\xffS\xe0\xa8\xf9\xa1\x87\xeb\xc9|s\x85\x14\xe1\x04\aP#:\x81qM\xdd(ZB\xe3'\xa4\xce\xd7Ow\xf7]a\x12fH}\xa2{G\xc2Z\x16 \xc1\x84܁\x9f\xd1;\xadJ\x82\t2\xaf\x94\x90\x96\xfe\xc8\n\x01rH~SoKa\x91\xef\x7f\xa9\xc1X\xe4՚ݐyA9\xac+\x9c\x81\xf9\x9am$\xbb\xe1%\x147\xdc\xc0\xab3\x00)mVH\xd84\x16t-㰲\xa3Z\xe7\x87`\xde\"\xfc\ns\xfc\xae\x82\xac7e\xb0\x9d؉\x8c&\x06i\xcfF\x05\f4\xa8+㳖~!55\xfc:\xc0\xc3\xe9\xb2\xd0+\x18\xb4\x1fvO\x1cn\xcd\x18ʕ\x83\x86:E\xaa!wǴ`\x87\x12\x1e\xca\f&}\xad\x97j\xdfN`2\xaf\xea\xd6\x11\x1cO\xb8J?AY\xa1ژA\xf1\xdeWC\x14\x91>y\xe35\x05\xc3\x1fԬ\xf2ڕ\x9d(7\xean\x0fȷ\x83Ƚ\xf6:\xe1*\x9b\xe4,\x96̈;\xc9+\xb3W\x16m\x9c\xaa\xedX\xad\xc1\x00n\xee6\x83F\x1d\xce#VdÉ\xd1V\xb1'.N9\xed\n\xca\xe5\xcd݆}C\x97\b\x02L\xe6,9\xb3\xb5\x96\xa4\x8e\xbf\x02Ϗ\xf7\xea\xcf\x06X^\x93V\nv\xf9*\x02x\v;\x9c\xf4\x1a\x10\x066\x00\xadq\x0e\x18BM\xd5vM\x0eG\x0e;^\x17\xd6+9a\xd8\xfb\x1fY)dm\xe1\x94\xefl\x9a\xf7D$ny\xa9\x0e\xa0\x13h\xf8\x91[\xfe\v\xd6\x1d\x90\x0ea0\x02\xe2\xd9Od\xdc\x1e#\x03\xc5&['\xa9l\xb3\xeb@\x15\x86]^\xe2<\xbbt.\xf1啫[\x8b®\x84\xa4~\"0]\xefO\xa2(B\xff\xe7Q\xc3\x11\xd7\xf1\xd6ܫ\x9f\x8c\x13\xeb\x14\xe2D\x9a\x8e(\x98J\xe5\xec@\xf5b2&\n`\xe6h,\x94\x9eR\x1dυ\x88Kڱ(<\x18öǀ\xfb\xf8\xb8e]\x14|[\xc05\xb3\xba\x1e\xefvJ\x91\x8d\xd1\xe6+\x18+\xb2\x04\xca\\\x0eI\xe3Z\x8e\x10F\xd3\x0f\x11\xa2\f(\x80.\x0f\x7fD\xb7\xdbS\b}\xa7\xa2\xe8\x10w\x9e*\x8c\xfd\x8fd\x1f\xd1\xdcgh\x84\xaf\xbdq\x17P\x90C!\x15+\x94|\x00\xedzD\xc7)H\x98\x06\x94\xb8<\x02\x15-\xad\x86\x02]\x06\xb6\xab\xd1\b\xaf\x19j\x82\xa8\x8c\bi,\xf0|}\xf9Z̃\xefYQ\xe7\x90\xdf\x14\xb5\xb1\xa0\xef0\x04\xccC\b<\xaae\aL\xfc4\t\xc0\xbb_\x85\xc8\x00\xf9\x90\xb9J+\x8a4cDj=\xb1c\x05.\xf0E\xa6zL[\x17\xab\xa3*\fX\xacr\xf9\xaf\x971%\x8a\x12\xd0\xef\xbdߏa\\CC\x8d\x9eF\x8d@l\xf4,\x94\x95=\x8eˑ\xb0PF\x888\xabr\x16\xb0\x97k\xcdǔj\x18N\x13џ\xcf\xde\x18\x88\x01\x83e\xa8\xf6\x1b\xb1x\xd8\xff?\"\x93\xcfb\xab\xa1u,.$\xb2\xb3\x10\xc6\xf6\xb89\f\x88\x1a\xcc0vF\x9ab\xd0\"\xa4\x83\x89ʭü\xdf3\xcdΙ\t1\xd1o$͋\xf3\x9eDŽ\xea\x0fH\xb0\xbdR\x8f)D\xfao\xac\xd7\x06\xca,\xa3%U\xb6\x85=?\b\xa5\xcdp\xb5\x05\xbeCVۨ\x9e\xe0\x96\xe5b\xb7\x03\x8d\xb0h\x81\xb0YO\x9c\"\xd6t\x98\xc0:\n(Za0\xae\x96\xe9\xc8<\xa2Fl(\x14\x8eE\xa12B\x1c\xbdx\xb2\xee\xb98\x88\xbc\xe6\x05\x19z.37>\xde\xe0\x17sOf\x04\xe2\x04\x7f\xe7N\x84Q \x97zQ\xb6\x92\x80\xeeu\xa9t\xcc\xf3t\xe5\x14L\x9c\f[N\xc1q,$m\x8b\xae\v0\x1e\x15\xe7\xc0\xb6z\xe7\xaa\xe5\x94[\xa0*\xf8\x16\nf\xa0\x80\xcc*\x1d'O\x8a\x10\xb8\x92\xaa?#\x94\x1dѤ\xfd hV\x89\xb6\x05\x03̽\xc8\xf6\xce\xddD)#X,W`Hc\xf0\xaa*\"V\xa8-\xb3\x92\xe1;\x9bS\x1amIP\x1fC\xb81EҖD\x1dܖ\x19mܧz#6oD\xef\xa1)\x9f%웓\xe6//\xecHn\x01\x86\x9c>\U000bab98\xb0\xe1k\nԞ\x1fh\xfe\xce\x18w\xdel\xd9\f[\xbf\xf8ly\x11\xae5h\xfc\x9d0\x8d\x8c՝\xb7U\x8b\x18\xf6s\xb7\xe5\x15\x13\xbb\x86a\xf9\x15ۉ\xc2\x02\xf9Rs\x88v\x1c\x9dYν$\x81Rm/\x96\x92\xdbl\xff\xa9Y\xd6Nh1\xa0\xd5\x10\x80\xf3\xcbC\fC\f<\x9d.\n4\xc0$\x90\x9dA\x91\x9b\xd6\xc4xn?\xef\x8aq\xf6\bG\xe7Y\x8d.\x0f\x8d\x15d-o@j\xa0\xcdER#\x8fp$P~\xb70\t\xde\x12Qq\xe5\x11\x8e\xa9U\aDE\xfc\xfc>\x85\xa3.~\xa0Q\xa4L\xa5\xb64D\xf5s\x87Y\x956X\xb6L)\x85\x12(~\xe6\xb0\x1b\x86\xf5\xb6\xc8\x1f\xe1\xf8\x83q\xec\xc3Y\xb3\x17\xd5\x02\n\xa0¦%\x19\xb5k\xf6\x86\xbf\xf1B\xe4Mg4O\x16@\xdc\xc8+\xf6YY\xfc\xe7\xd3wa\x10E\x99\xb3\x8f\n\xccge\xe9˫\x92\xd8\r\xe2L\x02\xbb\xc64-\xa53\vH\x97E\xfd\xb78\x90\tE\x11m\xd8&\f\xdbH\x8c\xcf\x1c}\x96\xb0i\x0f\x019\x87VY\x1b\xda]\x96J\xaeܒ\x96\xefm\x01\xd0.^\x9eUJ\xf78u\xb5\x10\xe2(\x8a\x1e\xbd{\xb4V\ue5d3}\xf9\xa9\xa2\xa1*x\x06y\xd8e\xa3$\x00n\xe1Ad\xac\x04\xfd\x00\xacB\xbb\x91.T\v4\xb9+gHa\xbak\x11\x8a7\v#{\xdace\x85\xb3>\xb1f`sR\xf5Ȏ\xfft\xf5\xb4Q\x92y'\x7f(\x89\xfa\xdd\x14\xb5e\x96e!\xbfN}\x10\x87\xa4s?JN\x1bO\x7fE\xf3J\xe2\xfd\xb74kȅ6k\xf6\x81\x12\xf4\n\xe8\xb6\x0f\xab\x84\x9d\xae\x92@\"&\xc20\x94\x93\x03/\xd0}@\xe5-\x19\x14ΙP\xbb\x13\x0f*M\xc5<\xed\x95q6\xbf\xd9\x18\xbb|\x84\xa3ߜ\xedj\x89ˍ\x8c\xae\xda\xf7\v\xea\xfc\x13\xa5\xd5x-J\x16GvI\xbf]\x92c\xb6d\x8a\x9c\xe1\xbc-\x90\xea\x05U\xbf\xaf\x1e\xeb-h\t\x16̪\xe4\xd5\xca\xcf\x06\xab\xca\xe8\x1e\xa7+\x94F\xb7$\x8c\xc08=x<ظI6C\xf7\x7f\x8e\x02\xc9\xf3\xa1R&\x92i\x11A\xebV\x19\xeb\x16\x0f{\xae\xfa\xc8\xeabJ\xe4\xe8W\x1c\x19\xdfY\xd0\xccX\xa5Cb\x17\xaa\xec\xc1\xe2:J\x8d\x99\x97\x1b\xb7O\xe4W2\x1d`\fP/[\xed\xe2\xec\xc1\xa5۫\xc2\xff\xcf\xc3\xcc\xc8\xd1\"ؕV\x19\x98h6B[\x12\xad\xce\xccbo\xb3\xd0\xcb]\xe0\xb7KR\xeb)\xcbС,s㑴g\x04E\x9f\xbew֬Q\x85\xe1\xdf)\xa2|\x0e\x8e\x8cr\xbb˒\x0f\x93\f\x93ѽq\xad\xc3\x04\xf4\xc0\\\xb0\xa5\x1fjRH\xcb|n/\x92\xbf7\xa7\xa5\x14rC\x1d\xb1\xf7\xaf\xe6\xe8\xb0`\x06b\x19Ice\xc0\x0e߾eH\xf3!5\xf6e!UM\xd1>\x8f\x86\x1egOwA\xd29\xc5\xd0\x11\x97\xcav\x17z|O?\x18\xb6\x13\xda\xd8\x16\xe1\x05P\x85\x99\xc8z\x1a\x1d\xde\x19\xf1\xa9\xfc\xa4\xf5\xd9\xe1\xe9\x17\u05fa\xb3$\xb9WO>\xc1sIP\x1e\x88\xbf\xe7\a`bDŽe 3UKZ,Cu\x81\xdd,\x80\xe8\x98\xe8\x8cI\xa2\xcd\xec4\x96u\x99N\x90\x15I\xa7\x90\xb3+k\xdd&?q\x91\xb6\xb2\xc5\xcec\xab\x9dJ\xa2\x1c+\xfd\xccP\x9fM\xd9\xcd\xe4-\xf9wQ\xd6%\xe3%\xb2eI̹sy\x98!\xed\xd7\xf1\xfa\x89\v\xebOS\xb8M\xd9e\xda4SeU\x80\x85\x90a\x99)iD\x0e\x8d\xfb\xe0\xf9?\x9a\xaf\x1a+\x9c\xed\xb8(j\xbd@G/\xe6\xccҘϫ\xa7\x97\x0f\xe4\xd2\x11Y\x111\x13\x17\xec\x178\xdc\xf3\xf6\xa3\xd2\xcb\\\xe6[\r/\xef\x9aVZ(ʁ\x9d\xf1Nga\x92\xf7\xda\xf7N\xbd\xf0ry\x8c\xb9\xa7\xb3P\t\x937\xf7\xb4)o\xee\xe9\x9b{\xfa\xe6\x9e\x0eʛ{\xfa枾\xb9\xa7\xe3\xe5\xcd=\xed\x947\xf74\xd9~\xa4`\xb8\xa2\x95ۉ\nIX%\xa6o̡=ӗ\xcfR\xf2gA\x96dWo\xc6[\x8e\x9c\x05Zt\x86\xc4t\x8c^\x93n\x8dS2L&w\xa64\xc1\v\x7f\x81\xb36\x01\x81\xb3\xcf\xdal&\x01\xbc\xe0Y\x1b\x8f\xe9p\xed\xfc\x05O\xda\x04Z,?\x84q\xe5ӘJ\xe0aK\xc8\xe5\xa0\xe4\xb1nc^l\x0f\x8f\xd1:\xbfq\xd6\xfdI\xb6\xe6\xf9\"\xf3\xffr~'\"6'\xa7S#P\x85A\xb9\xfacp\xe2,\xdaG\xa9\xed\xfe\x17\x1b]KX\xa7x\xdd5\x03\xddT\xcb~\xca\xeb\x1fG\xb0ϑ\xe4\xd4\xf371\xe7<\xae\xdb:\xc4Խ\xf3\x1e\xbfoZZ(\xbfTޒ\xa5\x9f{ߌ4{\xc6\xc9wn\x8e2\xdbk%Um\xfc\n\x0f\xf6\xf0!sW\x01\x84\x8e\xcc\x12e\xf0\x9e\xedU\x1d9\xe31Cׄ\xcc\xdbx\xbe\xad\xcf\xe0\x00\xcb\x0f\xef\xd7\xfd_\xac\xf2ٷ\x11\xac\x9f\x84ݻ\xfb\x18x\x9e\xa3\xa3\xde9\xe2\x13&\xaf\xbf\x93e(x\x11\x88J3)\n'\x95\x01B߀~\xa9ܒ\xdf\xd9~\xcb\xfc\xc2Sz\x8e\xee\xd2\xcc\xdc&\x97r\xdeK~F>\xee\xb2\xc3R\xb3\xb9\xb7)H\xb3\x94\x8c\xdb\xf1\\\xda\x19\xa8K\xf2lS\xd7\x14\x13rj\xd33i\xd3\xc8\xc3\xe8&\xa5\xd4\xfc\xd9\xe4(45W\xf6u2d\x13\xf3b;ٮ\xb3 \xcf̆M&XZ\xe6kr\xbek'\x8bu\x9eZ\x13Y\xae㹫\xb3 \xc7r[S2V\x93pM\xceSm\xb2O\xe7wF\x9e\x95\x9d\xfa\xf2\xe7`^r\xddb:\xd74)\xc34imc\x1e\xe7\xa4\x1cҥ\x99\xa3IT]\x9a%\xdad\x80Nt\x9c\x94\x1bz\x9a\xf795\x94ٌ\xd0x\xb6\xe7\x14ر<Є\x1c\xcf\t\x90\xdd\xec\xcf\xc5n\xc0\xac4\xcdVX\x9a\xbb9~?Z(\xf3ֹ\xf8-d\xf6\xb9dR\xba\xe74\xa7\x04w_\x06MPZ\x82\x9f8\xe6\x88\xc7Ce瞟\xe1\x88G@nv\xac\xac\v+\xaa\xa2sA\x99\xddñ\xb9\xf2\xe7WE\a\u05f7G\x82\xf6\xe5k#\xf21\x90\xfd\x90\x82\x1b\xf6\x04E\x81\xff\x9eP!s\xd7\x01fj\x05h\xa5\xe2\x1b\x81\xfe\xaa#\x7f\x97\xe0\x95[\x16\xa3S\xfdd\x01K\x844}\x01֤)\x99v\x8f\x9dWO\xdf\xfeR\x83>2\xbas+\xf8AQ1kO{\xfa\xc9l0&\f\xca\xc7k1w)e_\x19\xc5gC\xa3\x02\xd8\a\xe9\f\xf3\x10W\x82\x85Z\xa7\r\xa7\xa6\x94-FO1\x10R5\x10\"\xedS\xbc\xef%\xc7\x1f_#\xb8z\x89\xf0*\xc9\x11y\x8d\x10뵂\xac\xa5a֒䍤㋯\x11l-\t\xb7\x16\xf9\x8c\xe9\xc7\x13_\xebX\xe2+\x84]g\a^\x8bH\x97z\xecpq\xf8\x950\xbe\x99c\x86'>Z\x02\xc8\xe8\xf1\xc2\xf1\x10,\x01\xe2ɱ\xc2\xd9 ,e\x1e\fôg\x1f\x12LNdZ\xb4\x9b\x9e\x9a\x84\x94\xb6\xd1=\x7f\xf8/\xf1\xd0_\xe26x\n\xf6\x89\x87\xfb\x96\x1f\xeaK\xa4\xf3\x99\xe1\xd9d\u05c9\x87\xf7\x16\x05hg\x86h\x93\x10\xa7\x0e\xebM\ai\xd3\vp\xc3Czg\xb8\x13\t\x12\x96Pe\xf9A\xbbgo\xc6(\x9d\x83\x9e\xdd\xd7Z\"γ\x82<\x88\xa3\xfa\xfd\x0fvt\u008d\xa8X\xab\xbbg\x16\xe3\xa8j\xee\x1d\xc9؟\x84\xf4\xbb\xf5(\xb8\x1d\x9f\xa4\xb7\xf1\xd6:L\xf1}\x9d\xd6K\xf5\x17\xab\xbb\x1d;\x03\x15״\x8f\xbf=\xba\xa4 \xb3f\x9fx\xb6oz\x88\x80\xa4~\xf7ܰ\x9d\xd2%\xb7\xec\xb2\xd9\n}\xe7:\xc0\xbf/\u05cc\xfd\xa4\x9a\xf4\x91νb\x11\xa8F\x94UqĈ\x89]v\xc1ti^\xd6ɂ\x88\xc5(\xd8\\\xf8\v\v\a\x97\n\xefTQ\xa8\xa73\x97.x%\xfe\x8b\xde1I[\x1b\xfbp\xbb\xa1\xeaA\xaa\xe8\r\x94&{\xae\x91\xb1-L+\xf4v\xe0\xe4zt\xa1\x8ed\xaf6\x7fN@\xa4W\x04\x82\x9f\xe1\xd5x\xa6P\x8b\xddn\x1c\x96k\x12,.\x8fL\xf9{\xe2\x85\xceW\x15\xd7\xd1M=\xe6\xe5\xc1\\\xf50\fv|n\x05kҬ\x9d\xbe\x8a\xd0-=\x9a\x87\a\x12h\xb3\xf7X\xf5\xb7щ\xd2\x1dz>\a\xa7\xe9\x83˳G\x96_\x01\xa7i\x97iET\x8c\xfc\x14M\xc7{\xf1\xd5C\xe3/\x91\xffE\x1d\xe0ct\x15\xb1\xffd\xc0\xa0\xc9H\x02]\x80:umz\x9b5\x17\xbf\xce\xfa\x052\xe2\x02*\xfe\xe2\xeb\x05\xe3\xf3-\xc6^i\xf0\xf7\x7f\a\xd8\x13\xb6\r\xa7\xec\xed7\n7\x1bu\xe9g\xb8\x0f&\xc3R\xe1\xe0\xaa\xd6\b\xc8\xd83\v/E-\xab4\x7f\x80\x9f\x95{\t#\x85Z\xfd\x16\xbd\xc7P\xbc3\x17\xb2\x89\xfd\\\x8b)s?\xb6!\xc0\xf6\x90\xc1\xc9u\xf4\x88홷\xed[[$\f\xee\xfe\xfeg7 +JX\x7f\xac]\x86\t\xea]\x03H\xe90P\xd7h\x1b\xd7N{\xf5D\xf7\xb9w\x9f\xab\xe8<\b\x04t\xa8\x81\xd2F\xcf\x1aM]\x15\x8a\xe7\xa0o\x94܉\x87\x84\x81\xfd\xb9\xd7``\xd93\xfa\xe8\a\x1b\xeccd`\xa1\xe7W\xcc\fA\x97\xad(\xa0\xf8I\x14`\x1c≊\xfe\xf6\xb4e\xa3\xf7\xebr\xeb\x1c\xd4\x1d\xfe\xd8t2aM\xddPiM\xbf\x02\x8d\x8e\xa0[\xfd\xafM\x10\xf0ib\xb0\x86\x8fBZx\x88$\xf8\xcch\xf8C\xef\xe9\x8f0IR\xd4ڷ\xf1\x96\x1do\xb93]\xa7\x92\x05\xd5.\n\x8b\x1b\xa32A\x0e6\xed\x8eЩ\x91\u05fbsz*P\x9a\xa0cm\xe0˓\x04\xfd5\xa8d\xb3\x91\xb1\xb76\xfa\xb3\xe6\xa4a\xf4\x9d\r\xabȭ\x1fT\x1f\v\xe7\xa4'\x90q\xaf\xb4\x84m\x1ea\x9a\xb7yNI73\xaf\xe2Z~\xdc'Y\x8d?\x87\xb3j^\xe8\xb9H\xa0\xac{\x85\xa6\x0fx\xfc\xf1%\xf7\\M\xc6+[\xeb\xa0rjM\x17p#\x10p\xf7S\x9f\xf7\xfcR\xfb\x9c\xdd\f/\xdb\a\xeeڅ\xef\xd9\xe7\xf4F\xf8\xd7<\xa0\x14}Qȅ\x8c\uee7b\x15\xc2?\x8f\x9d\xa3\xf3\x80.,\x9f\x19\xe9-\xd6iN\xfcyBS\xc3p\xd1\xf9]\f\xf5\xf1#\\+\xf6\x19NC\xb6\x15\xfb$q\x10\xa7\x9e\x9c;\xa7\x059-\x97\x8f==79\xc4Cӊ\x0eɍh\x8b\xbe\x9a\x1bT\x1f\xa4\xf0\xd2\xc35M\x15w n\x8c\xad\xff,vn/#\xc31\xfd\xcbI\x8d\xa8\xe2\x9aTZ1\x855:\xa5N>\x1a\xd0\az)&\b\x89\xf7ֺ_\xeam{\xef<\xfb\xeb\xdf.\xfe/\x00\x00\xff\xff\x89~\x02\xaf\x9ft\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4V\xcfo\xeb6\f\xbe\xe7\xaf \xb0û\xcc\xce\xebv\x19r\x1b\xba\x1d\x8am\x0fE\xf3л\"\xd3\tWY\xf2H*]\xf6\xd7\x0f\x92\xec&\xb1\x9d\xb5\x1b0\xdd\"\xf1\xc7Ǐ\xe4\xe7TU\xb52==#\v\x05\xbf\x01\xd3\x13\xfe\xa9\xe8\xd3/\xa9_~\x90\x9a\xc2\xfax\xb7z!\xdfl\xe0>\x8a\x86\xee\t%D\xb6\xf8\x13\xb6\xe4I)\xf8U\x87j\x1a\xa3f\xb3\x020\xde\a5\xe9Z\xd2O\x00\x1b\xbcrp\x0e\xb9ڣ\xaf_\xe2\x0ew\x91\\\x83\x9c\x83\x8f\xa9\x8f\x9f\xeb\xbb\xef\xea\xcf+\x00o:܀ \xa775\x1a\x85\U0004f222R\x1f\xd1!\x87\x9a\xc2Jz\xb4)\xfe\x9eC\xec7p~(\xfeC\xee\x82{\x9bCms\xa8\xa7\x12*\xbf:\x12\xfd\xe5\x96ů4X\xf5.\xb2qˀ\xb2\x81\x1c\x02\xeb\x97s\xd2\nD\xb8\xbc\x90\xdfGgx\xd1y\x05 6\xf4\xb8\x81\xec\xdb\x1b\x8b\xcd\n` $Ǫ\x06.\x8ew%\x9c=`gJ\x12\x80У\xff\xf1\xf1\xe1\xf9\xfb\xed\xd55@\x83b\x99zʹ.T\x06$``@\x01\x1a\xc0X\x8b\"`#3z\x85\x82\x12ȷ\x81\xbb\xdcɷ\xd0\x00f\x17\xa2\x82\x1e\x10\x9e3\xe5Ce\xf5\x9bIϡGV\x1a\xd9\x18\xdc\xceCvq;\xc1\xfa)\x95S\xac\xa0IӅ\x923\r\x94`30\x00\xa1\x05=\x90\x00c\xcf(\xe8u\x8a2\xf3ӂ\xf1\x10v\xbf\xa3\xd5z\xe0AR\xb3\xa2k\xd2P\x1e\x91\x15\x18m\xd8{\xfa\xeb-\xb6$BRRgt\x9c\x93\xf3!\xaf\xc8\xde88\x1a\x17\xf1[0\xbe\x81Μ\x801e\x81\xe8/\xe2e\x13\xa9\xe1\xb7\xc0\x98\xc9\xdc\xc0A\xb5\x97\xcdz\xbd'\x1d\x97ˆ\xae\x8b\x9e\xf4\xb4\xce{B\xbb\xa8\x81e\xdd\xe0\x11\xddZh_\x19\xb6\aR\xb4\x1a\x19צ\xa7*C\xf7y\xc1\xea\xae\xf9\x86\x87u\x94OWX\xf5\x94&K\x94\xc9\xef/\x1e\xf2B\xfcC\a\xd2:\x94\xf9(\xae\xa5\x8a3\xd1\xe9*\xb1\xf3\xf4\xf3\xf6+\x8c\xa9s3\xa6\xecg\xdeώrnA\"\x8c|\x8b\\\x9a\xd8r\xe8rL\xf4M\x1fȗ鲎\xd0O闸\xebHe\x9c\xddԫ\x1a\xee\xb3\xe2\xc0\x0e!\xf6\x8dQljx\xf0po:t\xf7F\xf0\x7fo@bZ\xaaD\xec\xc7Zp)\x96S\xe3\xc2\xda\xc5\xc3(s7\xfa\xb5\xb0\xdd\xdb\x1em\xea`\"1ySK6\xaf\a\xb4\x81\xc1,\xb9\xd4\x1fB\x92=\xfe%\x96AI\n\x9a\x89\xbe\xa4\xfd|\x1fͲ\x9c䗃\x11\x9c^N0=&\x9bi~G-ړuXB\x145\xc1\xf7\xa1\xa4\x83>v\xf3\x9c\x15|\xc1ׅ\xdbG\x0eIY\xb3\xae_\x9f\x1b\xb3\x01\xe5{\xb3'?+wZY\xb1\xca߰K\xa9\xbe\x10\xe8!\x10p\xf4>\xed\xedL!3\x90\xa9\x92\xcflH\xb1[@\xb3\x88\xe7\xc1\xb7!\x7f\xf0MJl\xb4\xec\x13\x0e\xcd\x1e\xf2\x14\\\v\x01o\xf7\xba\x9c\xb9x}\x88\xd0r\xf2\x97\xf4\xbf9'\xb9!\xc6\xc5\xdcUF\xb5\xf8\x902.1\xbe\xbc_\x03\xca\xe8\x9c\xd99܀r\x9c{\x17_\xc3lNө\x19G\xed+u(j\xba\xfe\xbd\x01\x9a9\xa4=y=\xa0\xbf\xb5\r\xf0j\xa6*\x7f\x95\x19v\xa7[\xae\xf7o\xff\x01\xe7+UFw\x03I\xbb+\xa5\x05\xce>D\xcab\xf7\xcaH/\xfe\xf3\x98\x11\xb2\xbd\xb4\x1d5\xe3j5\xc6?\"\xf3\x1anBXl\xf6\xec2\x87o.\xca\x13\rl\xf6c\xc1\x7f\a\x00\x00\xff\xff\xb1J-\xe7\xa6\v\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4VA\x93\xdb6\x0f\xbd\xfbW`&\x87\xbdDr\xf2}\x97\x8e/\x9d̦\x87L\x93f'N\xf7N\x8b\x90\x8d\x9a\"U\x10\xd4\xc6\xfd\xf5\x1d\x90\xd2\xdak\xcb\xc9n\xa7\xd5\xc5c\n\x04\x1f\xde\xc3\x03UU\xd5\xc2\xf4t\x8f\x1c)\xf8\x15\x98\x9e\xf0\x9b\xa0\xd7\x7f\xb1\xde\xff\x14k\n\xcb\xe1\xedbOޮ\xe06E\t\xdd\x17\x8c!q\x83\xef\xb1%OB\xc1/:\x14c\x8d\x98\xd5\x02\xc0x\x1f\xc4\xe8rԿ\x00M\xf0\xc2\xc19\xe4j\x8b\xbeާ\rn\x129\x8b\x9c\x93OG\x0fo\xea\xb7\xff\xab\xdf,\x00\xbc\xe9p\x05Cp\xa9\xc3\xe8M\x1fwA\\hJ\xcez@\x87\x1cj\n\x8b\xd8c\xa3Gl9\xa4~\x05\xc7\x17%\xc5x|\x81~\x9f\xb3\xad\xc7l\x1f\xc7l9\xc0Q\x94_\xbf\x13\xf4\x91\xa2\xe4\xc0\xde%6\xee*\xb2\x1c\x13w\x81\xe5\xb7\xe3\xe9\x15\fѕ7\xe4\xb7\xc9\x19\xbe\xb6\x7f\x01\x10\x9b\xd0\xe3\n\xf2\xf6\xde4h\x17\x00#?9]5Q\xf3\xb6dlvؙr\x0e@\xe8ѿ\xbb\xfbp\xff\xff\xf5\x93e\x00\x8b\xb1a\xea%\xb3<_\"P\x04\x03\x13\x12x\xd8!#\xdcg>!J`\x8c#\xe8Ǥ\x00\x13\xfeX?.\xf6\x1czd\xa1\xa9\xf8\xf2\x9c\xf4\xd7\xc9\xea\x19\xae\x1b\x85^\xa2\xc0jca\x04\xd9\xe1T>ڱZ\b-Ȏ\"0\xf6\x8c\x11\xbd\x1c\x85<>\xa1\x05\xe3!l\xfe\xc0FjX#k\x1a\xd5&9\xab\xfd8 \v06a\xeb\xe9\xaf\xc7\xdc\x11$\xe4C\x9d\x11\x1c5?>\xe4\x05\xd9\x1b\a\x83q\t_\x83\xf1\x16:s\x00F=\x05\x92?ɗCb\r\x9f\x02#\x90o\xc3\nv\"}\\-\x97[\x92\xc9WM\xe8\xba\xe4I\x0e\xcbl\x11\xda$\t\x1c\x97\x16\at\xcbH\xdb\xcap\xb3#\xc1F\x12\xe3\xd2\xf4Te\xe8\xbe\xf8\xa0\xb3\xafxtb\xbcy\x82U\x0e\xdaEQ\x98\xfc\xf6\xe4E6\xc2w\x14P\x0f\x94F([K\x15G\xa2uI\xd9\xf9\xf2\xcb\xfa+LGg1\xce\xd9ϼ\x1f7ƣ\x04J\x18\xf9\x16\xb9\x88\xd8r\xe8rN\xf4\xb6\x0f\xe4%\xffi\x1c\xa1?\xa7?\xa6MG\xa2\xba\xff\x990\x8ajU\xc3m\x1e6\xb0AH\xbd5\x82\xb6\x86\x0f\x1enM\x87\xee\xd6D\xfc\xcf\x05P\xa6c\xa5\xc4>O\x82\xd39y\x1e\\X;5\xd88ޮ\xe85\xef\xe4u\x8f\xcd\x13\x03i\x16jitv\x1b\xf8\x8cW3\xf9|>_\xfd$|\xde\xe0P\x86|K\xdb\xf3U\x00cm\xbe\"\x8c\xbb\xbb\xba\xf7;\x84\xcd\xd4}\x9bO\xd2Fm\x03+\xa2\x81,r5\xd59\"I<\x16L\xe8l\xac/R^\xe1<\x97\xc2hUc\xe3.\x81>E\xf2\x18\x98\xef8C\xbeP~L\x90[\x8f\xbbq\xc6zAo\xf3P\xbf@\x13r\x0fG\xb4\xf0@\xb2+\xe6p\xa7\x97\xd4\xf3T\xd0g\x8f\x87\xb9\xe53\xec_w\xa8\x91e\x9c\"Dl\x18EqDtj^uf\r\xf0)\xc5l/3\x9b\x11tD\x90\x9dv\xef\xf1pI4\xfcH\xdc\xf1\xbe\xff1\xe4\x1b\xbd\x17'\xc0\x8c-2z\x99\xb5\xb8~b\xb0G\xc1\xecr\x1b\x9a\xa8\x06o\xb0\x97\xb8\f\x03\xf2@\xf8\xb0|\b\xbc'\xbf\xad\x94\xf0\xaa4B\\\xe6\xef\x86\xe5\xab\xfcs\xa5䯟\xdf\x7f^\xc1;k!\xc8\x0eYUk\x93\x9b\x1a\xed\xe4\xb6{\x9d'\xeekHd\x7f\xbe\xf9'\xbc\x84\xbe8\xe7\x19ܬs\xf7\x1f\xf4\xe6Π\x94\xa2uQ%0\xe8\xdcT\xb1\xbbQ\xcd2\x1f\xe6\x1aq´\t\xc1\xa1\xb9l=\x9d\xbe\xc4h/!Uz\xc2Kl\x06\xf0\xad:\nUu\xa6\xafJ\xb4\x91\xd0Qs\x16=\xf9\xfc\a\x96\xbc\x1b\xc3t<(\aӶ\xa9m\xcaWL\xfe\xa61[\xbc6\x16f\x14\x99/\xbcz<\xe0Y\x03]\x8c\xa4\xf8\U000917b7\x8d\x91\x9bq\xac7\x89\xb5\xfdǜ3\x9f?\xff\xceX\xefw&\xcex\xf3\x19\xa8\xeft\xe7$\x83\xa3\x16\x9bC\xe3\xb0$\x84\xd0\xce\xf4ދ \xeb\x83>us\x8d\xf8n0\xe4\xcc\xc6\xe1̻߽\xb9\xfa\xf6\xaa\xf8\xb3z^,F\xfdƱ+\x10N%\xf7\xd8e\xe3\xca\xdf\x01\x00\x00\xff\xff\xec\xa0\xe0\xa1k\r\x00\x00"), } diff --git a/pkg/apis/velero/v1/backup_types.go b/pkg/apis/velero/v1/backup_types.go index 41ca6c437..66a827bf0 100644 --- a/pkg/apis/velero/v1/backup_types.go +++ b/pkg/apis/velero/v1/backup_types.go @@ -178,10 +178,11 @@ type BackupSpec struct { // UploaderConfig specifies the configuration for the uploader. // +optional - UploaderConfigForBackup *UploaderConfigForBackup `json:"uploaderConfig,omitempty"` + // +nullable + UploaderConfig *UploaderConfigForBackup `json:"uploaderConfig,omitempty"` } -// UploaderConfigForBackup defines the configuration for the backup. +// UploaderConfigForBackup defines the configuration for the uploader when doing backup. type UploaderConfigForBackup struct { // ParallelFilesUpload is the number of files parallel uploads to perform when using the uploader. // +optional diff --git a/pkg/apis/velero/v1/pod_volume_backup_types.go b/pkg/apis/velero/v1/pod_volume_backup_types.go index cb43c55aa..b3070e3dd 100644 --- a/pkg/apis/velero/v1/pod_volume_backup_types.go +++ b/pkg/apis/velero/v1/pod_volume_backup_types.go @@ -55,7 +55,8 @@ type PodVolumeBackupSpec struct { // UploaderSettings are a map of key-value pairs that should be applied to the // uploader configuration. // +optional - UploaderSettings *map[string]string `json:"uploaderSettings,omitempty"` + // +nullable + UploaderSettings map[string]string `json:"uploaderSettings,omitempty"` } // PodVolumeBackupPhase represents the lifecycle phase of a PodVolumeBackup. diff --git a/pkg/apis/velero/v1/pod_volume_restore_type.go b/pkg/apis/velero/v1/pod_volume_restore_type.go index b864d627c..34bc7e530 100644 --- a/pkg/apis/velero/v1/pod_volume_restore_type.go +++ b/pkg/apis/velero/v1/pod_volume_restore_type.go @@ -52,7 +52,8 @@ type PodVolumeRestoreSpec struct { // UploaderSettings are a map of key-value pairs that should be applied to the // uploader configuration. // +optional - UploaderSettings *map[string]string `json:"uploaderSettings,omitempty"` + // +nullable + UploaderSettings map[string]string `json:"uploaderSettings,omitempty"` } // PodVolumeRestorePhase represents the lifecycle phase of a PodVolumeRestore. diff --git a/pkg/apis/velero/v1/restore_types.go b/pkg/apis/velero/v1/restore_types.go index 06684238a..417813152 100644 --- a/pkg/apis/velero/v1/restore_types.go +++ b/pkg/apis/velero/v1/restore_types.go @@ -126,14 +126,16 @@ type RestoreSpec struct { // UploaderConfig specifies the configuration for the restore. // +optional - UploaderConfigForRestore *UploaderConfigForRestore `json:"uploaderConfig,omitempty"` + // +nullable + UploaderConfig *UploaderConfigForRestore `json:"uploaderConfig,omitempty"` } // UploaderConfigForRestore defines the configuration for the restore. type UploaderConfigForRestore struct { // WriteSparseFiles is a flag to indicate whether write files sparsely or not. // +optional - WriteSparseFiles bool `json:"writeSparseFiles,omitempty"` + // +nullable + WriteSparseFiles *bool `json:"writeSparseFiles,omitempty"` } // RestoreHooks contains custom behaviors that should be executed during or post restore. diff --git a/pkg/apis/velero/v1/zz_generated.deepcopy.go b/pkg/apis/velero/v1/zz_generated.deepcopy.go index 42c2e9a0a..a3089d3b4 100644 --- a/pkg/apis/velero/v1/zz_generated.deepcopy.go +++ b/pkg/apis/velero/v1/zz_generated.deepcopy.go @@ -381,8 +381,8 @@ func (in *BackupSpec) DeepCopyInto(out *BackupSpec) { *out = new(bool) **out = **in } - if in.UploaderConfigForBackup != nil { - in, out := &in.UploaderConfigForBackup, &out.UploaderConfigForBackup + if in.UploaderConfig != nil { + in, out := &in.UploaderConfig, &out.UploaderConfig *out = new(UploaderConfigForBackup) **out = **in } @@ -978,13 +978,9 @@ func (in *PodVolumeBackupSpec) DeepCopyInto(out *PodVolumeBackupSpec) { } if in.UploaderSettings != nil { in, out := &in.UploaderSettings, &out.UploaderSettings - *out = new(map[string]string) - if **in != nil { - in, out := *in, *out - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val } } } @@ -1088,13 +1084,9 @@ func (in *PodVolumeRestoreSpec) DeepCopyInto(out *PodVolumeRestoreSpec) { out.Pod = in.Pod if in.UploaderSettings != nil { in, out := &in.UploaderSettings, &out.UploaderSettings - *out = new(map[string]string) - if **in != nil { - in, out := *in, *out - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val } } } @@ -1374,10 +1366,10 @@ func (in *RestoreSpec) DeepCopyInto(out *RestoreSpec) { *out = new(corev1.TypedLocalObjectReference) (*in).DeepCopyInto(*out) } - if in.UploaderConfigForRestore != nil { - in, out := &in.UploaderConfigForRestore, &out.UploaderConfigForRestore + if in.UploaderConfig != nil { + in, out := &in.UploaderConfig, &out.UploaderConfig *out = new(UploaderConfigForRestore) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -1694,6 +1686,11 @@ func (in *UploaderConfigForBackup) DeepCopy() *UploaderConfigForBackup { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UploaderConfigForRestore) DeepCopyInto(out *UploaderConfigForRestore) { *out = *in + if in.WriteSparseFiles != nil { + in, out := &in.WriteSparseFiles, &out.WriteSparseFiles + *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_upload_types.go b/pkg/apis/velero/v2alpha1/data_upload_types.go index 98f441064..347bf2dd1 100644 --- a/pkg/apis/velero/v2alpha1/data_upload_types.go +++ b/pkg/apis/velero/v2alpha1/data_upload_types.go @@ -51,7 +51,7 @@ type DataUploadSpec struct { // DataMoverConfig is for data-mover-specific configuration fields. // +optional // +nullable - DataMoverConfig *map[string]string `json:"dataMoverConfig,omitempty"` + DataMoverConfig map[string]string `json:"dataMoverConfig,omitempty"` // Cancel indicates request to cancel the ongoing DataUpload. It can be set // when the DataUpload is in InProgress phase diff --git a/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go index 9a9afaa6d..ca6c522bd 100644 --- a/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go @@ -226,13 +226,9 @@ func (in *DataUploadSpec) DeepCopyInto(out *DataUploadSpec) { } if in.DataMoverConfig != nil { in, out := &in.DataMoverConfig, &out.DataMoverConfig - *out = new(map[string]string) - if **in != nil { - in, out := *in, *out - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val } } out.OperationTimeout = in.OperationTimeout diff --git a/pkg/builder/backup_builder.go b/pkg/builder/backup_builder.go index daa356222..2f7be4c37 100644 --- a/pkg/builder/backup_builder.go +++ b/pkg/builder/backup_builder.go @@ -302,10 +302,10 @@ func (b *BackupBuilder) DataMover(name string) *BackupBuilder { // ParallelFilesUpload sets the Backup's uploader parallel uploads func (b *BackupBuilder) ParallelFilesUpload(parallel int) *BackupBuilder { - if b.object.Spec.UploaderConfigForBackup == nil { - b.object.Spec.UploaderConfigForBackup = &velerov1api.UploaderConfigForBackup{} + if b.object.Spec.UploaderConfig == nil { + b.object.Spec.UploaderConfig = &velerov1api.UploaderConfigForBackup{} } - b.object.Spec.UploaderConfigForBackup.ParallelFilesUpload = parallel + b.object.Spec.UploaderConfig.ParallelFilesUpload = parallel return b } diff --git a/pkg/builder/data_upload_builder.go b/pkg/builder/data_upload_builder.go index a35924fe9..29e7a0191 100644 --- a/pkg/builder/data_upload_builder.go +++ b/pkg/builder/data_upload_builder.go @@ -103,7 +103,7 @@ func (d *DataUploadBuilder) OperationTimeout(timeout metav1.Duration) *DataUploa } // DataMoverConfig sets the DataUpload's DataMoverConfig. -func (d *DataUploadBuilder) DataMoverConfig(config *map[string]string) *DataUploadBuilder { +func (d *DataUploadBuilder) DataMoverConfig(config map[string]string) *DataUploadBuilder { d.object.Spec.DataMoverConfig = config return d } diff --git a/pkg/builder/restore_builder.go b/pkg/builder/restore_builder.go index 405df89da..e7d5f8ef3 100644 --- a/pkg/builder/restore_builder.go +++ b/pkg/builder/restore_builder.go @@ -174,6 +174,6 @@ func (b *RestoreBuilder) ItemOperationTimeout(timeout time.Duration) *RestoreBui // WriteSparseFiles sets the Restore's uploader write sparse files func (b *RestoreBuilder) WriteSparseFiles(val bool) *RestoreBuilder { - b.object.Spec.UploaderConfigForRestore.WriteSparseFiles = val + b.object.Spec.UploaderConfig.WriteSparseFiles = &val return b } diff --git a/pkg/cmd/cli/restore/create.go b/pkg/cmd/cli/restore/create.go index 3a8bb2442..398f49771 100644 --- a/pkg/cmd/cli/restore/create.go +++ b/pkg/cmd/cli/restore/create.go @@ -149,8 +149,8 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) { flags.StringVar(&o.ResourceModifierConfigMap, "resource-modifier-configmap", "", "Reference to the resource modifier configmap that restore will use") - f = flags.VarPF(&o.WriteSparseFiles, "write-sparse-files", "", "Whether to write sparse files when restoring volumes") - f.NoOptDefVal = cmd.FALSE + f = flags.VarPF(&o.WriteSparseFiles, "write-sparse-files", "", "Whether to write sparse files during restoring volumes") + f.NoOptDefVal = cmd.TRUE } func (o *CreateOptions) Complete(args []string, f client.Factory) error { @@ -323,8 +323,8 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error { ItemOperationTimeout: metav1.Duration{ Duration: o.ItemOperationTimeout, }, - UploaderConfigForRestore: &api.UploaderConfigForRestore{ - WriteSparseFiles: boolptr.IsSetToTrue(o.WriteSparseFiles.Value), + UploaderConfig: &api.UploaderConfigForRestore{ + WriteSparseFiles: o.WriteSparseFiles.Value, }, }, } diff --git a/pkg/cmd/cli/restore/create_test.go b/pkg/cmd/cli/restore/create_test.go index 7409076fa..090697477 100644 --- a/pkg/cmd/cli/restore/create_test.go +++ b/pkg/cmd/cli/restore/create_test.go @@ -84,7 +84,7 @@ func TestCreateCommand(t *testing.T) { includeClusterResources := "true" allowPartiallyFailed := "true" itemOperationTimeout := "10m0s" - writeSparseFiles := "false" + writeSparseFiles := "true" flags := new(pflag.FlagSet) o := NewCreateOptions() diff --git a/pkg/cmd/const.go b/pkg/cmd/const.go index 806fff07b..7f4459899 100644 --- a/pkg/cmd/const.go +++ b/pkg/cmd/const.go @@ -1,4 +1,3 @@ package cmd var TRUE string = "true" -var FALSE string = "false" diff --git a/pkg/cmd/util/output/backup_describer.go b/pkg/cmd/util/output/backup_describer.go index f9bca5dfc..d0359d527 100644 --- a/pkg/cmd/util/output/backup_describer.go +++ b/pkg/cmd/util/output/backup_describer.go @@ -88,9 +88,9 @@ func DescribeBackup( DescribeResourcePolicies(d, backup.Spec.ResourcePolicy) } - if backup.Spec.UploaderConfigForBackup != nil && backup.Spec.UploaderConfigForBackup.ParallelFilesUpload > 0 { + if backup.Spec.UploaderConfig != nil && backup.Spec.UploaderConfig.ParallelFilesUpload > 0 { d.Println() - DescribeUploaderConfig(d, backup.Spec) + DescribeUploaderConfigForBackup(d, backup.Spec) } status := backup.Status @@ -135,10 +135,10 @@ func DescribeResourcePolicies(d *Describer, resPolicies *v1.TypedLocalObjectRefe d.Printf("\tName:\t%s\n", resPolicies.Name) } -// DescribeUploaderConfig describes uploader config in human-readable format -func DescribeUploaderConfig(d *Describer, spec velerov1api.BackupSpec) { +// DescribeUploaderConfigForBackup describes uploader config in human-readable format +func DescribeUploaderConfigForBackup(d *Describer, spec velerov1api.BackupSpec) { d.Printf("Uploader config:\n") - d.Printf("\tParallel files upload:\t%d\n", spec.UploaderConfigForBackup.ParallelFilesUpload) + d.Printf("\tParallel files upload:\t%d\n", spec.UploaderConfig.ParallelFilesUpload) } // DescribeBackupSpec describes a backup spec in human-readable format. diff --git a/pkg/cmd/util/output/backup_describer_test.go b/pkg/cmd/util/output/backup_describer_test.go index 6a55d4041..0d0b9bbd5 100644 --- a/pkg/cmd/util/output/backup_describer_test.go +++ b/pkg/cmd/util/output/backup_describer_test.go @@ -28,7 +28,7 @@ func TestDescribeUploaderConfig(t *testing.T) { buf: &bytes.Buffer{}, } d.out.Init(d.buf, 0, 8, 2, ' ', 0) - DescribeUploaderConfig(d, input) + DescribeUploaderConfigForBackup(d, input) d.out.Flush() expect := `Uploader config: Parallel files upload: 10 diff --git a/pkg/cmd/util/output/restore_describer.go b/pkg/cmd/util/output/restore_describer.go index 5d9273a70..3031407ee 100644 --- a/pkg/cmd/util/output/restore_describer.go +++ b/pkg/cmd/util/output/restore_describer.go @@ -32,6 +32,7 @@ import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/cmd/util/downloadrequest" "github.com/vmware-tanzu/velero/pkg/itemoperation" + "github.com/vmware-tanzu/velero/pkg/util/boolptr" "github.com/vmware-tanzu/velero/pkg/util/results" ) @@ -177,9 +178,9 @@ func DescribeRestore(ctx context.Context, kbClient kbclient.Client, restore *vel d.Println() d.Printf("Preserve Service NodePorts:\t%s\n", BoolPointerString(restore.Spec.PreserveNodePorts, "false", "true", "auto")) - if restore.Spec.UploaderConfigForRestore != nil && restore.Spec.UploaderConfigForRestore.WriteSparseFiles { + if restore.Spec.UploaderConfig != nil && boolptr.IsSetToTrue(restore.Spec.UploaderConfig.WriteSparseFiles) { d.Println() - d.Printf("Write Sparse Files:\t%T\n", restore.Spec.UploaderConfigForRestore.WriteSparseFiles) + DescribeUploaderConfigForRestore(d, restore.Spec) } d.Println() @@ -198,6 +199,12 @@ func DescribeRestore(ctx context.Context, kbClient kbclient.Client, restore *vel }) } +// DescribeUploaderConfigForRestore describes uploader config in human-readable format +func DescribeUploaderConfigForRestore(d *Describer, spec velerov1api.RestoreSpec) { + d.Printf("Uploader config:\n") + d.Printf("\tWrite Sparse Files:\t%T\n", boolptr.IsSetToTrue(spec.UploaderConfig.WriteSparseFiles)) +} + func describeRestoreItemOperations(ctx context.Context, kbClient kbclient.Client, d *Describer, restore *velerov1api.Restore, details bool, insecureSkipTLSVerify bool, caCertPath string) { status := restore.Status if status.RestoreItemOperationsAttempted > 0 { diff --git a/pkg/cmd/util/output/schedule_describer.go b/pkg/cmd/util/output/schedule_describer.go index 4c3ff7004..73abb51a1 100644 --- a/pkg/cmd/util/output/schedule_describer.go +++ b/pkg/cmd/util/output/schedule_describer.go @@ -48,9 +48,9 @@ func DescribeSchedule(schedule *v1.Schedule) string { DescribeResourcePolicies(d, schedule.Spec.Template.ResourcePolicy) } - if schedule.Spec.Template.UploaderConfigForBackup != nil && schedule.Spec.Template.UploaderConfigForBackup.ParallelFilesUpload > 0 { + if schedule.Spec.Template.UploaderConfig != nil && schedule.Spec.Template.UploaderConfig.ParallelFilesUpload > 0 { d.Println() - DescribeUploaderConfig(d, schedule.Spec.Template) + DescribeUploaderConfigForBackup(d, schedule.Spec.Template) } status := schedule.Status diff --git a/pkg/controller/data_download_controller.go b/pkg/controller/data_download_controller.go index a57e42fc8..487f12ce2 100644 --- a/pkg/controller/data_download_controller.go +++ b/pkg/controller/data_download_controller.go @@ -332,7 +332,7 @@ func (r *DataDownloadReconciler) runCancelableDataPath(ctx context.Context, fsRe } log.WithField("path", path.ByPath).Info("fs init") - if err := fsRestore.StartRestore(dd.Spec.SnapshotID, path, &dd.Spec.DataMoverConfig); err != nil { + if err := fsRestore.StartRestore(dd.Spec.SnapshotID, path, dd.Spec.DataMoverConfig); err != nil { return r.errorOut(ctx, dd, err, fmt.Sprintf("error starting data path %s restore", path.ByPath), log) } diff --git a/pkg/controller/data_upload_controller_test.go b/pkg/controller/data_upload_controller_test.go index 046dc84c1..6e10f05e0 100644 --- a/pkg/controller/data_upload_controller_test.go +++ b/pkg/controller/data_upload_controller_test.go @@ -296,7 +296,7 @@ func (f *fakeDataUploadFSBR) Init(ctx context.Context, bslName string, sourceNam return nil } -func (f *fakeDataUploadFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfigs *map[string]string) error { +func (f *fakeDataUploadFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfigs map[string]string) error { du := f.du original := f.du.DeepCopy() du.Status.Phase = velerov2alpha1api.DataUploadPhaseCompleted @@ -306,7 +306,7 @@ func (f *fakeDataUploadFSBR) StartBackup(source datapath.AccessPoint, realSource return nil } -func (f *fakeDataUploadFSBR) StartRestore(snapshotID string, target datapath.AccessPoint, uploaderConfigs *map[string]string) error { +func (f *fakeDataUploadFSBR) StartRestore(snapshotID string, target datapath.AccessPoint, uploaderConfigs map[string]string) error { return nil } diff --git a/pkg/controller/pod_volume_backup_controller_test.go b/pkg/controller/pod_volume_backup_controller_test.go index 14de4bb09..852e8d388 100644 --- a/pkg/controller/pod_volume_backup_controller_test.go +++ b/pkg/controller/pod_volume_backup_controller_test.go @@ -103,7 +103,7 @@ func (b *fakeFSBR) Init(ctx context.Context, bslName string, sourceNamespace str return nil } -func (b *fakeFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfigs *map[string]string) error { +func (b *fakeFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfigs map[string]string) error { pvb := b.pvb original := b.pvb.DeepCopy() @@ -115,7 +115,7 @@ func (b *fakeFSBR) StartBackup(source datapath.AccessPoint, realSource string, p return nil } -func (b *fakeFSBR) StartRestore(snapshotID string, target datapath.AccessPoint, uploaderConfigs *map[string]string) error { +func (b *fakeFSBR) StartRestore(snapshotID string, target datapath.AccessPoint, uploaderConfigs map[string]string) error { return nil } diff --git a/pkg/datapath/file_system.go b/pkg/datapath/file_system.go index 2dfdb9583..60a0c8347 100644 --- a/pkg/datapath/file_system.go +++ b/pkg/datapath/file_system.go @@ -129,7 +129,7 @@ func (fs *fileSystemBR) Close(ctx context.Context) { fs.log.WithField("user", fs.jobName).Info("FileSystemBR is closed") } -func (fs *fileSystemBR) StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfig *map[string]string) error { +func (fs *fileSystemBR) StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfig map[string]string) error { if !fs.initialized { return errors.New("file system data path is not initialized") } @@ -150,7 +150,7 @@ func (fs *fileSystemBR) StartBackup(source AccessPoint, realSource string, paren return nil } -func (fs *fileSystemBR) StartRestore(snapshotID string, target AccessPoint, uploaderConfigs *map[string]string) error { +func (fs *fileSystemBR) StartRestore(snapshotID string, target AccessPoint, uploaderConfigs map[string]string) error { if !fs.initialized { return errors.New("file system data path is not initialized") } diff --git a/pkg/datapath/file_system_test.go b/pkg/datapath/file_system_test.go index 43866f27f..c6cc9da73 100644 --- a/pkg/datapath/file_system_test.go +++ b/pkg/datapath/file_system_test.go @@ -100,7 +100,7 @@ func TestAsyncBackup(t *testing.T) { fs.initialized = true fs.callbacks = test.callbacks - err := fs.StartBackup(AccessPoint{ByPath: test.path}, "", "", false, nil, &map[string]string{}) + err := fs.StartBackup(AccessPoint{ByPath: test.path}, "", "", false, nil, map[string]string{}) require.Equal(t, nil, err) <-finish @@ -183,7 +183,7 @@ func TestAsyncRestore(t *testing.T) { fs.initialized = true fs.callbacks = test.callbacks - err := fs.StartRestore(test.snapshot, AccessPoint{ByPath: test.path}, &map[string]string{}) + err := fs.StartRestore(test.snapshot, AccessPoint{ByPath: test.path}, map[string]string{}) require.Equal(t, nil, err) <-finish diff --git a/pkg/datapath/mocks/types.go b/pkg/datapath/mocks/types.go index c765defea..60697e4b6 100644 --- a/pkg/datapath/mocks/types.go +++ b/pkg/datapath/mocks/types.go @@ -43,11 +43,11 @@ func (_m *AsyncBR) Init(ctx context.Context, bslName string, sourceNamespace str } // StartBackup provides a mock function with given fields: source, realSource, parentSnapshot, forceFull, tags, dataMoverConfig -func (_m *AsyncBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, dataMoverConfig *map[string]string) error { +func (_m *AsyncBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, dataMoverConfig map[string]string) error { ret := _m.Called(source, realSource, parentSnapshot, forceFull, tags, dataMoverConfig) var r0 error - if rf, ok := ret.Get(0).(func(datapath.AccessPoint, string, string, bool, map[string]string, *map[string]string) error); ok { + if rf, ok := ret.Get(0).(func(datapath.AccessPoint, string, string, bool, map[string]string, map[string]string) error); ok { r0 = rf(source, realSource, parentSnapshot, forceFull, tags, dataMoverConfig) } else { r0 = ret.Error(0) @@ -57,11 +57,11 @@ func (_m *AsyncBR) StartBackup(source datapath.AccessPoint, realSource string, p } // StartRestore provides a mock function with given fields: snapshotID, target, dataMoverConfig -func (_m *AsyncBR) StartRestore(snapshotID string, target datapath.AccessPoint, dataMoverConfig *map[string]string) error { +func (_m *AsyncBR) StartRestore(snapshotID string, target datapath.AccessPoint, dataMoverConfig map[string]string) error { ret := _m.Called(snapshotID, target, dataMoverConfig) var r0 error - if rf, ok := ret.Get(0).(func(string, datapath.AccessPoint, *map[string]string) error); ok { + if rf, ok := ret.Get(0).(func(string, datapath.AccessPoint, map[string]string) error); ok { r0 = rf(snapshotID, target, dataMoverConfig) } else { r0 = ret.Error(0) diff --git a/pkg/datapath/types.go b/pkg/datapath/types.go index 15688a095..d05c541e0 100644 --- a/pkg/datapath/types.go +++ b/pkg/datapath/types.go @@ -62,10 +62,10 @@ type AsyncBR interface { Init(ctx context.Context, bslName string, sourceNamespace string, uploaderType string, repositoryType string, repoIdentifier string, repositoryEnsurer *repository.Ensurer, credentialGetter *credentials.CredentialGetter) error // StartBackup starts an asynchronous data path instance for backup - StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, dataMoverConfig *map[string]string) error + StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, dataMoverConfig map[string]string) error // StartRestore starts an asynchronous data path instance for restore - StartRestore(snapshotID string, target AccessPoint, dataMoverConfig *map[string]string) error + StartRestore(snapshotID string, target AccessPoint, dataMoverConfig map[string]string) error // Cancel cancels an asynchronous data path instance Cancel() diff --git a/pkg/podvolume/backupper.go b/pkg/podvolume/backupper.go index d4f2f4d8e..93c252d5d 100644 --- a/pkg/podvolume/backupper.go +++ b/pkg/podvolume/backupper.go @@ -36,9 +36,9 @@ import ( "github.com/vmware-tanzu/velero/pkg/label" "github.com/vmware-tanzu/velero/pkg/nodeagent" "github.com/vmware-tanzu/velero/pkg/repository" + uploaderutil "github.com/vmware-tanzu/velero/pkg/uploader/util" "github.com/vmware-tanzu/velero/pkg/util/boolptr" "github.com/vmware-tanzu/velero/pkg/util/kube" - "github.com/vmware-tanzu/velero/pkg/util/uploaderconfig" ) // Backupper can execute pod volume backups of volumes in a pod. @@ -411,8 +411,8 @@ func newPodVolumeBackup(backup *velerov1api.Backup, pod *corev1api.Pod, volume c pvb.Spec.Tags["pvc-uid"] = string(pvc.UID) } - if backup.Spec.UploaderConfigForBackup != nil { - pvb.Spec.UploaderSettings = uploaderconfig.StoreBackupConfig(backup.Spec.UploaderConfigForBackup) + if backup.Spec.UploaderConfig != nil { + pvb.Spec.UploaderSettings = uploaderutil.StoreBackupConfig(backup.Spec.UploaderConfig) } return pvb diff --git a/pkg/podvolume/restorer.go b/pkg/podvolume/restorer.go index 93157ccc3..aa2d999ed 100644 --- a/pkg/podvolume/restorer.go +++ b/pkg/podvolume/restorer.go @@ -36,9 +36,9 @@ import ( "github.com/vmware-tanzu/velero/pkg/label" "github.com/vmware-tanzu/velero/pkg/nodeagent" "github.com/vmware-tanzu/velero/pkg/repository" + uploaderutil "github.com/vmware-tanzu/velero/pkg/uploader/util" "github.com/vmware-tanzu/velero/pkg/util/boolptr" "github.com/vmware-tanzu/velero/pkg/util/kube" - "github.com/vmware-tanzu/velero/pkg/util/uploaderconfig" ) type RestoreData struct { @@ -286,8 +286,8 @@ func newPodVolumeRestore(restore *velerov1api.Restore, pod *corev1api.Pod, backu pvr.Labels[velerov1api.PVCUIDLabel] = string(pvc.UID) } - if restore.Spec.UploaderConfigForRestore != nil { - pvr.Spec.UploaderSettings = uploaderconfig.StoreRestoreConfig(restore.Spec.UploaderConfigForRestore) + if restore.Spec.UploaderConfig != nil { + pvr.Spec.UploaderSettings = uploaderutil.StoreRestoreConfig(restore.Spec.UploaderConfig) } return pvr diff --git a/pkg/uploader/kopia/snapshot.go b/pkg/uploader/kopia/snapshot.go index 9ce0f1fa5..52b5879b1 100644 --- a/pkg/uploader/kopia/snapshot.go +++ b/pkg/uploader/kopia/snapshot.go @@ -38,11 +38,10 @@ import ( "github.com/kopia/kopia/snapshot/snapshotfs" "github.com/pkg/errors" - "github.com/vmware-tanzu/velero/pkg/util/uploaderconfig" - "github.com/vmware-tanzu/velero/pkg/kopia" "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" "github.com/vmware-tanzu/velero/pkg/uploader" + uploaderutil "github.com/vmware-tanzu/velero/pkg/uploader/util" ) // All function mainly used to make testing more convenient @@ -106,17 +105,17 @@ func getDefaultPolicy() *policy.Policy { } } -func setupPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceInfo snapshot.SourceInfo, uploaderCfg *map[string]string) (*policy.Tree, error) { +func setupPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceInfo snapshot.SourceInfo, uploaderCfg map[string]string) (*policy.Tree, error) { // some internal operations from Kopia code retrieves policies from repo directly, so we need to persist the policy to repo curPolicy := getDefaultPolicy() - if uploaderCfg != nil { - uploaderConfig, err := uploaderconfig.GetBackupConfig(uploaderCfg) + if len(uploaderCfg) > 0 { + parallelUpload, err := uploaderutil.GetParallelFilesUpload(uploaderCfg) if err != nil { return nil, errors.Wrap(err, "failed to get uploader config") } - if uploaderConfig.ParallelFilesUpload > 0 { - curPolicy.UploadPolicy.MaxParallelFileReads = newOptionalInt(uploaderConfig.ParallelFilesUpload) + if parallelUpload > 0 { + curPolicy.UploadPolicy.MaxParallelFileReads = newOptionalInt(parallelUpload) } } @@ -141,7 +140,7 @@ func setupPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceInfo snap // Backup backup specific sourcePath and update progress func Backup(ctx context.Context, fsUploader SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, - forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { if fsUploader == nil { return nil, false, errors.New("get empty kopia uploader") } @@ -237,7 +236,7 @@ func SnapshotSource( forceFull bool, parentSnapshot string, snapshotTags map[string]string, - uploaderCfg *map[string]string, + uploaderCfg map[string]string, log logrus.FieldLogger, description string, ) (string, int64, error) { @@ -369,7 +368,7 @@ func findPreviousSnapshotManifest(ctx context.Context, rep repo.Repository, sour } // Restore restore specific sourcePath with given snapshotID and update progress -func Restore(ctx context.Context, rep repo.RepositoryWriter, progress *Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, +func Restore(ctx context.Context, rep repo.RepositoryWriter, progress *Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) { log.Info("Start to restore...") @@ -400,13 +399,16 @@ func Restore(ctx context.Context, rep repo.RepositoryWriter, progress *Progress, IgnorePermissionErrors: true, } - if uploaderCfg != nil { - restoreCfg, err := uploaderconfig.GetRestoreConfig(uploaderCfg) + if len(uploaderCfg) > 0 { + writeSparseFiles, err := uploaderutil.GetWriteSparseFiles(uploaderCfg) if err != nil { return 0, 0, errors.Wrap(err, "failed to get uploader config") } - fsOutput.WriteSparseFiles = restoreCfg.WriteSparseFiles + if writeSparseFiles { + fsOutput.WriteSparseFiles = true + } } + log.Debugf("Restore filesystem output %v", fsOutput) err = fsOutput.Init(ctx) diff --git a/pkg/uploader/kopia/snapshot_test.go b/pkg/uploader/kopia/snapshot_test.go index be73146a7..a9a8cfbd6 100644 --- a/pkg/uploader/kopia/snapshot_test.go +++ b/pkg/uploader/kopia/snapshot_test.go @@ -96,7 +96,7 @@ func TestSnapshotSource(t *testing.T) { testCases := []struct { name string args []mockArgs - uploaderCfg *map[string]string + uploaderCfg map[string]string notError bool }{ { @@ -162,7 +162,7 @@ func TestSnapshotSource(t *testing.T) { {methodName: "Upload", returns: []interface{}{manifest, nil}}, {methodName: "Flush", returns: []interface{}{nil}}, }, - uploaderCfg: &map[string]string{ + uploaderCfg: map[string]string{ "ParallelFilesUpload": "10", }, notError: true, @@ -647,9 +647,9 @@ func TestBackup(t *testing.T) { var snapshotInfo *uploader.SnapshotInfo var err error if tc.isEmptyUploader { - snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), nil, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, &map[string]string{}, tc.tags, &logrus.Logger{}) + snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), nil, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, map[string]string{}, tc.tags, &logrus.Logger{}) } else { - snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), s.uploderMock, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, &map[string]string{}, tc.tags, &logrus.Logger{}) + snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), s.uploderMock, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, map[string]string{}, tc.tags, &logrus.Logger{}) } // Check if the returned error matches the expected error if tc.expectedError != nil { @@ -788,7 +788,7 @@ func TestRestore(t *testing.T) { repoWriterMock.On("OpenObject", mock.Anything, mock.Anything).Return(em, nil) progress := new(Progress) - bytesRestored, fileCount, err := Restore(context.Background(), repoWriterMock, progress, tc.snapshotID, tc.dest, tc.volMode, &map[string]string{}, logrus.New(), nil) + bytesRestored, fileCount, err := Restore(context.Background(), repoWriterMock, progress, tc.snapshotID, tc.dest, tc.volMode, map[string]string{}, logrus.New(), nil) // Check if the returned error matches the expected error if tc.expectedError != nil { diff --git a/pkg/uploader/provider/kopia.go b/pkg/uploader/provider/kopia.go index 1c2f95597..6d1dbbf72 100644 --- a/pkg/uploader/provider/kopia.go +++ b/pkg/uploader/provider/kopia.go @@ -119,7 +119,7 @@ func (kp *kopiaProvider) RunBackup( forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, - uploaderCfg *map[string]string, + uploaderCfg map[string]string, updater uploader.ProgressUpdater) (string, bool, error) { if updater == nil { return "", false, errors.New("Need to initial backup progress updater first") @@ -204,7 +204,7 @@ func (kp *kopiaProvider) RunRestore( snapshotID string, volumePath string, volMode uploader.PersistentVolumeMode, - uploaderCfg *map[string]string, + uploaderCfg map[string]string, updater uploader.ProgressUpdater) error { log := kp.log.WithFields(logrus.Fields{ "snapshotID": snapshotID, diff --git a/pkg/uploader/provider/kopia_test.go b/pkg/uploader/provider/kopia_test.go index 3baa724f6..507be4ae5 100644 --- a/pkg/uploader/provider/kopia_test.go +++ b/pkg/uploader/provider/kopia_test.go @@ -68,34 +68,34 @@ func TestRunBackup(t *testing.T) { testCases := []struct { name string - hookBackupFunc func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) + hookBackupFunc func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) volMode uploader.PersistentVolumeMode notError bool }{ { name: "success to backup", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return &uploader.SnapshotInfo{}, false, nil }, notError: true, }, { name: "get error to backup", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return &uploader.SnapshotInfo{}, false, errors.New("failed to backup") }, notError: false, }, { name: "got empty snapshot", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return nil, true, errors.New("snapshot is empty") }, notError: false, }, { name: "success to backup block mode volume", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return &uploader.SnapshotInfo{}, false, nil }, volMode: uploader.PersistentVolumeBlock, @@ -108,7 +108,7 @@ func TestRunBackup(t *testing.T) { tc.volMode = uploader.PersistentVolumeFilesystem } BackupFunc = tc.hookBackupFunc - _, _, err := kp.RunBackup(context.Background(), "var", "", nil, false, "", tc.volMode, &map[string]string{}, &updater) + _, _, err := kp.RunBackup(context.Background(), "var", "", nil, false, "", tc.volMode, map[string]string{}, &updater) if tc.notError { assert.NoError(t, err) } else { @@ -125,27 +125,27 @@ func TestRunRestore(t *testing.T) { testCases := []struct { name string - hookRestoreFunc func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) + hookRestoreFunc func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) notError bool volMode uploader.PersistentVolumeMode }{ { name: "normal restore", - hookRestoreFunc: func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) { + hookRestoreFunc: func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) { return 0, 0, nil }, notError: true, }, { name: "failed to restore", - hookRestoreFunc: func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) { + hookRestoreFunc: func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) { return 0, 0, errors.New("failed to restore") }, notError: false, }, { name: "normal block mode restore", - hookRestoreFunc: func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) { + hookRestoreFunc: func(ctx context.Context, rep repo.RepositoryWriter, progress *kopia.Progress, snapshotID, dest string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, log logrus.FieldLogger, cancleCh chan struct{}) (int64, int32, error) { return 0, 0, nil }, volMode: uploader.PersistentVolumeBlock, @@ -159,7 +159,7 @@ func TestRunRestore(t *testing.T) { tc.volMode = uploader.PersistentVolumeFilesystem } RestoreFunc = tc.hookRestoreFunc - err := kp.RunRestore(context.Background(), "", "/var", tc.volMode, &map[string]string{}, &updater) + err := kp.RunRestore(context.Background(), "", "/var", tc.volMode, map[string]string{}, &updater) if tc.notError { assert.NoError(t, err) } else { diff --git a/pkg/uploader/provider/mocks/Provider.go b/pkg/uploader/provider/mocks/Provider.go index 16efccf11..7651431b2 100644 --- a/pkg/uploader/provider/mocks/Provider.go +++ b/pkg/uploader/provider/mocks/Provider.go @@ -30,28 +30,28 @@ func (_m *Provider) Close(ctx context.Context) error { } // RunBackup provides a mock function with given fields: ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater -func (_m *Provider) RunBackup(ctx context.Context, path string, realSource string, tags map[string]string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg *map[string]string, updater uploader.ProgressUpdater) (string, bool, error) { +func (_m *Provider) RunBackup(ctx context.Context, path string, realSource string, tags map[string]string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg map[string]string, updater uploader.ProgressUpdater) (string, bool, error) { ret := _m.Called(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) var r0 string var r1 bool var r2 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, *map[string]string, uploader.ProgressUpdater) (string, bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, map[string]string, uploader.ProgressUpdater) (string, bool, error)); ok { return rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } - if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, *map[string]string, uploader.ProgressUpdater) string); ok { + if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, map[string]string, uploader.ProgressUpdater) string); ok { r0 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } else { r0 = ret.Get(0).(string) } - if rf, ok := ret.Get(1).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, *map[string]string, uploader.ProgressUpdater) bool); ok { + if rf, ok := ret.Get(1).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, map[string]string, uploader.ProgressUpdater) bool); ok { r1 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } else { r1 = ret.Get(1).(bool) } - if rf, ok := ret.Get(2).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, *map[string]string, uploader.ProgressUpdater) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, map[string]string, uploader.ProgressUpdater) error); ok { r2 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } else { r2 = ret.Error(2) @@ -61,11 +61,11 @@ func (_m *Provider) RunBackup(ctx context.Context, path string, realSource strin } // RunRestore provides a mock function with given fields: ctx, snapshotID, volumePath, volMode, uploaderConfig, updater -func (_m *Provider) RunRestore(ctx context.Context, snapshotID string, volumePath string, volMode uploader.PersistentVolumeMode, uploaderConfig *map[string]string, updater uploader.ProgressUpdater) error { +func (_m *Provider) RunRestore(ctx context.Context, snapshotID string, volumePath string, volMode uploader.PersistentVolumeMode, uploaderConfig map[string]string, updater uploader.ProgressUpdater) error { ret := _m.Called(ctx, snapshotID, volumePath, volMode, uploaderConfig, updater) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, uploader.PersistentVolumeMode, *map[string]string, uploader.ProgressUpdater) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, string, string, uploader.PersistentVolumeMode, map[string]string, uploader.ProgressUpdater) error); ok { r0 = rf(ctx, snapshotID, volumePath, volMode, uploaderConfig, updater) } else { r0 = ret.Error(0) diff --git a/pkg/uploader/provider/provider.go b/pkg/uploader/provider/provider.go index 4e01a2e18..20a3dc436 100644 --- a/pkg/uploader/provider/provider.go +++ b/pkg/uploader/provider/provider.go @@ -49,7 +49,7 @@ type Provider interface { forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, - uploaderCfg *map[string]string, + uploaderCfg map[string]string, updater uploader.ProgressUpdater) (string, bool, error) // RunRestore which will do restore for one specific volume with given snapshot id and return error // updater is used for updating backup progress which implement by third-party @@ -58,7 +58,7 @@ type Provider interface { snapshotID string, volumePath string, volMode uploader.PersistentVolumeMode, - uploaderConfig *map[string]string, + uploaderConfig map[string]string, updater uploader.ProgressUpdater) error // Close which will close related repository Close(ctx context.Context) error diff --git a/pkg/uploader/provider/restic.go b/pkg/uploader/provider/restic.go index a1a30b092..041f6eab5 100644 --- a/pkg/uploader/provider/restic.go +++ b/pkg/uploader/provider/restic.go @@ -30,8 +30,8 @@ import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/restic" "github.com/vmware-tanzu/velero/pkg/uploader" + uploaderutil "github.com/vmware-tanzu/velero/pkg/uploader/util" "github.com/vmware-tanzu/velero/pkg/util/filesystem" - "github.com/vmware-tanzu/velero/pkg/util/uploaderconfig" ) // resticBackupCMDFunc and resticRestoreCMDFunc are mainly used to make testing more convenient @@ -123,7 +123,7 @@ func (rp *resticProvider) RunBackup( forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, - uploaderCfg *map[string]string, + uploaderCfg map[string]string, updater uploader.ProgressUpdater) (string, bool, error) { if updater == nil { return "", false, errors.New("Need to initial backup progress updater first") @@ -146,14 +146,13 @@ func (rp *resticProvider) RunBackup( "parentSnapshot": parentSnapshot, }) - if uploaderCfg != nil { - uploaderConfig, err := uploaderconfig.GetBackupConfig(uploaderCfg) + if len(uploaderCfg) > 0 { + parallelFilesUpload, err := uploaderutil.GetParallelFilesUpload(uploaderCfg) if err != nil { return "", false, errors.Wrap(err, "failed to get uploader config") } - - if uploaderConfig.ParallelFilesUpload > 0 { - log.Warnf("ParallelFilesUpload is set to %d, but restic does not support parallel file uploads. Ignoring.", uploaderConfig.ParallelFilesUpload) + if parallelFilesUpload > 0 { + log.Warnf("ParallelFilesUpload is set to %d, but restic does not support parallel file uploads. Ignoring.", parallelFilesUpload) } } @@ -198,7 +197,7 @@ func (rp *resticProvider) RunRestore( snapshotID string, volumePath string, volMode uploader.PersistentVolumeMode, - uploaderCfg *map[string]string, + uploaderCfg map[string]string, updater uploader.ProgressUpdater) error { if updater == nil { return errors.New("Need to initial backup progress updater first") @@ -219,13 +218,11 @@ func (rp *resticProvider) RunRestore( restoreCmd.ExtraFlags = append(restoreCmd.ExtraFlags, rp.extraFlags...) } - if uploaderCfg != nil { - extraFlags, err := rp.parseRestoreExtraFlags(uploaderCfg) - if err != nil { - return errors.Wrap(err, "failed to parse uploader config") - } else if len(extraFlags) != 0 { - restoreCmd.ExtraFlags = append(restoreCmd.ExtraFlags, extraFlags...) - } + extraFlags, err := rp.parseRestoreExtraFlags(uploaderCfg) + if err != nil { + return errors.Wrap(err, "failed to parse uploader config") + } else if len(extraFlags) != 0 { + restoreCmd.ExtraFlags = append(restoreCmd.ExtraFlags, extraFlags...) } stdout, stderr, err := restic.RunRestore(restoreCmd, log, updater) @@ -234,15 +231,20 @@ func (rp *resticProvider) RunRestore( return err } -func (rp *resticProvider) parseRestoreExtraFlags(uploaderCfg *map[string]string) ([]string, error) { +func (rp *resticProvider) parseRestoreExtraFlags(uploaderCfg map[string]string) ([]string, error) { extraFlags := []string{} - uploaderConfig, err := uploaderconfig.GetRestoreConfig(uploaderCfg) + if len(uploaderCfg) == 0 { + return extraFlags, nil + } + + writeSparseFiles, err := uploaderutil.GetWriteSparseFiles(uploaderCfg) if err != nil { return extraFlags, errors.Wrap(err, "failed to get uploader config") } - if uploaderConfig.WriteSparseFiles { + if writeSparseFiles { extraFlags = append(extraFlags, "--sparse") } + return extraFlags, nil } diff --git a/pkg/uploader/provider/restic_test.go b/pkg/uploader/provider/restic_test.go index 77e576c98..06486a27f 100644 --- a/pkg/uploader/provider/restic_test.go +++ b/pkg/uploader/provider/restic_test.go @@ -150,9 +150,9 @@ func TestResticRunBackup(t *testing.T) { } if !tc.nilUpdater { updater := FakeBackupProgressUpdater{PodVolumeBackup: &velerov1api.PodVolumeBackup{}, Log: tc.rp.log, Ctx: context.Background(), Cli: fake.NewClientBuilder().WithScheme(util.VeleroScheme).Build()} - _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, &map[string]string{}, &updater) + _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, map[string]string{}, &updater) } else { - _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, &map[string]string{}, nil) + _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, map[string]string{}, nil) } tc.rp.log.Infof("test name %v error %v", tc.name, err) @@ -223,9 +223,9 @@ func TestResticRunRestore(t *testing.T) { var err error if !tc.nilUpdater { updater := FakeBackupProgressUpdater{PodVolumeBackup: &velerov1api.PodVolumeBackup{}, Log: tc.rp.log, Ctx: context.Background(), Cli: fake.NewClientBuilder().WithScheme(util.VeleroScheme).Build()} - err = tc.rp.RunRestore(context.Background(), "", "var", tc.volMode, &map[string]string{}, &updater) + err = tc.rp.RunRestore(context.Background(), "", "var", tc.volMode, map[string]string{}, &updater) } else { - err = tc.rp.RunRestore(context.Background(), "", "var", tc.volMode, &map[string]string{}, nil) + err = tc.rp.RunRestore(context.Background(), "", "var", tc.volMode, map[string]string{}, nil) } tc.rp.log.Infof("test name %v error %v", tc.name, err) @@ -417,19 +417,19 @@ func TestParseUploaderConfig(t *testing.T) { testCases := []struct { name string - uploaderConfig *map[string]string + uploaderConfig map[string]string expectedFlags []string }{ { name: "SparseFilesEnabled", - uploaderConfig: &map[string]string{ + uploaderConfig: map[string]string{ "WriteSparseFiles": "true", }, expectedFlags: []string{"--sparse"}, }, { name: "SparseFilesDisabled", - uploaderConfig: &map[string]string{ + uploaderConfig: map[string]string{ "writeSparseFiles": "false", }, expectedFlags: []string{}, diff --git a/pkg/uploader/util/uploader_config.go b/pkg/uploader/util/uploader_config.go new file mode 100644 index 000000000..f04601627 --- /dev/null +++ b/pkg/uploader/util/uploader_config.go @@ -0,0 +1,70 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "strconv" + + "github.com/pkg/errors" + + velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" +) + +const ( + parallelFilesUpload = "ParallelFilesUpload" + writeSparseFiles = "WriteSparseFiles" +) + +func StoreBackupConfig(config *velerov1api.UploaderConfigForBackup) map[string]string { + data := make(map[string]string) + data[parallelFilesUpload] = strconv.Itoa(config.ParallelFilesUpload) + return data +} + +func StoreRestoreConfig(config *velerov1api.UploaderConfigForRestore) map[string]string { + data := make(map[string]string) + if config.WriteSparseFiles != nil { + data[writeSparseFiles] = strconv.FormatBool(*config.WriteSparseFiles) + } else { + data[writeSparseFiles] = strconv.FormatBool(false) + } + return data +} + +func GetParallelFilesUpload(uploaderCfg map[string]string) (int, error) { + parallelFilesUpload, ok := uploaderCfg[parallelFilesUpload] + if ok { + parallelFilesUploadInt, err := strconv.Atoi(parallelFilesUpload) + if err != nil { + return 0, errors.Wrap(err, "failed to parse ParallelFilesUpload config") + } + return parallelFilesUploadInt, nil + } + return 0, nil +} + +func GetWriteSparseFiles(uploaderCfg map[string]string) (bool, error) { + writeSparseFiles, ok := uploaderCfg[writeSparseFiles] + if ok { + writeSparseFilesBool, err := strconv.ParseBool(writeSparseFiles) + if err != nil { + return false, errors.Wrap(err, "failed to parse WriteSparseFiles config") + } + return writeSparseFilesBool, nil + } + return false, nil +} diff --git a/pkg/uploader/util/uploader_config_test.go b/pkg/uploader/util/uploader_config_test.go new file mode 100644 index 000000000..60b76f505 --- /dev/null +++ b/pkg/uploader/util/uploader_config_test.go @@ -0,0 +1,149 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "reflect" + "testing" + + "github.com/pkg/errors" + + velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" +) + +func TestStoreBackupConfig(t *testing.T) { + config := &velerov1api.UploaderConfigForBackup{ + ParallelFilesUpload: 3, + } + + expectedData := map[string]string{ + parallelFilesUpload: "3", + } + + result := StoreBackupConfig(config) + + if !reflect.DeepEqual(result, expectedData) { + t.Errorf("Expected: %v, but got: %v", expectedData, result) + } +} + +func TestStoreRestoreConfig(t *testing.T) { + boolTrue := true + config := &velerov1api.UploaderConfigForRestore{ + WriteSparseFiles: &boolTrue, + } + + expectedData := map[string]string{ + writeSparseFiles: "true", + } + + result := StoreRestoreConfig(config) + + if !reflect.DeepEqual(result, expectedData) { + t.Errorf("Expected: %v, but got: %v", expectedData, result) + } +} + +func TestGetParallelFilesUpload(t *testing.T) { + tests := []struct { + name string + uploaderCfg map[string]string + expectedResult int + expectedError error + }{ + { + name: "Valid ParallelFilesUpload", + uploaderCfg: map[string]string{parallelFilesUpload: "5"}, + expectedResult: 5, + expectedError: nil, + }, + { + name: "Missing ParallelFilesUpload", + uploaderCfg: map[string]string{}, + expectedResult: 0, + expectedError: nil, + }, + { + name: "Invalid ParallelFilesUpload (not a number)", + uploaderCfg: map[string]string{parallelFilesUpload: "invalid"}, + expectedResult: 0, + expectedError: errors.Wrap(errors.New("strconv.Atoi: parsing \"invalid\": invalid syntax"), "failed to parse ParallelFilesUpload config"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result, err := GetParallelFilesUpload(test.uploaderCfg) + + if result != test.expectedResult { + t.Errorf("Expected result %d, but got %d", test.expectedResult, result) + } + + if (err == nil && test.expectedError != nil) || (err != nil && test.expectedError == nil) || (err != nil && test.expectedError != nil && err.Error() != test.expectedError.Error()) { + t.Errorf("Expected error '%v', but got '%v'", test.expectedError, err) + } + }) + } +} + +func TestGetWriteSparseFiles(t *testing.T) { + tests := []struct { + name string + uploaderCfg map[string]string + expectedResult bool + expectedError error + }{ + { + name: "Valid WriteSparseFiles (true)", + uploaderCfg: map[string]string{writeSparseFiles: "true"}, + expectedResult: true, + expectedError: nil, + }, + { + name: "Valid WriteSparseFiles (false)", + uploaderCfg: map[string]string{writeSparseFiles: "false"}, + expectedResult: false, + expectedError: nil, + }, + { + name: "Invalid WriteSparseFiles (not a boolean)", + uploaderCfg: map[string]string{writeSparseFiles: "invalid"}, + expectedResult: false, + expectedError: errors.Wrap(errors.New("strconv.ParseBool: parsing \"invalid\": invalid syntax"), "failed to parse WriteSparseFiles config"), + }, + { + name: "Missing WriteSparseFiles", + uploaderCfg: map[string]string{}, + expectedResult: false, + expectedError: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result, err := GetWriteSparseFiles(test.uploaderCfg) + + if result != test.expectedResult { + t.Errorf("Expected result %t, but got %t", test.expectedResult, result) + } + + if (err == nil && test.expectedError != nil) || (err != nil && test.expectedError == nil) || (err != nil && test.expectedError != nil && err.Error() != test.expectedError.Error()) { + t.Errorf("Expected error '%v', but got '%v'", test.expectedError, err) + } + }) + } +} diff --git a/pkg/util/uploaderconfig/uploaderconfig.go b/pkg/util/uploaderconfig/uploaderconfig.go deleted file mode 100644 index fdd6d67ef..000000000 --- a/pkg/util/uploaderconfig/uploaderconfig.go +++ /dev/null @@ -1,50 +0,0 @@ -package uploaderconfig - -import ( - "strconv" - - "github.com/pkg/errors" - - velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" -) - -const ( - parallelFilesUpload = "ParallelFilesUpload" - writeSparseFiles = "WriteSparseFiles" -) - -func StoreBackupConfig(config *velerov1api.UploaderConfigForBackup) *map[string]string { - data := make(map[string]string) - data[parallelFilesUpload] = strconv.Itoa(config.ParallelFilesUpload) - return &data -} - -func StoreRestoreConfig(config *velerov1api.UploaderConfigForRestore) *map[string]string { - data := make(map[string]string) - data[writeSparseFiles] = strconv.FormatBool(config.WriteSparseFiles) - return &data -} - -func GetBackupConfig(data *map[string]string) (velerov1api.UploaderConfigForBackup, error) { - config := velerov1api.UploaderConfigForBackup{} - var err error - if item, ok := (*data)[parallelFilesUpload]; ok { - config.ParallelFilesUpload, err = strconv.Atoi(item) - if err != nil { - return velerov1api.UploaderConfigForBackup{}, errors.Wrap(err, "failed to parse ParallelFilesUpload") - } - } - return config, nil -} - -func GetRestoreConfig(data *map[string]string) (velerov1api.UploaderConfigForRestore, error) { - config := velerov1api.UploaderConfigForRestore{} - var err error - if item, ok := (*data)[writeSparseFiles]; ok { - config.WriteSparseFiles, err = strconv.ParseBool(item) - if err != nil { - return velerov1api.UploaderConfigForRestore{}, errors.Wrap(err, "failed to parse WriteSparseFiles") - } - } - return config, nil -} diff --git a/pkg/util/uploaderconfig/uploaderconfig_test.go b/pkg/util/uploaderconfig/uploaderconfig_test.go deleted file mode 100644 index 85ab2ec32..000000000 --- a/pkg/util/uploaderconfig/uploaderconfig_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package uploaderconfig - -import ( - "reflect" - "strings" - "testing" - - velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" -) - -func TestStoreBackupConfig(t *testing.T) { - config := &velerov1api.UploaderConfigForBackup{ - ParallelFilesUpload: 3, - } - - expectedData := map[string]string{ - parallelFilesUpload: "3", - } - - result := StoreBackupConfig(config) - - if !reflect.DeepEqual(*result, expectedData) { - t.Errorf("Expected: %v, but got: %v", expectedData, *result) - } -} - -func TestStoreRestoreConfig(t *testing.T) { - config := &velerov1api.UploaderConfigForRestore{ - WriteSparseFiles: true, - } - - expectedData := map[string]string{ - writeSparseFiles: "true", - } - - result := StoreRestoreConfig(config) - - if !reflect.DeepEqual(*result, expectedData) { - t.Errorf("Expected: %v, but got: %v", expectedData, *result) - } -} - -func TestGetBackupConfig(t *testing.T) { - data := &map[string]string{ - parallelFilesUpload: "3", - } - - expectedConfig := velerov1api.UploaderConfigForBackup{ - ParallelFilesUpload: 3, - } - - result, err := GetBackupConfig(data) - - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if !reflect.DeepEqual(result, expectedConfig) { - t.Errorf("Expected: %v, but got: %v", expectedConfig, result) - } - - // Test error case - (*data)[parallelFilesUpload] = "invalid" - _, err = GetBackupConfig(data) - if !strings.Contains(err.Error(), "failed to parse ParallelFilesUpload") { - t.Errorf("Expected error message containing 'failed to parse ParallelFilesUpload', but got: %v", err) - } -} - -func TestGetRestoreConfig(t *testing.T) { - data := &map[string]string{ - writeSparseFiles: "true", - } - - expectedConfig := velerov1api.UploaderConfigForRestore{ - WriteSparseFiles: true, - } - - result, err := GetRestoreConfig(data) - - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if !reflect.DeepEqual(result, expectedConfig) { - t.Errorf("Expected: %v, but got: %v", expectedConfig, result) - } - - // Test error case - (*data)[writeSparseFiles] = "invalid" - _, err = GetRestoreConfig(data) - if !strings.Contains(err.Error(), "failed to parse WriteSparseFiles") { - t.Errorf("Expected error message containing 'failed to parse WriteSparseFiles', but got: %v", err) - } -}